Record Soul on Cut 10 (PA.f161-PA.f168)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-23 01:00:50 +02:00
commit c3da080f85

View file

@ -3196,6 +3196,82 @@ Interpreter, the elaborator sweep and lenses.
- **PA.f160 (Cut 9, low):** the additive fold is monotone only while a play
view exists; losing it drops the version by the whole accumulated
revision. Subsumed by PA.f148's fix.
- **Soul on Cut 10** (Opus, 2026-09-23, against `0c09324`, Windows).
- Held: the submodule pin is unmoved; the bridge imports the vendored
lowering's own `dist` and re-spells nothing; the round trip posts
through `api_router`; the binding-shape and envelope fixes are both
killed by their mutations; PA.f148 holds for world commands; PA.f151
holds in a live surface dump (no question id, no `answers` control);
PA.f152 and PA.f159 hold against a second account ("only the world's
owner may play"); admission is genuinely synchronous.
- **Verdict: not ready for the playtest.** PA.f161 and PA.f162 block.
- Triage: PA.f161 to PA.f168 are Cut 11.
- **PA.f161 (Cut 10, high, blocker):** the fold moved out of the document
and into its consumer. `runtime.rs:1233` compares the client's echoed
`sourceVersion` against `authenticated_wake_version`, which is
`surface_version + play.revision`. Both the vendored lowering and
`web/src/main.ts` echo `document.version` alone, and any row that has
ever held a question has `revision >= 1`, so **every answer is refused as
stale, permanently**. `authenticated_wake_version`'s own doc says it is
never a value a client feeds back. PA.f84's safety survives (it
over-refuses), its usability does not.
- **Ruling (Self, under the standing go):** the play row records the
world's `surface_version` at the moment its question opened. An answer
is stale when the client's `sourceVersion` is **older than that**, and
that is the only comparison. The question's identity stays in the row
and is resolved server-side, so PA.f84 keeps its guarantee: an answer
cannot land on a question the player never saw. `playRevision` either
gains this reader or goes (PA.f165).
- **PA.f162 (Cut 10, high, blocker):** the round-trip test shells out to
`node` and needs `jsdom` and `ajv`, which nothing in Ghostlight declares
or installs. On a clean checkout it fails. Idunn's Linux gate runs
`cargo test --locked` in a pinned container that installs no vendored npm
packages and may carry no node, so **the release gate fails before it
builds**. Hands' 145 was measured against `node_modules` left in the main
tree by its own debugging.
- **Ruling (Self, under the standing go):**
- The bridge's captured intents are committed as a fixture, stamped
with the submodule revision that produced them. The Rust test
replays that fixture through `api_router`, so the gate needs no node.
- A second test regenerates the fixture with the bridge and fails if it
differs from what the current pin produces. It runs only when the
bridge is available, and it **says plainly when it is skipped**; a
silently skipped job is a scar this pipeline already carries.
- The `gamecult-ops` runbook gets that dev job. The fixture without
the regeneration check would be a copy of the client's behaviour
pretending to be the client.
- **PA.f163 (Cut 10, medium, fix):** PA.f150's test is vacuous. Deleting
the spawned task's `publish_projection` leaves the whole suite green,
because this same cut made admission synchronous, so `dispatch_world`'s
own Ok arm already published. The test asserts only that `recv()`
returned. The fix is still needed: the question, narration and refusal
all land after the response. **Fix:** assert the wake that follows the
turn's own commit, not the one the response already caused.
- **PA.f164 (Cut 10, medium, fix):** a `world.create` form filled as
labelled is refused with "missing field `targets`". `lens_weights`
carries an authored `value`, which the lowering captures;
`targets` and `jurisdictions` carry only `placeholder`, which it never
captures. **Fix:** seed `"[]"` and `"{}"` as authored values, and check
every other control for the same gap.
- **PA.f165 (Cut 10, low, fix):** `playRevision` has no reader outside
tests. It becomes PA.f161's reader or it goes.
- **PA.f166, PA.f167, PA.f168 (Cut 10, low, fix):** `play.rs:681` still
describes the fold Cut 10 undid; `local_draft`'s doc calls `accessMode`
inert when the lowering disables a control without it; `unwrap_bindings`
discards flat siblings instead of refusing them.
- **Also for Cut 11:** several new doc comments are scar tours — narrating
the previous wrong machine before stating the rule (`eve.rs:215`,
`eve.rs:689`, `runtime.rs:1416`). `AGENTS.md` forbids that, and in
PA.f161's case the narration is where the false claim lived.
- **Unverified leg, for the playtest:** seeding is still gated on
`GHOSTLIGHT_SEED_VAULT_ROOT`. The round trip proves the payload reaches
the vault lookup, never that a seed succeeds. Nobody has run that end to
end.
- **Judgement on `deserialize_json_capture`:** kept, narrowly. It is the
smallest server-side accommodation for a lowering with no JSON control,
but it loosens the payload for every caller, including CultMesh, to buy
something only the browser needed. It must not become the reason
structured controls never arrive.
- **PA.f77 (introduced by 7c, medium, fix):**
`table_view_prints_only_a_subjects_own_granted_affordances`
(`table.rs:2886`) fails about one run in four. Its unscoped