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 (67)
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 (32)
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 (27)
May 02, 5-6 PM (9)
May 02, 6-7 PM (29)
May 02, 7-8 PM (11)
May 02, 8-9 PM (14)
May 02, 9-10 PM (1)
May 02, 10-11 PM (20)
May 02, 11-12 AM (18)
May 03, 12-1 AM (8)
May 03, 1-2 AM (1)
May 03, 2-3 AM (4)
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 (10)
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 (2)
May 03, 4-5 PM (5)
May 03, 5-6 PM (0)
May 03, 6-7 PM (5)
May 03, 7-8 PM (6)
May 03, 8-9 PM (8)
May 03, 9-10 PM (15)
May 03, 10-11 PM (23)
May 03, 11-12 AM (16)
May 04, 12-1 AM (4)
May 04, 1-2 AM (4)
May 04, 2-3 AM (10)
May 04, 3-4 AM (9)
May 04, 4-5 AM (5)
May 04, 5-6 AM (6)
May 04, 6-7 AM (5)
May 04, 7-8 AM (28)
May 04, 8-9 AM (24)
May 04, 9-10 AM (43)
May 04, 10-11 AM (34)
May 04, 11-12 PM (61)
May 04, 12-1 PM (34)
May 04, 1-2 PM (47)
May 04, 2-3 PM (60)
May 04, 3-4 PM (26)
May 04, 4-5 PM (6)
3,614 commits this week Apr 27, 2026 - May 04, 2026
chore(deps): bump github.com/blinklabs-io/gouroboros
Bumps [github.com/blinklabs-io/gouroboros](https://github.com/blinklabs-io/gouroboros) from 0.153.1 to 0.166.1.
- [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.153.1...v0.166.1)

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

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump github.com/fxamacker/cbor/v2 from 2.9.0 to 2.9.2
Bumps [github.com/fxamacker/cbor/v2](https://github.com/fxamacker/cbor) from 2.9.0 to 2.9.2.
- [Release notes](https://github.com/fxamacker/cbor/releases)
- [Commits](https://github.com/fxamacker/cbor/compare/v2.9.0...v2.9.2)

---
updated-dependencies:
- dependency-name: github.com/fxamacker/cbor/v2
  dependency-version: 2.9.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump the actions-deps group with 4 updates
Bumps the actions-deps group with 4 updates: [step-security/harden-runner](https://github.com/step-security/harden-runner), [sbt/setup-sbt](https://github.com/sbt/setup-sbt), [oasdiff/oasdiff-action](https://github.com/oasdiff/oasdiff-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `step-security/harden-runner` from 2.19.0 to 2.19.1
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/8d3c67de8e2fe68ef647c8db1e6a09f647780f40...a5ad31d6a139d249332a2605b85202e8c0b78450)

Updates `sbt/setup-sbt` from 1.1.22 to 1.1.23
- [Release notes](https://github.com/sbt/setup-sbt/releases)
- [Commits](https://github.com/sbt/setup-sbt/compare/508b753e53cb6095967669e0911487d2b9bc9f41...93e926cbdb4a428e41b4ef754124ec82925ffdc2)

Updates `oasdiff/oasdiff-action` from 0.0.43 to 0.0.45
- [Release notes](https://github.com/oasdiff/oasdiff-action/releases)
- [Commits](https://github.com/oasdiff/oasdiff-action/compare/c002f996c3d084acf62ea6dd4f2e7a57b7bc2a35...e7609f171f253c3e2be2a2e5c508f749ca476a07)

Updates `github/codeql-action` from 4.35.2 to 4.35.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...e46ed2cbd01164d986452f91f178727624ae40d7)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: sbt/setup-sbt
  dependency-version: 1.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: oasdiff/oasdiff-action
  dependency-version: 0.0.45
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: github/codeql-action
  dependency-version: 4.35.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
...

Signed-off-by: dependabot[bot] <[email protected]>
Add protoc build-tool for cardano-node 10.7.x (proto-lens, cardano-rpc)
cardano-node 10.7.x's ouroboros-consensus pulls in proto-lens-protobuf-types
and a new cardano-rpc package, both of which invoke protoc at build time
through proto-lens-setup's custom Setup.hs.  Without protoc on PATH the
build fails with 'couldn't find the executable protoc'.

The pre-release pkg already had this for proto-lens-protobuf-types since
commit f8709bd; now mirror it in the stable pkg (post-10.6.4 → 10.7.1
bump) and add cardano-rpc to both.
refactor(validate): extract phase2 evaluator and surface failure context
Move the amaru-uplc invocation out of `tx.rs` into a dedicated
`phase2::evaluator` module exposing `eval_script` -> `ScriptEvalResult`.
This isolates the script-evaluation surface from the rest of phase-two
plumbing and makes it directly testable.

Promote machine failures from a silently-discarded `Err` on
`result.term` into structured data: `MachineFailure { message, budget,
logs }` is propagated up and surfaced on `TxEvalResult` via a new
`failure_message: Option<String>` field. Previously a failing script
would yield `success: false` with no diagnostic; callers now receive
the evaluator's error message and the same line is emitted at debug
level via `tracing`.

Restructure `Error::Machine` from an opaque tuple wrapping the
arena-borrowed `MachineError` into a `{ message, budget, logs }` struct
with a clean `Display` impl backed by free `format_machine_traces` and
`indent_trace` helpers. The previous variant could never actually be
constructed (the arena lifetime didn't permit it) and was dead.

Drop the `* 11 / 10` budget inflation hack in `tx.rs` — the evaluator's
reported `consumed_budget` is now passed through verbatim. Callers
that relied on the old margin will see slightly lower numbers.

Add unit tests in `evaluator.rs` covering: CBOR decode failure typing,
flat decode failure typing, machine failure capturing logs and a
non-empty message, V2 application order (datum -> redeemer -> context),
V2 with missing datum, and a regression test confirming `serialiseData`
on V3 evaluates without panicking.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
chore(testnet): align cardano_node_adversary pins to origin/main master
Pulls in master's current shared-image versions:
- sidecar:1ff6913       (post legacy-probe delete, #119)
- tracer-sidecar:5271661 (fork-tree probe build)
- configurator + log-tailer + tracer + cardano-node digests already match
- tx-generator from master is intentionally not added — adversary
  testnet runs nodes only

The adversary container itself stays pinned to its own SHA
(adversary:b75cfe3) since master has no adversary equivalent.

Layer 3 of #123 (perturbation metric emit from finally_tips_agree.sh)
is dropped: that script was deleted on main by #119, the cluster-wide
"did the cluster fork" oracle now lives in tracer-sidecar's fork-tree
probe. Re-implementing the perturbation metric on top of that surface
is a follow-up.
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.
asteria-game: widen liveness probe budget to absorb cold-restart
eventually_alive.sh / finally_alive.sh were exiting 1 in timelines
where Antithesis had killed the asteria-game container as a node
fault and the eventually_ check fired ~520ms after the container
respawned. The indexer's first-boot reconnect goes through
node-replaying with exponential backoff (1s, 2s, 4s, 8s, 16s … ≈
13 s by attempt 7) plus the N2C handshake and first-block write —
roughly 30-40s before tipSlot becomes non-null. The old 25 s budget
(15 s settle + 5×2 s retries) collided with that cold-start.

Bump SLEEP_SETTLE 15->30 and MAX_ATTEMPTS 5->15 in both scripts:
60 s budget. The probes still complete in well under the
post-fault window, and the script's contract ("indexer is at chain
tip within budget") is unchanged.

Investigation: see the failing example at vtime 132.9s on
b5698f4 — fault_injector logs show
  93.33  FAULT kill node target=["asteria-game"] dur=12.88
 107.26  containers_meta init+start asteria-game
 107.78  composer fires stub/eventually_alive.sh
 132.89  attempts_exhausted=5 last_reply.tipSlot=null
fix(client): avoid error if unpack thread closed before the sender thread
Archives unpacker that can know when a uncompression finished by locking
at the bytes, finishing immediatly.
In that case a race condition can occurs if the sender thread, that
reads the bytes from the remote location, do a last loop who will read 0
bytes, then `sender.send_async(..)` returns an "sending on a closed
channel" error.