diff --git a/release/director/plan.md b/release/director/plan.md index 95cd59f7..d03e68f6 100644 --- a/release/director/plan.md +++ b/release/director/plan.md @@ -139,7 +139,7 @@ status: `open → doing → done`, or `closed`. each row is one unit; its accept | C2 | proven-present S0: verify the node writes the conformance corpus from height 0 and generates invalid blocks; if not, build it | soft3 · wide | a test that writes the corpus for a mined chain and replays every generated invalid block to its native verdict | done 2026-10-26 (session 98) — **soft3#291 merged into `release/phase1` as `80384de`** (head `1340129`). Receipt: diagnostic **40406033133** (`diag/c2-s91-s98` `5281881` = `1340129` + the s91 workflow only, never merged; rehearsal 40357603776's ported stand, this head's crate): `cargo test --locked`, lib **287 passed 0 failed**, every binary ok, **`warnings: 0`**, both `chain::tests::corpus` tests ok. Session 91 (died, unlogged; session 92 wrongly said it pushed nothing) had merged `release/phase1` in (`0283085`) and run **40393654353**: the first receipt that #291 compiles (285 passed, `warnings: 0`) and 2 red, `truncated_body` drawing `reject:rejected`. Cause: `empty_body`/`truncated_body` took the valid header and `grind` searched from nonce 0 like the tests' `solve`, so both had the **valid block's id**; the first rejection put it in the §5.4 rejected set. `1340129` (sonnet, reviewed): `grind` skips the valid id and every id already generated; tests assert ids distinct; no assertion weakened. The poisoning this exposed is C2a. Receipts on #291 (comments 6427961374 and the merge receipt) — was doing 2026-10-26 (session 44) — **verified: not built** (no `corpus` anywhere in `crate/`, `conformance/` or `release/` on `release/phase1` `d5761ce`). Built as **soft3#291** (draft, `feat/c2-corpus` `0cde8c3`, into `release/phase1`, `wide` + `blocked`): `chain/corpus.rs` (writer of `blocks.jsonl`, record 0 = genesis with R(G); `verdict_code` with exhaustive matches and no wildcard over `BlockVerdict`/`ChainError`/`HeaderError`/`BlockError`/`TxError`; `invalid_blocks` = 20 mutations, one per §5.5 step, re-ground past step 5; `replay`), the acceptance test `chain/tests/corpus.rs`, `soft3 node --corpus DIR` at `KernelChain::accept_block`. Implemented by sonnet and reviewed here. **Never compiled: no stand compiles soft3 today.** Diagnostic `diag/c2-corpus` ran 8 rounds against `cybergraph=pull/3/head bbg=pull/9/head foculus=pull/5/head` plus the 0.4 tier; the last, 40297730975 (`test-unlocked.log`), stops in **bbg#9**: `unresolved import zheng::LookOpening` (`RootLeaves`, `Accumulator`, `root_from_leaves`), the 0.3-tier zheng API, so soft3 never compiled. Posted on cybergraph#3 for the owner (L4). next: #291 is gated by soft3-tests once L4 lands (or the storage chain is rebased onto the 0.4 tier); then read `chain::corpus`, fix, un-draft, merge | | C2a | §5.5 body malleation: a body that is not the one its header commits to (does not split, empty against a non-empty `tx_root`, `tx_root` mismatch) makes the node mark **the valid header** invalid (`engine_api.rs:136-139` `invalidate(id)` on any `decode_body` error, as `specs/chain.md` §5.5 says: "a block failing 6–8 marks the header invalid"), so a peer relaying an honest header with a corrupted body makes the node refuse the honest block while the id stays in the rejected set (the class of Bitcoin CVE-2012-2459). Found by C2's generator (run 40393654353, session 98). Fix: check the commitment (split + `tx_root`) first; a body that fails it is dropped without touching the header; only failures after the match invalidate | soft3 · wide, `decision` (changes `specs/chain.md` §5.5: D6, the owner's hand) | a PR into `release/phase1` with the §5.5 wording and the engine change, and a test that sends the valid header with a corrupted body, then the valid body, and gets `Extended`: red on `release/phase1`, green on the PR, on the build service; asked of the owner with a deadline before the 2026-11-02 freeze (a security fix with a failing test may merge in the freeze) | to the owner 2026-10-26 (session 101) — **receipts read and posted, #350 ready for review** (comment 6428610063). Red **40408280127** (`784f8a4` = `release/phase1` `5ff6d82` + the test only): the test FAILED at `rules.rs:288`, `case 0: the honest block was refused`, `Err(Rejected(..))` vs `Ok(Extended)`; lib 287/1. Green **40408283118** (`093f7c3` = `f047eba` + diag workflow): the test `ok`, lib **288 passed 0 failed**, every binary ok, **`warnings: 0`**; its job reads `failure` only because `upload-artifact` refused the name `c2a-diag/c2a-green` (a `/`), after every test step succeeded. #350 head `c53b409` differs from the green tree by one doc-comment and one spec cross-reference (`git diff f047eba c53b409`). Review: tagged leaf/node hashing with odd-node promotion (`tree.rs` `odd_nodes_promote_not_duplicate`) means a body passing 6a is the header's up to a hemera collision, so 6b still condemns rightly; no duplicate-leaf route. Waits on the owner (D6), deadline 2026-10-29 12:00 UTC — was doing 2026-10-26 (session 100) — **soft3#350** (draft, `decision`, `wide`, into `release/phase1`; the owner's to merge, D6): `72032b2` the test `body_malleation_never_invalidates_the_honest_header` alone (truncated, empty, wrong-`tx_root` bodies on the valid header, then the valid body → `Extended`; a 6b failure under a matching root → `Rejected` on resend), `ef18f6b` `apply::body_matches` (6a: fits `MAX_BLOCK_BYTES`, splits, non-empty, `tx_root` equal; never invalidates) then `decode_matched` (6b: invalidates as before), `f047eba` §5.5 step 6 → 6a/6b, `c53b409` section reference. Implemented by a sonnet subagent, reviewed by me: diff minimal, replay and `decoded` unchanged, the net layer keeps no id blacklist (`kernel.rs` scores the peer), corpus verdicts unchanged. Receipts dispatched on 40357603776's stand: **red** `diag/c2a-red` run **40408280127** (test commit on `release/phase1`), **green** `diag/c2a-green` run **40408283118** (fix head, whole suite, warnings). Next: read both, post them on #350, mark it ready; owner's deadline 2026-10-29 12:00 UTC | | C3 | the economy at genesis: the conformance vectors of registry rows 26 (passive stake earns 0), 27 (θ split), 41 (epoch record agreed) run in soft3-tests | soft3 · wide | the named vectors pass in soft3-tests on all legs | built; acceptance waits on L4 (session 58) — **verified on `release/phase1` `771e070`: every vector the three rows name is already in the crate and runs under `soft3-tests` (`cargo test --locked` in `crate/`); nothing to build.** The gates are in `cyber/launch.md`. **Row 26**, the 2-epoch vector that pays the passive position 0: `economy/vectors.rs:263-274` (+1, 0, −1 locks; `the passive position earns nothing`) is blessed as `chain.snap` `two epochs: epoch 1 record`/`payouts`/`budget, paid, pool after`, and `tests/economy.rs` `multi_epoch_settlement_end_to_end` asserts `v = 0 never earns`. **Row 27**, θ split, focus pool min(½, θ^½), integer root: `economy/tests.rs` `integers_of_section_14` holds the `specs/chain-conformance.md` §14 table (`focus_bps` 0/99/999/5,000/5,000; `cut` at 1,000 and 5,000 bps), and `coinbase_split_follows_the_active_stake_of_the_last_boundary` checks that the passive stake does not count. **Row 41**, the epoch record agreed: `two_nodes_agree_on_every_epoch_and_a_restart_replays_it` (node B fed blocks only, records equal for epochs 1–3, restart replays them), plus the blessed reorg pair. `chain/conformance.rs` `committed_chain_snap_matches_this_build` holds every `chain::economy@v1` entry to `conformance/chain.snap` (tru engine `e660d1e` = tru head in tick `20261026T121504Z`). **Not yet passing**: soft3-tests has not compiled on any leg since L4 (rehearsal 40307972588, package-resolution: `cybergraph` has no `local-storage`). The row closes on the first rehearsal after L4 with these tests green on all legs. If hemera 0.4 moves the economy digests, that is G6's drift, blessed in the PR that causes it | -| C4 | cybernode: land the owner's soft3#406 (the node leaves soft3, proposals/cybernode.md C2–C4) on `release/phase1` | soft3 · wide | `drift` green; `crate/Cargo.lock` resolved by the build service; a rehearsal with `soft3=fix/cybernode-drift` and 40446879208's overrides in which soft3-tests, soft3-release and node-status are no worse than in 40446879208; merged | doing 2026-10-27 (session 160): **#407's rehearsal is read in full: it is two gates worse than 40446879208 on the stack leg, and both reds are #406's.** Rehearsal 40525967811 (manager `fix/cybernode-drift` `f16cc0f`, 40446879208's overrides; artifacts in `state/run-40525967811/`) compared gate by gate with 40446879208. The mac legs are no worse: aarch64-apple-darwin and x86_64-apple-darwin soft3-tests, soft3-release and node-status are green on both, and phase1-pins and release-notes-source are red on both, as before. The stack leg has the same reds as before (phase1-pins, release-notes-source, stack-mudra, stack-neuron, stack-zheng) **plus two new ones**: (1) **stack-chain-genesis**, green → red. The genesis build reproduces pussy particle `bae85f40…`, state_root `d48fee47…` and block0_id `73208ee2…`, but `conformance check chain` reports all 54 entries as `(new)`, so it read an empty snapshot. The run took cybernode `main` `52538a6` (`sources.json`), whose `cli.rs:906` defaults `--snap` to cybernode's own `conformance/`. cybernode#1 `31fca56` already makes that default `chain_snap_path()`, the soft3 sibling, so this red closes when #1 merges. (2) **simulation-gate**, green → red in 0.165 s, exit 101: `cannot update the lock file …/simulation/Cargo.lock because --locked was passed`. simulation-chain takes soft3 by path (`../../soft3/crate`, feature `sim`), and its lock at `5483a3f` still records `soft3 0.10.0` with the node inline, while #406 makes soft3 0.11.0 depending on `cybernode`. simulation is `push: false` to the director, so its lock goes to the owner from a fork, as cybernode#1 did. Dispatched diagnostic **40547036801** (`diag/simulation-lock` `47f8f20`, never merged): the same stand with cybernode at `31fca56`. It re-resolves simulation's lock from the committed one (no `generate-lockfile`) and uploads the lock and its diff, then runs both gates' own commands with `--locked`. Its targets are simulation-gate green and `chain.snap: 54 entries, no drift`. #407 still does not merge. Next: read 40547036801, then open the simulation lock PR (fork) for the owner. Once cybernode#1 and that PR merge, #407 gets the pins, the `cybernode-tests` gate and a rehearsal. Was (session 158): **cybernode#1 is green, 314 passed and 0 failed, and it is ready for the owner.** Diagnostic 40536044737 (`diag/cybernode-lock-snap` `3cf0ef6`, never merged; the train's stand with 40446879208's overrides, `materialized 33 red: []`) checked out cybernode at exactly `31fca56` (asserted with `rev-parse HEAD`) and applied no patch. The committed `rs/Cargo.lock` has sha256 `91533a1c…` and resolves under `cargo metadata --locked`, and no `CARGO_BIN_EXE_soft3` is left. `cargo test --locked`: lib **310 passed, 0 failed, 1 ignored**, plus integration suites 2 + 1 + 1, for **314 passed, 0 failed**. That equals soft3-tests' 314 in 40446879208 (C2 acceptance). `committed_chain_snap_matches_this_build ... ok` (log line 1313), and it reads soft3's snapshot through the sibling path. `cargo build --release --locked` succeeded (5m 59s) and there were no warnings (receipt `state/run-40536044737/measure.log`, sha256 `741b84b7…`). I marked cybernode#1 ready and posted the receipt (comment 6447200525). It merges by the owner's hand, because cybernode is `push: false`. Next, once cybernode#1 merges: on #407, move the `cybernode` pin to the merge commit and add the `cybernode-tests` gate (`cargo test --locked` in `cybernode/rs`, 1800 s, all four platforms, with `SOFT3_CONFORMANCE_DIR` set explicitly). Then run a rehearsal and merge. Was (session 157): **313 of 314 node tests pass in cybernode. The one red is `chain.snap`, which stayed in soft3; the fix is on cybernode#1.** Diagnostic 40532608817 (`diag/cybernode-lock-bin` `7da072d`, cybernode `52538a6` with the lock and the bin rename applied on the stand) ran `cargo test --locked --no-fail-fast`: lib **309 passed, 1 failed, 1 ignored**, then integration suites 2 + 1 + 1, for **313 passed and 1 failed** (Summary step). `cybernode-release` succeeded and there were no warnings (receipt `state/run-40532608817/`). The red is `chain::conformance::tests::committed_chain_snap_matches_this_build`, which panicked at `src/chain/conformance.rs:313` with `conformance/chain.snap: NotFound`. It reads `rs/../conformance/chain.snap`. Because `proposals/cybernode.md` (§ the table, "conformance snapshots" → soft3) keeps conformance snapshots in soft3, that file is not in cybernode (`git/trees/52538a6`) and is at soft3 `conformance/chain.snap`. The `cybernode conformance` CLI default (`cli.rs:906`) had the same dead path. **Decided (opus; no fable, since the proposal settles it):** the snapshot stays in soft3, and cybernode reads it from `$SOFT3_CONFORMANCE_DIR/chain.snap`, or else from the sibling soft3 checkout (`rs/../../soft3/conformance/chain.snap`, the train's layout). A missing file still fails the test. **cybernode#1 head `31fca56`** (sonnet subagent, reviewed: one `chain_snap_path()`, both sites use it, `--snap` still overrides, nothing skipped; comment 6446771337). Dispatched diagnostic **40536044737** (`diag/cybernode-lock-snap` `3cf0ef6`, never merged). It takes cybernode at exactly `31fca56` with its committed lock and applies no patch on the stand. The target is 314 passed, 0 failed, which equals soft3-tests' 314 in 40446879208 (C2 acceptance). Next: read 40536044737. If green, mark cybernode#1 ready for the owner. Then, on #407: the `cybernode-tests` gate (with `SOFT3_CONFORMANCE_DIR` set explicitly), the pin moved to the merge commit, a rehearsal, and the merge. Was (session 156): **cybernode's tests did not compile, so the fix went to the owner as cybernode#1.** Diagnostic 40529591978 (`diag/cybernode-lock` `bb9b199`, red): the lock resolves on the stand, sha256 `91533a1c…` (artifact `cybernode-lock`, 819-line diff against #407's seed lock). `cargo build --release --locked` finished in 4m 35s and `cybernode --version` printed `cybernode 0.1.0`. But `cargo test --locked` stopped at `tests/chain_adversary.rs:89`: `environment variable CARGO_BIN_EXE_soft3 not defined` (`test-cybernode.log:440`), so **0 of the 312 tests ran**. The move renamed the bin `soft3` → `cybernode` and kept the CLI (`src/cli.rs:39-41` `node`/`mine`/`chain`). That line is the only `CARGO_BIN_EXE_soft3` in `rs/tests`. cybernode is `push: false` for `cyberia-apparatus` and has only `main`, so the lock and the one-line fix went in as a fork PR: **cybernode#1** (draft, `cyberia-apparatus:fix/lock-and-bin-name` `9a2ee26`, lock sha256 checked; the lane label was refused, 403 admin, so `contained` is stated in the body). Dispatched diagnostic **40532608817** (`diag/cybernode-lock-bin` `7da072d` = `bb9b199` + a step that applies the rename on the stand, never merged) to measure the count. Its target is 312 passed. Next: read 40532608817. If green, mark cybernode#1 ready for the owner. Once it merges: pin cybernode to the merge commit on #407, add the `cybernode-tests` gate, run a rehearsal, then merge #407. Was (session 155): **#407 is green but blinds the gate: it moves the node's tests out of every gate, so it does not merge yet.** Rehearsal 40525967811 (`fix/cybernode-drift` `f16cc0f`, 40446879208's overrides), both linux legs (`candidate-x86_64-unknown-linux-gnu`, `candidate-aarch64-unknown-linux-gnu`, `receipt/release-validation.json`): soft3-tests, soft3-release and node-status are **green**, `exit_code: 0`, `warnings: false`, the same as 40446879208. But `logs/soft3-tests.txt` shows **2 passed in 3 suites (x86_64), against 314 passed in 6 suites** in 40446879208. The chain_adversary, mine_e2e and chain_checkpoints tests, the C2 corpus, the C3 economy vectors and the G14 and G16 receipts all left with the node to `cybernode/rs`. No gate runs them there: `train_gates.py` `run_gates` stack owners have no `cybernode`, and `cybernode/rs` at `52538a6` has **no `Cargo.lock`** (`gh api …/contents/rs`), so `cargo test --locked` cannot run in it. `proposals/cybernode.md` C2 acceptance asks for "`cargo test` in cybernode equals the soft3 crate's test count before the move", and § 9 leaves the tests to the director. **Decided (opus; no fable):** before #407 merges, (a) cybernode gets an `rs/Cargo.lock` resolved by the build service and seeded from #407's soft3 lock, so the shared versions are identical; (b) the pin moves to that commit; (c) the soft3 product legs gain a `cybernode-tests` gate (`cargo test --locked` in `cybernode/rs`, 1800 s, all four platforms, the same as soft3-tests had). Step (a) is dispatched: diagnostic **40529591978** (`diag/cybernode-lock` `bb9b199` = `f16cc0f` + one workflow, never merged; same stand). It resolves the lock, runs `cargo test --locked --no-fail-fast` and `cargo build --release --locked` in `cybernode/rs`, and uploads `cybernode-lock`. Its target is 312 node tests passed. 40525967811's mac and stack legs were still running at 15:18. Next: read 40529591978, then the cybernode lock PR, the pin, the gate on #407 and a rehearsal. Was (session 154): **rehearsal re-dispatched with #407 as the manager: 40525967811.** 40522989900 measured nothing: its manager was `release/phase1` `0c6db6b`, whose `release/phase1.toml` has no `cybernode` sibling (#407 adds it; `train_sources.py` `snapshot` reads the manifest from the manager), so all four building legs went red in 0.03 s on `failed to read …/sources/cybernode/rs/Cargo.toml` (`candidate-x86_64-unknown-linux-gnu` `logs/soft3-tests.txt`, exit 101; receipt in `state/run-40522989900/`). Cancelled it (its stack leg could not measure soft3 either; the `release-train` group queues) and dispatched `--ref fix/cybernode-drift` (`f16cc0f`; differs from `release/phase1` only in `plan.md`, so the train code is the same) with the same 15 overrides as exact commits (`state/run-40522989900/overrides.txt`). next: compare soft3-tests, soft3-release, node-status per leg against 40446879208, then merge #407. Was (session 153): **lock committed, rehearsal dispatched.** Diagnostic 40519917254 (`measure` success) built soft3 at #407's head `d49849a` and cybernode at its pin `52538a6` with 40446879208's overrides: lock before `cb7c91ab…` (= #407's), after `e4e90704…`, diff = one new `cybernode` 0.1.0 package holding the node's 23 deps, `soft3` 0.10.0 → 0.11.0 depending on `cyb` + `cybernode`; `cargo test --locked` (lib 2 passed) and `cargo build --release --locked` (3m 34s) finished there. That lock committed to #407 as `f16cc0f` (sha256 checked against the receipt). Rehearsal **40522989900** (`candidate-20261027.92`, `cut=false`) dispatched with 40446879208's overrides and `soft3=f16cc0f`; next: compare soft3-tests, soft3-release, node-status per leg against 40446879208, then merge #407. Run 40519226722 (14:14, `main`, tick's dispatch on the moved defaults) is red as the defaults are before the landings (package-resolution `lens/gpu`), nothing new. Was (session 152): **#406 reviewed and carried by soft3#407** (`fix/cybernode-drift` = #406 `58920a8` + `d49849a`; #406 untouched, closes as merged when #407 merges). #406's `drift` was red (run 40517639036: `layer 7 component missing from the home ladder: soft3`); `d49849a` (sonnet subagent, reviewed): registry `cybernode` ops → `apparatus` (§ 7.1), new `cybernode` product at layer 7, `soft3` without `layer`/`role`, foculus·radio·sync·solong `part_of = "cybernode"`, chart rung-7 node/8 edges/`LADDER`, a `status.md` row — checker `no drift`, Components registry on #407 green (run 40519963024). Open: #406 left `crate/Cargo.lock` stale (0 `cybernode` entries) while soft3-tests/soft3-release run `--locked` (`train_gates.py:304-305`) → diagnostic `diag/cybernode-406-lock` `b1fba54` (never merged), run **40519917254**, resolves the lock on the stand and runs both gate commands; next: commit its lock to #407, then the rehearsal. `cybernode` is public (`visibility: public`), so the train can check out the sibling pin `52538a6`. Review comment on #406: 6444426906 | +| C4 | cybernode: land the owner's soft3#406 (the node leaves soft3, proposals/cybernode.md C2–C4) on `release/phase1` | soft3 · wide | `drift` green; `crate/Cargo.lock` resolved by the build service; a rehearsal with `soft3=fix/cybernode-drift` and 40446879208's overrides in which soft3-tests, soft3-release and node-status are no worse than in 40446879208; merged | doing 2026-10-27 (session 161): **both stack reds that #406 introduced close on the train's stand; simulation's lock went to the owner as simulation#2.** Diagnostic 40547036801 (`diag/simulation-lock` `47f8f20`, never merged; soft3 `f16cc0f`, 40446879208's overrides, cybernode at cybernode#1 `31fca56`; artifacts in `state/run-40547036801/`): simulation's committed lock (sha256 `ddb2329f…`) fails `--locked` as in 40525967811; re-resolved from it, with no `generate-lockfile` (sha256 `7ca0d5c4…`), the diff is only a new `cybernode 0.1.0` entry carrying soft3 0.10.0's 23 dependencies, plus `soft3 0.11.0` depending on `cybernode` alone. **simulation-gate: success** with the train's command, 16 scenarios, 0 fail, economy's 2 expected reds, 14m 22s. **stack-chain-genesis: success**: pussy `bae85f40…`, `chain.snap: 54 entries, no drift`. Opened **cyberia-to/simulation#2** (draft, fork `cyberia-apparatus/simulation` created this session, commit `5518998`; no lane label: simulation has none and the director has read access only). **Merge order, decided (opus, no fable):** the train checks out simulation at `main` HEAD and soft3 is 0.10.0 on both `main` and `release/phase1`, so simulation#2 merged early would turn simulation-gate red the other way round. It merges when soft3 `main` carries 0.11 (#407 → `release/phase1` → #376); until then rehearsals take `simulation=pull/2/head`. Receipt posted on #407 (comment 6448798473). Next: once cybernode#1 merges, on #407 move the `cybernode` pin, add the `cybernode-tests` gate, then a rehearsal with `simulation=pull/2/head`, and merge. Was (session 160): **#407's rehearsal is read in full: it is two gates worse than 40446879208 on the stack leg, and both reds are #406's.** Rehearsal 40525967811 (manager `fix/cybernode-drift` `f16cc0f`, 40446879208's overrides; artifacts in `state/run-40525967811/`) compared gate by gate with 40446879208. The mac legs are no worse: aarch64-apple-darwin and x86_64-apple-darwin soft3-tests, soft3-release and node-status are green on both, and phase1-pins and release-notes-source are red on both, as before. The stack leg has the same reds as before (phase1-pins, release-notes-source, stack-mudra, stack-neuron, stack-zheng) **plus two new ones**: (1) **stack-chain-genesis**, green → red. The genesis build reproduces pussy particle `bae85f40…`, state_root `d48fee47…` and block0_id `73208ee2…`, but `conformance check chain` reports all 54 entries as `(new)`, so it read an empty snapshot. The run took cybernode `main` `52538a6` (`sources.json`), whose `cli.rs:906` defaults `--snap` to cybernode's own `conformance/`. cybernode#1 `31fca56` already makes that default `chain_snap_path()`, the soft3 sibling, so this red closes when #1 merges. (2) **simulation-gate**, green → red in 0.165 s, exit 101: `cannot update the lock file …/simulation/Cargo.lock because --locked was passed`. simulation-chain takes soft3 by path (`../../soft3/crate`, feature `sim`), and its lock at `5483a3f` still records `soft3 0.10.0` with the node inline, while #406 makes soft3 0.11.0 depending on `cybernode`. simulation is `push: false` to the director, so its lock goes to the owner from a fork, as cybernode#1 did. Dispatched diagnostic **40547036801** (`diag/simulation-lock` `47f8f20`, never merged): the same stand with cybernode at `31fca56`. It re-resolves simulation's lock from the committed one (no `generate-lockfile`) and uploads the lock and its diff, then runs both gates' own commands with `--locked`. Its targets are simulation-gate green and `chain.snap: 54 entries, no drift`. #407 still does not merge. Next: read 40547036801, then open the simulation lock PR (fork) for the owner. Once cybernode#1 and that PR merge, #407 gets the pins, the `cybernode-tests` gate and a rehearsal. Was (session 158): **cybernode#1 is green, 314 passed and 0 failed, and it is ready for the owner.** Diagnostic 40536044737 (`diag/cybernode-lock-snap` `3cf0ef6`, never merged; the train's stand with 40446879208's overrides, `materialized 33 red: []`) checked out cybernode at exactly `31fca56` (asserted with `rev-parse HEAD`) and applied no patch. The committed `rs/Cargo.lock` has sha256 `91533a1c…` and resolves under `cargo metadata --locked`, and no `CARGO_BIN_EXE_soft3` is left. `cargo test --locked`: lib **310 passed, 0 failed, 1 ignored**, plus integration suites 2 + 1 + 1, for **314 passed, 0 failed**. That equals soft3-tests' 314 in 40446879208 (C2 acceptance). `committed_chain_snap_matches_this_build ... ok` (log line 1313), and it reads soft3's snapshot through the sibling path. `cargo build --release --locked` succeeded (5m 59s) and there were no warnings (receipt `state/run-40536044737/measure.log`, sha256 `741b84b7…`). I marked cybernode#1 ready and posted the receipt (comment 6447200525). It merges by the owner's hand, because cybernode is `push: false`. Next, once cybernode#1 merges: on #407, move the `cybernode` pin to the merge commit and add the `cybernode-tests` gate (`cargo test --locked` in `cybernode/rs`, 1800 s, all four platforms, with `SOFT3_CONFORMANCE_DIR` set explicitly). Then run a rehearsal and merge. Was (session 157): **313 of 314 node tests pass in cybernode. The one red is `chain.snap`, which stayed in soft3; the fix is on cybernode#1.** Diagnostic 40532608817 (`diag/cybernode-lock-bin` `7da072d`, cybernode `52538a6` with the lock and the bin rename applied on the stand) ran `cargo test --locked --no-fail-fast`: lib **309 passed, 1 failed, 1 ignored**, then integration suites 2 + 1 + 1, for **313 passed and 1 failed** (Summary step). `cybernode-release` succeeded and there were no warnings (receipt `state/run-40532608817/`). The red is `chain::conformance::tests::committed_chain_snap_matches_this_build`, which panicked at `src/chain/conformance.rs:313` with `conformance/chain.snap: NotFound`. It reads `rs/../conformance/chain.snap`. Because `proposals/cybernode.md` (§ the table, "conformance snapshots" → soft3) keeps conformance snapshots in soft3, that file is not in cybernode (`git/trees/52538a6`) and is at soft3 `conformance/chain.snap`. The `cybernode conformance` CLI default (`cli.rs:906`) had the same dead path. **Decided (opus; no fable, since the proposal settles it):** the snapshot stays in soft3, and cybernode reads it from `$SOFT3_CONFORMANCE_DIR/chain.snap`, or else from the sibling soft3 checkout (`rs/../../soft3/conformance/chain.snap`, the train's layout). A missing file still fails the test. **cybernode#1 head `31fca56`** (sonnet subagent, reviewed: one `chain_snap_path()`, both sites use it, `--snap` still overrides, nothing skipped; comment 6446771337). Dispatched diagnostic **40536044737** (`diag/cybernode-lock-snap` `3cf0ef6`, never merged). It takes cybernode at exactly `31fca56` with its committed lock and applies no patch on the stand. The target is 314 passed, 0 failed, which equals soft3-tests' 314 in 40446879208 (C2 acceptance). Next: read 40536044737. If green, mark cybernode#1 ready for the owner. Then, on #407: the `cybernode-tests` gate (with `SOFT3_CONFORMANCE_DIR` set explicitly), the pin moved to the merge commit, a rehearsal, and the merge. Was (session 156): **cybernode's tests did not compile, so the fix went to the owner as cybernode#1.** Diagnostic 40529591978 (`diag/cybernode-lock` `bb9b199`, red): the lock resolves on the stand, sha256 `91533a1c…` (artifact `cybernode-lock`, 819-line diff against #407's seed lock). `cargo build --release --locked` finished in 4m 35s and `cybernode --version` printed `cybernode 0.1.0`. But `cargo test --locked` stopped at `tests/chain_adversary.rs:89`: `environment variable CARGO_BIN_EXE_soft3 not defined` (`test-cybernode.log:440`), so **0 of the 312 tests ran**. The move renamed the bin `soft3` → `cybernode` and kept the CLI (`src/cli.rs:39-41` `node`/`mine`/`chain`). That line is the only `CARGO_BIN_EXE_soft3` in `rs/tests`. cybernode is `push: false` for `cyberia-apparatus` and has only `main`, so the lock and the one-line fix went in as a fork PR: **cybernode#1** (draft, `cyberia-apparatus:fix/lock-and-bin-name` `9a2ee26`, lock sha256 checked; the lane label was refused, 403 admin, so `contained` is stated in the body). Dispatched diagnostic **40532608817** (`diag/cybernode-lock-bin` `7da072d` = `bb9b199` + a step that applies the rename on the stand, never merged) to measure the count. Its target is 312 passed. Next: read 40532608817. If green, mark cybernode#1 ready for the owner. Once it merges: pin cybernode to the merge commit on #407, add the `cybernode-tests` gate, run a rehearsal, then merge #407. Was (session 155): **#407 is green but blinds the gate: it moves the node's tests out of every gate, so it does not merge yet.** Rehearsal 40525967811 (`fix/cybernode-drift` `f16cc0f`, 40446879208's overrides), both linux legs (`candidate-x86_64-unknown-linux-gnu`, `candidate-aarch64-unknown-linux-gnu`, `receipt/release-validation.json`): soft3-tests, soft3-release and node-status are **green**, `exit_code: 0`, `warnings: false`, the same as 40446879208. But `logs/soft3-tests.txt` shows **2 passed in 3 suites (x86_64), against 314 passed in 6 suites** in 40446879208. The chain_adversary, mine_e2e and chain_checkpoints tests, the C2 corpus, the C3 economy vectors and the G14 and G16 receipts all left with the node to `cybernode/rs`. No gate runs them there: `train_gates.py` `run_gates` stack owners have no `cybernode`, and `cybernode/rs` at `52538a6` has **no `Cargo.lock`** (`gh api …/contents/rs`), so `cargo test --locked` cannot run in it. `proposals/cybernode.md` C2 acceptance asks for "`cargo test` in cybernode equals the soft3 crate's test count before the move", and § 9 leaves the tests to the director. **Decided (opus; no fable):** before #407 merges, (a) cybernode gets an `rs/Cargo.lock` resolved by the build service and seeded from #407's soft3 lock, so the shared versions are identical; (b) the pin moves to that commit; (c) the soft3 product legs gain a `cybernode-tests` gate (`cargo test --locked` in `cybernode/rs`, 1800 s, all four platforms, the same as soft3-tests had). Step (a) is dispatched: diagnostic **40529591978** (`diag/cybernode-lock` `bb9b199` = `f16cc0f` + one workflow, never merged; same stand). It resolves the lock, runs `cargo test --locked --no-fail-fast` and `cargo build --release --locked` in `cybernode/rs`, and uploads `cybernode-lock`. Its target is 312 node tests passed. 40525967811's mac and stack legs were still running at 15:18. Next: read 40529591978, then the cybernode lock PR, the pin, the gate on #407 and a rehearsal. Was (session 154): **rehearsal re-dispatched with #407 as the manager: 40525967811.** 40522989900 measured nothing: its manager was `release/phase1` `0c6db6b`, whose `release/phase1.toml` has no `cybernode` sibling (#407 adds it; `train_sources.py` `snapshot` reads the manifest from the manager), so all four building legs went red in 0.03 s on `failed to read …/sources/cybernode/rs/Cargo.toml` (`candidate-x86_64-unknown-linux-gnu` `logs/soft3-tests.txt`, exit 101; receipt in `state/run-40522989900/`). Cancelled it (its stack leg could not measure soft3 either; the `release-train` group queues) and dispatched `--ref fix/cybernode-drift` (`f16cc0f`; differs from `release/phase1` only in `plan.md`, so the train code is the same) with the same 15 overrides as exact commits (`state/run-40522989900/overrides.txt`). next: compare soft3-tests, soft3-release, node-status per leg against 40446879208, then merge #407. Was (session 153): **lock committed, rehearsal dispatched.** Diagnostic 40519917254 (`measure` success) built soft3 at #407's head `d49849a` and cybernode at its pin `52538a6` with 40446879208's overrides: lock before `cb7c91ab…` (= #407's), after `e4e90704…`, diff = one new `cybernode` 0.1.0 package holding the node's 23 deps, `soft3` 0.10.0 → 0.11.0 depending on `cyb` + `cybernode`; `cargo test --locked` (lib 2 passed) and `cargo build --release --locked` (3m 34s) finished there. That lock committed to #407 as `f16cc0f` (sha256 checked against the receipt). Rehearsal **40522989900** (`candidate-20261027.92`, `cut=false`) dispatched with 40446879208's overrides and `soft3=f16cc0f`; next: compare soft3-tests, soft3-release, node-status per leg against 40446879208, then merge #407. Run 40519226722 (14:14, `main`, tick's dispatch on the moved defaults) is red as the defaults are before the landings (package-resolution `lens/gpu`), nothing new. Was (session 152): **#406 reviewed and carried by soft3#407** (`fix/cybernode-drift` = #406 `58920a8` + `d49849a`; #406 untouched, closes as merged when #407 merges). #406's `drift` was red (run 40517639036: `layer 7 component missing from the home ladder: soft3`); `d49849a` (sonnet subagent, reviewed): registry `cybernode` ops → `apparatus` (§ 7.1), new `cybernode` product at layer 7, `soft3` without `layer`/`role`, foculus·radio·sync·solong `part_of = "cybernode"`, chart rung-7 node/8 edges/`LADDER`, a `status.md` row — checker `no drift`, Components registry on #407 green (run 40519963024). Open: #406 left `crate/Cargo.lock` stale (0 `cybernode` entries) while soft3-tests/soft3-release run `--locked` (`train_gates.py:304-305`) → diagnostic `diag/cybernode-406-lock` `b1fba54` (never merged), run **40519917254**, resolves the lock on the stand and runs both gate commands; next: commit its lock to #407, then the rehearsal. `cybernode` is public (`visibility: public`), so the train can check out the sibling pin `52538a6`. Review comment on #406: 6444426906 | | R0 | soft3's landing: `release/phase1 → main` with the receipts (D1, D11) | soft3 · wide (`decision`: the owner's approval) | the PR open with receipts, conflict-free, PR gates on its head; merged by the director after the owner approves | to the owner 2026-10-27 (session 125). **soft3#376** is open: head `cd15055`, base `main` `2e5ba00`, 274 ahead and 0 behind, so it merges with no conflict. It has 48 files and no `specs/` file. Labels `decision`, `wide`; `mergeable_state: blocked` means it waits on the review. Receipts on the PR come from rehearsal 40446879208 at `5ca1d64`. On all five legs, soft3-tests, soft3-release and node-status are green (receipt sha256 `64cdcf80` `2abcae89` `19b762ea` `40d01b8a` `8c6d71d5`). The reds are only the owned ones (G8, G9, L3b, L3c). Since `5ca1d64` the only input change is `release/phase1.toml` (#373, whose PR gates are green). The order is noted on lens#36 (comment 6435030150). Each later plan PR adds commits to #376's head. That is plan text only, and the PR gates rerun. | | R1 | the candidate: a dispatched `cut=false` run green on all five legs from origin defaults, then the 12:00 cut of the same inputs | soft3 | `release-validation.json` green on every leg; the draft `candidate-YYYYMMDD.N` exists; the owner's promotion the only step left | open | @@ -153,6 +153,8 @@ reading the order: G2 makes "green" checkable for every sibling PR; L1 → L2 **decide the genesis checkpoint key by 2026-11-02 00:00 UTC (H-01 of soft3#398)**: the pipeline writes `checkpoint_key: [0; 33]` (`crate/src/bin/soft3.rs:547`, `release/phase1` `e2d6ecf`), so the blessed particles commit to no checkpoints: pussy `bae85f40…` and bostrom `f78c60ed…` (`conformance/chain-genesis.toml`). The low-hashrate mitigation of `specs/chain.md` §5.3 is therefore off at genesis. Two choices: (a) a foundation secp256k1 key that you create and hold, whose 33-byte public key goes into the genesis params, after which the director re-blesses both particles (G5, G6) before the freeze; or (b) launch without checkpoints, recorded as a decision that accepts the deep-reorg exposure. #398's default is (a), with a 180-day sunset; the spec's `CHECKPOINT_SUNSET` is 525,600 blocks, about 6 months. The director never creates or holds keys +**merge simulation#2 (C4) in step with soft3 0.11 reaching `main`, not before**: simulation's `Cargo.lock` for soft3 0.11 (the node in cybernode), resolved by the build service; simulation-gate green with it on the train's stand (diagnostic 40547036801: 16 scenarios, 0 fail). It is a draft from the fork because simulation is read-only to `cyberia-apparatus`. Merge it right after soft3#376 lands with #407 in it. Merged earlier, it breaks simulation-gate against soft3 0.10.0. + **merge cybernode#1 (C4), ready since 2026-10-27 16:20 UTC, green at `31fca56`: 314 passed, 0 failed, diagnostic 40536044737**: the lock the build service resolved, plus `CARGO_BIN_EXE_soft3` → `CARGO_BIN_EXE_cybernode` in one test. Without it, none of the node's tests compile in cybernode, and soft3#407 (your #406) holds until a `cybernode-tests` gate can run them. It also turns stack-chain-genesis green again: without #1 the CLI looks for `chain.snap` in cybernode's tree, so rehearsal 40525967811 shows all 54 entries `(new)`. A second fork PR, simulation's lock for soft3 0.11, follows once diagnostic 40547036801 produces it. cybernode is read-only to the director, so it comes from a fork. **merge soft3#384 into `feat/soft3-director` (#247's branch) and reinstall the loop on agent-a, when you choose** — `loop.sh` started an opus session on every tick although `tick.sh` promises "no tokens unless something changed" (sessions 126–132 ran on identical ticks). #384 adds `owner_activity` (your newest event in `cyberia-to/*`) to the tick and skips a session when the tick is unchanged (session 144: the comparison ignores `.prs[].mergeable`, which flaps `UNKNOWN` after every push and started sessions on unchanged ticks; head `39d6175`) since an idle session, with a 3 h heartbeat. It is your branch, so the director does not merge it. Until then the idle sessions continue, one plan PR each. @@ -309,3 +311,4 @@ reading the order: G2 makes "green" checkable for every sibling PR; L1 → L2 | 2026-10-27 16:20 | director session 158 | **C4: cybernode#1 is green and ready for the owner.** Diagnostic 40536044737 took cybernode at `31fca56` with its committed lock and no patch: **314 passed, 0 failed** (lib 310 + 2 + 1 + 1), `committed_chain_snap_matches_this_build` ok, the release build succeeded, no warnings. I marked cybernode#1 ready and posted the receipt (comment 6447200525). #407 waits on that merge, then gets the pin, the `cybernode-tests` gate and a rehearsal. Nothing merged except this plan PR. No subagent, no fable. | | 2026-10-27 16:55 | director session 159 | **L2: lens#36 conflict-free again.** C4 still waits on the owner (cybernode#1 open, unmerged, `31fca56`). Found lens#36 `mergeable: false`/`dirty`: the owner's lens `master` `11113c6` renamed CLAUDE.md → AGENTS.md, while `release/0.2` had edited CLAUDE.md. `git merge-tree` was clean locally (ort rename 92%), GitHub was not. Resolved on the line (D2): **lens#42** (`sync/master-agents-into-release-0.2` `a5c802e`, `contained`) changed only `CLAUDE.md => AGENTS.md` (owner's header + the line's `cyberia/` links). CI 40542129252: test (10m9s), heavy, clippy, fmt and lockfile all pass. Reviewed, merged into `release/0.2` as `d6dcc3f`. #36 is now `mergeable: true`, `blocked` (the owner's review, comment posted). hemera#25, nox#43 and soft3#376 are `blocked`, not dirty. `red-40519226722.json` (`main`, before the landings) holds nothing new. No subagent (a one-file merge), no fable. Next: C4 once cybernode#1 merges; until then the landings wait on the owner | | 2026-10-27 17:10 | director session 160 | **C4: #407's rehearsal is read in full, and it has two new stack reds, both caused by #406.** The tick was unchanged (`changed=0`), cybernode#1 was still unmerged, and `red-40519226722.json` (`main`, from before the landings) held nothing new, so the unit was what no session had recorded: 40525967811's mac and stack legs. The mac legs are no worse than 40446879208. On the stack leg, **stack-chain-genesis** is red (all 54 `chain.snap` entries `(new)`: cybernode `52538a6` reads its own tree; cybernode#1 `31fca56` fixes it) and **simulation-gate** is red (simulation's lock still has soft3 0.10.0; simulation is read-only to us). Dispatched diagnostic **40547036801** (`diag/simulation-lock`, never merged) to resolve simulation's lock on the train's stand and run both gates with `--locked`. Nothing merged except this plan PR. No subagent: a measurement workflow adapted from `diag/cybernode-lock-snap`, not product code. No fable question. Next: read 40547036801, then the simulation lock PR from a fork | +| 2026-10-27 17:40 | director session 161 | **C4: #406's two stack reds close on the train's stand; simulation's lock went to the owner as simulation#2.** Diagnostic 40547036801: simulation-gate success (16 scenarios, 0 fail, economy's 2 expected reds) with the lock re-resolved for soft3 0.11 (only `cybernode` added and `soft3` repointed), and stack-chain-genesis success (`chain.snap: 54 entries, no drift`) with cybernode#1 `31fca56`. Forked simulation and opened **simulation#2** (draft, `5518998`). It merges when soft3 `main` reaches 0.11, not before, because the train takes simulation at `main` HEAD. Receipt on #407 (comment 6448798473). Tick `20261027T172110Z`: the drift is the same in kind. `red-40519226722.json` (`main`, from before the landings) holds nothing new. cybernode#1 is still unmerged. Nothing merged except this plan PR. No subagent: a lockfile copied from its receipt. No fable question. Next: C4 once cybernode#1 merges (pin, `cybernode-tests` gate, rehearsal with `simulation=pull/2/head`) |