Apr 20, 5-6 PM (31)
Apr 20, 6-7 PM (24)
Apr 20, 7-8 PM (10)
Apr 20, 8-9 PM (7)
Apr 20, 9-10 PM (16)
Apr 20, 10-11 PM (28)
Apr 20, 11-12 AM (18)
Apr 21, 12-1 AM (24)
Apr 21, 1-2 AM (5)
Apr 21, 2-3 AM (13)
Apr 21, 3-4 AM (4)
Apr 21, 4-5 AM (3)
Apr 21, 5-6 AM (8)
Apr 21, 6-7 AM (15)
Apr 21, 7-8 AM (44)
Apr 21, 8-9 AM (119)
Apr 21, 9-10 AM (36)
Apr 21, 10-11 AM (35)
Apr 21, 11-12 PM (98)
Apr 21, 12-1 PM (57)
Apr 21, 1-2 PM (71)
Apr 21, 2-3 PM (60)
Apr 21, 3-4 PM (33)
Apr 21, 4-5 PM (31)
Apr 21, 5-6 PM (27)
Apr 21, 6-7 PM (38)
Apr 21, 7-8 PM (35)
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 (65)
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 (12)
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 (4)
Apr 26, 10-11 PM (26)
Apr 26, 11-12 AM (21)
Apr 27, 12-1 AM (6)
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 (46)
Apr 27, 9-10 AM (29)
Apr 27, 10-11 AM (61)
Apr 27, 11-12 PM (78)
Apr 27, 12-1 PM (66)
Apr 27, 1-2 PM (44)
Apr 27, 2-3 PM (51)
Apr 27, 3-4 PM (38)
Apr 27, 4-5 PM (34)
Apr 27, 5-6 PM (2)
3,913 commits this week Apr 20, 2026 - Apr 27, 2026
asteria-stub iter 2: fix ping flag + SDK path; drop oura
Three changes against the b0fa4bb run findings:

1. cardano-cli ping needs --tip to have a query target. Without it
   the call exits non-zero and the retry loop in eventually_alive +
   finally_alive exhausts on every invocation (78 + 44 always-failing
   examples). Match the working form from sidecar's
   eventually_converged.sh: `ping -j --magic 42 ... --tip --quiet -c1`.

2. Replace asteria-stub's `ANTITHESIS_OUTPUT_DIR=/sdk` env + named
   volume with `tmpfs: - /tmp`. The named-volume path was not
   introspected by Antithesis — zero `stub *` SDK assertions showed
   up in the report even though 387 heartbeat invocations ran
   cleanly. The sidecar's default `/tmp` (via tmpfs mount) is the
   known-working convention.

3. Drop oura entirely (service + oura-daemon.toml). v1.9.4 panics
   under fault injection (exit 101 — 1 finding per run on average)
   and v2.0.0 was never pushed to ghcr. Not needed for the
   convergence + chain-sync property suite.

Image tag bumped v0 → v1 so publish-images rebuilds from this commit.
A follow-up will pin to digest after publish lands.
chore(deps): bump github.com/blinklabs-io/ouroboros-mock (#1713)
Bumps [github.com/blinklabs-io/ouroboros-mock](https://github.com/blinklabs-io/ouroboros-mock) from 0.9.1 to 0.10.0.
- [Commits](https://github.com/blinklabs-io/ouroboros-mock/compare/v0.9.1...v0.10.0)

---
updated-dependencies:
- dependency-name: github.com/blinklabs-io/ouroboros-mock
  dependency-version: 0.10.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>
build(deps): bump webiny/action-conventional-commits from 1.3.1 to 1.4.2
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/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]>
chore(deps): bump github.com/blinklabs-io/ouroboros-mock
Bumps [github.com/blinklabs-io/ouroboros-mock](https://github.com/blinklabs-io/ouroboros-mock) from 0.9.1 to 0.10.0.
- [Commits](https://github.com/blinklabs-io/ouroboros-mock/compare/v0.9.1...v0.10.0)

---
updated-dependencies:
- dependency-name: github.com/blinklabs-io/ouroboros-mock
  dependency-version: 0.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
feat(nix): wrap cage-tests-e2e with cardano-node on PATH
The devnet E2E spawns `cardano-node` as a subprocess via
`System.Process.proc`, which looks the binary up on PATH. Without
`cardano-node` available at runtime, the test fails with
`createProcess: posix_spawnp: does not exist`.

Pin `cardano-node` 10.5.4 (matching the upstream
`cardano-node-clients` devnet Dockerfile) as a flake input and
wrap `components.tests.e2e-tests` with a runCommand that puts
`cardano-node/bin` on PATH via `makeWrapper`. The wrapped
derivation sets `meta.mainProgram = "cage-tests-e2e"` so
`pkgs.lib.getExe` resolves to the wrapper and `nix run
.#cage-tests-e2e` is self-sufficient — no surrounding
`nix shell` needed.

Verified locally:
  MPFS_BLUEPRINT=...result E2E_GENESIS_DIR=...genesis \
  nix run .#cage-tests-e2e
  → Cage E2E boot, request, update, retract [✔]
  → Finished in 66.8s — 1 example, 0 failures.

This is the structural fix for the cross-language fidelity guard:
every PR's `e2e` job now runs the full mint/request/update/retract
flow against a freshly-booted devnet `cardano-node` with the new
parameterized validator from `plutus.json`. Any divergence
between the Haskell encoding and the Aiken validator surfaces here
in CI before merge.

Refs #47.
chore(deps): bump webiny/action-conventional-commits from 1.3.1 to 1.4.2 (#1715)
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 github.com/blinklabs-io/plutigo from 0.1.8 to 0.1.9 (#1714)
Bumps [github.com/blinklabs-io/plutigo](https://github.com/blinklabs-io/plutigo) from 0.1.8 to 0.1.9.
- [Release notes](https://github.com/blinklabs-io/plutigo/releases)
- [Changelog](https://github.com/blinklabs-io/plutigo/blob/main/RELEASE_NOTES.md)
- [Commits](https://github.com/blinklabs-io/plutigo/compare/v0.1.8...v0.1.9)

---
updated-dependencies:
- dependency-name: github.com/blinklabs-io/plutigo
  dependency-version: 0.1.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
build(deps): bump webiny/action-conventional-commits from 1.3.1 to 1.4.2 (#2055)
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>
build(deps): bump actions/setup-node from 6.3.0 to 6.4.0 (#2054)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.3.0 to 6.4.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/53b83947a5a98c8d113130e565377fae1a50d02f...48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.4.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>
fix(haskell): bundle devnet genesis, fix lint, set E2E_GENESIS_DIR in CI
The new `e2e` job from the previous commit failed in CI for two
reasons:

1. The devnet bootstrap genesis files (alonzo/byron/conway/shelley
   genesis JSONs, topology, node-config, delegate keys) were not
   present at `haskell/e2e-test/genesis/` — they live in the
   upstream `cardano-node-clients:devnet` source tree but are not
   visible at runtime when the test binary runs from a nix store
   path. `e2e-test/genesis/alonzo-genesis.json: does not exist`.

2. `fourmolu -m check` on CI flagged my multi-line `-- ^`
   Haddock comments (in `Types.hs`, `Config.hs`,
   `TxBuilder/Sweep.hs`) — fourmolu requires the `{- ^ ... -}`
   block-comment syntax for multi-line constructor/field docs.
   Also one duplicate `Cardano.Ledger.Core` import in
   `TxBuilder/Boot.hs` from my earlier edit.

Fixes:

- Mirror the upstream genesis directory into
  `haskell/e2e-test/genesis/` (committed: alonzo-genesis.json,
  byron-genesis.json, conway-genesis.json, shelley-genesis.json,
  node-config.json, topology.json, delegate-keys/).
- Set `E2E_GENESIS_DIR=$GITHUB_WORKSPACE/haskell/e2e-test/genesis`
  in the e2e CI step. The `Cardano.Node.Client.E2E.Setup.genesisDir`
  helper already honors this env var, falling back to a relative
  `e2e-test/genesis` path otherwise.
- Run `fourmolu -i` to autofix multi-line Haddock formatting and
  consolidate duplicate imports.

Local validation:
- `cabal build all`: clean.
- `fourmolu -m check`: clean.
- `hlint`: "No hints".
- `cabal test cage-tests`: 37 examples, 0 failures.
- `aiken check`: 1293 checks, 0 errors.

The actual on-devnet behavior of the e2e test will be verified
when CI runs the `e2e` job against this commit.

Refs #47.
feat(haskell): TxBuilder.Sweep + CI E2E job + nix exposure
Closes the cross-language fidelity gap that hid the original
divergence between the Aiken validator and the Haskell library.

TxBuilder.Sweep:
- New module `Cardano.MPFS.Cage.TxBuilder.Sweep` exposing
  `sweepUtxoImpl`. Standalone sweep tx: spends one
  non-legitimate UTxO at the cage's address, references the
  state UTxO so the validator can read the owner's
  verification-key hash, and is signed by the state owner.
  Same shape as `Retract` (also redeemer-pointed to a state
  ref). Bundling sweep with `Modify` is supported by the
  on-chain validator but produced by a higher-level
  transaction builder (out of scope here).

Nix exposure:
- `cage-tests-e2e` exposed via `haskell/nix/checks.nix` and
  `haskell/nix/apps.nix`. Runnable as
  `nix run .#cage-tests-e2e`.

CI:
- New `e2e` job in `.github/workflows/ci.yml`: needs
  `build` (which produces `plutus.json`), then runs
  `nix run .#cage-tests-e2e` with
  `MPFS_BLUEPRINT=$GITHUB_WORKSPACE/result`. The E2E test
  spins a devnet `cardano-node` subprocess, applies the seed
  parameter to the blueprint at runtime, and submits txs
  against the live validator — verifying that the Haskell
  encoding matches what the Aiken validator decodes.

This is the structural fix for Constitution Principle I
(Cross-Language Encoding Fidelity). Before this commit, CI
ran neither E2E nor any cross-language round-trip check, so
divergences between the Aiken validator and the Haskell
library went undetected. With this job, every PR exercises
the full mint/request/update/retract flow against the
freshly-built blueprint.

Refs #47.
feat(haskell): per-cage parameterization in blueprint, config, boot, and E2E
Brings the off-chain Haskell library's parameterization model in
line with the new validator parameter `seed: OutputReference`.
Each cage instance now has its own per-seed parameterized script
bytes, script hash, policy id, and address.

Blueprint:
- Replace `applyVersion :: Integer -> SBS -> SBS` (old `_version`
  parameter) with `applyDataParam :: Data -> SBS -> SBS` and
  `applyOutputRef :: OnChainTxOutRef -> SBS -> SBS` — the latter
  wraps the former with the canonical `Constr 0 [bytes, integer]`
  encoding produced by `ToData OnChainTxOutRef`.

Config:
- Add `cageSeed :: OnChainTxOutRef` field to `CageConfig`. The
  config is now /per-cage/: callers construct one per minted token
  by applying `applyOutputRef` to the unparameterized blueprint
  and recording the seed used.

Boot:
- `bootTokenImpl` consumes `cfg.cageSeed` from the caller's
  wallet (instead of arbitrarily picking the first UTxO). New
  helper `lookupSeed` finds the seed UTxO in the wallet and
  errors clearly if cfg's seed isn't present.
- The asset name is derived from the cfg's seed (no longer from a
  redeemer-supplied OutputReference) — matching the validator's
  on-chain derivation.

E2E:
- `withE2E` now takes the unparameterized blueprint bytes,
  queries the genesis wallet's UTxOs after the node is up, picks
  the first as seed, and applies `applyOutputRef` to derive the
  per-cage script bytes. `cageCfg` updated to take both bytes
  and seed.
- Drop dead imports.

Validation:
- `cabal build all`: clean.
- `cabal test cage-tests`: 37 examples, 0 failures.
- `just vectors-check`: clean (Aiken vectors unchanged).

Refs #47.