The codebook is TRIGGERED by plug-and-play, not minted - #257
Conversation
Builds the activation path I had been calling "not built yet" as though it were an external constraint. It was mine. The mechanism: `resolve_hotplug` resolves a plugged classid against `class_ids::ALL` FIRST, then against whatever a compiled-in feature ACTIVATED. Canon wins — a feature can ADD a concept the global codebook lacks; it can never SHADOW one it has. `ogar-vocab` gains a `blocks` feature, off by default, carrying the Blocks palette concept (0x1717) + its capability table. `ogar-blockly` deps `ogar-vocab` with `features = ["blocks"]`, so activation is CARGO PRESENCE, not runtime detection — the same rule lance-graph-ogar documents. A consumer that never touches a block editor never compiles the module and sees 0x17XX exactly as before: a reserved domain, zero concepts. Critically, `class_ids::ALL` is UNCHANGED at 90. That surface is mirrored into lance-graph under a compile-time count fuse, so minting there is by construction a lance-graph change — which is how the earlier attempt turned lance-graph red. The activated rows live beside it and are consulted alongside it, never merged in. One source of truth for the id: `BLOCK_PALETTE` is declared here and READ by `ogar_blockly::BlockConcept::Palette`. The reverse is impossible (ogar-blockly deps ogar-vocab), and two constants for one id is exactly the drift the join exists to catch. A real bug the tests caught, worth recording: `derive_action_rows` resolved `object_class` through the CODEBOOK only, so the concept resolved as a plugged classid (plug accepted) while its capabilities silently fell into the slag ledger — the port answered `NoCapabilitiesFor(0x1717)` for a table sitting right there. BOTH halves of the join must consult the same set; `activated_concept_id` is the by-name half of `resolve_concept_row`'s by-id lookup. Proven both ways in a SEPARATE crate outside this workspace, so feature unification could not fake it: feature OFF -> Err(UnknownClassid(5911)) zero 0x17XX rows feature ON -> resolves, all 5 capabilities Plus tests asserting 0x1717 is absent from class_ids::ALL (or "it resolved" proves nothing about WHERE), that plugging 0x1701/0x1702 does NOT resolve (they are the substrate's), and the three drift arms. Workspace: 80 test binaries, 0 failures. clippy -D warnings clean with the feature on. fmt scoped with -p, never --all.
Six files this change never touched (ogar-encryption, ogar-obo x4, ogar-render-askama) picked up formatting churn again. The path is worth naming because it is not obvious: running `cargo fmt --all` from INSIDE blockly-rs — which now path-deps OGAR — followed the dep OUT of that repo and reformatted OGAR's sources in this working tree. Same trap, third instance this session, each at a different distance: 1. `cargo fmt --all` inside OGAR -> 309 lines of churn 2. `cargo fmt --all` in blockly-rs CI -> failed on ogar-render-askama 3. `cargo fmt --all` in blockly-rs -> silently dirtied THIS tree The lesson generalizes past fmt: once a repo path-deps a sibling, EVERY workspace-wide cargo flag reaches into that sibling. Scope with -p, in CI and at the keyboard both. blockly-rs's CI is already scoped; this is the working-tree half of the same rule. These files are restored to their committed state, not reformatted — whether OGAR main should be fmt-clean is OGAR's call, and making it so from a blockly-rs session is precisely the boundary violation that started this arc. Workspace still 0 failures after the revert.
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_7ee889c2-3f7f-497e-97db-1b12d664a632) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 716bc9ce05
ℹ️ 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".
| activated_concepts() | ||
| .iter() | ||
| .find(|&&(_, cid)| cid == id) | ||
| .copied() |
There was a problem hiding this comment.
Recognize activated IDs in
verify_registration
When the blocks feature is enabled, resolve_hotplug now accepts 0x1717 through this activated-concept lookup, but the other public registration path, verify_registration, still checks every subject only against class_ids::ALL. Consequently, a CapabilityRegistration using BLOCKS_SUBJECT_CLASSIDS, the matching action names, and the expected blockly-abi consumer deterministically returns RegistrationDrift::Unminted(0x1717) even though this feature declares the ID as minted; the activated lookup needs to be shared with that verifier as well.
Useful? React with 👍 / 👎.
#257 shipped the plug-and-play activation but tested it in only ONE direction, which I noticed after it merged. `cargo test --workspace` cannot exercise the off path: `ogar-ro` dev-deps `ogar-blockly`, so feature unification turns ogar-vocab's `blocks` feature ON for the entire workspace run. Every test asserting "activated" therefore ran, and nothing ever asserted "not activated" — the exact vacuous shape of a guard nobody watched stay silent. The one proof I had was a throwaway crate outside the workspace, which CI never sees. Two tests under `cfg(all(test, not(feature = "blocks")))`, so they VANISH when any activating feature is on rather than passing hollowly (measured: 2 tests off, 0 tests on). They assert a default build activates nothing, that 0x1717 answers UnknownClassid, that the domain still routes on the reserved byte alone, and that no 0x17XX row ever reached `class_ids::ALL` — the surface mirrored into lance-graph under the compile-time fuse, caught on THIS side first. Plus the CI step that can reach them: `cargo test -p ogar-vocab`, crate-scoped so `ogar-blockly` is not in the graph. The gate is verified to fail when it should: seeding one row into the `not(blocks)` arm of `activated_concepts` turned the first test red, then restored.
Builds the activation path I had repeatedly described as "not built yet" as though it were an external constraint. It wasn't — it was mine, and this is it.
The mechanism
resolve_hotplugresolves a plugged classid againstclass_ids::ALLfirst, then against whatever a compiled-in feature activated. Order is deliberate: canon wins. A feature can ADD a concept the global codebook lacks; it can never SHADOW one it has.ogar-vocabgains ablocksfeature — off by default — carrying the palette concept (0x1717) and its capability table.ogar-blocklydepends onogar-vocabwithfeatures = ["blocks"], so activation is Cargo presence, not runtime detection (the rulelance-graph-ogaralready documents). A consumer that never touches a block editor never compiles the module and sees0x17XXexactly as before: a reserved domain, zero concepts.class_ids::ALLis UNCHANGED at 90That surface is mirrored into
lance_graph_contract::ogar_codebookunder a compile-time count fuse, so minting there is by construction a lance-graph change — which is how the earlier attempt turned lance-graph red and dragged inogar-class-view,all_promoted_classesand both fuse halves. The activated rows live beside the canon and are consulted alongside it, never merged in. A block editor's palette is not lance-graph's concern.Proven both ways, outside this workspace
Tested from a separate crate so feature unification could not fake the negative half:
Plus tests asserting
0x1717is absent fromclass_ids::ALL— without that, "it resolved" proves nothing about where it resolved from — that plugging0x1701/0x1702does not resolve (those are the substrate's, and a consumer claiming them would own the shape every sibling rides), and all three drift arms.A real bug the tests caught
derive_action_rowsresolvedobject_classthrough the CODEBOOK only. So the concept resolved as a plugged classid (plug accepted) while its capabilities silently fell into the slag ledger, and the port answeredNoCapabilitiesFor(0x1717)for a table sitting right there. Both halves of the join must consult the same set —activated_concept_idis the by-name half ofresolve_concept_row's by-id lookup.One source of truth
BLOCK_PALETTEis declared here and read byogar_blockly::BlockConcept::Palette. The reverse is impossible (ogar-blocklydepsogar-vocab), and two constants for one id is exactly the drift the classid join exists to catch.Verification
cargo test --workspace— 80 test binaries, 0 failurescargo clippy -D warningswith the feature ON — cleancargo fmtscoped with-p, never--allThe second commit reverts fmt churn that leaked in from running
cargo fmt --allinside blockly-rs, which now path-deps OGAR and so reached back into this tree. Third instance of that trap this session, at three different distances; the generalizable rule is that once a repo path-deps a sibling, every workspace-wide cargo flag reaches into that sibling.Generated by Claude Code