ogar-blockly: everything is a call — (function : value), shape-carved - #236
Merged
Conversation
Operator-ruled rework of the function body from a flat opcode stream to the V3 indexed reading: every 12-byte lane is 6x(u8:u8) rails indexed against a label codebook, and the unit is a Call -- function index : value byte(s). There is no opcode/function distinction any more. ADD is function 0x40, a user block is another index in the same <256 codebook, and invoking either is the same bytes. PaletteOp is renamed FnIndex; the Inventory SoA is the label codebook those indices resolve against, which is why labels stay out of payloads (slot purity) while one byte still names anything in scope. Three earlier defects/claims retire in place: - The "nesting gap" is withdrawn. It was an artifact of treating the body as self-delimiting bytecode. Nesting is by reference -- a function index names another function's node -- exactly as SB3 nests via block ids. No END marker, no jump offset, no need. - The operand gap (codex P1 on #235) closes. The value byte is the immediate (WAIT:10, REPEAT:4); computed arguments use a stack discipline ((NUMBER:5)(NUMBER:3)(ADD:_)); wide literals spend the value byte as a constant-pool index (pool is a named follow-up). - Arity is a classid property, not an encoding trick. LaneShape (mirroring CascadeShape G6D2/G4D3/G3D4) carves the same 360 bytes as 180 pairs / 120 triples / 90 quads. A function needing more immediates picks a wider carving, never a wider field. Narrowing is loud: BodyError::ValueBeyondShape refuses a call the shape would truncate instead of dropping a byte. Length recovery is call-level, per shape -- the byte-level rposition regression is caught by test in every shape. Both guards were verified by breaking them: the truncation guard fails the suite with "two immediates must not fit Pairs", the len regression with "Quads: trailing bare call lost". The retired edge-block design (12 in-family + 4 out-of-family) is stripped from this crate's docs; slot 1 is documented reserved- zeroed with the retirement named, so the deprecated shape cannot be re-learned from here. Relations ride the payload rails as indexed calls. Also recorded in the ledger: the operator's literal-over-grammar ruling (grammar lines like A = B + C are a projection over the pair stream, never the storage format) and the baby-steps roadmap -- ABI-shaped Blockly/Scratch first, later a PowerAutomate-shaped low-code editor, both Mario-editor ergonomics over ClassView : WideFieldMask projections. Ledger: docs/DISCOVERY-MAP.md D-BLOCKS-PALETTE (correction 2). Gates: 16 tests pass (2 falsifier break-runs verified), fmt clean, clippy -D warnings clean, workspace check + tests clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011DN5odWu4eisdevH9bPWyz
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_751ef3ad-9cb0-49e1-a9b1-2463afdd8ee0) |
Adversarial review of 450fe91 (4 finder lenses, per-finding refutation): 7 raw findings, 3 confirmed, 4 refuted. The confirmed three collapse to two distinct defects, both doc-level, both real falsehoods about the public surface: - VALUE_SLAB_LEN's doc still linked [OPS_PER_FUNCTION], a constant this rework renamed to BODY_BYTES -- a dangling intra-doc link that also carried the retired "360 of them are operations" framing, contradicting the crate's own "no opcode distinct from a function call". Now links BODY_BYTES and says call payload (180/120/90 calls per LaneShape). - The crate doc's stack example wrote (CONST:5)(CONST:3)(ADD:0), but FnIndex::CONST does not exist -- the numeric literal is NUMBER (0x46), which the test for this exact example already used. Worse, a near-miss FnIndex::CONSTANT (0x5C) exists and means a named math constant, so a reader searching CONST would land on wrong bytes. Now (NUMBER:5)(NUMBER:3)(ADD:0). Deliberately NOT changed: the earlier D-BLOCKS-PALETTE ledger text that names OPS_PER_FUNCTION. That entry is append-only history and accurately described the crate as it stood when written; correction 2 supersedes it in place. Gate added to the routine: RUSTDOCFLAGS="-D rustdoc::broken_intra_doc_links" cargo doc -- the check that catches this class (clippy does not). Clean, alongside 16 tests, fmt, clippy -D warnings. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011DN5odWu4eisdevH9bPWyz
AdaWorldAPI
marked this pull request as ready for review
August 4, 2026 17:24
AdaWorldAPI
pushed a commit
that referenced
this pull request
Aug 4, 2026
Docs-only. Turns the session's rulings into a durable plan and records the a2ui-rs wiring as a ledger entry. docs/BLOCK-EDITOR-PLAN.md sequences W0-W5 with gates, five open decisions, and five falsifiers. It opens by naming what is LOCKED so a future session cannot re-derive it: the 0x17XX domain, the plug-and-play producer posture, the provenance fence, one content classid, (function:value) calls, arity-by-classid via LaneShape, nesting by reference, loud narrowing, literal-over-grammar, and the retired edge block. Every one is shipped code with tests (#234, #235, #236), not intention. The headline finding for the a2ui wiring is that most of it already exists. Charter C1.6 says a click IS a navigates_to/ActionInvocation edge, and a2ui-server already ships receive_action -> KlickwegEdge -> lower_action_fire -> ActionInvocation as pure compile-time value construction (#209, warden COMPILE-TIME-CLEAN, 34 tests). Placing a block, connecting two blocks and clicking a placed block are each a click by ordinal address, so each is already a Klickweg edge. Edit telemetry and harvested-app telemetry unify in one closed predicate set with NO new predicate -- the Predicate enum is count-locked at 79 and extending it is a gated ontology change, not a consequence of this arc. Nesting maps 1:1: the ObjectSlot "A3 Klickwege brick" recursion desktop -> window -> region -> widget becomes canvas -> script -> block -> input, which a2ui-wasm::resolve_nested walks unchanged. The gaps are recorded as measured, not assumed. Interaction-to-edge and nested addressing exist. A palette of pickables, 2-D placement (Skin::Form and Skin::Flow are both 1-D list renderers) and multi-facet body ingest (a2ui-wasm implements one 12-byte facet; a body is thirty) are absent -- none charter-forbidden, but the editor tier is a real build rather than wiring. Drag/connect is the one T2 pressure point: local drag state is fine, the result must travel as an address-carried write. Open decision D2 proposes that "place tile at slot N" rides ActionInvoke{ordinal: PLACE, args:[N, fn]} rather than a third FrameKind: args is explicitly ClassView/ActionDef-carved, so it is an address-carried write, and a third kind would widen a deliberately closed vocabulary. Roadmap order is operator-set: ABI-shaped Blockly/Scratch first, Klickwege wiring second, PowerAutomate-shaped skin third -- both skins Mario-editor ergonomics over ClassView : WideFieldMask, which is T1 applied at editor scale. The W1 falsifier is unchanged from the first turn of the arc: a drag produces zero SoA writes, an operand change exactly one. Ledger: docs/DISCOVERY-MAP.md D-BLOCKS-KLICKWEGE, graded [H] (PLAN) -- the W0 substrate it builds on is [G]/CODED, the wiring is unbuilt. Gates: docs-only; 16 ogar-blockly tests and workspace check re-verified unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011DN5odWu4eisdevH9bPWyz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Operator-ruled rework of the function body from a flat opcode stream to the V3 indexed reading: every 12-byte lane is
6 × (u8:u8)rails indexed against a label codebook, and the unit is aCall=function : value.There is no opcode/function distinction
ADDis function0x40; a user-defined block is another index in the same<256codebook; invoking either is the same bytes.PaletteOp→FnIndex. TheInventorySoA turns out to be the label codebook those indices resolve against — which is why labels stay out of payloads (slot purity §2) while one byte still names anything in scope.Three earlier defects/claims retire in place
1 — The "nesting gap" is withdrawn. The prior correction recorded the absence of a stream delimiter as a real defect. That was an artifact of treating the body as self-delimiting bytecode. Nesting is by reference — a function index names another function's node — exactly as SB3 nests via block ids. No
END, no jump offset, no need.2 — The operand gap (codex P1 on #235) closes. The value byte is the immediate (
WAIT:10); computed arguments use a stack discipline ((NUMBER:5)(NUMBER:3)(ADD:_)); wide literals spend the value byte as a constant-pool index (pool = named follow-up).3 — Arity is a classid property.
LaneShape(mirroringCascadeShapeG6D2/G4D3/G3D4) carves the same 360 bytes three ways:Pairs6 × (u8:u8)fn : valTriples4 × (u8:u8:u8)fn : val : valQuads3 × (u8:u8:u8:u8)fn : val ×3A function needing more immediates picks a wider carving, never a wider field. The shape comes from the classid, uniform per body —
read_from_value_slab(shape, slab)takes it as a parameter because it is never in the slab.Narrowing is loud
BodyError::ValueBeyondShaperefuses a call the shape would truncate instead of dropping a byte. Length recovery is call-level, per shape — the byte-levelrpositionregression is caught in every shape.Both guards verified by breaking them: the truncation guard fails the suite with
two immediates must not fit Pairs; the len regression withQuads: trailing bare call lost.The retired edge-block design is stripped
Slot 1 is documented reserved-zeroed with the retirement named (operator-deprecated this session), so the shape cannot be re-learned from this crate. Relations ride the payload rails as indexed calls.
Also recorded in the ledger
A = B + Clines are a projection over the pair stream, never the storage format — preserving positional addressing, the SIMD sweep, and single-pass lowering into rash'sInputtree.ClassView : WideFieldMaskprojections.Gates
cargo test -p ogar-blockly— 16 pass, 0 failed (2 falsifier break-runs verified)cargo clippy -p ogar-blockly --all-targets -- -D warnings— cleancargo fmt -p ogar-blockly -- --check— cleancargo check --workspace --all-targets— clean; workspace tests cleanexamples/density.rs— re-runnable layout/density accounting per shapeAn adversarial review fleet (4 finder lenses → per-finding refutation) is running over this diff; any confirmed finding lands as a follow-up commit on this PR.
Ledger
docs/DISCOVERY-MAP.md→D-BLOCKS-PALETTEcorrection 2 (append-only; retirements named in place).Generated by Claude Code