Apr 21, 8-9 PM (37)
Apr 21, 9-10 PM (14)
Apr 21, 10-11 PM (34)
Apr 21, 11-12 AM (12)
Apr 22, 12-1 AM (2)
Apr 22, 1-2 AM (3)
Apr 22, 2-3 AM (3)
Apr 22, 3-4 AM (4)
Apr 22, 4-5 AM (3)
Apr 22, 5-6 AM (17)
Apr 22, 6-7 AM (34)
Apr 22, 7-8 AM (21)
Apr 22, 8-9 AM (37)
Apr 22, 9-10 AM (18)
Apr 22, 10-11 AM (47)
Apr 22, 11-12 PM (45)
Apr 22, 12-1 PM (56)
Apr 22, 1-2 PM (64)
Apr 22, 2-3 PM (44)
Apr 22, 3-4 PM (86)
Apr 22, 4-5 PM (46)
Apr 22, 5-6 PM (17)
Apr 22, 6-7 PM (10)
Apr 22, 7-8 PM (18)
Apr 22, 8-9 PM (15)
Apr 22, 9-10 PM (23)
Apr 22, 10-11 PM (31)
Apr 22, 11-12 AM (17)
Apr 23, 12-1 AM (7)
Apr 23, 1-2 AM (4)
Apr 23, 2-3 AM (4)
Apr 23, 3-4 AM (6)
Apr 23, 4-5 AM (3)
Apr 23, 5-6 AM (8)
Apr 23, 6-7 AM (17)
Apr 23, 7-8 AM (26)
Apr 23, 8-9 AM (33)
Apr 23, 9-10 AM (33)
Apr 23, 10-11 AM (29)
Apr 23, 11-12 PM (30)
Apr 23, 12-1 PM (51)
Apr 23, 1-2 PM (69)
Apr 23, 2-3 PM (74)
Apr 23, 3-4 PM (26)
Apr 23, 4-5 PM (22)
Apr 23, 5-6 PM (7)
Apr 23, 6-7 PM (7)
Apr 23, 7-8 PM (11)
Apr 23, 8-9 PM (14)
Apr 23, 9-10 PM (6)
Apr 23, 10-11 PM (28)
Apr 23, 11-12 AM (18)
Apr 24, 12-1 AM (7)
Apr 24, 1-2 AM (4)
Apr 24, 2-3 AM (7)
Apr 24, 3-4 AM (5)
Apr 24, 4-5 AM (8)
Apr 24, 5-6 AM (13)
Apr 24, 6-7 AM (12)
Apr 24, 7-8 AM (33)
Apr 24, 8-9 AM (40)
Apr 24, 9-10 AM (41)
Apr 24, 10-11 AM (72)
Apr 24, 11-12 PM (57)
Apr 24, 12-1 PM (100)
Apr 24, 1-2 PM (57)
Apr 24, 2-3 PM (35)
Apr 24, 3-4 PM (19)
Apr 24, 4-5 PM (16)
Apr 24, 5-6 PM (38)
Apr 24, 6-7 PM (27)
Apr 24, 7-8 PM (12)
Apr 24, 8-9 PM (42)
Apr 24, 9-10 PM (17)
Apr 24, 10-11 PM (30)
Apr 24, 11-12 AM (16)
Apr 25, 12-1 AM (8)
Apr 25, 1-2 AM (1)
Apr 25, 2-3 AM (10)
Apr 25, 3-4 AM (5)
Apr 25, 4-5 AM (3)
Apr 25, 5-6 AM (13)
Apr 25, 6-7 AM (1)
Apr 25, 7-8 AM (4)
Apr 25, 8-9 AM (24)
Apr 25, 9-10 AM (17)
Apr 25, 10-11 AM (4)
Apr 25, 11-12 PM (4)
Apr 25, 12-1 PM (13)
Apr 25, 1-2 PM (3)
Apr 25, 2-3 PM (10)
Apr 25, 3-4 PM (6)
Apr 25, 4-5 PM (10)
Apr 25, 5-6 PM (16)
Apr 25, 6-7 PM (13)
Apr 25, 7-8 PM (30)
Apr 25, 8-9 PM (55)
Apr 25, 9-10 PM (13)
Apr 25, 10-11 PM (21)
Apr 25, 11-12 AM (22)
Apr 26, 12-1 AM (5)
Apr 26, 1-2 AM (0)
Apr 26, 2-3 AM (2)
Apr 26, 3-4 AM (5)
Apr 26, 4-5 AM (2)
Apr 26, 5-6 AM (2)
Apr 26, 6-7 AM (3)
Apr 26, 7-8 AM (8)
Apr 26, 8-9 AM (3)
Apr 26, 9-10 AM (0)
Apr 26, 10-11 AM (2)
Apr 26, 11-12 PM (1)
Apr 26, 12-1 PM (6)
Apr 26, 1-2 PM (4)
Apr 26, 2-3 PM (14)
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 (51)
Apr 27, 3-4 PM (39)
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 (15)
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 (36)
Apr 28, 8-9 AM (54)
Apr 28, 9-10 AM (58)
Apr 28, 10-11 AM (49)
Apr 28, 11-12 PM (56)
Apr 28, 12-1 PM (48)
Apr 28, 1-2 PM (53)
Apr 28, 2-3 PM (68)
Apr 28, 3-4 PM (31)
Apr 28, 4-5 PM (13)
Apr 28, 5-6 PM (47)
Apr 28, 6-7 PM (9)
Apr 28, 7-8 PM (2)
Apr 28, 8-9 PM (0)
3,805 commits this week Apr 21, 2026 - Apr 28, 2026
docs(skills): drop stale AShard/EpochEndAccumulate references
The `crates/cardano/src/ashard/` module was merged into
`crates/cardano/src/ewrap/` (it became EWRAP's per-shard leg) and the
`EpochEndAccumulate` delta was renamed to `EWrapProgress`. The debug
guide's tables, narrative, file-path references, and instrumentation
hints still pointed at the old names and paths.

Updates the Step 3 classification table, Step 5 work-unit narrative +
source-file map, and Step 6 instrumentation table to:
- talk about EWRAP/ESTART each having a per-shard leg + finalize, not
  a separate ASHARD work unit;
- point at `ewrap/rewards.rs`, `crates/cardano/src/shard.rs`, and the
  per-unit `work_unit.rs` files;
- reference `EWrapProgress` (not `EpochEndAccumulate`) and the
  `EpochWrapUpV2` / `EpochTransitionV2` deltas where boundary close /
  open is described.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
chore(cardano): clear clippy warnings
- shard.rs: const-context divisibility check now uses
  `u32::is_multiple_of` (stable-const since Rust 1.87) per
  `clippy::manual_is_multiple_of`.
- model/epochs.rs: replace `let mut x = T::default(); x.f = ...; x` with
  a struct-literal `..Default::default()` form per
  `clippy::field_reassign_with_default`; also demote a doc comment
  attached to a `prop_compose!` invocation to a regular `//` comment
  (rustdoc can't attach docs to macro invocations).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
chore(cardano): housekeeping fixes from PR review
- genesis/mod.rs: fix copy/paste typo "Ewrap (which now runs before
  Ewrap)" → "per-shard Ewrap pass (which runs before the global Ewrap
  finalize)" (PR #978 comment 3154574432).
- work_units.md: add `text` language to fenced sequence diagram block
  for markdownlint MD040 (3153861508); fix stale loader name
  `BoundaryWork::load_ewrap` → `load_finalize` (3153861515).
- tests/memory.rs: sample heap allocation across full iteration as well
  as iterator construction, so a backend that buffers the shard on first
  `next()` no longer slips through (3153861530).
- model/epochs.rs: hoist `#[allow(deprecated)]` from per-item attributes
  on the prop_compose!/test items (where the macro hides the lint site)
  to the whole `prop_tests` module — silences the test-build deprecation
  warnings introduced by the V1/V2 split.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fix(cardano): assert shard invariants in release builds
`shard_key_ranges` previously guarded `total_shards` and `shard_index`
with `debug_assert!`, which compiles to nothing in release. A `0` would
divide by zero in `variant_range`, and a non-divisor of 256 would
silently produce broken partitions. Since `total_shards` can come from
persisted `ShardProgress.total` (not just the compile-time
`ACCOUNT_SHARDS` constant), the invariants must hold at runtime in all
profiles.

Promotes the validation to unconditional `assert!` / `panic!` with
informative messages.

Addresses PR #978 review comment 3153861503.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fix(cardano): refresh ending_state before archive write in ewrap finalize
`commit_finalize` was archiving `self.ending_state()` at the epoch-start
temporal key, but `stream_and_apply_namespace::<D, EpochState>` only
applied the boundary-closing deltas (PParamsUpdate, TreasuryWithdrawal,
EpochWrapUp) to the writer — `ending_state` itself was never refreshed.
The archived row therefore carried the pre-commit snapshot (stale
rolling/pparams, populated `ewrap_progress`).

Adds an EpochState-specific variant of the streaming helper that
returns the post-apply singleton; `commit_finalize` swaps the result
into `self.ending_state` before the archive write, so the archived
EpochState matches what's about to be committed to the live state
store.

Addresses PR #978 review comment 3153861497.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fix(cardano): resume sharded work units at committed shard cursor
Previously, `EwrapWorkUnit` / `EstartWorkUnit` / `RupdWorkUnit::initialize`
read only `*_progress.total` from persisted state and the core lifecycle
loop iterated `0..total_shards` unconditionally, so a crash mid-boundary
replayed shards `0..k-1` on restart. That is unsafe: `AccountTransition`
deltas (Estart) are non-idempotent — replaying a committed shard would
double-rotate every account in it.

Adds `WorkUnit::start_shard()` (defaulting to `0`); `run_lifecycle` now
loops `start_shard..total_shards`. The three sharded work units cache
the committed cursor in `initialize` from `*_progress.committed`, and
their `start_shard()` returns it. `CardanoWorkUnit` delegates the new
method to its variants. The bootstrap test harness mirrors the real
runner.

Also propagates `load_epoch` failures via `?` instead of the previous
`Err(_) => ACCOUNT_SHARDS` swallow, so a state-read failure can no
longer silently repartition an in-flight boundary.

Addresses PR #978 review comments 3153861491 (restart cursor) and
3154574387 (propagate load_epoch failures).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
asteria-stub: minimal test-composer host for property experimentation
New `components/asteria-stub/` ships a tiny Debian image with
cardano-cli (+ liblmdb0 runtime), jq, and bash. Its only job is to
host composer scripts at `/opt/antithesis/test/v1/stub/`:

  - parallel_driver_heartbeat.sh — short tick, emits Sometimes
  - eventually_alive.sh         — post-fault: pings p1/p2/p3, Always
  - finally_alive.sh            — post-workload: pings p1/p2/p3, Always

The container itself just `sleep infinity`s. This is intentional:
the stub is the experimentation harness for evolving property checks
before touching the real asteria-player. Real game logic stays in
PR #67's `components/asteria-player/`.

Conventions adopted from the working sidecar template:
  - cardano-cli ping uses `-j --magic 42 --host X --port Y --tip
    --quiet -c1`. Without `-j --tip` the cli has no query target and
    exits non-zero.
  - SDK output goes to /tmp/sdk.jsonl (default path) on a tmpfs
    mount; Antithesis introspects that path. A named-volume
    convention (e.g. ANTITHESIS_OUTPUT_DIR=/sdk) is not picked up.
  - liblmdb0 must be apt-installed; cardano-cli loads liblmdb.so.0
    at start regardless of subcommand.

On failure, eventually_alive / finally_alive emit a self-classifying
JSON detail with the failing host, exit code, and the cardano-cli
stderr — so the next failure self-diagnoses without another round
trip.

Image referenced by content digest in
testnets/cardano_node_master/docker-compose.yaml; the publish-images
workflow builds and pushes both `:asteria-stub-v3` and
`:<full-commit>` on PR. Bootstrap relied on a paired git tag so the
script could resolve the friendly name back to a commit; once
merged, the digest pin is the only contract.
refactor(cardano): version EpochWrapUp/EpochTransition for WAL compat
Bincode encodes CardanoDelta variants by positional index and structs by
positional fields, so this branch's three new variants (EWrapProgress,
EStartProgress, RupdProgress) inserted mid-enum and the appended `prev_*_progress`
fields on EpochWrapUp / EpochTransition would have made pre-upgrade WAL
rows undecodable.

Freezes CardanoDelta indices 0..=38 to match pre-PR `main`, restores the
legacy struct shapes verbatim under `#[deprecated]`, and introduces
EpochWrapUpV2 / EpochTransitionV2 carrying the new undo state. The three
sharded-progress variants plus the V2 variants are appended at the end
of the enum. New commit paths in estart/reset.rs and ewrap/wrapup.rs
emit V2; the legacy types remain solely for replay of older WAL rows
and carry TODO(wal-compat) cleanup notes.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>