feat(contract): episodic-RISC-spine — VersionScheduler + head2head + EpisodicEdges64 + ViewAngle (D-MBX-9-IN, D-H2H-1, D-EW64-1, D-VIEW-1)#446
Conversation
The dual of MailboxSoaOwner (E-SUBSTRATE-IS-THE-SCHEDULER): lowers a Lance
versions() tick to the next legal KanbanMove. Zero-dep, read-only over the
MailboxSoaView (propose-not-dispose, R1); composes only existing contract types
(MailboxSoaView / KanbanColumn / KanbanMove / ExecTarget).
- scheduler::{DatasetVersion(u64), VersionScheduler (trait), NextPhaseScheduler}
- NextPhaseScheduler: Rubicon forward-arc; Libet -550us on Planning->CognitiveWork;
None on absorbing (Commit/Prune). 6 tests.
- 509 contract lib tests (+6); scheduler.rs clippy pedantic+nursery clean.
First verifiable slice of the "wire all loose ends" agent wave (4 grounding agents
mapped reactive seam / thinking+JIT / world-spine / hot-path+bindspace). Firewall
kept: EW64+markov_soa is the particle->wave; old Vsa16kF32 singleton hunted, not
re-materialized. CI-gated twin (LanceVersionScheduler over VersionedGraph::versions())
named not written (no protoc offline).
Board: AGENT_LOG wave entry + LATEST_STATE inventory + STATUS_BOARD D-MBX-9-IN row.
https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
head2head::{Head2Head, WinnerCriterion, CompetitionOutcome} — picks the winning
competing-expert bid over the existing a2a_blackboard. Pure read + arg-extremum:
no new identity, copies nothing (select-not-duplicate, I-VSA-IDENTITIES). Go
metaphor: DissonanceMin=infight, SupportSpread=Raumgewinn, Tempered=default;
margin = the dark-horse signal. The SELECTION half of item-4 superposition;
the parallel-mailbox executor is the CI-gated consumer side.
516 contract lib tests (+7); head2head.rs clippy pedantic+nursery clean.
Board: LATEST_STATE inventory + STATUS_BOARD D-H2H-1.
https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
…EW64-1, D-VIEW-1) + plan v1
AriGraph episodic edges, RISC-encoded (the corrected EW64, replacing the earlier
"CE64 lens"/"16-bit pointer" framings):
- episodic_edges::{EpisodicEdges64(u64), EdgeRef} — 4x[4-bit family | 12-bit local].
family 0 = intra-basin (inherited from HHTL/class_id, ~98.6% per #444);
1..=15 = cross-family index into the OGIT-class-inherited palette (~1.4%).
Identities inherited, never on the edge (I-VSA-IDENTITIES); a CAM_PQ facet code.
- view_angle::ViewAngle — 4-bit view-schema selector; the class presence bitmask
doubles as the attention mask (inherited view-schema, never per-instance semantics).
527 contract lib tests (+11); both files clippy pedantic+nursery clean.
Plan: .claude/plans/episodic-risc-spine-v1.md (3 lifecycle-separated structures:
CAM/OGIT identity, Lance-version pseudo-radix index, CLAM ephemeral KV; bounded-horizon
compression). Finding: EPIPHANIES E-EPISODIC-CLOSURE. CI-gated next (no protoc offline):
D-EW64-2 SoA columns, D-STORY-1 CLAM clusterer, D-STORY-2 session index,
D-STORY-3 palette256/4096 archetypes, D-HORIZON-1 stopping rule.
Board: INTEGRATION_PLANS + LATEST_STATE + STATUS_BOARD + EPIPHANIES + AGENT_LOG.
https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
…roken) bc6a29f pushed broken — lib.rs carried the re-exports WITHOUT the module declarations (E0432), compounded by duplicated content from a garbled edit cascade (6x `pub mod view_angle`, a dup `pub mod jit`, two `EpisodicEdges64` struct defs → size_of 16 not 8). - lib.rs: restored from 5bd02d9 + re-added `pub mod episodic_edges;` + `pub mod view_angle;` + the two re-exports, deterministically (once each). - episodic_edges.rs + view_angle.rs: clean full rewrites (dup defs removed). - INTEGRATION_PLANS: register episodic-risc-spine v1 (missed bc6a29f's commit). cargo test -p lance-graph-contract --lib -> 527 passed, 0 failed. Both files clippy pedantic+nursery clean; board entries verified single. https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
…-cascade) The episodic-wave board edits got duplicated by a garbled edit/retry cascade (2x each in LATEST_STATE/STATUS_BOARD/EPIPHANIES/AGENT_LOG) and the INTEGRATION_PLANS registration was dropped. Restored the four files from 5bd02d9 and re-inserted each entry exactly once; added the episodic-risc-spine-v1 plan registration. Verified single-entry. Pure docs; no code change.
056f1e8 still carried the E0658 `const fn to_slot` (my earlier gate checked for "527 passed" but the real green count is 526 = 516 + 7 episodic + 3 view_angle, so it wrongly refused to commit). This lands it: - to_slot drops `const` (u16::from not const-stable on 1.95). - episodic_edges: allow cast_possible_truncation (bounded nibble/slot narrowings) + doc_markdown (domain acronyms); view_angle needs no allow. cargo test -p lance-graph-contract --lib -> 526 passed, 0 failed. clippy pedantic+nursery: 0 findings in episodic_edges.rs / view_angle.rs.
…CausalEdge64) EpisodicEdges64 shipped value-API only — no byte contract — so AriGraph consumers serializing it across the surrealkv WAL / baton wire / Lance-column boundary had no frozen grammar (and a raw-pointer read would be host-endian, silently wrong on BE). Add the same LE contract the canonical reference CausalEdge64 exposes: to_u64 / from_u64 / to_le_bytes / from_le_bytes / write_le / read_le. Canonical little-endian, platform-independent; changing the layout is now an explicit WAL/wire migration, never silent (cognitive-risc-core: "LE byte contract"). cargo test -p lance-graph-contract --lib -> 528 passed, 0 failed (+2 LE tests). clippy pedantic+nursery: 0 findings in episodic_edges.rs / view_angle.rs. https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds ViewAngle, EpisodicEdges64/EdgeRef, Head2Head, DatasetVersion/VersionScheduler/NextPhaseScheduler; re-exports types; implements DeepNSM Trajectory::split_arcs and sentence landing (fact/story); and updates plans, boards, agent logs, epiphanies, knowledge docs, and a clippy tech-debt entry. ChangesEpisodic RISC Spine v1
Sequence DiagramsequenceDiagram
participant Dataset
participant VersionScheduler
participant NextPhaseScheduler
participant KanbanColumn
participant Blackboard
participant Head2Head
Dataset->>VersionScheduler: on_version(view, DatasetVersion, ExecTarget)
VersionScheduler->>NextPhaseScheduler: determine_next_phase()
NextPhaseScheduler->>KanbanColumn: next_phases()
KanbanColumn-->>NextPhaseScheduler: forward-arc phases
NextPhaseScheduler-->>VersionScheduler: Option<KanbanMove>
VersionScheduler-->>Dataset: propose KanbanMove
Blackboard->>Head2Head: select(blackboard)
Head2Head->>Head2Head: score bids by WinnerCriterion
Head2Head-->>Blackboard: CompetitionOutcome {winner, runner_up, margin}
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0807749327
ℹ️ 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".
| if slot == 0 { | ||
| None | ||
| } else { | ||
| Some(Self { family: (slot >> 12) as u8, local: slot & Self::MAX_LOCAL }) |
There was a problem hiding this comment.
Reject local-zero slots when unpacking edges
When reading packed data from from_u64/from_le_bytes, any slot like 0x1000 (family nibble set, local bits zero) is decoded as Some(EdgeRef { local: 0, ... }), even though local is documented and validated as 1-based and 0 is the empty-slot sentinel. In that scenario count(), iter(), and downstream family/local resolution will treat an invalid serialized slot as a real edge pointing at local index 0; from_slot should reject slots whose low 12 bits are zero, not just the all-zero slot.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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 @.claude/board/LATEST_STATE.md:
- Around line 45-50: The blockquote starting with the 2026-05-31 entries
contains blank lines between lines beginning with ">" which triggers
markdownlint MD028; edit the block so there are no empty lines between any
consecutive ">" lines (i.e., collapse the three quoted entries for
D-EW64-1/D-VIEW-1, D-H2H-1, and D-MBX-9-IN into a continuous blockquote by
removing the blank lines only), preserving all text and line prefixes (do not
change the content of EpisodicEdges64, ViewAngle,
Head2Head/WinnerCriterion/CompetitionOutcome,
VersionScheduler/DatasetVersion/NextPhaseScheduler, etc.).
In @.claude/board/STATUS_BOARD.md:
- Line 566: The table row for D-EW64-1 (the cell containing
episodic_edges::{EpisodicEdges64, EdgeRef} — AriGraph episodic edges ...)
includes literal pipe characters which are being parsed as column separators;
update that cell to escape each literal '|' (e.g. replace '|' with '\|') or wrap
the entire description in a code span/HTML-safe block so the pipes are treated
as content, not delimiters—ensure you modify the row containing the identifier
D-EW64-1 and the text "episodic_edges::{EpisodicEdges64, EdgeRef}" accordingly.
In `@crates/lance-graph-contract/src/episodic_edges.rs`:
- Around line 85-90: from_slot currently returns Some(...) for non-zero slot
values whose decoded local field can be zero, which violates EdgeRef::new()'s
invariant forbidding local==0; update from_slot to decode family and local
(using Self::MAX_LOCAL) and return None when slot==0 OR when local==0 (i.e., if
slot == 0 || (slot & Self::MAX_LOCAL) == 0) so you never construct an invalid
Self; apply the same validation change to the other from_slot implementation
mentioned (the one around the 219-227 region) to ensure consistent invariants.
In `@crates/lance-graph-contract/src/head2head.rs`:
- Around line 89-95: The free function distinct_support must be turned into an
impl method on Head2Head and invoked via the carrier instance instead of as a
standalone function: add a method impl Head2Head::distinct_support(&self,
support: /*same type as existing distinct_support param*/) that contains the
current distinct_support logic, update Head2Head::score to call
self.distinct_support(e.support) where distinct_support was used, and replace
any other free-function calls to distinct_support in the same module (around the
other uses noted at lines ~128–140) with self.distinct_support(...) so all calls
follow the carrier-method pattern.
- Around line 103-116: The selection of winner and runner-up uses max_by
comparing only self.score(...) so equal scores fall back to non-deterministic
insertion order; update both maxima (the first max_by that computes best and the
second that computes runner) to use a deterministic tie-breaker by comparing a
tuple (self.score(entry), tie_breaker) instead of just score — e.g.,
(self.score(a), a.expert_id) or (self.score(a), a.timestamp or a.entry_id) so
equal scores are resolved consistently; change the closure in
entries.iter().max_by to compare scores first via total_cmp and if equal compare
the chosen stable field (expert_id or a stable id) and apply the same tie-break
rule in the runner selection code that produces runner_up/runner_score.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 3f95fd22-faf6-46f2-9a14-dff30fdf35f7
📒 Files selected for processing (11)
.claude/board/AGENT_LOG.md.claude/board/EPIPHANIES.md.claude/board/INTEGRATION_PLANS.md.claude/board/LATEST_STATE.md.claude/board/STATUS_BOARD.md.claude/plans/episodic-risc-spine-v1.mdcrates/lance-graph-contract/src/episodic_edges.rscrates/lance-graph-contract/src/head2head.rscrates/lance-graph-contract/src/lib.rscrates/lance-graph-contract/src/scheduler.rscrates/lance-graph-contract/src/view_angle.rs
| > **2026-05-31 — ADDED (D-EW64-1 + D-VIEW-1, episodic-RISC-spine)**: `episodic_edges::{EpisodicEdges64(u64), EdgeRef{family:u8,local:u16}}` — AriGraph episodic edges, 4x[4-bit family | 12-bit local]: family 0 = intra-basin (inherited, ~98.6% per #444), 1..=15 = cross-family index into the OGIT-class-inherited palette (~1.4%; identities inherited, never on the edge — I-VSA-IDENTITIES). Plus `view_angle::ViewAngle` (4-bit view-schema selector; presence bitmask doubles as attention mask, inherited). Zero-dep; 527 contract lib tests; clippy pedantic+nursery clean. Plan: episodic-risc-spine-v1.md. | ||
|
|
||
| > **2026-05-31 — ADDED (D-H2H-1, head2head superposition winner-select)**: `lance_graph_contract::head2head::{Head2Head (judge), WinnerCriterion (DissonanceMin≈infight / SupportSpread≈Raumgewinn / ConfidenceMax / Tempered=default), CompetitionOutcome}`. `Head2Head::select(&Blackboard) -> Option<CompetitionOutcome>` picks the winning competing-expert bid over the existing `a2a_blackboard` (confidence/dissonance/support) — pure read + arg-extremum, **no new identity, copies nothing** (select-don't-duplicate, `I-VSA-IDENTITIES`); `margin` = the dark-horse signal. The *selection* half of head2head superposition; parallel-mailbox *execution* is the CI-gated consumer side. Zero-dep; 516 contract lib tests (+7); clippy pedantic+nursery clean. | ||
|
|
||
| > **2026-05-31 — ADDED (D-MBX-9-IN, VersionScheduler contract slice, on `b6e3cc6`/lance7)**: `lance_graph_contract::scheduler::{DatasetVersion(u64), VersionScheduler (trait), NextPhaseScheduler (reference impl)}`. The IN-direction dual of `MailboxSoaOwner` (`E-SUBSTRATE-IS-THE-SCHEDULER`): `on_version<V: MailboxSoaView>(&V, DatasetVersion, ExecTarget) -> Option<KanbanMove>` lowers a Lance `versions()` tick to the next legal Rubicon `KanbanMove`; `NextPhaseScheduler` is the forward-arc reference (Libet `-550ms` anchor on Planning→CognitiveWork, `None` on absorbing). Read-only over the view (**propose-not-dispose**, R1); composes only existing contract types; zero-dep. 509 contract lib tests (+6); clippy pedantic-clean. CI-gated twin = `LanceVersionScheduler` over `VersionedGraph::versions()` via callcenter `LanceVersionWatcher`. Closes D-MBX-9 IN-direction at the type level (OUT twin + core impl remain CI-gated). | ||
|
|
There was a problem hiding this comment.
Remove blank lines inside this blockquote block.
The added blockquote has empty lines between quoted paragraphs, triggering MD028 (no-blanks-blockquote).
🧹 Suggested markdownlint-safe rewrite
> **2026-05-31 — ADDED (D-EW64-1 + D-VIEW-1, episodic-RISC-spine)**: `episodic_edges::{EpisodicEdges64(u64), EdgeRef{family:u8,local:u16}}` — AriGraph episodic edges, 4x[4-bit family | 12-bit local]: family 0 = intra-basin (inherited, ~98.6% per `#444`), 1..=15 = cross-family index into the OGIT-class-inherited palette (~1.4%; identities inherited, never on the edge — I-VSA-IDENTITIES). Plus `view_angle::ViewAngle` (4-bit view-schema selector; presence bitmask doubles as attention mask, inherited). Zero-dep; 527 contract lib tests; clippy pedantic+nursery clean. Plan: episodic-risc-spine-v1.md.
-
+>
> **2026-05-31 — ADDED (D-H2H-1, head2head superposition winner-select)**: `lance_graph_contract::head2head::{Head2Head (judge), WinnerCriterion (DissonanceMin≈infight / SupportSpread≈Raumgewinn / ConfidenceMax / Tempered=default), CompetitionOutcome}`. `Head2Head::select(&Blackboard) -> Option<CompetitionOutcome>` picks the winning competing-expert bid over the existing `a2a_blackboard` (confidence/dissonance/support) — pure read + arg-extremum, **no new identity, copies nothing** (select-don't-duplicate, `I-VSA-IDENTITIES`); `margin` = the dark-horse signal. The *selection* half of head2head superposition; parallel-mailbox *execution* is the CI-gated consumer side. Zero-dep; 516 contract lib tests (+7); clippy pedantic+nursery clean.
-
+>
> **2026-05-31 — ADDED (D-MBX-9-IN, VersionScheduler contract slice, on `b6e3cc6`/lance7)**: `lance_graph_contract::scheduler::{DatasetVersion(u64), VersionScheduler (trait), NextPhaseScheduler (reference impl)}`. The IN-direction dual of `MailboxSoaOwner` (`E-SUBSTRATE-IS-THE-SCHEDULER`): `on_version<V: MailboxSoaView>(&V, DatasetVersion, ExecTarget) -> Option<KanbanMove>` lowers a Lance `versions()` tick to the next legal Rubicon `KanbanMove`; `NextPhaseScheduler` is the forward-arc reference (Libet `-550ms` anchor on Planning→CognitiveWork, `None` on absorbing). Read-only over the view (**propose-not-dispose**, R1); composes only existing contract types; zero-dep. 509 contract lib tests (+6); clippy pedantic-clean. CI-gated twin = `LanceVersionScheduler` over `VersionedGraph::versions()` via callcenter `LanceVersionWatcher`. Closes D-MBX-9 IN-direction at the type level (OUT twin + core impl remain CI-gated).
-🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 46-46: Blank line inside blockquote
(MD028, no-blanks-blockquote)
[warning] 48-48: Blank line inside blockquote
(MD028, no-blanks-blockquote)
[warning] 50-50: Blank line inside blockquote
(MD028, no-blanks-blockquote)
🤖 Prompt for 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.
In @.claude/board/LATEST_STATE.md around lines 45 - 50, The blockquote starting
with the 2026-05-31 entries contains blank lines between lines beginning with
">" which triggers markdownlint MD028; edit the block so there are no empty
lines between any consecutive ">" lines (i.e., collapse the three quoted entries
for D-EW64-1/D-VIEW-1, D-H2H-1, and D-MBX-9-IN into a continuous blockquote by
removing the blank lines only), preserving all text and line prefixes (do not
change the content of EpisodicEdges64, ViewAngle,
Head2Head/WinnerCriterion/CompetitionOutcome,
VersionScheduler/DatasetVersion/NextPhaseScheduler, etc.).
| | D-MBX-9 | Rubicon kanban view in `surrealkv`-on-lance (4 columns: Planning · Cognitive work · Evaluation · Commit·Plan·Prune); ractor lifecycle hooks = kanban moves | surreal_container + ractor | 250 | HIGH | **Queued** | gates on D-MBX-7 + D-MBX-8 + surreal_container BLOCKED(B/C/D) resolved (OQ-11.6) + D-PERSONA-5 | | ||
| | D-MBX-9-IN | contract slice of D-MBX-9 IN-direction (`E-SUBSTRATE-IS-THE-SCHEDULER`): `scheduler::{DatasetVersion, VersionScheduler, NextPhaseScheduler}` — Lance `versions()` tick → next legal `KanbanMove`, zero-dep, read-only-over-view (propose-not-dispose) | lance-graph-contract | 130 | LOW | **Shipped (contract)** | 509 lib tests (+6); clippy pedantic-clean; CI-gated twin `D-MBX-9-IN-impl` (LanceVersionScheduler over `VersionedGraph::versions()`) named not written | | ||
| | D-H2H-1 | head2head superposition winner-select (item 4, Go infight-vs-Raumgewinn): `head2head::{Head2Head, WinnerCriterion, CompetitionOutcome}` — `select(&Blackboard)` arg-extremum over existing bids, select-not-duplicate | lance-graph-contract | 130 | LOW | **Shipped (contract)** | 516 lib tests (+7); clippy pedantic+nursery clean; parallel-mailbox executor = CI-gated consumer side | | ||
| | D-EW64-1 | `episodic_edges::{EpisodicEdges64, EdgeRef}` — AriGraph episodic edges (4x[4b family|12b local]); intra=inherited (~98.6%), cross=4-bit nibble->OGIT-class palette (~1.4%) | lance-graph-contract | 120 | LOW | **Shipped (contract)** | 527 lib tests; clippy clean; SoA columns = D-EW64-2 (CI-gated) | |
There was a problem hiding this comment.
Escape literal | characters in the table cell.
This row is currently parsed as 8 columns (MD056) because | inside the description is unescaped.
🧩 Minimal fix
-| D-EW64-1 | `episodic_edges::{EpisodicEdges64, EdgeRef}` — AriGraph episodic edges (4x[4b family|12b local]); intra=inherited (~98.6%), cross=4-bit nibble->OGIT-class palette (~1.4%) | lance-graph-contract | 120 | LOW | **Shipped (contract)** | 527 lib tests; clippy clean; SoA columns = D-EW64-2 (CI-gated) |
+| D-EW64-1 | `episodic_edges::{EpisodicEdges64, EdgeRef}` — AriGraph episodic edges (4x[4b family\|12b local]); intra=inherited (~98.6%), cross=4-bit nibble->OGIT-class palette (~1.4%) | lance-graph-contract | 120 | LOW | **Shipped (contract)** | 527 lib tests; clippy clean; SoA columns = D-EW64-2 (CI-gated) |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | D-EW64-1 | `episodic_edges::{EpisodicEdges64, EdgeRef}` — AriGraph episodic edges (4x[4b family|12b local]); intra=inherited (~98.6%), cross=4-bit nibble->OGIT-class palette (~1.4%) | lance-graph-contract | 120 | LOW | **Shipped (contract)** | 527 lib tests; clippy clean; SoA columns = D-EW64-2 (CI-gated) | | |
| | D-EW64-1 | `episodic_edges::{EpisodicEdges64, EdgeRef}` — AriGraph episodic edges (4x[4b family\|12b local]); intra=inherited (~98.6%), cross=4-bit nibble->OGIT-class palette (~1.4%) | lance-graph-contract | 120 | LOW | **Shipped (contract)** | 527 lib tests; clippy clean; SoA columns = D-EW64-2 (CI-gated) | |
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 566-566: Table column count
Expected: 7; Actual: 8; Too many cells, extra data will be missing
(MD056, table-column-count)
🤖 Prompt for 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.
In @.claude/board/STATUS_BOARD.md at line 566, The table row for D-EW64-1 (the
cell containing episodic_edges::{EpisodicEdges64, EdgeRef} — AriGraph episodic
edges ...) includes literal pipe characters which are being parsed as column
separators; update that cell to escape each literal '|' (e.g. replace '|' with
'\|') or wrap the entire description in a code span/HTML-safe block so the pipes
are treated as content, not delimiters—ensure you modify the row containing the
identifier D-EW64-1 and the text "episodic_edges::{EpisodicEdges64, EdgeRef}"
accordingly.
| const fn from_slot(slot: u16) -> Option<Self> { | ||
| if slot == 0 { | ||
| None | ||
| } else { | ||
| Some(Self { family: (slot >> 12) as u8, local: slot & Self::MAX_LOCAL }) | ||
| } |
There was a problem hiding this comment.
Validate decoded slot invariants in from_slot.
from_slot currently accepts non-zero slots where local == 0, which creates an EdgeRef state that new() explicitly forbids. This can surface from raw u64/byte decoding.
🔧 Proposed fix
const fn from_slot(slot: u16) -> Option<Self> {
if slot == 0 {
None
} else {
- Some(Self { family: (slot >> 12) as u8, local: slot & Self::MAX_LOCAL })
+ let family = (slot >> 12) as u8;
+ let local = slot & Self::MAX_LOCAL;
+ Self::new(family, local)
}
}
@@
for family in 0..16u8 {
for &local in &[1u16, 2, 100, 4095] {
let e = EdgeRef::new(family, local).unwrap();
assert_eq!(EdgeRef::from_slot(e.to_slot()).unwrap(), e);
}
}
assert_eq!(EdgeRef::from_slot(0), None);
+ assert_eq!(EdgeRef::from_slot(0x1000), None); // non-empty family with local=0 is invalid
}Also applies to: 219-227
🤖 Prompt for 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.
In `@crates/lance-graph-contract/src/episodic_edges.rs` around lines 85 - 90,
from_slot currently returns Some(...) for non-zero slot values whose decoded
local field can be zero, which violates EdgeRef::new()'s invariant forbidding
local==0; update from_slot to decode family and local (using Self::MAX_LOCAL)
and return None when slot==0 OR when local==0 (i.e., if slot == 0 || (slot &
Self::MAX_LOCAL) == 0) so you never construct an invalid Self; apply the same
validation change to the other from_slot implementation mentioned (the one
around the 219-227 region) to ensure consistent invariants.
| pub fn score(&self, e: &BlackboardEntry) -> f32 { | ||
| match self.criterion { | ||
| WinnerCriterion::DissonanceMin => 1.0 - e.dissonance, | ||
| WinnerCriterion::ConfidenceMax => e.confidence, | ||
| WinnerCriterion::SupportSpread => distinct_support(e.support) as f32, | ||
| WinnerCriterion::Tempered => e.confidence * (1.0 - e.dissonance), | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Move distinct_support onto Head2Head to follow carrier-method usage.
distinct_support at Line [130] is a free function. Route it through a Head2Head method and call it from Line [93].
♻️ Proposed refactor
impl Head2Head {
@@
pub fn score(&self, e: &BlackboardEntry) -> f32 {
match self.criterion {
WinnerCriterion::DissonanceMin => 1.0 - e.dissonance,
WinnerCriterion::ConfidenceMax => e.confidence,
- WinnerCriterion::SupportSpread => distinct_support(e.support) as f32,
+ WinnerCriterion::SupportSpread => self.distinct_support(e.support) as f32,
WinnerCriterion::Tempered => e.confidence * (1.0 - e.dissonance),
}
}
+
+ fn distinct_support(&self, support: [u16; 4]) -> usize {
+ let mut seen = [0u16; 4];
+ let mut n = 0;
+ for a in support {
+ if a != 0 && !seen[..n].contains(&a) {
+ seen[n] = a;
+ n += 1;
+ }
+ }
+ n
+ }
@@
-/// Count of distinct non-zero atoms in a 4-slot support vector (the territory
-/// measure for [`WinnerCriterion::SupportSpread`]). `0` is the no-atom sentinel.
-fn distinct_support(support: [u16; 4]) -> usize {
- let mut seen = [0u16; 4];
- let mut n = 0;
- for a in support {
- if a != 0 && !seen[..n].contains(&a) {
- seen[n] = a;
- n += 1;
- }
- }
- n
-}As per coding guidelines, **/*.rs: Use only method calls on the carrier struct that holds the state, never free functions. Carrier pattern: trajectory.resolve() instead of resolve(trajectory, config, awareness).
Also applies to: 128-140
🤖 Prompt for 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.
In `@crates/lance-graph-contract/src/head2head.rs` around lines 89 - 95, The free
function distinct_support must be turned into an impl method on Head2Head and
invoked via the carrier instance instead of as a standalone function: add a
method impl Head2Head::distinct_support(&self, support: /*same type as existing
distinct_support param*/) that contains the current distinct_support logic,
update Head2Head::score to call self.distinct_support(e.support) where
distinct_support was used, and replace any other free-function calls to
distinct_support in the same module (around the other uses noted at lines
~128–140) with self.distinct_support(...) so all calls follow the carrier-method
pattern.
| let best = bb | ||
| .entries | ||
| .iter() | ||
| .max_by(|a, b| self.score(a).total_cmp(&self.score(b)))?; | ||
| let winner = best.expert_id; | ||
| let winner_score = self.score(best); | ||
|
|
||
| let runner = bb | ||
| .entries | ||
| .iter() | ||
| .filter(|e| e.expert_id != winner) | ||
| .max_by(|a, b| self.score(a).total_cmp(&self.score(b))); | ||
| let (runner_up, runner_score) = | ||
| runner.map_or((None, 0.0), |r| (Some(r.expert_id), self.score(r))); |
There was a problem hiding this comment.
Add an explicit tie-breaker in winner/runner-up selection.
Line [106] and Line [114] compare only score. Equal-score bids currently resolve by insertion order, which can vary with parallel posting and make outcomes unstable.
🔧 Proposed fix
- let best = bb
- .entries
- .iter()
- .max_by(|a, b| self.score(a).total_cmp(&self.score(b)))?;
+ let best = bb.entries.iter().max_by(|a, b| {
+ let sa = self.score(a);
+ let sb = self.score(b);
+ sa.total_cmp(&sb)
+ // stable tie-break: lower ExpertId wins on equal score
+ .then_with(|| b.expert_id.cmp(&a.expert_id))
+ })?;
@@
- let runner = bb
- .entries
- .iter()
- .filter(|e| e.expert_id != winner)
- .max_by(|a, b| self.score(a).total_cmp(&self.score(b)));
+ let runner = bb.entries.iter().filter(|e| e.expert_id != winner).max_by(|a, b| {
+ let sa = self.score(a);
+ let sb = self.score(b);
+ sa.total_cmp(&sb)
+ .then_with(|| b.expert_id.cmp(&a.expert_id))
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let best = bb | |
| .entries | |
| .iter() | |
| .max_by(|a, b| self.score(a).total_cmp(&self.score(b)))?; | |
| let winner = best.expert_id; | |
| let winner_score = self.score(best); | |
| let runner = bb | |
| .entries | |
| .iter() | |
| .filter(|e| e.expert_id != winner) | |
| .max_by(|a, b| self.score(a).total_cmp(&self.score(b))); | |
| let (runner_up, runner_score) = | |
| runner.map_or((None, 0.0), |r| (Some(r.expert_id), self.score(r))); | |
| let best = bb.entries.iter().max_by(|a, b| { | |
| let sa = self.score(a); | |
| let sb = self.score(b); | |
| sa.total_cmp(&sb) | |
| // stable tie-break: lower ExpertId wins on equal score | |
| .then_with(|| b.expert_id.cmp(&a.expert_id)) | |
| })?; | |
| let winner = best.expert_id; | |
| let winner_score = self.score(best); | |
| let runner = bb.entries.iter().filter(|e| e.expert_id != winner).max_by(|a, b| { | |
| let sa = self.score(a); | |
| let sb = self.score(b); | |
| sa.total_cmp(&sb) | |
| .then_with(|| b.expert_id.cmp(&a.expert_id)) | |
| }); | |
| let (runner_up, runner_score) = | |
| runner.map_or((None, 0.0), |r| (Some(r.expert_id), self.score(r))); |
🤖 Prompt for 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.
In `@crates/lance-graph-contract/src/head2head.rs` around lines 103 - 116, The
selection of winner and runner-up uses max_by comparing only self.score(...) so
equal scores fall back to non-deterministic insertion order; update both maxima
(the first max_by that computes best and the second that computes runner) to use
a deterministic tie-breaker by comparing a tuple (self.score(entry),
tie_breaker) instead of just score — e.g., (self.score(a), a.expert_id) or
(self.score(a), a.timestamp or a.entry_id) so equal scores are resolved
consistently; change the closure in entries.iter().max_by to compare scores
first via total_cmp and if equal compare the chosen stable field (expert_id or a
stable id) and apply the same tie-break rule in the runner selection code that
produces runner_up/runner_score.
…g vs story-arc) Capstone synthesis tying the four world-spine threads into one engine: English SPO bifurcates by temporality — atemporal => FACT (aerial 10000^2 splat resonance -> OWL/DOLCE frozen identity), temporal => STORY-ARC (±5 context_chain coreference -> EpisodicEdges64 basin -> WitnessTable accumulate-then-prune). The DeepNSM `SentenceStructure.temporals` field is the fact/story router signal (WIRED today, unread). The 10000^2 gaussian splat is the literal->basin resolver (similarity proposes / CAM confirms; jc-certified rho=0.9973 offline). Reconciles with E-EPISODIC-CLOSURE's three lifecycle structures: FACT -> frozen identity, story-recent -> within-session CLAM (±5), story-old -> cross-session append-index (±500). Firewall held end-to-end (language stays upstream in DeepNSM, both destinations agnostic opaque handles, float only offline, 4096 story-basins != COCA-4096). Design-only (no code): the routing + 3 missing wires are net-new/CONJECTURE. First buildable slice named: Trajectory::split_arcs -> (BasinArc, LiteralArc) in deepnsm (firewall-safe; gives the dead MarkovBundler a producer). - NEW .claude/knowledge/english-fact-story-bifurcation-grail-v1.md (assembly map) - EPIPHANIES.md: prepend E-ENGLISH-BIFURCATES - AGENT_LOG.md: prepend session entry https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
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 @.claude/knowledge/english-fact-story-bifurcation-grail-v1.md:
- Around line 32-50: The fenced code block in the Markdown (the triple-backtick
block containing the DeepNSM diagram) is missing a language tag; add a language
identifier (e.g., "text") to the opening ``` so the block becomes ```text to
satisfy MD040 and markdownlint. Locate the fenced block by searching for the
diagram content beginning with "DeepNSM (English sensor — MUST stay English)"
and update the opening fence only—do not alter the block contents or trailing
closing fence.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7a286373-5c29-482a-8eea-7b2c1997d744
📒 Files selected for processing (3)
.claude/board/AGENT_LOG.md.claude/board/EPIPHANIES.md.claude/knowledge/english-fact-story-bifurcation-grail-v1.md
| ``` | ||
| DeepNSM (English sensor — MUST stay English) | ||
| COCA-4096 + PoS-FSM → SpoTriple{ s, p, o : 12-bit ranks } | ||
| + SentenceStructure{ modifiers, negations, TEMPORALS } ← parser.rs:57-66 | ||
| │ | ||
| ┌──────────┴──────────┐ router reads `temporals` | ||
| atemporal │ │ temporal (WIRED field, today UNREAD) | ||
| ▼ ▼ | ||
| FACT-LANDING STORY-ARC | ||
| aerial 10000² splat ±5 coreference (context_chain) | ||
| resonance → DOLCE class → → EpisodicEdges64 basin (family==0) | ||
| (similarity proposes, → WitnessTable accumulate → prune | ||
| CAM confirms) │ | ||
| │ │ | ||
| ▼ ▼ | ||
| frozen identity CLAM ±5 ──age──► append-index ±500 | ||
| (OGIT/CAM, (within-session, (cross-session, | ||
| never moves) the only mover) immutable pointer) | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the fenced code block.
The fence starting at Line 32 has no language identifier (MD040). Please label it (for example text) to satisfy markdownlint and keep docs checks clean.
Suggested patch
-```
+```text
DeepNSM (English sensor — MUST stay English)
COCA-4096 + PoS-FSM → SpoTriple{ s, p, o : 12-bit ranks }
+ SentenceStructure{ modifiers, negations, TEMPORALS } ← parser.rs:57-66
│
┌──────────┴──────────┐ router reads `temporals`
atemporal │ │ temporal (WIRED field, today UNREAD)
▼ ▼
FACT-LANDING STORY-ARC
aerial 10000² splat ±5 coreference (context_chain)
resonance → DOLCE class → → EpisodicEdges64 basin (family==0)
(similarity proposes, → WitnessTable accumulate → prune
CAM confirms) │
│ │
▼ ▼
frozen identity CLAM ±5 ──age──► append-index ±500
(OGIT/CAM, (within-session, (cross-session,
never moves) the only mover) immutable pointer)</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 32-32: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for 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.
In @.claude/knowledge/english-fact-story-bifurcation-grail-v1.md around lines 32
- 50, The fenced code block in the Markdown (the triple-backtick block
containing the DeepNSM diagram) is missing a language tag; add a language
identifier (e.g., "text") to the opening ``` so the block becomes ```text to
satisfy MD040 and markdownlint. Locate the fenced block by searching for the
diagram content beginning with "DeepNSM (English sensor — MUST stay English)"
and update the opening fence only—do not alter the block contents or trailing
closing fence.
…URCATES first slice)
First verifiable wire of the English-bifurcation grail, on the canonical
substrate (OQ-ARC-PRODUCER resolved: the 16384-dim role-indexed Trajectory,
not the 512-bit ContextWindow — Trajectory carries the TEMPORAL role band
[9000..9200) that IS the router, and already bridges to contract
context_chain via disambiguator_glue).
- BasinArc / LiteralArc: the language<->meaning duality as typed Rust.
basin = the role-superposed spine bundle (declared/exact); literal = the
COCA ranks that fed it (detected/prunable). Trajectory::split_arcs names
the pair at the disambiguator_glue seam.
- temporal_energy() / threads_story() / landing(): the fact/story router.
Reads the TEMPORAL band as the bifurcation signal. OQ-ROUTER-SIGNAL
resolved to FORK not switch — fact is universal (every SPO is a
fact-candidate), story is additive when temporal ("the dog, which is a
mammal, ran" yields both). Threshold explicit, no hidden default.
Firewall-safe: both arcs stay English-side; f32 is upstream-only; no COCA
rank reaches the agnostic graph as identity. deepnsm 94+4+8+1 tests green
(+5 new); arcs.rs clippy-clean at pedantic+nursery.
https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
- grail doc: § Session update (OQ-ARC-PRODUCER + OQ-ROUTER-SIGNAL resolved, slice shipped) - AGENT_LOG: E-ENGLISH-BIFURCATES first-wire entry - TECH_DEBT: TD-DEEPNSM-CLIPPY-195 (12 pre-existing clippy-1.95 lints, arcs.rs unaffected) https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
…cke) — E-BROCA-WERNICKE-HIPPO User correction (anti-spaghetti): the Markov bundler is the PROJECTION; sentence resolution is literal comprehension + ambiguity resolution, tokenless — they are separate faculties and must not share a carrier. The first slice (9af7f15) fused the fact/story router onto Trajectory (the projection). Corrected here. - arcs.rs → projection-only (Broca): split_arcs + BasinArc/LiteralArc. Removed temporal_energy/threads_story/landing (they read the projection band). - comprehension.rs (NEW, Wernicke): Landing{fact,story} + SentenceStructure:: {is_temporal,triple_landing,landings}. Reads the comprehended, TOKENLESS structure (temporals: per-triple (usize,u16)), not the VSA band. Per-triple fork (a sentence can carry both a timeless relation and a dated event). - lib.rs: both faculties declared with the boundary stated. Capture: EPIPHANIES E-BROCA-WERNICKE-HIPPO + grail doc § three faculties. New insight: the WitnessTable lifecycle (spo_fact_ref None->Some->tombstone) IS hippocampal->neocortical consolidation — an aged story crystallises into a DOLCE fact, so fact-landing has two sources (input fork AND consolidation). Firewall held: Broca+Wernicke = deepnsm (English); Hippocampus+neocortex = downstream/agnostic; only the Landing{fact,story} bit crosses. deepnsm lib 95 green; both files default-clippy-clean. https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
…gnosis (E-ARCUATE-CONDUCTION) Map the distributed language network (10 landmarks) onto the workspace, honest status; the payoff is a falsifiable diagnosis: The stack has CONDUCTION APHASIA. disambiguator_glue IS the arcuate fasciculus (Trajectory -> context_chain) and is shipped, but MarkovBundler::push is never called by pipeline.rs -> the cable carries no signal. Production (Broca) and comprehension (Wernicke) work in isolation; repetition (connecting them) fails -- the exact clinical signature. The fix names the next wire: pipeline -> push -> Trajectory -> disambiguator_glue -> context_chain (±5) -> comprehension. Other placements: PFC = MUL + free-energy + global_context (planner-side, unconnected); temporal-semantic = COCA 4096^2 + DOLCE; angular = vocabulary + nsm_primes. Honest modality boundary: auditory/motor/phonology = N/A (text+COCA, not audio) -- do not build phonology. - grail doc: § full language network (table + diagram + N/A boundary) - EPIPHANIES: E-ARCUATE-CONDUCTION (prepend) - AGENT_LOG: entry https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.claude/board/AGENT_LOG.md (1)
1-276:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winVerify board-hygiene compliance: all required board files must be updated in the same commit.
According to the coding guidelines, every PR that adds deliverables (D-MBX-9-IN, D-H2H-1, D-EW64-1, D-VIEW-1) or epiphanies must update LATEST_STATE.md, STATUS_BOARD.md, INTEGRATION_PLANS.md, EPIPHANIES.md, and AGENT_LOG.md in the SAME commit to avoid "retroactive-hygiene commits" (which are flagged as anti-patterns).
The review stack context indicates these board updates are split across different "cohorts/layers." Please confirm that all required board file updates—LATEST_STATE (contract inventory), STATUS_BOARD (deliverables), INTEGRATION_PLANS (new plans), EPIPHANIES (findings), and this AGENT_LOG—are included in a single atomic commit, not spread across multiple commits within the PR.
As per coding guidelines: "Board files are APPEND-ONLY: prepend new entries... Retroactive-hygiene commits (merge PR, later update board) are anti-patterns."
🤖 Prompt for 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. In @.claude/board/AGENT_LOG.md around lines 1 - 276, The board-hygiene check flags that the required board files (LATEST_STATE, STATUS_BOARD, INTEGRATION_PLANS, EPIPHANIES, AGENT_LOG) must be updated atomically in the same commit; fix it by collecting the missing/prepended updates for any of these symbols not present in the current commit and add them to a single commit (either by amending the last commit or creating a new fixup and squashing) so the PR contains one atomic change that appends/prepends entries per the append-only rule; ensure each updated symbol (LATEST_STATE, STATUS_BOARD, INTEGRATION_PLANS, EPIPHANIES, AGENT_LOG) is present, uses the prepend/append convention, and that there are no subsequent retroactive board-only commits before merging.
♻️ Duplicate comments (1)
.claude/knowledge/english-fact-story-bifurcation-grail-v1.md (1)
258-272:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd a language tag to the fenced code block.
The fence starting at line 258 has no language identifier (MD040 markdownlint warning). Please label it (for example,
text) to satisfy markdownlint and maintain documentation consistency.Suggested patch
-``` +```text Prefrontal Cortex = MUL + free-energy gate + global_context (planner-side, unconnected) │ Broca ───────────┼──── Arcuate Fasciculus ────── Wernicke🤖 Prompt for 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. In @.claude/knowledge/english-fact-story-bifurcation-grail-v1.md around lines 258 - 272, The fenced code block beginning with ``` (the block containing "Prefrontal Cortex = MUL + free-energy gate + global_context ..." and the ASCII brain diagram) lacks a language identifier; add a language tag (e.g., text) to the opening fence so the block becomes ```text to satisfy markdownlint MD040 and keep documentation consistent, updating the opening fence only (leave the block contents and closing ``` unchanged).
🤖 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.
Outside diff comments:
In @.claude/board/AGENT_LOG.md:
- Around line 1-276: The board-hygiene check flags that the required board files
(LATEST_STATE, STATUS_BOARD, INTEGRATION_PLANS, EPIPHANIES, AGENT_LOG) must be
updated atomically in the same commit; fix it by collecting the
missing/prepended updates for any of these symbols not present in the current
commit and add them to a single commit (either by amending the last commit or
creating a new fixup and squashing) so the PR contains one atomic change that
appends/prepends entries per the append-only rule; ensure each updated symbol
(LATEST_STATE, STATUS_BOARD, INTEGRATION_PLANS, EPIPHANIES, AGENT_LOG) is
present, uses the prepend/append convention, and that there are no subsequent
retroactive board-only commits before merging.
---
Duplicate comments:
In @.claude/knowledge/english-fact-story-bifurcation-grail-v1.md:
- Around line 258-272: The fenced code block beginning with ``` (the block
containing "Prefrontal Cortex = MUL + free-energy gate + global_context ..." and
the ASCII brain diagram) lacks a language identifier; add a language tag (e.g.,
text) to the opening fence so the block becomes ```text to satisfy markdownlint
MD040 and keep documentation consistent, updating the opening fence only (leave
the block contents and closing ``` unchanged).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 250971c7-711a-4bc0-ac96-c950f806e22a
📒 Files selected for processing (3)
.claude/board/AGENT_LOG.md.claude/board/EPIPHANIES.md.claude/knowledge/english-fact-story-bifurcation-grail-v1.md
✅ Files skipped from review due to trivial changes (1)
- .claude/board/EPIPHANIES.md
… signal (E-ARCUATE-CONDUCTION) First increment of the conduction-aphasia fix. Arcuate owns the MarkovBundler producer + the ±5 ContextChain evidence ring; feed(sentence) pushes to the bundler and, on each emitted Trajectory, sign-binarizes the projection and slides it into the ring's newest slot; disambiguate(candidates) delegates to the chain. This gives MarkovBundler::push its first caller and owns the ring-slide the contract leaves to the language side (ContextChain has fill + coherence + replay but no streaming advance) -- so the projection now flows from Broca into Wernicke's window. Separate seam, NOT wired into pipeline.rs's live 512-bit ContextWindow (that coexistence is a distinct decision, deferred to avoid spaghetti). Firewall: only Binary16K crosses into the contract; no COCA; no new dep. deepnsm lib 99 green (+4 arcuate); arcuate.rs default-clippy-clean. OQ-ARC-WINDOW: double-windowing (bundler ±radius + chain ±5) — ring holds windowed-projection fingerprints; per-sentence (radius-0) may be preferable. https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
Summary
The episodic-RISC-spine contract wave — four zero-dep, offline-verified contract types that lay the addressing spine converged in the 2026-05-31 design dialogue, plus the plan + finding that ground them. All contract-level; no
lance/protocneeded; 528lance-graph-contractlib tests, clippy pedantic+nursery clean.The four slices
scheduler::{DatasetVersion, VersionScheduler, NextPhaseScheduler}E-SUBSTRATE-IS-THE-SCHEDULER): a Lanceversions()tick → the next legal RubiconKanbanMove. The dual ofMailboxSoaOwner; read-only over the view (propose-not-dispose, R1). Also the pseudo-radix reader —DatasetVersionis the append-only session index's fixed pointer.head2head::{Head2Head, WinnerCriterion, CompetitionOutcome}DissonanceMin/ Raumgewinn ≈SupportSpread): an arg-extremum over the existinga2a_blackboardbids. Select, never duplicate (I-VSA-IDENTITIES);margin= the dark-horse signal.episodic_edges::{EpisodicEdges64, EdgeRef}view_angle::ViewAnglehead2headcompetes angles.The design it grounds (
.claude/plans/episodic-risc-spine-v1.md)The episodic spine closes on three lifecycle-separated structures, zero overlap:
You don't build a radix — append-never-renumber gives you one. The compression is the bounded solution horizon (a research is a free-energy descent that rests at the homeostasis floor; awareness = the stop), not a codec. Full finding:
EPIPHANIES.mdE-EPISODIC-CLOSURE.Firewall held throughout: identity exact (CAM/OGIT), stories flexible (CLAM/discovery), never swapped. DeepNSM stays English upstream; aerial stays a zero-dep proposer.
Corrections folded in (this wave retracts earlier framings)
CausalEdge64, and not 16-bit pointers — it's a 4-bit inherited-palette nibble + a 12-bit within-family local ("lookup in OGIT, not in the data").Verification & honesty
cargo test -p lance-graph-contract --lib→ 528 passed, 0 failed; clippy pedantic+nursery clean on the new files.protoc, which the sandbox lacks.AGENT_LOG(an early episodic commit pushed broken; repaired + gated green).Board hygiene in-commit:
LATEST_STATEinventory ·STATUS_BOARDrows ·INTEGRATION_PLANSregistration ·EPIPHANIESfinding ·AGENT_LOGwave entry.https://claude.ai/code/session_012SorR8UbtEvYmbX8cXftj7
Generated by Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores