docs: W1 done, D3 resolved, and D4's constant-pool recommendation REVERSED - #238
Conversation
W1's gate is green in blockly-rs (4d39590) and the three follow-ups the plan listed as prerequisites have landed (31e18fb, e4b5e7e). Recorded here rather than left to the commit log, per the append-only rule. D4's recommendation is REVERSED, in place rather than rewritten. The Inventory host conflates two codebooks: Inventory indexes functions, which are shared by definition; constants are per-function data, which are owned by definition, so a pool there is a shared-mutable sink with N writers. Shipped instead is a sibling pool node with per-facet classids naming each constant's type — an f64 and a UTF-8 string are different readings of 12 bytes, and a discriminant byte inside the payload would be a second schema under one classid. Two further options are recorded as killed by named constraints so they are not re-proposed: literal-as-call-run breaks the W1 one-write gate (call count would track literal width), and stealing content slots makes the call budget per-function so a new string can overflow the calls. The pool remains gated on an operator mint and is opt-in in code: lower_script still refuses a wide literal, so a placeholder classid cannot reach stored data before the concepts exist. The proposed ids are labelled a proposal, and the cheap alternative (one concept plus a type-tag byte) is refused on the record. D3 resolved with two anchors, because the obvious one was insufficient: the census compared against SYMBOLS, so a renumber upstream would have left it passing while every stored program changed meaning. W2's producer half is recorded with the reasoning for the ordinal choice and the injection that proved its falsifier non-vacuous.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_6f80a617-a032-4c20-81fc-2b95a10139f1) |
…W4 gap Marks every wave DONE and records what the work found, including two places the plan's own audit was wrong and one place it missed a defect. W2's audit was corrected on two points by reading the source: Form and Flow do not map the position address at all (they place by iteration order), so Grid is the FIRST address-driven skin rather than a symmetric addition; and FACET_LEN=12 is a byte WIDTH, not a facet count — the framing that a prior session's withdrawn truncation claim died on. It also missed the real defect: an out-of-range mask position was silently dropped while apply returned Ok. W4 is marked done with an explicit gap rather than a claim: the lowering is proven end-to-end, but the gate as written names a .sb3 round-trip and no .sb3 is imported yet. Saying so is cheaper than letting a future session discover it. D1/D2/D5 resolved as recommended; D3 and D4 already recorded above, D4 reversed.
The previous entry marked W4 done with an explicit gap: the gate names a .sb3 round-trip and none was imported. That gap is now closed, and the entry records how rather than merely that. The arms meet at execution rather than at the IR — not a compromise. An IR diff is not available (load_block takes a CompileContext with private fields and no public constructor), but it would also be the weaker check: a structural diff is satisfied by two trees that are equal and both wrong. Records both injections, because 'identical output' is the easiest assertion in the world to satisfy with an inert harness.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 99d25ee504
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| operator ruling and a ledger correction. | ||
|
|
||
| ### W1 — the POC cast (`blockly-rs`) — **NEXT** | ||
| ### W1 — the POC cast (`blockly-rs`) — **DONE** |
There was a problem hiding this comment.
Keep W1 open until the Blockly prefix is minted
Marking W1 as DONE makes the W1 checklist read as complete, but the same section still names an OGAR-side app-prefix mint for blockly-rs in ogar-vocab::ports; at this commit the ports implementation and allocation table still only reserve the existing app prefixes and have no blockly-rs entry. Anyone starting the W2 address work from this plan will assume the low-u16 render prefix exists and may hardcode or collide on an unallocated value, so either keep W1 partially open or move the mint into explicit remaining work.
Useful? React with 👍 / 👎.
| while "one surface, many skins" quietly collapsed to "one skin". Verified by | ||
| injection. | ||
|
|
||
| ### W4 — execution (`scratch-rs`, GPL leaf) — **DONE** |
There was a problem hiding this comment.
Keep W4 open until the .sb3 gate passes
This heading declares W4 DONE, but the newly added falsifier status below says the required .sb3 parity gate is not met and that rash_loader_sb3::ProjectLoader plus a fixture project are still remaining W4 work. That contradiction makes the wave tracker claim execution is complete while the plan's own release gate is still open, so downstream scheduling can skip the actual import/parity work.
Useful? React with 👍 / 👎.
…med was real Codex flagged W1 as marked DONE while its own section still named an unfinished app-prefix mint, warning that someone could hardcode a colliding value. Correct, and the hypothetical was already instantiated: blockly-abi's Klickwege tests used 0x1000, which ogar-vocab::ports reserves for the V3-adoption monitor marker with a test asserting it must never be a port APP_PREFIX. Fixed in blockly-rs e53aefe. W1 is now 'DONE (one mint outstanding)' and the mint moved into a new Remaining section that collects all three open operator decisions in one place, with the allocation state and the reserved value recorded so the next reader does not re-derive them. No value is proposed for any of the three — a mint is an operator decision by standing rule. Codex's other P2 (W4 marked DONE while its gate was open) was already resolved in 7077e3a, one commit after the 99d25ee it reviewed: the .sb3 gate is green.
|
Both P2s addressed. W1 (line 81) — correct, and the risk it names was already instantiated. Fixed in W1 is now DONE (one mint outstanding) and the app-prefix mint is moved into a new § Remaining — operator mints, which collects all three open decisions in one place. The concrete part: Worth noting what limited the blast radius: W4 (line 258) — already resolved. This reviewed The arms meet at execution rather than at the IR. That is not a compromise: an IR diff isn't available ( Both injections were run, because "identical output" is the easiest assertion in the world to satisfy with an inert harness: changing the fixture to Generated by Claude Code |
Records what landed in
blockly-rsfor W1 and reverses D4's recommendation in the plan doc. Docs only — no code in this repo changes.W1 is done, and the gate is green
The falsifier — a drag produces zero SoA writes, an operand change produces exactly one — passes in
blockly-rs(4d39590). Both halves route throughWorkspace::apply, so a handler that let a drag reach the record fails the test. Verified by injecting exactly that leak and confirming two tests fail; without the apply step the first half would have beenf(x) == f(x), which is how the first version was written and why it was rewritten.D4 — the recommendation is REVERSED
The plan recommended the Inventory SoA as the constant pool's home. That is withdrawn, in place rather than rewritten.
It conflates two codebooks. Inventory indexes functions, which are shared by definition; constants are per-function data, which are owned by definition. A per-function pool in the one table every function shares is a shared-mutable sink with N writers.
Shipped instead: a sibling pool node — same 30 content slots, same 16-byte stride, identity inherited from the owning function, and a per-facet classid naming each constant's type. An
f64and a UTF-8 string are different readings of 12 bytes, so a discriminant byte inside the payload would be a second schema under one classid.Two further options are recorded as killed by named constraints, so they are not re-proposed:
255→1000000rewrites the tail of the bodyCapacity is explicit: 255 usable indices, 30 per node, 9 nodes; the 256th is
PoolFulland the remedy is a function split, never a wider index. Reachable only underQuads(270 addressable value bytes > 255).Still gated on an operator mint. The pool is opt-in in code —
lower_scriptstill refuses a wide literal, and onlylower_script_with_poolinterns, under caller-supplied classids with deliberately invalid placeholders in the interim. The proposed ids (0x1703..0x1705) are labelled a proposal, not an assumption, and the cheap alternative (one concept plus a type-tag byte) is refused on the record.D3 — resolved, with two anchors because one was insufficient
The pre-existing census compared against
FnIndex::LT— the symbol. A renumber upstream would have left every symbolic assertion passing while every stored program changed meaning. So the bytes are now pinned too, and asserted mutually distinct, so a collapsed palette cannot be matched by a collapsed expectation table.ValueParam encoding
A code encodes as its ordinal in the codebook's own pinned table, keyed on
(block type, field name)— deliberately not Blockly's live array order, since reordering an options array is cosmetic upstream and would silently reinterpret stored programs here. Keyed on the field becausetext_getSubstring'sWHERE1/WHERE2differ only in their third entry.W2's producer half
Recorded with the reasoning for the ordinal choice: the ordinal is the call index, so
raise_calls(body)[ordinal]IS the clicked block's call by construction, which makes an address checkable against the ABI rather than merely self-consistent. Proven non-vacuous by injection — a pre-order walk yields unique, dense, plausible ordinals and fails two tests.Companion
AdaWorldAPI/blockly-rs@e4b5e7e— 47 tests,fmt/clippy -D warnings/ rustdoc broken-link gates clean.Generated by Claude Code