feat(P4): autopoiesis-triangle wiring on the SoA/ractor carrier (Bricks 1-2)#729
Conversation
The autopoiesis triangle (FrozenStyle/LearnedStyle/ExploreStyle, shipped #717 as NodeRow value tenants) needs a SoA-native read seam so the ractor KanbanActor — the sole-mutator MailboxSoaOwner — can read FrozenStyle during CognitiveWork and the planner can project the lanes. Everything is SoA: the triangle read is a MailboxSoaView column read, not a symbiont Vec<NodeRow> access (symbiont is the deprecated/blocked arm). Adds, following the established deferred-binding pattern (identity_plane_at / edge_block_at — default None, the owner overrides): - StyleLane { Frozen, Learned, Explore } (mirrors IdentityPlane). - MailboxSoaView::style_lane_at(row, lane) -> Option<[u8;12]> (default None). - MailboxSoaView::triangle_at(row, family) -> Option<(u8,u8,u8)> composing the three lanes, with the family>=12 guard (the #717 triangle_for aliasing guard) so an out-of-range family is None, never an aliased slot. Non-breaking (all defaults): existing MailboxSoaView/Owner impls (surreal_container read view, MailboxSoa owner, planner consumer) compile unchanged; the in-RAM MailboxSoa owner overrides these when it materializes the triangle columns (Brick 2). +2 tests: default-None deferred binding, and an owner override proving triangle_at composition + the family-range guard. Corrected carrier per operator ruling: symbiont deprecated; everything is SoA; every thinking is an owned SoA kanban update; ractor is the compile-time ownership guarantee (KanbanActor &mut state, E-CE64-MB-4). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Awg6TXocHcwTtc6eGsHcdD
…4 Brick 2) Wire the autopoiesis triangle onto the SoA — the corrected carrier. The lanes are three per-row [[u8;12];N] columns on MailboxSoA<N> (the in-RAM MailboxSoaOwner the ractor KanbanActor owns), NOT a symbiont Vec<NodeRow> (deprecated). Value = a palette256 atom indexed by StyleFamily ordinal 0..11; atom 0 = null (a zeroed lane reads all-null, never a wrong policy). Adds: - frozen_style / learned_style / explore_style columns (zero-init). - MailboxSoaView::style_lane_at override (real read, populated-guarded — the KanbanActor reads FrozenStyle during CognitiveWork through the real view). - Owner write ops (crate-visible, &mut self, un-gated — no planner dep): set_style_lane, set_style_atom, promote_family (frozen[f] := learned[f], returns whether it changed). Per R1 these are the owner's own cognitive ops; the VALUE decisions (explore coprime-walk atom, NARS-revision learned atom) belong to the caller (KanbanActor phase handlers, Brick 3). Every op is &mut self, so when driven from KanbanActor::handle (whose State IS this owner) the single-writer no-aliasing guarantee is compile-time (E-CE64-MB-4, ractor sole-mutator), not by-convention — the exact hazard the ancestry map flagged on the old symbiont path. Guards: family>=12 is a no-op (the #717 triangle_for aliasing guard); row>=populated is a no-op (logical-row discipline). +1 test: owned write/read/promote round-trip, idempotent promotion, field isolation across the 11 untouched family slots, and both guards. 104/104 lib tests green, clippy clean (no new warnings). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Awg6TXocHcwTtc6eGsHcdD
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_8adb500f-2f89-45ba-8d43-ab4c22ffd412) |
|
Warning Review limit reached
Next review available in: 50 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds a frozen 256-address cognitive palette contract, StyleLane and triangle accessors to ChangesTriangle lane pipeline
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b750881af3
ℹ️ 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".
Codex caught a real stale-policy leak: reset_row cleared every other per-row column (energy/plasticity/sentinels/thoughtspace/identity planes) but not the new frozen_style/learned_style/explore_style lanes. A reused row would read an old checkpoint/learned/explore policy via style_lane_at instead of the documented all-null default — the exact class of leak the existing reset field-isolation tests guard against for the other columns. Fix: reset_row zeroes the three lanes (atom 0 = null). Regression: the triangle test now writes all three lanes on a row, resets it, and asserts the all-null default returns. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Awg6TXocHcwTtc6eGsHcdD
Operator ruling 2026-07-18: "226 ARE the frozen; anything else needs 6x2x8bit (12 slots for an Orchestration for v3 substrate replayability)." This lands the FROZEN half — the 226-atom palette256 value catalogue that the FROZEN triangle lane's 12 bytes index (12xu8 reading). The LEARNED/EXPLORE orchestration reading of the same content-blind register is the 6x(8:8) le-contract §3 register (replayable, E-H268-REPLAYABLE-TILE-1) — a separate follow-up, not this catalogue. cognitive_palette.rs — a zero-dep ADDRESSING table (I-VSA-IDENTITIES: address space only, content resolves in the registries): - AtomId(u8): 0 null | 1..=144 Verb (holograph dntree) | 145..=178 Recipe (34 NARS runbooks) | 179..=214 Persona (ThinkingStyle::ALL 36) | 215..=226 Family (StyleFamily::ALL 12; local == ordinal) | 227..=255 reserved. - AtomCatalogue resolve() — total over all 256 bytes, never panics. - verb/recipe/persona/family constructors (bounds-checked), AtomId::NULL. - const-asserted layout (ATOM_COUNT==226, RESERVED_BASE==227, 29 reserved). - RESERVE-DON'T-RECLAIM: offsets permanent (consumers store bare u8), append only into the 29 reserved slots. Distinct from the LOCKED 33-dim atoms.rs ThinkingStyleVector basis: that is the style-VECTOR lane basis; this is the FROZEN lane's VALUE catalogue. The composition (144 verb ∥ 34 recipe ∥ 36 persona ∥ 12 family; 30 reserved) is the triangle plan §1 spec; all four source counts verified against the real catalogues before freezing offsets. 6 tests; clippy clean. Board: LATEST_STATE Contract Inventory updated (same commit, hygiene rule). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Awg6TXocHcwTtc6eGsHcdD
…r (P4 Brick 4) Completes the operator's "one register, two readings" ruling (2026-07-18): "226 ARE the frozen; anything else needs 6x2x8bit (12 slots for an Orchestration for v3 substrate replayability)." The 12×u8 FROZEN reading (style_lane_at → 226-atom palette256, shipped) is the frozen half; this is the "anything else" half. MailboxSoaView::style_rails_at(row, lane) -> Option<[(u8,u8); 6]> reads the SAME 12-byte content-blind register as the six (u8:u8) rails (le-contract §3, 12 = 6×2): the V3-replayable orchestration reading (L1 part_of:is_a / L4 palette256², E-H268-REPLAYABLE-TILE-1). rail k = (lane[2k], lane[2k+1]). One register, two ClassView-selected readings — identical bytes, different interpretation. Default composes style_lane_at, so any owner materializing the lane (MailboxSoa) gets it for free; None when unmaterialized. +2 tests (rail carving on known bytes + deferred-None). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Awg6TXocHcwTtc6eGsHcdD
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/lance-graph-contract/src/soa_view.rs`:
- Around line 180-217: Establish one canonical triangle representation and apply
it consistently: in crates/lance-graph-contract/src/soa_view.rs:180-217,
separate palette and orchestration accessors or formally define every lane as
12×AtomId; in crates/lance-graph-contract/src/cognitive_palette.rs:16-20, update
the documented contract to match; in
crates/cognitive-shader-driver/src/mailbox_soa.rs:155-171, use
representation-specific storage types or document the unified atom format; and
in crates/cognitive-shader-driver/src/mailbox_soa.rs:762-825, make
Learned-to-Frozen promotion explicitly convert orchestration registers instead
of copying bytes as palette atom IDs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 01b07e04-9008-4e88-a108-2c669f73ccb3
📒 Files selected for processing (5)
.claude/board/LATEST_STATE.mdcrates/cognitive-shader-driver/src/mailbox_soa.rscrates/lance-graph-contract/src/cognitive_palette.rscrates/lance-graph-contract/src/lib.rscrates/lance-graph-contract/src/soa_view.rs
…class, not per-lane (CodeRabbit #729 Major) CodeRabbit flagged a real coherence gap: the palette doc implied Learned/ Explore are 6x(8:8) orchestration registers while the view/storage exposed them as 12 palette atoms, so promote_family could reinterpret an orchestration byte as a Frozen palette atom ID. Resolution (forced by the le-contract §3 content-blind-register rule): the reading is ClassView-selected PER ROW/CLASS, never per lane. A policy/thinking row reads all three lanes as 12xu8 palette atoms; an orchestration row reads all three as 6x(8:8) rails. Frozen/Learned/Explore therefore always share one representation within a row, so promote_family's byte copy is representation-preserving by construction (AtomId->AtomId, or rail->rail, never across). The 6x(8:8) is the ALTERNATE reading of the same register, not a per-lane property of Learned/Explore. Doc-only (storage stays uniform [[u8;12];N], promotion stays a byte copy): - cognitive_palette.rs: reading is per-row/class; all three lanes palette in a policy row; promotion coherent. - soa_view.rs style_rails_at: the alternate reading, ClassView-selected per row-class; exposes rails mechanically, whether a row uses it is the ClassView's call. - mailbox_soa.rs: column block + promote_family doc — representation-preserving by construction; write ops are byte-level and representation-agnostic. Tests unchanged and green (contract 6/6 palette, shader triangle 1/1). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Awg6TXocHcwTtc6eGsHcdD
…e two-place model Operator directives (2026-07-18) fold into the M20 assembly plan: - Base layout has ONE root (lance-graph-contract), consumed by the OGAR-aligned cluster (lance-graph-ogar + OGAR + ogar-vocab). Awareness facets are OGAR-minted ClassView READINGS over one reserved facet region, NOT 19 named base ValueTenant variants — supersedes the auditor's bake-19 path. Activation overridable in 2 places (base region + OGAR mint); shrink later = re-mint (drop redundant readings), no base edit, no ENVELOPE_LAYOUT_VERSION bump. - Reuses the mechanism #729 P4 SHIPPED the same day: MailboxSoaView::style_rails_at (6x(8:8) ClassView-selected reading) + the "one register, two readings, per-class-not-per-lane" doctrine (3248bd9). Awareness facets = additional style_rails_at-shaped readings, one rung wider; style_lane_at (226-atom FROZEN palette256) is the frozen sibling. - Single-import prerequisite = close ENTROPY M21 (woa-rs/q2 NodeGuid hand-copies). symbiont is deprecated (surrealdb -> OGAR); its bridge.rs NODE_ROW_STRIDE copy retires with symbiont, not a fix target (drops the W2c SurrealDB arm from the live path). - Auditor LAYOUT-GATED verdict re-scoped: the delta is now reserve ONE facet region + the reading contract, re-audit needed before any canonical_node.rs edit. Rebased onto origin/main (picks up #729 P4 triangle bricks + the merged D-AW-1 via #730). Doc-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016b33swuXE23hKtqxsHu9p1
… tenants recipe_claim_audit exercises the REAL shipped recipe_kernels: 28/34 recipes measure/realize their claim on the ThoughtCtx proxy (2 INERT bugs CAS/ETD, 4 CONSTANT input-independent ARE/ZCF/ICR/HKF), but 34/34 read ONLY the scalar proxy basis — none touch the SPO/CAM-PQ/Markov/qualia organ they name. The dominant weakness is substrate-wiring, not recipe composition. Wire the three real tenants into the recipe input: - causal_witness::CausalWitnessFacet — A9 "24 edges": a reading of the 12-byte content-blind register as 24 signed i4 loci (G24N4), each a context pointer into the ±8 Markov window. The THIRD ClassView reading of the same register #729 shipped two of (FROZEN 12xu8 + Orchestration 6x(8:8)); no stored bytes. - recipe_substrate::SubstrateView — projects SPO + witness + qualia into the recipe input. Qualia is ADDITIVE + STAKES-only (temperature, never logic); causality is the witness KAUSAL edge, not a qualia; a missing tenant emits NaN/empty (the NaN-disqualifier signal). - recipe_dispatch — the 34 as a rung-ordered, NaN-gated causal ladder keyed by NARS inference type (deduction/induction/abduction/revision/counterfactual). Thinking is a causal act: the ladder is a causal chain, each step logs its triggering cause (Versuchsleitereffekt = observer effect), dispatch is a deterministic Schroedinger collapse, a NaN input is an unmeasurable conjugate. 3 modules + 3 probes (recipe_claim_audit, loci_recipe_relevance, recipe_ladder_over_substrate — all gates green), +18 tests -> 970 green, clippy clean. Additive, zero-dep, nothing existing touched. Board hygiene: E-RECIPE-SUBSTRATE-WIRING-1, LATEST_STATE, STATUS_BOARD D-REC-WIRE-1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
P4 — ancestry pipeline consolidation, on the corrected carrier
Operator ruling this session: symbiont is deprecated; everything is SoA; every thinking is an owned SoA kanban update; ractor is the compile-time ownership guarantee. An earlier implementation map routed the triangle wiring through
symbiont/kanban_loop.rs'sVec<NodeRow>— wrong. The correct carrier is theMailboxSoaowned by the ractorKanbanActor(lance-graph-supervisor), whosehandleis the sole mutator (&mut state, one message at a time → no aliasing = E-CE64-MB-4 realized by ractor's serialized mailbox, not a lock).This PR lands the SoA-native foundation for the autopoiesis triangle (
FrozenStyle/LearnedStyle/ExploreStyle, shipped #717 as NodeRow value tenants).Brick 1 — triangle read seam on
MailboxSoaView(contract)StyleLane { Frozen, Learned, Explore }(mirrorsIdentityPlane).MailboxSoaView::style_lane_at(row, lane) -> Option<[u8;12]>+triangle_at(row, family) -> Option<(u8,u8,u8)>, both deferred-binding (defaultNone, the owner overrides) — the establishedidentity_plane_at/edge_block_atpattern.triangle_atcarries thefamily >= 12guard (the feat(contract): D-TRI-1 value-tenant half — autopoiesis triangle (3 SoA lanes) #717triangle_foraliasing guard).MailboxSoaView/Ownerimpls compile unchanged.Brick 2 — triangle SoA columns + owned write ops (
cognitive-shader-driver)[[u8;12]; N]columns onMailboxSoA<N>(zero-init; atom 0 = null).style_lane_atoverride (real read,populated-guarded) — the KanbanActor readsFrozenStylethrough the real view.&mut self, un-gated — no planner dep):set_style_lane,set_style_atom,promote_family(frozen[f] := learned[f], returns whether it changed). Per R1 these are the owner's own cognitive ops; the value decisions (explore coprime-walk atom, NARS-revision learned atom) belong to the caller (Brick 3).&mut self→ driven fromKanbanActor::handlethe single-writer guarantee is compile-time, resolving the "owner-only by convention" hazard the map flagged.Tests
Brick 1: default-
Nonedeferred binding + owner override provingtriangle_atcomposition + the family-range guard. Brick 2: owned write/read/promote round-trip, idempotent promotion, field isolation across the 11 untouched family slots, both guards.lance-graph-contract6/6 soa_view +cognitive-shader-driver104/104 lib green; clippy clean (no new warnings).Deferred (deliberately, for review/operator steer)
KanbanActor::handlewiring — CognitiveWork reads Frozen, Evaluation revises Learned + promotes) needs a design decision: where the per-row triangle cognitive op fires (a phase-entry hook on the concrete owner vs an external op) and what supplies the learned atom / winning family (the BusDto outcome + held-out-arm scoring, D-TRI-6). Surfaced rather than guessed.144 verb ∥ 34 recipe ∥ 36 persona ∥ 12 family) does not exist as one indexed table; it overlaps in content with the LOCKED 33-dimatoms.rsTSV and the dntree 144-verb table. Its layout is permanent (RESERVE-DON'T-RECLAIM), so it needs ratification, not a solo guess — Bricks 1-2 work with the family-ordinal value semantics until then.🤖 Generated with Claude Code
https://claude.ai/code/session_01Awg6TXocHcwTtc6eGsHcdD
Generated by Claude Code
Summary by CodeRabbit
New Features
Bug Fixes