Apr 26, 3-4 PM (14)
Apr 26, 4-5 PM (0)
Apr 26, 5-6 PM (13)
Apr 26, 6-7 PM (13)
Apr 26, 7-8 PM (7)
Apr 26, 8-9 PM (7)
Apr 26, 9-10 PM (5)
Apr 26, 10-11 PM (27)
Apr 26, 11-12 AM (21)
Apr 27, 12-1 AM (7)
Apr 27, 1-2 AM (7)
Apr 27, 2-3 AM (9)
Apr 27, 3-4 AM (9)
Apr 27, 4-5 AM (5)
Apr 27, 5-6 AM (13)
Apr 27, 6-7 AM (7)
Apr 27, 7-8 AM (82)
Apr 27, 8-9 AM (47)
Apr 27, 9-10 AM (33)
Apr 27, 10-11 AM (62)
Apr 27, 11-12 PM (80)
Apr 27, 12-1 PM (66)
Apr 27, 1-2 PM (44)
Apr 27, 2-3 PM (52)
Apr 27, 3-4 PM (42)
Apr 27, 4-5 PM (36)
Apr 27, 5-6 PM (26)
Apr 27, 6-7 PM (13)
Apr 27, 7-8 PM (26)
Apr 27, 8-9 PM (13)
Apr 27, 9-10 PM (16)
Apr 27, 10-11 PM (42)
Apr 27, 11-12 AM (28)
Apr 28, 12-1 AM (17)
Apr 28, 1-2 AM (8)
Apr 28, 2-3 AM (4)
Apr 28, 3-4 AM (5)
Apr 28, 4-5 AM (5)
Apr 28, 5-6 AM (8)
Apr 28, 6-7 AM (8)
Apr 28, 7-8 AM (37)
Apr 28, 8-9 AM (54)
Apr 28, 9-10 AM (59)
Apr 28, 10-11 AM (53)
Apr 28, 11-12 PM (56)
Apr 28, 12-1 PM (49)
Apr 28, 1-2 PM (54)
Apr 28, 2-3 PM (69)
Apr 28, 3-4 PM (31)
Apr 28, 4-5 PM (14)
Apr 28, 5-6 PM (47)
Apr 28, 6-7 PM (9)
Apr 28, 7-8 PM (9)
Apr 28, 8-9 PM (14)
Apr 28, 9-10 PM (20)
Apr 28, 10-11 PM (34)
Apr 28, 11-12 AM (29)
Apr 29, 12-1 AM (13)
Apr 29, 1-2 AM (1)
Apr 29, 2-3 AM (1)
Apr 29, 3-4 AM (6)
Apr 29, 4-5 AM (1)
Apr 29, 5-6 AM (4)
Apr 29, 6-7 AM (12)
Apr 29, 7-8 AM (45)
Apr 29, 8-9 AM (75)
Apr 29, 9-10 AM (49)
Apr 29, 10-11 AM (28)
Apr 29, 11-12 PM (51)
Apr 29, 12-1 PM (39)
Apr 29, 1-2 PM (21)
Apr 29, 2-3 PM (66)
Apr 29, 3-4 PM (25)
Apr 29, 4-5 PM (36)
Apr 29, 5-6 PM (16)
Apr 29, 6-7 PM (10)
Apr 29, 7-8 PM (14)
Apr 29, 8-9 PM (13)
Apr 29, 9-10 PM (17)
Apr 29, 10-11 PM (25)
Apr 29, 11-12 AM (29)
Apr 30, 12-1 AM (6)
Apr 30, 1-2 AM (8)
Apr 30, 2-3 AM (1)
Apr 30, 3-4 AM (6)
Apr 30, 4-5 AM (2)
Apr 30, 5-6 AM (8)
Apr 30, 6-7 AM (15)
Apr 30, 7-8 AM (17)
Apr 30, 8-9 AM (100)
Apr 30, 9-10 AM (19)
Apr 30, 10-11 AM (50)
Apr 30, 11-12 PM (120)
Apr 30, 12-1 PM (69)
Apr 30, 1-2 PM (45)
Apr 30, 2-3 PM (117)
Apr 30, 3-4 PM (29)
Apr 30, 4-5 PM (34)
Apr 30, 5-6 PM (9)
Apr 30, 6-7 PM (20)
Apr 30, 7-8 PM (23)
Apr 30, 8-9 PM (28)
Apr 30, 9-10 PM (13)
Apr 30, 10-11 PM (25)
Apr 30, 11-12 AM (15)
May 01, 12-1 AM (18)
May 01, 1-2 AM (15)
May 01, 2-3 AM (6)
May 01, 3-4 AM (7)
May 01, 4-5 AM (3)
May 01, 5-6 AM (5)
May 01, 6-7 AM (8)
May 01, 7-8 AM (13)
May 01, 8-9 AM (24)
May 01, 9-10 AM (16)
May 01, 10-11 AM (16)
May 01, 11-12 PM (17)
May 01, 12-1 PM (39)
May 01, 1-2 PM (30)
May 01, 2-3 PM (19)
May 01, 3-4 PM (16)
May 01, 4-5 PM (25)
May 01, 5-6 PM (11)
May 01, 6-7 PM (20)
May 01, 7-8 PM (22)
May 01, 8-9 PM (65)
May 01, 9-10 PM (15)
May 01, 10-11 PM (40)
May 01, 11-12 AM (61)
May 02, 12-1 AM (6)
May 02, 1-2 AM (11)
May 02, 2-3 AM (5)
May 02, 3-4 AM (8)
May 02, 4-5 AM (6)
May 02, 5-6 AM (2)
May 02, 6-7 AM (2)
May 02, 7-8 AM (14)
May 02, 8-9 AM (7)
May 02, 9-10 AM (8)
May 02, 10-11 AM (11)
May 02, 11-12 PM (7)
May 02, 12-1 PM (7)
May 02, 1-2 PM (3)
May 02, 2-3 PM (14)
May 02, 3-4 PM (9)
May 02, 4-5 PM (26)
May 02, 5-6 PM (8)
May 02, 6-7 PM (29)
May 02, 7-8 PM (11)
May 02, 8-9 PM (14)
May 02, 9-10 PM (0)
May 02, 10-11 PM (20)
May 02, 11-12 AM (17)
May 03, 12-1 AM (8)
May 03, 1-2 AM (1)
May 03, 2-3 AM (3)
May 03, 3-4 AM (7)
May 03, 4-5 AM (1)
May 03, 5-6 AM (4)
May 03, 6-7 AM (32)
May 03, 7-8 AM (5)
May 03, 8-9 AM (1)
May 03, 9-10 AM (3)
May 03, 10-11 AM (9)
May 03, 11-12 PM (11)
May 03, 12-1 PM (16)
May 03, 1-2 PM (11)
May 03, 2-3 PM (2)
May 03, 3-4 PM (1)
3,802 commits this week Apr 26, 2026 - May 03, 2026
chore(deps): bump github.com/blinklabs-io/gouroboros (#694)
Bumps [github.com/blinklabs-io/gouroboros](https://github.com/blinklabs-io/gouroboros) from 0.163.4 to 0.166.0.
- [Release notes](https://github.com/blinklabs-io/gouroboros/releases)
- [Changelog](https://github.com/blinklabs-io/gouroboros/blob/main/RELEASE_NOTES.md)
- [Commits](https://github.com/blinklabs-io/gouroboros/compare/v0.163.4...v0.166.0)

---
updated-dependencies:
- dependency-name: github.com/blinklabs-io/gouroboros
  dependency-version: 0.166.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
chore(deps): bump webiny/action-conventional-commits from 1.3.1 to 1.4.2 (#695)
Bumps [webiny/action-conventional-commits](https://github.com/webiny/action-conventional-commits) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/webiny/action-conventional-commits/releases)
- [Commits](https://github.com/webiny/action-conventional-commits/compare/faccb24fc2550dd15c0390d944379d2d8ed9690e...7f91b1595ca1951cdb671ddc9f07a49081ec5b69)

---
updated-dependencies:
- dependency-name: webiny/action-conventional-commits
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
chore(deps): Bump webiny/action-conventional-commits from 1.3.1 to 1.4.2 (#319)
Bumps [webiny/action-conventional-commits](https://github.com/webiny/action-conventional-commits) from 1.3.1 to 1.4.2.
- [Commits](https://github.com/webiny/action-conventional-commits/compare/v1.3.1...v1.4.2)

---
updated-dependencies:
- dependency-name: webiny/action-conventional-commits
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
tracer-sidecar: accept newer node trace field names
cardano-node 10.7+ ships two breaking changes to the
ChainDB.AddBlockEvent JSON payload that silently dropped
events from any node running a newer version:

  - 'newTipSelectView' renamed to 'newSuffixSelectView'
    (and 'oldTipSelectView' to 'oldSuffixSelectView')
  - inside that view, 'chainLength' renamed to 'blockNo' and
    'kind' changed from 'PraosChainSelectView' to
    'PraosTiebreakerView' (with an extra 'weightBoost' field)

The master testnet pins three different cardano-node images
spanning both schemas.  Before this fix, only the older p1
image was decoded; p2 and p3's events failed FromJSON and
were silently skipped, leaving tracer-sidecar with a
single-host view of the cluster.

Both old and new field names are now accepted (case
fallthrough on .:?).  No semantic change for older nodes.

This was already the right fix on its own merits, and is a
strict prerequisite for the #119 fork-tree probe (which
needs at least two hosts to ever report a non-zero cluster
fork depth).
tracer-sidecar: add pure ForkTree module + tests
ForkTreeState tracks per-host current tips and a global
parent map. Edges are recorded on AddedToCurrentChain
(producer's own extension always captures the true parent);
SwitchedToAFork only updates the host's tip without
recording an edge.

clusterForkDepth = max(tip.chainLength) - commonAncestor.chainLength,
where commonAncestor walks each host's ancestry back (capped
at maxDepth) and intersects to find the deepest shared block.

8 hspec unit tests cover: empty state, sequential extension,
agreement, 1-block fork, root-only common ancestor, deep 5-block
divergence, setTip without edge, depth-cap truncation.

Part of #119 — pure algebra commit; wiring + persistence in
follow-up commits on this branch.
tracer-sidecar: wire ForkTree into Spec (#119 step 3)
Adds cluster-wide fork-depth probe to the Spec:

- Extends State with forkTree, forkObserved, forkExceededK
- updateForkTree rule: parses AddedToCurrentChain /
  SwitchedToAFork into Tip records, feeds them to ForkTree
  (recordExtension / setTip), and updates the two derived
  flags
- Sometimes assertion 'cluster fork observed' fires once
  cluster fork depth has been > 0 — proves fault injection
  drives the fork path
- AlwaysOrUnreachable assertion 'cluster fork depth < k'
  fires false the moment depth crosses k = 432

Golden output regenerated to include the two new
declarations.

Phase 1 of #119 (in-memory probe). Persistence (#119 step 4)
and master compose mount (step 5) follow.
chore(testnet): bump adversary + sidecar pins to b75cfe3 for #123 perturbation metrics
Pulls in:
- adversary:b75cfe3 — emits SDK assertions per attack with must_hit:true
  (was must_hit:false, which Antithesis classified as "Unreachability
  assertions → adversary_chain_sync_started NEW". Matching the existing
  helper_sdk_lib.sh convention fixes the registration.)
- sidecar:b75cfe3 — finally_tips_agree.sh emits finally_perturbation_metrics
  with blocks_produced_total and max_slot_lag

Both pins resolve to the post-fix sidecar feat commit so publish-images
rebuilds against the corrected SDK module + cabal build-depends.
feat(adversary): emit Antithesis SDK assertions to prove the attacker fired
Adds Adversary.SDK with Reachable / Sometimes assertion emitters that
write to \$ANTITHESIS_OUTPUT_DIR/sdk.jsonl (default /tmp/sdk.jsonl).
Wires two assertions into app/Main.hs:

  - reachable("adversary_chain_sync_started", {target_host, point, limit})
    fires once per invocation before connectToNode. Antithesis report
    will show, segmented by target_host, "the adversary fired against
    pN at least once". A host that never gets attacked is visible as
    a missing Reachable hit.

  - sometimes(true|false, "adversary_chain_sync_completed",
              {target_host, tip|reason})
    fires once per invocation on completion. true on clean exit,
    false on connect/protocol failure. Sometimes-true vs Sometimes-
    false buckets quantify how often the adversary actually completed
    a full --limit sync vs being cut short by chaos.

Layer 1 of three for issue #123.
feat(sidecar): emit blocks_total + max_slot_lag perturbation metrics from finally_tips_agree
Adds an emit_perturbation_metrics() helper to
components/sidecar/composer/convergence/finally_tips_agree.sh that, on
every run, computes:

  - blocks_produced_total : sum of producers' block heights at end-of-test
  - max_slot_lag          : max(slot) − min(slot) across producers

and emits them as a Sometimes(true) "finally_perturbation_metrics" event
with both numbers in details. The Antithesis report's per-bucket
distribution view then shows the curve across runs without needing a
separate observer.

Slot lag is 0 on a perfectly synchronous cluster, mildly positive
under fault injection, large under attack pressure — gives us a
quantitative comparison for master vs adversary side-by-sides.

Layer 3 of three for issue #123.
feat(testnet): cardano_node_tx_generator iteration testnet for the Haskell tx-generator daemon
Rebases on current main (which now has the workflow inputs.test fix
e3b09a0 and the publish-images all-testnets glob 81f3bf1, so the
sibling publish workflow + script from earlier iterations of this
branch are dropped). Master-side files (testnets/cardano_node_master/,
scripts/, master workflows) are untouched.

Adds:

  * testnets/cardano_node_tx_generator/{docker-compose.yaml,
    testnet.yaml,relay-topology.json,tracer-config.yaml,README.md}
    — mirrors master's image set 1:1 (cardano-node x3 by digest,
    cardano-tracer by digest, configurator/log-tailer/tracer-sidecar
    by digest, sidecar:65039df) plus the tx-generator service
    active. Network name 'cardano-node-tx-generator-testnet' to
    avoid collision with master's network when both run on the
    same docker daemon.
  * components/tx-generator/flake.nix bumped to upstream
    711eb22ac03e67b753f7ce70e635cddcf6f3cdce — full
    reconnect-resilience stack: PR #105 (supervisor +
    BlockedIndefinitelyOnSTM catch), #110 (post-reconnect indexer
    freshness gate), #114 (pre-submit chain-tip probe), #115
    (refill duplicate-submit recovery), #116 (recovery-await timeout
    aligned with dcAwaitTimeoutSeconds), #117 (refill recovery-await
    timeout -> IndexNotReady), #118 (same recovery in transact arm).
  * Composer scripts hardened (set -u, always exit 0, lastTxId gate
    on did_not_grow).
  * docs/components/tx-generator.md — daemon architecture: composer-
    as-clock contract, deterministic per-request flow, single-bearer
    N2C topology with in-tree address-to-UTxO indexer, NDJSON wire
    schema with response classes, per-request build/probe/submit/
    recovery flow, reconnect-resilience PR stack, composer scripts
    convention, persistent state, assertion classes.
  * docs/testnets/cardano-node-tx-generator.md — testnet rationale,
    image-set parity table with master, dispatch invocations, ref to
    the repo-wide publish-images flow.
  * mkdocs.yml — Components and Testnets nav entries.

Verified clean on a 1h no-faults Antithesis dispatch:
findings_new=0, all tx_generator_*_landed assertions firing, no
tx_generator_*_submit_rejected. Compose tag in this commit is
PLACEHOLDER; the next commit on this branch sets it to this commit's
SHA so publish-images.sh can resolve it as a downstream commit ref.
fix(composer): hard 5s wall-clock on tx-generator nc -U calls
The faults-enabled 1h Antithesis run on cardano_node_tx_generator
(commit 12a80b8, session 95887c0ae21ed981bf9e85943bda257f-50-7,
report OOdYZcg__MdS4qqvkORdLTR-) flagged 2 driver-script findings:

  tx-generator/parallel_driver_refill.sh        command_runtime=25.78s
  tx-generator/eventually_population_grew.sh    command_runtime=24.54s

both with command_return_code=1 and empty stderr. Reading the
indexed log streams returns 0 events for these scripts' .err
streams — they didn't crash, they were killed by the composer's
per-step deadline while blocked inside 'nc -U' against the daemon's
control socket.

Likely path: under a specific fault window the daemon's accept loop
wedges (mid-reconnect / mid-deadlock during a network-partition or
node-pause event), 'nc -U -q 1' has no kernel-side timeout to bail
on, the composer wrapper's ~25s deadline fires, exit code propagates
as 1 — surfacing as a finding on the built-in 'Commands finish with
zero exit code' Always property.

Wrap each control-socket request in 'timeout --kill-after=2s 5s sh -c
"..."' so any blocked nc is bailed out within 5s + 2s SIGKILL grace,
the empty-RSP branch hits the 'tx_generator_*_daemon_unreachable'
Reachability marker, and the script exits 0. The underlying daemon
wedge is a separate ticket on the upstream cardano-node-clients repo
— this composer fix masks the symptom so the testnet baseline isn't
contaminated by it.
chore(deps): Bump pozil/auto-assign-issue from 2 to 3 (#444)
Bumps [pozil/auto-assign-issue](https://github.com/pozil/auto-assign-issue) from 2 to 3.
- [Release notes](https://github.com/pozil/auto-assign-issue/releases)
- [Commits](https://github.com/pozil/auto-assign-issue/compare/v2...v3)

---
updated-dependencies:
- dependency-name: pozil/auto-assign-issue
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
chore(deps): Bump webiny/action-conventional-commits from 1.3.1 to 1.4.2 (#445)
Bumps [webiny/action-conventional-commits](https://github.com/webiny/action-conventional-commits) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/webiny/action-conventional-commits/releases)
- [Commits](https://github.com/webiny/action-conventional-commits/compare/v1.3.1...v1.4.2)

---
updated-dependencies:
- dependency-name: webiny/action-conventional-commits
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>