docs/architecture/— the architecture documents (CE64 upper half, SoA three-tier model, ownership and addressing, ONA/NAL fold assimilation, and the rest; diagrams inimg/). Check here before re-deriving a design..claude/knowledge/epistemic-frontier-capstone.md— how the address space, the alpha channel, the 64 thought layers, presence bits, the CE64 fields, the NAL ladder and the front ends connect, with file and status per node.
.grok/board/CLAUDE_LANE_FOLD_CAPSTONE.md. Settled numbers, the ten open points, the refusal list. Do not re-derive. Do not cite 0.6 ns as a join.
Nanoseconds for a single operation. At most microseconds for a batch. A result in milliseconds is a failed gate, never a measurement to report, discuss, commit or push. This holds for lab crates, probes, examples, benchmarks and PR bodies alike.
- DECISION (2026-10-21): an ms number means the work left the fold. The
substrate's reference is mask-risc / Quack, which fold over u64 mask words
into a terminal (
Count,Any,Keep, …) in nanoseconds;folding-doctrine.md§6.2 records 56 ns fused against 138 620 ns materialized for the same query. - BASIS: every ms result seen so far came from leaving that path. Examples:
crepe-plan-probe::native::tuples_over_mask(a heap row per result, a copy per combination, then sort and merge: 243–310 ms), and a count "fold" made of scalar loops plus a per-slot sort (1.2–1.6 ms; pushed, then reverted inc49db8dc). See.claude/board/entries/2026-10-21-coresearch-ms-vs-ns-folding.md. - The mental model. A value is read through a template, never split into
objects. PowerShell's
"{0}..{15}" -f $lane.splitbuilds nothing: it names positions 0–15 of one value and reads them in place. A ClassView carving (6×(u8:u8),4×(u8:u8:u8),3×(u8:u8:u8:u8)) is that template over the 16-byte facet. A fold acts on all positions at once (one compare → one mask). A tuple, by contrast, is the value split into owned heap objects. It discards the template, and it is where the milliseconds come from. - A tuple is a violation on four levels (2026-10-21), and no part of a
tuple builder is kept:
- Zero copy: copying lane values into owned rows makes a second owner
of bytes the substrate already holds (
.claude/knowledge/zero-copy-lens-law.md: no escape hatch, no cost argument). - Folding: it enumerates where a fold belongs.
- Natural order: the substrate already holds rows in its natural order (mask/lane slot order, readable in place). Sorting decoded rows ignores that order and imposes another one on copies. Order belongs to the substrate's coordinates, never to decoded rows.
- Time: the per-row alloc, clone and sort is where the milliseconds come from. It is a violation as an intermediate or a final answer, at any speed. A fold that happens to sit inside a tuple builder (for example multiplying side counts) is not "the good half": it belongs at the terminal, over the kept mask.
- Zero copy: copying lane values into owned rows makes a second owner
of bytes the substrate already holds (
- What follows for a session:
- Before reporting any timing, check the unit. ms → stop; find where the path left the mask-risc terminals.
- Never decode a join or population into owned rows (
Vec<Vec<_>>,Vec<(Vec<_>, _)>, tuple sets) to answer count, exists, sum, min, max or group. Those are folds. - Never invent a "reference" or tuple decoder that was not asked for.
- mask-risc is the reference folding algebra. Do not change it for a new algebra until tests prove the new algebra also runs in nanoseconds.
- SCOPE: every crate in this workspace, plus every number quoted in a board entry, plan, PR or Linear comment.
- There are no boundaries (2026-10-21). The whole substrate is zero copy:
no membrane, wire, process edge or "consumer side" where values get copied
out. The only "exception" is the inversion, global to local, and it is
still zero copy: the one thing it materializes is the pointer table
$i(the local positions). Everything else is read in place through$i.- A "tuple" is a zero-copy fold template, never a value:
"{0}{1}" -f $laneA[$i],$laneB[$i]reads column 0 from lane A and column 1 from lane B at position$i. Whole-template form:"{$i[0]}..{$i[15]}" -f $table{$i[0]}..$table{$i[15]}. - Violation: a
(Guid, Guid)pair stored or returned as a value (as in dir-sim). Correct: two lanes, one pointer table, the template read at$i. - This holds for tests and oracles too: answers are compared by folds through the template, never by expanding them into rows.
- A "tuple" is a zero-copy fold template, never a value:
- REVISIT WHEN: never on cost grounds.
- SCOPED EXCEPTION — cold, out-of-fold compile and oracle costs (DECISION,
operator, 2026-10-22: "Report the cold costs in microseconds, not gated").
A cold compile outside the fold (egglog saturation + proof in
egglog-r2il-probe) or a differential-oracle reference arm (MORK increpe-plan-probe/examples/mork_split.rs) may be reported, always in µs and always labelled "reported, not gates". It never licenses a ms-scale in-fold path: encode, lower, execute and every query terminal stay under the rule above. BASIS: these phases run once per program or only as an oracle, never per query. REVISIT WHEN: a cold phase moves onto a per-query path.
Always depend on the AdaWorldAPI fork of any crate that has one. NEVER use the
upstream crates.io version of a forked crate. Non-negotiable; applies to every
Cargo.toml and every dependency decision in this repo. Every repo in this
workspace is local — prefer the local/fork source over the registry, always.
- Crates with an
AdaWorldAPI/<name>fork — e.g.ndarray,surrealdb, and any other — MUST be wired via the fork (path/git/[patch.crates-io]), never the registry version.
⊘ CARVE-OUT — the lance family is UPSTREAM-AUTHORITATIVE (operator-ruled 2026-08-05,
E-LANCE-IS-UPSTREAM-AUTHORITATIVE-1).lance,lancedb, and the wholelance-*family (lance-arrow/lance-core/lance-index/lance-linalg/lance-namespace/lance-datafusion/ …) are consumed from crates.io upstream, never from a fork — "lance and lancedb are never used from forks because it's too risky and the upstream is authoritative." Forking the storage engine underneath a stack that trusts its durability guarantees buys a maintenance liability, not freedom. This list previously NAMED lance/lancedb as must-fork; that was wrong and is corrected here, not deleted.AdaWorldAPI/lanceandAdaWorldAPI/lancedbDO exist as repos — their existence is NOT evidence of intent to depend on them, and a session that finds them must not read the P0 above as a mandate to wire them in. Registry pins for this family are therefore CORRECT, not a policy violation to "fix". The version discipline that DOES apply: the family moves in exact lockstep, so a bump is one deliberate, measured PR — never a drift. ⊘ The parenthetical that stood here — "(=X.Y.Zacross every member,lancedbpinning its matchinglance)" — is SUPERSEDED by the operator ruling 2026-09-18 ("never pin to x.00, always float x."*): the family still moves in lockstep, but WE express that as a floating patch (11.*,0.38.*), never a.0.0exact pin. Lockstep is about the MAJOR moving together; it never required us to restate lancedb's own=11.0.0, and restating it can only narrow the graph. Full rule and the receipt: § Key Dependencies below — which is the ONE authoritative pin policy in this file.
- If a fork's coordinates (git URL, branch/tag, feature flag) are unknown, STOP and ask. Do NOT fall back to crates.io as a convenience or to make a build pass.
"warning: Patch <crate> ... was not used in the crate graph"is a policy alert. It can indicate missing fork wiring OR a transitive semver mismatch that prevents the patch from applying. Do not ignore it: verify directCargo.tomlpatch entries and a THROWAWAYcargo generate-lockfileresolve (deleted after reading — this repo tracks no lock), then track/resolve any transitive blocker explicitly before closing the issue.- crates.io is permitted ONLY for crates that have no AdaWorldAPI fork / no local source.
Any session touching SoA rows, tenants, mailbox ownership, kanban,
thinking templates, classids, or the DTO ladder starts at
.claude/v3/README.md (or invokes the /v3 skill — same bootload).
The V3 folder is the consolidated home for what is NEW since the
mailbox-kanban ruling + classid canon-high flip (both operator-ruled and
fleet-shipped 2026-07-02):
.claude/v3/README.md— orientation + doc map (start here).claude/v3/INTEGRATION-PLAN.md— the W0–W6 wave plan.claude/v3/COMPONENT-MAP.md— every subsystem: reuse / repurpose / retire.claude/v3/ENTROPY-MILESTONES.md— the systematic N→1 collapse ledger.claude/v3/MODULE-TABLE.md— per-file census of core / contract / planner.claude/v3/soa_layout/— LE contract, tenant lanes, consumer map, routing.claude/v3/knowledge/— V3 doctrine docs (READ BY:headers).claude/v3/knowledge/persona-vs-rung-ladder.md— MANDATORY before touching StyleFamily / ThinkingStyle / runbooks / recipes / the 144 verbs / RungLevel semantics / persona modeling: the operator-ruled rung-content ladder (0–1 observation, 2 = 144 verb atoms, 3 = the 34 NARS tactic recipes = THE runbooks, 4 = StyleFamily macros + autopoiesis triangle) and the demarcation that the adjective-36 incontract::thinkingis the SEPARATE, unwired persona-modeling storyline — never rung 3, never "NARS runbooks" (corrects E-STYLE-FAMILY-VS-RUNBOOK-1's label). Open items O1–O6 tracked there..claude/v3/agents/BOOT.md— the four V3 cards (v3-mailbox-warden,v3-envelope-auditor,v3-kanban-executor-engineer,v3-template-smith).claude/v3/knowledge/sonnet-worker-guardrails.md— MANDATORY in every Sonnet worker brief (§1 preamble pasted verbatim; §2 vocabulary disambiguation; §5 STOP+report triggers). No grindwork spawn without it./v3-auditcommand — mechanical conformance greps before any commit
Headline rulings the folder carries (canonical text on the board):
no singleton CollapseGate (one mailbox = one kanban board as tenant);
SoaEnvelope LE ownership (mailbox_owner(), write-on-behalf iron rule);
compiled thinking templates (elixir-template × StepMask, Rig as oracle);
classid canon-high with the 0x1000 V3-adoption monitor;
PerturbationDto/Resonance split (D-PERT-1). Sections of THIS file that
predate these rulings (e.g. CollapseGate wording below) are read through
.claude/v3/knowledge/v3-substrate-primer.md §6 "must not be reinvented".
Updated: 2026-04-21 (categorical-algebraic inference click) Role: The obligatory spine — query engine, codec stack, semantic transformer, and orchestration contract Status: 22 crates, 7 in workspace, 15 excluded (standalone/DTO), Phases 1-2 DONE, Phases 6-7 DONE (grammar + governance), Phase 3 IN PROGRESS
Parsing, disambiguation, learning, memory, and awareness are one
operation. Element-wise multiply + add on role-indexed identity
fingerprints in Vsa16kF32 = Box<[f32; 16_384]> (64 KB lossless
VSA carrier).
Correction of initial 2026-04-21 framing: earlier this session posted a version claiming "XOR on
[u64; 157]" — that was a Frankenstein confusion between Binary16K (Hamming-compare format,[u64; 256]) and the actual VSA carrier (real-valued multiply+add). See.claude/knowledge/vsa-switchboard-architecture.mdfor the corrected three-layer framing andCHANGELOG.mdfor the format- switch history.
2026-05-26 Baton scoping (read with
EPIPHANIES.mdE-BATON-1): "The Click" describes how a singleThinkresolves locally, within one compartment — the bundle is an ephemeral computation, never a persisted or transmitted singleton.Vsa16kF32is deprecated as a carrier: it does NOT cross mailbox boundaries and there is no materialized singleton BindSpace. Inter-mailbox state is the Baton — discrete owned(u16 target, CausalEdge64)handoffs (CollapseGateEmissioninlance-graph-contract;wire_cost_bytes() = 13 + 10·baton_count, NOT16384·4). "Baton" is the workspace's native term for the little-endian contract (the user's name for it before the information-science framing). The mailbox-as-owner (rotating sea-star topology) is what makes the handoff sound: Rust move/ownership semantics prove no aliasing / no data race / no use-after-free at compile time — UB becomes a compile error (canonical §9 E-CE64-MB-4). Cumulative state lives in CausalEdge64 emissions + AriGraph SPO-G quads + BindSpace SoA columns. The bundle MATH here (§I-SUBSTRATE-MARKOV Chapman-Kolmogorov, §I-VSA-IDENTITIES) is untouched — only the cross-boundary carrier is scoped out.2026-06-11 supersession (PR #477 three-tier model + tombstone commit): the Baton/emission framing above is itself now SUPERSEDED. There is no inter-mailbox handoff type at all —
CollapseGateEmission,MailboxSoA::emit(), andwire_cost_bytes() = 13 + 10·baton_countwere removed from source (the tombstone commit). The ratified invariant: every SoA envelope is zero-copy from creation to Lance tombstone; Lance's own columnar I/O writes LE bytes from the in-place backing store described bySoaEnvelope; nothing is serialized or transmitted between mailboxes.last_emission_cyclewas renamedlast_active_cycle(in-place consumption stamp). Canonical reference:docs/architecture/soa-three-tier-model.md. What survives from this block: Vsa16kF32-never-crosses-boundaries, the mailbox-as-owner compile-time safety argument (E-CE64-MB-4), and the bundle math — all untouched.2026-07-10 supersession (operator ruling
E-MARKOV-TEMPORAL-STREAM-1): in most cases the singleton-BindSpace VSA substrate is NOT used, and the Markov trajectory below moves off the VSA braid onto thetemporal.rssorted stream — grammar-resolver ambiguities are resolved live and granularly against a version-range read (QueryReference::at(v, rung)+ deinterlace), which generalizes the ±5 window (any width, per-reader rung, no N≤32 bundle-SNR ceiling, replayable — still a projection, zero copies). Episodic = Lance versions (the OGAR D-DELTA mapping, now primary); episodic basins =part_of:is_arails (le-contract L1–L3); the perturbation shader's carrier is the L46× palette256:palette256tenant over the Morton 2bit×2bit 4×4 cascade. VSA is demoted to its I-VSA-IDENTITIES four-test niche (≤32 lossless role superposition within one compartment) — the bundle ALGEBRA below stays valid in that niche; the [FORMAL-SCAFFOLD] consult is recorded in the board entry (Chapman-Kolmogorov now holds exactly by stream order, a strengthening). Diagram + "three things" §1 below are read through this note. Probes D-MTS-1..3 (plantemporal-markov-and-style-classes-v1) gate the code migration.
Sentence → FSM → RoleKey_fp × content_fp → vsa_bundle (Σ) with ρ^d braiding
│ │
Kan extension Markov ±5 trajectory
(Shaw 2501.05368: (temporal causality is
element-wise optimal structural, not learned)
in ℝ value category)
│ │
└────────┬────────────────┘
▼
FreeEnergy::compose(likelihood, kl)
likelihood = vsa_cosine(unbind(bundle), codebook_fp)
kl = awareness.divergence_from(prior) (NARS-revised)
│
┌─────────────┼──────────────┐
▼ ▼ ▼
Commit Epiphany FailureTicket
(F < 0.2) (ΔF < 0.05) (F > 0.8)
│ │ │
▼ ▼ ▼
AriGraph both triples LLM resolves
one triple + Contradiction the <25% tail
│
▼
awareness.revise(key, outcome) ← φ-1 ceiling = permanent humility
│
▼
global_context += fact → reshapes NEXT cycle's F landscape
Three things that must never be complicated:
- Markov = f32 multiply + add of identity fingerprints. Per-sentence Vsa16kF32, braided by position (vsa_permute), superposed via element-wise add. No HMM. No transition matrix. No weights. Lossless up to N ≤ √d / 4 ≈ 32 bundled items (f32 dynamic range).
- Roles = spine coordinates. SUBJECT[0..4K) is "who". PREDICATE[4K..8K) is "what". Unbinding = multiply by role key = reading a coordinate. Temporal causality is structural (braiding × slices).
- Meaning = AriGraph facts + resonance + magnitude. Resonance = cosine similarity against global context or codebook. Magnitude = Contradiction depth from Staunen × Wisdom qualia. Opinions are committed contradictions preserved, not resolved.
The object speaks for itself. trajectory.resolve(ambiguity) —
not resolve(trajectory, config, awareness, graph). Every method
lives on the carrier that has the state to reason with it.
The shader can't resist the thinking. StreamDto flows in → CognitiveShader encodes (bind + braid + bundle) → decodes (unbind + margin + F) → if F > homeostasis floor, awareness bits persist in MetaWord → dispatch fires again → another encode/decode cycle → F descends → bits clear → shader rests. The system doesn't choose to think. It can't NOT think while surprise exists. Active inference is the dispatch mechanism, not a metaphor.
Thinking is a struct. The universal DTO makes the object do the work:
struct Think {
trajectory: Vsa16kF32, // the Markov-braided role-indexed bundle
awareness: ParamTruths, // NARS-revised per-key epistemic state
free_energy: FreeEnergy, // (1 - likelihood) + kl
resolution: Resolution, // Commit / Epiphany / FailureTicket
}Not a function. Not a pipeline. Not a service. A struct whose
fields ARE the cognitive state and whose methods ARE the inference.
think.resolve() reads its own trajectory, computes its own F,
updates its own awareness, returns its own Resolution. The DTO
carries cognition the way a photon carries electromagnetism — not
as payload, as identity.
AriGraph, episodic memory, SPO, CAM-PQ are thinking tissue — not storage. The reason the struct becomes AGI is that memory is wired INTO it, not called FROM it:
struct Think {
trajectory: Vsa16kF32, // ← encode (Markov-braided roles)
awareness: ParamTruths, // ← epistemic state (NARS-revised)
free_energy: FreeEnergy, // ← surprise (likelihood + kl)
resolution: Resolution, // ← decision (commit/epiphany/escalate)
// ── thinking tissue (not external services) ──
episodic: &EpisodicMemory, // ← what happened before (retrieval)
graph: &TripletGraph, // ← what is believed (SPO facts)
global_context: &Vsa16kF32, // ← ambient prior (superposed facts)
codec: &CamPqCodec, // ← compressed distance (O(1) lookup)
}The graph is not a database the struct queries. The graph is part
of the struct's reasoning surface — graph.nodes_matching(features)
is how Think resolves coreference, episodic.retrieve_similar(fp)
is how Think remembers, codec.distance(a, b) is how Think
compares without decompressing. These are methods on tissue, not
calls to services. Cut the graph out and Think can't resolve
pronouns. Cut episodic out and Think has no memory. Cut CAM-PQ out
and Think can't do fast similarity. They're organs, not accessories.
This is why it's AGI and not just a parser. A parser takes text in and produces structure out. Think takes text in, resolves it against everything it has ever committed (graph), everything it recently saw (episodic ±5..±500), everything it believes about its own competence (awareness), and everything the current style expects (prior) — then commits the result back into the tissue it just read from. The loop IS cognition. The tissue IS the loop.
The DTO becomes the grammar of awareness. The struct's fields (trajectory, awareness, free_energy, resolution, episodic, graph, global_context, codec) are not data — they are grammatical roles of cognition itself. Trajectory is the Subject (what is being thought about). Awareness is the Modal (how confidently). Free energy is the Kausal (why this thought, not another). Resolution is the Predicate (what the thought concludes). Graph is the Lokal (where in the space of known facts). Episodic is the Temporal (when, relative to what came before). The TEKAMOLO of cognition IS the struct layout. Parsing text and parsing thought use the same role-indexed slices — because thinking about a sentence and thinking about thinking use the same algebraic substrate.
Proof chain (Shaw → beim Graben → Jian → Schulz → Alpay →
Graichen → Gallant → Kleyko): see
.claude/plans/categorical-algebraic-inference-v1.md §5.
Litmus tests for any proposed change:
Does this add a free function on a carrier's state, or a method on the carrier? → Free function = reject. Method = accept.
Which of the five lenses does this serve (Parsing / Free-Energy / NARS / Memory / Awareness)? → None = investigate drift.
Full plan: .claude/plans/categorical-algebraic-inference-v1.md.
Paper grounding: .claude/knowledge/paper-landscape-grammar-parsing.md.
Epiphanies that dilute first: EPIPHANIES.md E-PAPER-1 through E-PAPER-7.
You are in the driving seat. This workspace is not a codebase you observe; it is a cognitive stack you steer. Three consequences:
-
The board is live state, not reference.
.claude/board/*.mdis where the session's hand lives. Updating it AFTER the work, as cleanup, is the tell that you were treating the board as a stale artifact — do not do that (see § Mandatory Board-Hygiene Rule below). -
AGI is the glove, not the oracle. Per PR #223's AGI-as-SoA invariant: AGI = (topic, angle, thinking, planner) = struct-of-arrays consuming
cognitive-shader-driver. The four axes are the fourBindSpacecolumns —FingerprintColumns/QualiaColumn/MetaColumn/EdgeColumn. You fit your hand into those columns throughShaderDriverdispatch andOrchestrationBridgerouting. You do NOT wrap the axes in a new struct (breaks the SIMD sweep) and you do NOT query an "AGI service" (there is none; AGI is the runtime behaviour of the SoA under dispatch). -
Consult, don't guess. When a subsystem comes into scope, the curated surface beats hand-exploration — always. Grepping ndarray for a primitive name when the family-codec-smith agent or the
encoding-ecosystem.mdknowledge doc has the answer is a rediscovery tax, not a diligence win.
A PR that adds a type, plan, deliverable, or epiphany without updating the relevant board file in the SAME commit is incomplete.
| The PR adds... | The PR MUST also update (in the same commit) |
|---|---|
| A contract type / module | .claude/board/LATEST_STATE.md — "Current Contract Inventory" |
| A merged PR (post-merge commit) | .claude/board/LATEST_STATE.md table + .claude/board/PR_ARC_INVENTORY.md PREPEND entry |
| A new integration plan | .claude/board/INTEGRATION_PLANS.md PREPEND + .claude/plans/<name>-v<N>.md |
| A new D-id / deliverable | .claude/board/STATUS_BOARD.md row (status = Queued → In progress → In PR → Shipped) |
| A finding / measurement / probe result / open point | .claude/board/entries/YYYY-MM-DD-<entry-id>.md (the entry verbatim) + python3 .claude/tools/entries_index.py --write in the SAME commit |
| A genuine Eureka (passes the § Closeout admission gate below) | .claude/board/EPIPHANIES.md PREPEND dated entry |
| An ordinary correction / lesson learned | NOTHING — one closeout line, see § Closeout below |
| A tech-debt observation | .claude/board/TECH_DEBT.md entry |
| A half-seen pattern / an idea someone is now probing / method gold with a receipt | .claude/board/BREADCRUMBS.md crumb / TORQUE.md row / GOLDSTAUB.md entry (see § Closeout) |
| A fruit (any ledger row a session could pick up) | a **Fruit:** line on that row, then python3 .claude/tools/fruits_index.py --write |
| An unresolved issue / blocker | .claude/board/ISSUES.md entry |
| A completed agent run | .claude/board/AGENT_LOG.md PREPEND entry (D-ids, commit, tests, outcome) |
Sessions with Private Repositories making board entries on a public repository have to exclusively focus on the necessary updates in the public repository, and keep a separation of concerns.
Termination clause — the rule does not recurse (added 2026-08-04, three
links deep; scope corrected same-day per codex P2). A PR whose ENTIRE
content is board hygiene for prior PRs — it adds no type, plan,
deliverable, epiphany, or code — generates NONE of the merged-PR row's
obligations: no arc entry AND no LATEST_STATE update. It is discharged
by the entries it wrote. Exempting only the arc entry would leave the
chain alive through the other half — recording the still-required
LATEST_STATE update is itself a hygiene-only PR, forever. Without this
clause the rule is an infinite chain: #884 recorded #881/#882/#883, #885
recorded #884, and an entry for #885 would need its own forever. The
chain that produced this clause stops at #885.
The test is content, not intent: does the PR change anything a future session would need the "why" for? A hygiene-only PR's why is the entry it added, already in the arc — a second entry saying "this PR added an entry" carries no architectural context and costs a real read. A mixed PR still gets its entry — if it lands hygiene and a decision, scope, code, or correction (as #884 did with the D-KIA-C1b re-scope), the non-hygiene half is what the entry is for.
This is a stopping rule, not a loosening: the original gap — merging #881, #882 and #883 with no entries at all — remains a real violation. What is excluded is only the degenerate tail.
DECISION (2026-09-20). The workspace was accumulating correction-shaped
prose faster than architecture: a mistake became a correction, then a finding,
then an epiphany, then a post-mortem, then a correction OF the post-mortem, then
permanent terminology. Measured: EPIPHANIES.md is 33,528 lines with no
admission gate, and no closeout surface existed anywhere under .claude/. The
default is now fix → compress → keep open points visible → move on.
SCOPE: all ordinary work — implementation, audits, PR review, probes,
integration, /5plus3 alike. REVISIT WHEN: the ledger starts losing a
discovery rather than a correction.
The default closeout is ONE compact status record — not a board entry, not a file:
PR #<id> | STATUS: <fixed|measured|open|rejected|done> |
OUTCOME: <smallest useful statement of what changed> |
OPEN: <remaining live question(s), or none>
Several trivial corrections collapse into one line (OUTCOME: 4 review defects corrected; executable contract unchanged). Do not create one permanent
artifact per correction. If a session fixed several things and discovered no
new architecture, a boring closeout IS success: STATUS: done | OUTCOME: review corrections applied; architecture unchanged | OPEN: none.
MIRROR — self-reflection without paperwork. At a meaningful closeout, at most these four fields; omit any field that carries nothing, and omit the whole section when it carries nothing. Silence is allowed.
MIRROR
- LESSON: <one sentence, only if useful>
- BLIND SPOT: <what relevant thing was not inspected / weighted / challenged>
- BIAS CHECK: <heuristic that may have distorted the search or conclusion>
- STILL OPEN: <uncertainty we genuinely do not yet understand>
Kahneman/Tversky as QUESTIONS, never as labels. Never write "this was anchoring" or "confirmation bias caused X" — diagnosing a past self is the residue this rule exists to stop. Ask only whether any MAY have contributed:
- Anchoring — did the first plausible explanation become the reference later evidence was read against, instead of being re-tested independently?
- Availability — was the easiest grep hit, the recent PR or the vivid failure overweighted because it was cheap to retrieve?
- Representativeness — did something LOOK like a known pattern and get treated as the same mechanism without reading the actual contract?
- Base rate / population — was the denominator, frequency or index space ignored; do two similarly shaped masks describe different populations?
- Framing — did the task's wording make one reading feel inevitable; would the conclusion survive a different phrasing?
- WYSIATI — did "what we saw" become "all that exists"; did
search = 0become absence; did a small visible set become the whole search space? - Sunk cost — was a mechanism, doc or test preserved mainly because it was already written?
- Confirmation pressure — after forming the hypothesis, did we look for a disable, a counterexample and an alternative, or only for agreement?
OPEN stays open. UNKNOWN is a valid result. Never manufacture a doctrine,
a carrier, a term, a follow-up PR or an Epiphany to turn OPEN into CLOSED — a
visible blind spot is healthier than a fabricated conclusion. Write it plainly:
OPEN: ownership still undecided; no measured row-level predicate yet; search space not closed; competing explanations remain.
Epiphany admission gate — lessons learned are NOT Epiphanies. "the
hand-written ternlog immediate was wrong", "the test failed by underflow rather
than by its assertion", "the CI job attribution was guessed", "the grep was
correct and the conclusion false", "the tail hid the root diagnostic" are
LESSONS. Each may become one MIRROR line. None enters EPIPHANIES.md. A
candidate must be all three — NEW (not already represented),
LOAD-BEARING (changes future architecture, reasoning or representation),
DURABLE (still matters once the PR and the mistake are forgotten) — and pass
one test:
Would this insight still matter if the mistake that led to it had never happened? NO ⇒ it is not an Epiphany.
Concretely: "I was wrong about which CI job held the step" is a correction
(STATUS: fixed | OUTCOME: job attribution corrected | OPEN: none). "Two masks
can share a Boolean algebra while inhabiting different population axes, so
algebraic compatibility does not imply representational substitutability"
survives its own mistake and is a candidate. Keep the categories separate.
The transient tier, and the ONE promotion rule. Ordinary work lands in
.claude/board/entries/ as a dated file — the transient work/finding tier,
not an Epiphany staging folder. It is noisy on purpose: a finding there may be
wrong, superseded tomorrow, or merely a measurement. Its index is GENERATED
(entries_index.py --write; never > README.md — the file is its own input)
and CI runs the three structural falsifiers, so a stranded file or a stale
header cannot recur.
At closeout each entry is reconciled against project truth — reuse what exists:
PLAN-INVENTORY's verdict rubric (OPEN = its own status line and/or its
STATUS_BOARD D-ids say work remains · CLOSED = its deliverable is
delivered · SUPERSEDED = a higher-numbered sibling or its status says so ·
AMBIGUOUS = no house-format status and no board row), SUPERSESSION-INDEX's
route column, and preflight_drift for board-claim-vs-cargo-reality. Then
exactly the destinations below, and no other:
⊘ AMENDED 2026-10-23 (operator: "breadcrumbs of something bigger", "go ahead"). This read "exactly four destinations, and no fifth". Four left no home for a NEW, promising but not-yet-DURABLE idea, for a half-seen pattern, or for method gold. Each was either squeezed into EPIPHANIES (the proof-of-work abuse the gate was written against) or died at closeout. Measured that day:
IDEAS.md's newest Open row was 2026-09-07, while 260 entries landed inentries/in October. The three rows marked (new) are the amendment. The EPIPHANIES gate itself is unchanged.
| the entry is… | destination |
|---|---|
| fixed / obsolete / duplicate / already represented | nothing durable — it dies in the tier; git keeps the journey |
| still genuinely unresolved | one compact OPEN row (ISSUES.md or STATUS_BOARD.md) |
| implemented / closed | one compact DONE row (STATUS_BOARD.md, or LATEST_STATE.md if it changed the inventory) |
| a half-seen pattern: rhymes with another observation, claims nothing (new) | one crumb in BREADCRUMBS.md (three linked crumbs force a naming attempt) |
| NEW and promising, not yet DURABLE: an idea with a next probe (new) | IDEAS.md Open row; once a session moves on it, a TORQUE.md row (owner, next probe, kill, promote, 14-day stall back to IDEAS) |
| a method/efficiency insight that costs again whenever forgotten, with a receipt (new) | one GOLDSTAUB.md entry: claim + receipt + scope + date, never rewritten |
| NEW and LOAD-BEARING and DURABLE, and still true after reconciliation | EPIPHANIES.md — the rare case, entered from a TORQUE or IDEAS row after its probe ran |
A surviving Eureka must clear both gates: the three-way admission test above
and still being true against the current implementation. MIRROR is never
promoted by itself — it is transient reflection and normally dies at closeout;
only a factual consequence of it (a real open implementation issue) becomes a
row, and a BIAS CHECK line has no durable home at all.
The checkpoint, and DELTA-ONLY closeout. .claude/board/FINDINGS-BASELINE-2026-09-20.md
is the one historical catch-up over the 306 findings that went into the
EPIPHANIES.md monolith after the 2026-08-06 split — a k-frame. From it
forward, closeout consumes only the delta: read PROCESSED_THROUGH_SHA
from .claude/board/PROCESSED_THROUGH, reconcile
PROCESSED_THROUGH_SHA..<captured HEAD>, write the compact state, then
advance the marker to that captured head. Routine work never censuses the
historical EPIPHANIES.md monolith again.
The watermark is a SHA, not a date — imports, backdated headings, rebases
and concurrent work all make a calendar watermark lie, the same reason
supersession_index.py refuses git mtime as a signal. It names the CONSUMED
INPUT, never the commit that records it: a commit cannot contain its own hash.
If the SHA is unreachable (shallow clone), tooling FAILS CLOSED — an invisible
delta is not an empty one.
The historical prose is FROZEN, not reconciled. Frozen means not reread by
routine closeout. Most historical rows were NOT adjudicated — mechanically
unjoinable, conflicting evidence, or, most of them, graded FINDING / RULING
/ CORRECTION, an epistemic grade answering how well established rather than
is it done. The generated baseline owns the exact counts; they are not
restated here. FROZEN ≠ RECONCILED, and the ambiguous rows are
not an invitation to another archaeology pass; if one matters later it resurfaces
as live work and enters the transient tier like anything else.
A promotion to EPIPHANIES.md after the baseline must name the
entries/YYYY-MM-DD-*.md it came from — epiphany_provenance.py checks that
the reference RESOLVES, and nothing more. It proves the route; whether the
content is a Eureka stays the admission gate above, because a regex that judged
Eureka-ness would be a guard that fires on everything.
No recursive post-mortems. A correction does not entitle a post-mortem, and a corrected post-mortem does not entitle another — § Termination clause above is the same stopping rule one level down. A review earns a follow-up only for a still-live executable defect, an unresolved implementation task, or a true Eureka needing independent architectural work. Documenting what went wrong is not itself a follow-up task.
Ore and slag. Ask what survived that future work genuinely needs. Keep: the current contract, the measured result, the open point, a genuine Eureka. Discard: stale reasoning, the correction narrative, the duplicate explanation, the wrong hypothesis, procedural autobiography, and any elaborate lesson already encoded in a test or a guard. The closeout should usually be SMALLER than the reasoning history it closes. Optimize for clarity, current truth, visible uncertainty and minimal durable residue — never for maximum documentation. The architecture should stay enjoyable to work on.
An assertion implied by the code it tests is not a test. Before a test lands, answer: what input would make this fail? If none exists, delete or rewrite it.
Measured instances, all found the same day (E-VACUOUS-ASSERTION-IS-THE-HOUSE-STYLE-1):
assert!(results.len() <= 10) where the code above it is
results.truncate(top_k) with top_k: 10; elimination_rate() > 0.0 (true
of any input that eliminates anything); a closed_class_guess flag firing
150/150; a "multipass" wave that was single-pass because every test used a
one-hop chain (E-MULTIPASS-WAS-SINGLE-PASS-1).
Consequences, non-negotiable for new work:
- A filter needs an anti-vacuity test — assert the excluded set is
non-trivial (
kept * 3 < total), not merely that filtering happened. - A guard/channel needs a can-it-fire test — prove it triggers on some real input. A watchdog that cannot bark is the defect one level up.
- …and its twin, a can-it-STAY-SILENT test (added 2026-07-27,
E-ANTI-EIGENVALUE-MACHINERY-CAN-ITSELF-BECOME-THE-EIGENVALUE-1). A guard that fires on everything carries exactly as much information as one that never fires — that is theclosed_class_guess150/150 defect, and an escalation channel that objects to everything has become the dominant mode it exists to interrupt. Both halves must use NON-TRIVIAL inputs: an empty-input silence case proves the guard handles emptiness, not that it discriminates. Measured instance: the two dissent channels fire 114/180 and 144/180 over the style×rung matrix — discriminating, but only because it was checked; nothing in the suite had required it. - A tolerance/threshold parameter needs an inertness test — raising it must
silence something, lowering it must admit something. Otherwise the knob is
decoration (
heel_threshold 50.0against a 25.5 maximum, task #35). - A doc-comment claim is not a behaviour. If the prose says "multipass", "95% skipped", or "prunes N×", a test must exercise the claim or the claim must be labelled claimed, unverified.
- Prefer
== Nover>= Nwhen reading a schema'd file; a permissive arity guard is a silent-misread waiting for a schema change.
The governance files are APPEND-ONLY (prepend new entries; never
edit past entries except the **Status:** / **Confidence:**
lines). The retroactive-hygiene commit pattern (merge PR → later
notice board is stale → separate cleanup commit) is an
anti-pattern. The 2026-04-20 session surfaced this gap between
PR #223/#224/#225 merges and the LATEST_STATE / PR_ARC update;
this rule exists so it does not recur.
.claude/board/SUPERSESSION-INDEX.md is produced by
.claude/tools/supersession_index.py, which reads .claude/plans/,
crates/, .claude/v3/COMPONENT-MAP.md, and the board itself
(.claude/board/entries/*.md + EPIPHANIES.md, supersession_index.py:48-49
— the "board coverage" column counts each plan's D-ids cited there,
:85). It lists every ruled symbol (RETIRE / REPURPOSE / …) and every plan
that names one without citing the ruling.
Regenerate LAST, after the board writes — not after the plan edit.
Because the board is an input, a run made before prepending an EPIPHANIES
entry cannot see the D-ids that entry cites, produces a byte-identical file,
and reads as "already current" while CI (which regenerates on the merge
commit) goes red on the coverage column. Measured on #1085: regenerated
early, output identical, regenerate-and-diff failed on exactly the two
rows the new entry's D-ARW-0 / D-ARW-8 citations moved. The workflow's
own error text names only the first three inputs and will mislead the same
way; the file list here is the accurate one.
-
If your PR adds or edits a plan, or changes a symbol's verdict, regenerate and commit in the same PR:
python3 .claude/tools/supersession_index.py > .claude/board/SUPERSESSION-INDEX.md -
The
Supersession index is currentworkflow regenerates and diffs on every PR touching those inputs. A stale index fails CI with the command above in the error. Do not edit the file by hand to make the diff pass — the commentary is generated too, so hand-edits are wiped on the next run. -
Why the gate exists: a stale table authorises work against a retired symbol. It went stale within the hour of first landing, because generation was manual and another PR added a plan. A generated artifact with no staleness gate is a hand-maintained artifact with extra steps.
What the gate does NOT prove. It proves the table is current, never
that a route is right. ARCHIVE? reads the status's leading token from
the plan's metadata region only — it cannot tell you whether a plan is
genuinely finished. The first ARCHIVE? batch was current and 3/3 wrong:
every plan was live, matched on a word that did not predicate it (a phase
inside an ACTIVE status, a predecessor inside a PROPOSAL, a
Status legend: defining a tick mark). A route is a prompt to read the
plan, never a licence to act on it — verify against STATUS_BOARD.md,
anchoring the join on each row's own leading cell, before archiving or
rescoping anything.
Before grep'ing, reading source files, or proposing a type:
- Does a specialist agent card cover this domain? Check
.claude/agents/*.md— 19 specialists + 5 meta-agents. For codec work:family-codec-smith,palette-engineer,certification-officer. For DTO / bus surface:bus-compiler,host-glove-designer. For truth / architecture:truth-architect,integration-lead. See.claude/agents/BOOT.mdfor the Knowledge Activation trigger table. - Does a knowledge doc answer this? Check
.claude/knowledge/*.md— each has aREAD BY:header naming which agents / domains load it.encoding-ecosystem.mdis MANDATORY before any codec work;lab-vs-canonical-surface.mdis MANDATORY before any REST / gRPC / Wire DTO / OrchestrationBridge / shader-lab work. - Does the board already record the answer?
LATEST_STATE.md§ Contract Inventory lists every type that exists today. Proposing a type that already exists is a 30-turn rediscovery tax — check first.
Only AFTER exhausting 1-3 do you grep source files yourself. Hand- exploration is the last resort, not the first move. A subagent spawn (Opus for accumulation) that loads the curated docs first is almost always cheaper than a grep session on the main thread.
When a task touches the cognitive stack:
- Topic (what the session is reasoning about) = a read from
FingerprintColumns. Never a new struct. - Angle (whose perspective) = a read from
QualiaColumn(18×f32). Never a new struct. - Thinking (which style dispatches) = a write of
MetaWordbits toMetaColumn. Never a new trait. - Planner (why/how, causal composition) = a write to
EdgeColumn(CausalEdge64). Never a new bridge.
The four SoA columns ARE the AGI surface. New capability lands as a
new column, not a new layer. See .claude/knowledge/lab-vs-canonical-surface.md
§ "AGI IS the struct-of-arrays (per Era 8)" for the full doctrine
and the Invariants I1-I11 that bind it.
VSA-bundling in d=10000 guarantees the Chapman-Kolmogorov
semigroup property by construction (see EPIPHANIES.md
E-SUBSTRATE-1). Saturating bundle is associative and commutative
in expectation; Johnson-Lindenstrauss + concentration-of-measure
suppress deviations from associativity at rate ~e^(-d). This is
the fundament on which the four [FORMAL-SCAFFOLD] pillars
(Cartan-Kuranishi + φ-Weyl + γ+φ + Jirak 2016) stand.
Consequences:
- Do NOT replace bundle with XOR or non-commutative binding for
state-transition paths without reviewing [FORMAL-SCAFFOLD] in
EPIPHANIES.md.
MergeMode::Xorbreaks the Markov guarantee — it is a legitimate merge mode for single-writer deltas (see I1), but it is NOT a Markov-respecting transition kernel. - D7's implicit Markov reliance is grounded, not silent. The Chapman-Kolmogorov consistency test is therefore an implementation sanity check (regression against implementation bugs), not a falsification gate for the theoretical property.
- Any substrate-level change that weakens associativity (binding operator swap, dimension reduction below 10000, removal of concentration-of-measure assumption) MUST consult [FORMAL-SCAFFOLD] and document the trade-off explicitly.
Cross-ref: I1 (BindSpace read-only, CollapseGate bundles);
contract::collapse_gate::MergeMode::{Bundle, Xor}.
Bits in the workspace's 16384-bit fingerprints are weakly dependent by construction: (a) correlated projections of embeddings, (b) overlapping role-key-indexed slices (Finnish [9840..9910) ∩ TEKAMOLO [9000..9900); NSM primes distribute non-disjointly over S/P/O), (c) palette codebook quantization shares a 4096-centroid codebook, (d) XOR bundle accumulation induces weak dependence as an operational consequence.
Classical IID Berry-Esseen is WRONG for this system. Use
Jirak 2016 (arxiv 1606.01617, Annals of Probability 44(3)
2024–2063, "Berry-Esseen theorems under weak dependence") for any
noise-floor or statistical-significance claim. Rate: n^(p/2-1)
for p ∈ (2,3], n^(-1/2) in L^q for p ≥ 4.
Consequences:
- ICC, Spearman ρ, and similar significance metrics must cite Jirak's rate, not classical Berry-Esseen, when claiming "observed value is N σ above noise floor."
- σ-threshold calibration (UNBUNDLE_HARDNESS_THRESHOLD, ABDUCTION_THRESHOLD, …) should cite Jirak-derived bounds when a principled threshold is needed; hand-tuned values are acceptable but must say so.
- The three revival candidates in [FORMAL-SCAFFOLD]'s Coupled revival track deposit the mechanism for deriving Jirak-derived thresholds when they activate (VAMPE + Jirak pair replaces hand-tuned σ thresholds with bound-derived ones).
Cross-ref: EPIPHANIES.md [FORMAL-SCAFFOLD] five-pillar entry;
E-ORIG-7 (the earlier statement of this finding before it became
an iron rule); Jirak 2016.
VSA operates on IDENTITY fingerprints that POINT TO content. Never on content's bitpacked/quantized register itself.
The register-loss problem: XOR-bundling (or any superposition) of CAM-PQ codes, quantized indices, or sign-binarized fingerprints destroys the mapping from bits back to their codebook entries. The register is destroyed — you can't recover which codebook centroids contributed.
The right pattern, three layers:
-
Switchboard carrier (in
crystal/fingerprint.rs) — one set of types + one algebra, domain-agnostic:Vsa16kF32(64 KB hot path),Vsa16kBF16(32 KB AMX-accelerated),Vsa16kF16(32 KB Apple/ARM),Vsa16kI8(16 KB quantized),Binary16K(2 KB Hamming compare). Algebra:vsa_bind(multiply),vsa_bundle(add),vsa_cosine(similarity). -
Domain role catalogues (per-domain) —
grammar/role_keys.rs, futurepersona/role_keys.rs,callcenter/role_keys.rs. Each provides its own set of role IDENTITY fingerprints in Vsa16kF32 with disjoint[start:end)slice allocations. Role keys are bipolar ±1 in their slice, zero elsewhere. Catalogue, not algebra. -
Content stores — YAML registries, TripletGraph, EpisodicMemory. Actual content lives here, O(1) retrieval by identity (name / enum / fingerprint). Never bundled, never superposed.
The four tests before reaching for VSA (in order):
- Test 0 — register laziness: Does this thing have a natural
name / ID / enum variant? If yes, use the register.
HashMap,enum,graph.nodes_matching(id)beat VSA at exact-match tasks. - Test 1 — bundle size: Is N ≤ √d / 4 ≈ 32 at 16K dim? If not, superposition SNR drops below threshold. Use direct lookup instead.
- Test 2 — role orthogonality: Are the role keys mutually orthogonal (disjoint slice, or orthogonal bipolar)? If not, unbind doesn't recover cleanly.
- Test 3 — cleanup codebook: Is there a known codebook to match against after unbind? Without it, raw bundle inspection is unreliable.
Any "no" short-circuits — it's not a VSA workload, use the right tool instead.
Consequences:
- CAM-PQ vs VSA: Never superpose CAM-PQ codes directly. CAM-PQ is for search (compressed nearest-neighbor); VSA is for bundling (lossless role superposition). Switching between them requires decompression, not mixing.
- Lazy VSA check: If Vsa16kF32 is being reached for as a fancy lookup when a HashMap would do, stop. That's register laziness, not VSA usage.
- Archetype / persona / thinking-style unification: All four are Layer-2 role catalogues. Each entry gets ONE identity fingerprint. Content (slots, rules, prompts) lives in YAML. Resonance (cosine vs codebook) dispatches to content.
Cross-ref: FormatBestPractices.md (Jirak-grounded per-workload
decision matrix — which format to use when, with SNR/capacity/cache/
precision analysis), .claude/knowledge/vsa-switchboard-architecture.md
(the full three-layer architecture with decision matrix), CHANGELOG.md
(format-switch history — when each variant was introduced, when
renames/reverts happened, why), I-SUBSTRATE-MARKOV (Chapman-Kolmogorov
semigroup), I-NOISE-FLOOR-JIRAK (weak dependence from CAM-PQ
contamination). Together these three iron rules bound the substrate:
(1) VSA bundling guarantees the Markov property; (2) classical
Berry-Esseen is wrong under CAM-PQ-induced weak dependence; (3)
CAM-PQ and VSA are separate tools for separate operations — bundle
identities, not content.
Every v1 API path under a v2-layout feature must transparently route through the canonical mapping OR be feature-gated to a documented no-op with a migration pointer.
The anti-pattern: leaving a v1 accessor or setter that reads/writes the OLD bit positions under a v2 feature that reclaimed those bits. The same function name silently produces different semantics depending on which feature is active, and downstream callers see corruption only at runtime on workloads that hit the reclaim zone.
Sprint-11 caught this anti-pattern 5 times via codex review:
CausalEdge64::pack(..., temporal=X)under v2 writingtemporal << 52into bits 52-63 which v2 reclaimed for plasticity[2] + W-slot + lens- spare. Fix: feature-gate the temporal write to no-op under v2.
CausalEdge64::inference_type()reading 3 unsigned bits 46-48 under v2 where the actual storage is 4-bit signed mantissa at 46-49. Fix: route throughfrom_mantissa(inference_mantissa())under v2.CausalEdge64::set_temporal()writing bits 52-63 unconditionally even under v2 (where those bits are W/lens/spare). Fix: feature-gate the entire setter to a documented no-op under v2.CausalEdge64::pack(..., InferenceType::Counterfactual, ...)under v2 writing the raw enum discriminant (6) into the mantissa field;inference_mantissa()reads it as +6 →from_mantissa(+6)decodes as Intervention (not Counterfactual). Fix: writeinference.to_mantissa()(-6 for Counterfactual) instead of the raw discriminant under v2.- W3 spec test
pal8_v1_v2_round_trip_zero_defaultusedtemporal=1023to construct a v1 edge; under v2 those bits aliased W/truth/spare and the test would fail on ordinary v1 data. Fix: usetemporal=0(the only safe v1 migration value) for the round-trip and add a pairedpal8_v1_nonzero_temporal_is_blocked_by_version_gatetest to assert the corruption is observable (the version gate is mandatory).
Consequences:
- Backward-compat shims for layout-breaking changes require systematic test coverage of the layout-bit boundary. Field-isolation matrix tests (writing each field, asserting all other fields unchanged) are MANDATORY when a layout reclaims previously-used bits.
- The same function name MUST NOT silently produce different
semantics under different feature flags. If the v1 API can't route
to the v2 canonical mapping, feature-gate it to a no-op AND add a
doc-comment migration pointer to the v2 successor (e.g.
inference_mantissa(),pack_v2()). - Layout reclaim must be paired with a version gate on serialization paths. A v1 binary blob under a v2 reader MUST refuse to decode without an explicit version byte (otherwise the bit aliases silently corrupt the reclaim zone).
- The codex P1 review is the canonical pre-merge gate for this pattern. When a PR ships v2-feature work, expect codex to flag any v1 accessor that hasn't been routed through the canonical mapping. Resolve before merge; don't defer.
Cross-ref: EPIPHANIES.md E-META-10 (the original finding);
.claude/knowledge/i4-substrate-decisions.md (the 5-instance catalogue);
.claude/board/sprint-log-11/meta-review-opus.md CSI-2 (Opus's
identification of the systemic pattern across Wave A).
Start here: .claude/BOOT.md — the one-page session entry point.
It names the three files below as mandatory reads, so load them
whether you went through BOOT.md or landed here directly.
.claude/board/LATEST_STATE.md— current contract inventory, recently shipped PRs, active branches, queued work, explicit deferrals. What exists..claude/board/PR_ARC_INVENTORY.md— per-PR Added / Locked / Deferred / Docs / Confidence, reverse chronological. APPEND-ONLY; only the Confidence line is updatable; corrections append as new dated lines; reversals get their own PR entry. Why it exists..claude/agents/BOOT.md— the 19 specialist + 5 meta-agent ensemble (workspace-primer,integration-lead,adk-coordinator,adk-behavior-monitor,truth-architect), the Knowledge Activation trigger table (domain → agent → docs), and the Handover Protocol spec. This is the A2A orchestration specification for this workspace. How to coordinate.
After these three, load domain-specific knowledge docs only as triggered by the user's request.
Companion dashboards (mid-session references, not cold-start mandatory):
.claude/board/STATUS_BOARD.md— deliverable-level dashboard. All D-ids across every active plan with Status. Consult when asking "where is D5" or "is this shipped yet.".claude/board/INTEGRATION_PLANS.md— versioned plan index (APPEND-ONLY). Active plan lives at.claude/plans/<name>-v<N>.md. Consult before proposing a new plan.
If you want the pattern explained rather than the specifics:
see .claude/skills/cca2a/SKILL.md — explanation-only skill
covering the A2A two-layer model, governance rules, and how this
workspace's conventions diverge from official Claude Code docs.
Read once to grok; then stop re-deriving across sessions.
This workspace accumulated substantial curated content across
prior sessions. Before drafting a new .claude/*.md or proposing
a new architectural direction, grep these:
.claude/prompts/(41 files) — scoped session / probe / handover / research prompts. SeeSCOPED_PROMPTS.mdas index..claude/plans/+.claude/board/INTEGRATION_PLANS.md— versioned integration plans (APPEND-ONLY index; prior versions retained with Status annotation)..claude/*.md(61 top-level docs) — calibration reports, session handovers, epiphanies, integration-plan snapshots, audits, inventory maps, invariant matrices. Examples:SESSION_CAPSTONE.md,INTEGRATIONSPLAN_2026_04_01.md,INTEGRATION_SESSIONS.md,INVENTORY_MAP.md,HANDOVER_NEXT_SESSION.md,KNOWLEDGE_SYNC_SIGNED_SESSION.md..claude/knowledge/*.md(newer, structured) — withREAD BY:headers + Knowledge Activation triggers..claude/agents/*.md(19 specialists + 5 meta-agents) — seeREADME.mdfor function inventory,BOOT.mdfor orchestration..claude/hooks/*.sh— SessionStart + PostCompact context injectors..claude/skills/cca2a/— the pattern explanation skill.
Rule: grep the existing ~100 files before writing a new one. Most architectural concerns have prior art in this workspace.
Orchestration in this workspace runs at two distinct layers. Each layer uses a different "blackboard" substrate; both must be respected when spawning subagents or composing cognitive cycles.
For cognitive-cycle orchestration inside the running system:
lance_graph_contract::a2a_blackboard—Blackboardwithentries: Vec<BlackboardEntry>+round: u32. Each entry carriesexpert_id,capability,result,confidence,support [u16; 4],dissonance,cost_us. Experts write; later rounds read prior entries and build on them. This IS the A2A bus for multi-expert inference.lance_graph_contract::orchestration::OrchestrationBridge— trait bridgingStepDomain(Codec / Thinking / Query / Semantic / Persistence / Inference / Learning) intoUnifiedStep. Each domain contributes aBridgeSlot; orchestration routes steps across domains without duplicating state.lance_graph_contract::orchestration_mode— explicit modes for how a cycle composes (linear, parallel, blackboard-broadcast, etc.).ExpertCapabilityenum — the capability taxonomy experts declare. Do NOT invent new capabilities ad-hoc; grepa2a_blackboard.rsfirst.- Reference doc:
docs/ORCHESTRATION_IS_GRAPH.md— capstone treating orchestration AS graph traversal (the runtime A2A is a directed blackboard-graph).
Use Layer 1 when the question is "how do two cognitive experts compose their outputs at runtime."
For subagent coordination during this session:
.claude/board/AGENT_LOG.mdis the Layer-2 blackboard — with ONE writer. Every agent run gets one entry (D-ids, commit, tests, outcome); later agents read prior entries to see what was shipped, found, or is in flight — same as Layer-1 experts reading priorBlackboardEntryrounds. This replaces explicit message passing between agents: no backend coordination, just file reads.⊘ ONE-WRITER CORRECTION (operator-ruled 2026-07-22,
E-AGENT-LOG-SHARED-SINK-ANTIPATTERN-1). Sub-agents do NOT append toAGENT_LOG.md(or any shared board file). Concurrent append to one file is a lost-write race, and a shared append-log is the exact shared-mutable-sink the runtime substrate eliminated (one-writer-per-mailbox,SoaEnvelope::mailbox_owner, no singleton; E-CE64-MB-4) — re-created one layer up. The rule now: each sub-agent writes ONLY its own agent-tag file (exec-runs/<slug>.txtfor an executor;<agentId>.mdfor any worker that must leave a record); the orchestrating main thread is the SOLE writer ofAGENT_LOG.mdand every shared board file, consolidating the tag-files after committing. A shared append-log is not an A2A channel — real A2A is a message to an owned mailbox; co-appending to one log is pseudo-A2A with a race. Full statement:.claude/knowledge/tiered-agent-execution-protocol.md§ "ONE WRITER PER FILE". Every agent prompt MUST include: "Read.claude/board/AGENT_LOG.mdbefore starting. Do NOT write it — leave your record in your own tag-file; the orchestrator consolidates." Base case (made explicit 2026-08-04, recursion sweep): the consolidation itself is not an agent run and gets no entry. Without this the rule diverges the moment board hygiene is delegated — which has happened (see this log's own "Sonnet W3 (board hygiene)" runs): a worker writing the log entry is an agent run, needing an entry, written by a worker. The one-writer rule already implies the base case; stating it means a future session doesn't have to re-derive it. Cf.CLAUDE.md§ Termination clause andE-THE-HYGIENE-RULE-RECURSED-1.LATEST_STATE.md+PR_ARC_INVENTORY.mdare the structural blackboard — what types exist, which PRs shipped. Every subagent reads them for current state.- Knowledge docs in
.claude/knowledge/are the extended blackboard — cross-session persistent entries. Each doc has aREAD BY:header declaring which subagent types load it (the equivalent ofExpertCapabilitymatchers). .claude/plans/*.md— plan files authored viaPlanagents; session-scoped blackboard for multi-turn work. Other agents reference the active plan for context.- Parallel subagent spawns in one main-thread turn are the cheapest Layer-2 A2A pattern. Independent work fans out; results aggregate back to the main thread, which does the cross-source synthesis (accumulation → main thread on Opus per policy above).
Use Layer 2 when the question is "how do I coordinate N subagents without burning main-thread turns re-reading the same state."
See .claude/agents/BOOT.md — it's the meta-card for the 19
specialist agents + 5 meta-agents in this workspace. It covers:
- Meta-agent scopes (
workspace-primer,integration-lead,adk-coordinator,adk-behavior-monitor,truth-architect). - Session-start knowledge bootload — every subagent loads Tier-0
(
LATEST_STATE.md+PR_ARC_INVENTORY.md) unconditionally, then Tier-1 knowledge docs by trigger table. - Knowledge Activation Protocol — the trigger → agent → doc mapping (updated 2026-04-19 with grammar / crystal / NARS / coreference / AriGraph / codec rows).
- Handover Protocol —
.claude/handovers/YYYY-MM-DD-HHMM-<from>- to-<to>.mdfiles carry What-I-did / FINDING / CONJECTURE / Blockers / Open-questions. APPEND-ONLY.
A new session doesn't reinvent the ensemble — it reads this README, picks the agents whose objects are being touched, and lets them bootload their own Tier-0 + Tier-1 docs.
| Question | Layer | Primary substrate |
|---|---|---|
| "What expert capabilities compose this cycle?" | 1 | contract::a2a_blackboard::Blackboard |
| "How do cross-domain steps compose?" | 1 | OrchestrationBridge + UnifiedStep |
| "What does subagent A need to know before drafting?" | 2 | Mandatory reads + domain knowledge docs |
| "How do I not re-read the same context on every turn?" | 2 | Knowledge doc with READ BY: header |
| "How do I coordinate 3 subagents in parallel?" | 2 | Single main-thread turn with parallel Agent spawns |
Layer 1 and Layer 2 do NOT conflict — they operate at different time scales. A runtime A2A cycle inside a running shader does not involve Claude subagents; a Claude-session subagent spawn does not write to the runtime Blackboard. Keep them architecturally distinct.
The split that matters: grindwork vs accumulation.
- Grindwork (single-task mechanical): write-this-file-from-spec, grep-this-pattern, list-these-paths, run-these-tests, draft-this- section — Sonnet. Bounded input, known output shape, no synthesis across sources.
- Accumulation (multi-source synthesis): harvest-across-repos, combine-N-docs-into-insights, trace-architecture-across-files, cross-reference and integrate, judgment calls that depend on seeing several inputs at once — Opus. Cheaper tiers produce shallow outputs when asked to accumulate; quality drop is visible and costly.
By subagent type:
- Main thread:
claude-opus-4-7[1m](or current Opus) with deep thinking. Synthesis, architecture, review, decisions — all accumulation. Plansubagent: Opus. Planning is accumulation by definition.- Code-review subagent: Opus. Review is multi-file judgment.
general-purposesubagent: depends on task. Pure grindwork → Sonnet. Anything accumulating → Opus. When in doubt: Opus.Exploresubagent: Sonnet default. Search is pattern matching. If the explore requires synthesis across many files (mapping an architecture), escalate to Opus.haikufor scoped, read-only harvest grindwork and guarded execution. DECISION (2026-10-14): Haiku is no longer on the forbidden list. It is the default for cheap harvest discovery: one question over a closed, named search space, returning candidates, counts or verbatim quotes with their locations — never a conclusion. Its tokens are cheap enough that reading every file in full is the default, never rationed by a brief. Its main job is deep mapping of the substrate, whose token size makes reading it on the main thread too expensive: a Haiku mapper turns one bounded unit into a compact fact map, and the orchestrator reasons over the map. Six cards carry the contract:harvest-scout(find candidates),census-counter(count, with the command),quote-harvester(verbatim text with line numbers),substrate-mapper(a fact map of one module, crate or folder, written to one file),spec-editor(exact edits to one file from a written spec) andguarded-executor(run a pre-written-p-scoped command card). Haiku still does not author content, draft, review, synthesize or decide; those stay with Sonnet and Opus. The orchestrator watches closely: it Reads every harvested item it relies on, re-runs at least one reported count per reply, spot-checks every map against its source, reads the diff of everyspec-editoredit, and records hits and misses per run; a card that misses or concludes twice on one kind of task is dropped back to Sonnet for that kind. Full contract and supervision rules:.claude/knowledge/tiered-agent-execution-protocol.md§ Haiku harvest tier. SCOPE: this workspace. REVISIT WHEN: the run ledger shows a miss rate that makes the spot checks cost more than a Sonnet run, or Haiku is proposed for edits that author content.
Concrete test before spawning a subagent:
"Does this agent have to read N sources and produce something that only makes sense when those sources are held in mind together?"
Yes → Opus. No (one source in, one shape out) → Sonnet. Read-only and the answer is a list, a count, a quote or a fact map, or an edit fully written out in the brief → Haiku card.
Settings baseline (.claude/settings.local.json, gitignored):
alwaysThinkingEnabled: true, effortLevel: high,
fastModePerSessionOptIn: true. Main thread stays at full depth.
Every mcp__github__get_file_contents call drops the full file into
session context and recharges on every subsequent turn. A 50 KB doc
read three times in a session = 150 KB of replayed context, not 50 KB.
This is the second-biggest cost lever after model choice.
Preferred pattern for cross-repo reads:
# One zipball per repo per session, stored under /tmp/sources/:
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
-L https://api.github.com/repos/AdaWorldAPI/<repo>/zipball/HEAD \
-o /tmp/<repo>.zip
unzip -q /tmp/<repo>.zip -d /tmp/sources/
# Then use local Read, Grep, Glob — zero context cost until output.Or via pygithub's repo.get_archive_link('zipball') when Python
is already the path.
Use MCP github ONLY for:
create_pull_request— can't be done via zipball.add_issue_comment/add_reply_to_pull_request_comment/ review thread writes — writes to GitHub state.pull_request_readon our own PRs to check reviews / comments — tiny JSON, not worth zipball overhead.get_me,subscribe_pr_activity— session setup.
Do NOT use MCP github for:
- Cross-repo file exploration — zipball + local grep is 95 % cheaper.
- Surveying many files from the same repo — same reason.
- Directory listings — extracted tree is free to traverse locally.
Edge case: single targeted read when the exact path is known and
you'll read once → mcp__github__get_file_contents is fine. Zipball
overhead (download + extract) only pays off at 3+ reads per repo.
This maps to the grindwork/accumulation split too: zipball-then-grep-then-synthesize is accumulation, and the synthesis step (main thread or Opus subagent) reads just the relevant greps, not whole files.
Graph query engine AND cognitive codec stack for the Ada architecture. lance-graph is no longer just "The Face" — it has become the obligatory spine together with ndarray. Everything flows through lance-graph: Cypher/GQL/Gremlin/SPARQL parsing, semiring algebra, SPO triples, CAM-PQ compressed search, distributional semantics (DeepNSM), attention-as-table-lookup (bgz-tensor), thinking orchestration, and the contract crate that unifies all consumers.
Architecture:
ndarray = The Foundation (SIMD, GEMM, HPC, Fingerprint<256>, CAM-PQ codec)
lance-graph = The Spine (query + codec + semantics + contracts) <-- THIS REPO
ladybug-rs = The Agents/Orchestrator (agent + workflow roles, in the spine)
(crewai-rust / n8n-rs = EVICTED 2026-06-21 — agent + workflow-DAG roles folded
into ladybug-rs + the in-tree thinking-engine; no longer consumers)
> **⊘ OPERATOR RULING 2026-09-05 — planning migrates to `ogar-loco` / `ogar-r2il`;
> DataFusion is in GRACE PERIOD.** *"Every planning is in migration to ogar-loco and
> ogar-r2il, especially datafusion is out of the picture, what exists gets a grace
> period, nothing new will migrate to it."* Every DataFusion-hosted surface below
> (`datafusion_planner`, `sql_query`, Python `SessionContext`, `rls.rs`, `query`/
> `query-lite`, the `datafusion-*` forward-stubs) is maintained, not extended; new
> behaviour lands in loco/r2il programs or on Lance directly. Board:
> E-PLANNING-MIGRATES-TO-LOCO-R2IL-DATAFUSION-IS-GRACE-PERIOD-1. Lance itself is
> unaffected (E-LANCE-IS-UPSTREAM-AUTHORITATIVE-1).
Dependency chain:
ladybug-rs ──► lance-graph-contract (traits)
in-tree ──► lance-graph-contract (planner / callcenter / smb-bridge; symbiont ⊘ DEPRECATED 2026-08-18, operator no-go)
lance-graph──► ndarray (default dep, with fallback)
[workspace]
members = [
"crates/lance-graph", # Core: Cypher parser, DataFusion planner, graph algebra, NSM
"crates/lance-graph-catalog", # Catalog providers (Unity Catalog, connectors)
"crates/lance-graph-python", # Python bindings (PyO3/maturin)
"crates/lance-graph-benches", # Benchmarks
"crates/lance-graph-planner", # Unified query planner (16 strategies, MUL, thinking, elevation)
"crates/lance-graph-contract", # Zero-dep trait crate (THE single source of truth for types)
"crates/neural-debug", # Static scanner + runtime registry
]
exclude = [
"crates/lance-graph-codec-research", # ZeckBF17 research codec
"crates/bgz17", # Palette semiring codec (0 deps, 121 tests)
"crates/deepnsm", # Distributional semantic engine (0 deps, 4096 COCA)
"crates/bgz-tensor", # Metric-algebraic tensor codec (attention as lookup)
]lance-graph (core, ~18K LOC) — crates/lance-graph/
parser.rs+ast.rs— Cypher parser (nom, 44 tests)semantic.rs— semantic analysislogical_plan.rs— logical plandatafusion_planner/— Cypher→DataFusion SQL (~6K LOC: scan, join, predicate pushdown, vector, UDF, cost)graph/spo/— SPO triple store (truth, merkle, semiring, builder, 30 tests)graph/blasgraph/— GraphBLAS sparse matrix (~5K LOC: 7 semirings, CSR/CSC/COO/HyperCSR, HHTL, cascade)graph/neighborhood/— neighborhood search (CLAM, scope, zeckf64)graph/metadata.rs— MetadataStore (Arrow RecordBatch CRUD)graph/graph_router.rs— Three-backend graph router (blasgraph/DataFusion/palette)nsm/— DeepNSM DataFusion wiring (tokenizer, parser, encoder, similarity, UDF scaffold)nsm_bridge.rs— NSM→SPO mapping with NARS truth values + Arrow export (13 tests)
lance-graph-planner (10,326 LOC) — crates/lance-graph-planner/
- 16 composable strategies: CypherParse, GqlParse, GremlinParse, SparqlParse, ArenaIR, DPJoinEnum, RuleOptimizer, HistogramCost, SigmaBandScan, MorselExec, TruthPropagation, CollapseGate, StreamPipeline, JitCompile, WorkflowDAG, ExtensionPlanner
thinking/— 12 styles, NARS dispatch, sigma chain (Ω→Δ→Φ→Θ→Λ), semiring auto-selectionmul/— Meta-Uncertainty Layer (Dunning-Kruger, trust qualia, compass, homeostasis, gate)elevation/— dynamic elevation L0:Point→L5:Async (cost model that smells resistance)adjacency/— Kuzu-style CSR/CSC substrate with batch intersectionphysical/— CamPqScanOp, CollapseOp, TruthPropagatingSemiringapi.rs— Planner + CamSearch + Polyglot detection
lance-graph-contract (1,076 LOC, ZERO DEPS) — crates/lance-graph-contract/
thinking.rs— 36 ThinkingStyles, 6 clusters, τ addresses, FieldModulation, ScanParamsmul.rs— SituationInput, MulAssessment, DkPosition, TrustTexture, FlowState, GateDecisionplan.rs— PlannerContract trait, PlanResult, QueryFeatures, StrategySelectororchestration.rs— OrchestrationBridge trait, StepDomain, UnifiedStep, BridgeSlotcam.rs— CamCodecContract, DistanceTableProvider, IvfContractjit.rs— JitCompiler, StyleRegistry, KernelHandlenars.rs— InferenceType(5), QueryStrategy(5), SemiringChoice(5)
deepnsm (standalone, ~2,200 LOC, 0 deps) — crates/deepnsm/
- Replaces transformer inference: 680GB model → 16.5MB, 50ms/token → <10μs/sentence
- 4,096-word COCA vocabulary (98.4% English coverage)
- 4096² u8 distance matrix from CAM-PQ codebook
- 512-bit VSA encoder: XOR bind + majority bundle (word order sensitive)
- 6-state PoS FSM → SPO triples (36-bit packed)
bgz-tensor (workspace-excluded; deps: ndarray + holograph, both path — the old "0 deps" note was stale, corrected 2026-07-16) — crates/bgz-tensor/
- Attention via table lookup: Q·K^T/√d → table[q_idx][k_idx] in O(1)
- Weight matrix 64MB → Base17 136KB → 256 archetypes 8.5KB → distance table 128KB
- AttentionSemiring: distance table (u16) + compose table (u8) = multi-hop in O(1)
- HHTL cascade: 95% of pairs skipped
bgz17 (standalone, ~3,500 LOC, 0 deps, 121 tests) — crates/bgz17/
- Palette semiring codec, PaletteMatrix mxm, PaletteCsr, Base17 VSA
- SIMD batch_palette_distance, TypedPaletteGraph, container pack/unpack
ndarray is the default dependency. lance-graph should always use ndarray for:
Fingerprint<256>(canonical type, replaces standaloneNdarrayFingerprintmirror)- SIMD dispatch via
simd_caps()singleton - CAM-PQ codec (ndarray implements
CamCodecContract) - CLAM tree (ndarray has 46 tests, full build+search+rho_nn)
- BLAS L1/L2/L3 via MKL/OpenBLAS/native backend
- ZeckF64 (ndarray is canonical, 3 copies need dedup)
- HDR cascade search
- JIT compilation via jitson/Cranelift
Fallback without ndarray: When the ndarray-hpc feature is disabled, lance-graph falls
back to its standalone implementations in blasgraph/ndarray_bridge.rs. This is for:
- Minimal builds (CI, wasm, embedded)
- Downstream consumers who don't need HPC compute
- Compilation without the full ndarray dependency tree
# In crates/lance-graph/Cargo.toml:
[dependencies]
ndarray = { path = "../../../ndarray", optional = true, default-features = false }
[features]
default = ["unity-catalog", "delta", "ndarray-hpc"]
ndarray-hpc = ["dep:ndarray"]# Check workspace (default: with ndarray)
cargo check
# Check without ndarray (fallback mode)
cargo check -p lance-graph --no-default-features
# Run core tests
cargo test -p lance-graph
# Run planner tests
cargo test -p lance-graph-planner
# Run contract tests
cargo test -p lance-graph-contract
# Run standalone codec tests (fast, no network)
cargo test --manifest-path crates/bgz17/Cargo.toml
cargo test --manifest-path crates/deepnsm/Cargo.toml
cargo test --manifest-path crates/bgz-tensor/Cargo.toml
# Run all workspace tests
cargo test
# Python bindings
cd crates/lance-graph-python && maturin develop- Phase 1 (blasgraph CSC/Planner): DONE — CscStorage, HyperCsrStorage, TypedGraph, 7 semirings, SIMD Hamming
- Phase 2 (bgz17 container/semiring): DONE — 121 tests, PaletteSemiring, PaletteMatrix, PaletteCsr, Base17 VSA
- Unified planner: DONE — 16 strategies, MUL assessment, thinking orchestration, dynamic elevation, CAM-PQ operator
- Contract crate: DONE — zero-dep trait crate with canonical types for all consumers
- Polyglot parsing: DONE — Cypher, GQL (ISO 39075), Gremlin, SPARQL → same IR
- DeepNSM: DONE — distributional semantic engine, 4096 COCA vocabulary, 512-bit VSA
- bgz-tensor: DONE — attention as table lookup, AttentionSemiring, HHTL cascade
- NSM bridge: DONE — NSM→SPO mapping, NARS truth values, Arrow 57 RecordBatch, 13 tests
- Deep audit: DONE — 8 inventory documents in docs/ (see docs/UNIFIED_INVENTORY.md)
- Wire ndarray as default dep (Cargo.toml change +
ndarray-hpcfeature flag) - Replace
NdarrayFingerprintwithndarray::hpc::fingerprint::Fingerprint<256> - Dedup ZeckF64 (3 copies → 1 canonical in ndarray)
- Wire CAM-PQ: ndarray codec → lance-graph UDF → planner operator
- Contract adoption: planner + n8n-rs + crewai-rust depend on contract crate
- Move bgz17 from
excludetomemberswithbgz17-codecfeature flag - Consolidate nsm/ module to thin wrappers over crates/deepnsm/
- Wire planner strategies to lance-graph core (actual parser, not regex)
- Wire elevation to execution with timing feedback
- GraphRouter 3-backend routing (DataFusion + palette + blasgraph)
- n8n-rs OrchestrationBridge implementation
- End-to-end integration test (query → thinking → plan → execute → result)
- bgz17: 121 passing (standalone)
- lance-graph core: ~100+ passing (SPO + Cypher + semirings + NSM bridge)
- lance-graph-planner: ~15 passing (strategy selection, truth propagation, collapse gate)
- lance-graph-contract: ~15 passing (thinking styles, τ addresses, modulation)
- Total: 250+ passing
# THE PIN RULE. ⊘ The 2026-09-05 half-sentence "Exact-pin (`=X.Y.Z`) ONLY
# where an upstream crate itself demands exact-equals" is SUPERSEDED by the
# operator ruling 2026-09-18: *"never pin to x.00, always float x.*"* / *"so no
# decimal .0.0"*. NOTHING in this workspace carries a `.0.0` exact pin any more;
# the patch FLOATS (`11.*`, `0.38.*`) even where lancedb spells its own
# requirement `=11.0.0`. Floating is strictly SAFER, not looser: our own pin can
# only ever be equal to or NARROWER than what the family asks for, so an exact
# one buys nothing and deadlocks the moment lancedb's transitive requirement
# moves by a patch (the Cargo.toml:141-144 receipt below is exactly that
# failure). What survives verbatim: everywhere else the MAJOR, so the
# family can converge on the newest compatible patch. Nothing outside the
# lance / lancedb / arrow / datafusion family is pinned at all, and NO repo
# tracks a Cargo.lock (.gitignore; ISS-STALE-AUTHORITY-LOCKS, RESOLVED).
#
# Measured against crates.io 2026-09-05 -- lancedb 0.38.0 requires:
# lance* = "=11.0.0" (EXACT -- imposed on us, not our choice)
# arrow* = "^58.0.0" datafusion* = "^54.0.0" (CARET -- so ours must be too)
# An exact `=58.4.0` on our side is strictly NARROWER than anything the family
# asks for, and that is what makes a graph unsatisfiable: see Cargo.toml:141-144,
# where cargo could not satisfy our `lance = "=6.0.1"` against lancedb's
# transitive `lance = "=6.0.0"`. Relaxing resolves to the identical versions
# today (arrow 58.4.0 / datafusion 54.1.0) and takes 58.5.0 automatically.
#
# The arrow ceiling is NOT ours and does NOT move with lance: lance 9, 10 AND 11
# all require arrow ^58 / datafusion ^54, as do lancedb 0.33 / 0.37.1 / 0.38.0.
# arrow 59.x and datafusion 55 exist but are unreachable from ANY published
# lance or lancedb -- so 58/54 is the LATEST compatible, not a conservative one.
# A lancedb bump therefore buys a newer lance major and nothing else.
# (Rust crate line is 0.33.0 -> 0.37.1 -> 0.38.0; 0.34/0.35/0.36 do not exist as
# Rust crates -- those numbers are the independently-versioned PyPI package.)
#
# The lance family moves in EXACT lockstep -- currently the 13 line. Line of state:
# lance 7 (2026-06-14) -> 9 (the lance-9 sweep, b2b08b07 / PR #896 arc) -> 10
# (#1187, D-LNC-1) -> 11 (#1190, D-LNC-3, probe-gated on the D-LNC-2 fragment-id
# probe #1189) -> 12 (2026-09-25, lancedb 0.39) -> 13 (2026-10-10, lancedb 0.40,
# Rust 1.99; lance 13 needs object_store ^0.14.1). arrow/datafusion did NOT move
# with any of them. lance 12 DID move `object_store` 0.13 -> 0.14 while
# datafusion 54 stays on 0.13, so both are in the graph; our direct
# `object_store` follows lance (every call site hands it to lance).
# ⊘ The "=9.0.0 / lancedb =0.33.0" ruling recorded below as
# E-PIN-LANCE9-LANCEDB033-DF541-ARROW58-NO-DF53-1 is SUPERSEDED on its lance
# and lancedb coordinates ONLY (now 13 / 0.40.0); its datafusion half stands
# verbatim -- DF 54.1, never DF 53, and the `delta` feature stays removed.
# (A duplicated copy of this sentence stood here since the lance-9 sweep; both
# copies carried the stale number, so both are replaced by this one.)
arrow = "58" # unmoved by the lance-9, -10 and -11 sweeps alike
datafusion = "54" # OUR direct pin, in every crate that DEPENDS on it
# (lance-graph, -catalog, -callcenter, -python, holograph),
# and the sub-crates move with it: datafusion-common / -expr
# / -sql / -functions-aggregate are all "54". lance /
# lancedb / lance-index / lance-datafusion require 54 too.
# (Grep caveat: `lance-graph-planner/Cargo.toml` has
# `datafusion = []` under [features] — a FEATURE NAME, not a
# version pin. It is not a counter-example.)
#
# ⊘ SUPERSEDED 2026-08-18 (operator pin ruling,
# E-PIN-LANCE9-LANCEDB033-DF541-ARROW58-NO-DF53-1): the
# "BOTH MAJORS ARE REQUIRED" note that stood here is
# RETIRED. DF 53 resolved only through deltalake 0.32
# behind the (already non-default, already broken)
# `delta` feature; deltalake tops out at 0.32.4/DF^53,
# so the feature was REMOVED and the lock now carries
# exactly ONE datafusion = 54.1.0. The ruling: lance 9 /
# lancedb 0.33 / datafusion 54.1 (no DF 53) / arrow 58,
# always, across AdaWorldAPI forks. A Delta reader
# can return via a git-pin on delta-rs upstream — its
# MAIN already pins DF 54 + arrow 58 (verified
# 2026-08-18; crates.io releases still DF 53) — as its
# own deliberate PR if a consumer needs Delta.
# Probe: .claude/plans/lance9-datafusion54-upgrade-probe-v1.md
lance = "13.*" # lancedb 0.40 requires `=13.0.0`; we float the patch
lance-linalg = "13.*" # and resolve to whatever it demands (today 13.0.0)
lance-index = "13.*"
lancedb = "0.40.*" # the lance-13 pairing (`default-features = false` in
# the workspace table; consumers behind `lancedb-sdk`
# add `remote`, which 0.40.0 still needs to compile).
# NOTE: the Rust crate line is 0.33.0 -> 0.37.1 ->
# 0.38.0 -> 0.39.0 -> 0.40.0; 0.34/0.35/0.36 exist only as the
# independently-versioned PyPI package.
rust = "1.99.0" # rust-toolchain.toml is authoritative; see its bump log
ndarray = { path = "../../../ndarray" } # AdaWorldAPI fork, default, optional fallback
nom = "7.1"
snafu = "0.8"
# deltalake — REMOVED 2026-08-18 with the `delta` feature (see the datafusion
# supersession note above; it was the sole DF-53 source).Full planes (16Kbit, ρ=1.000) → ZeckBF17 (48B, ρ=0.982) → Base17 (34B, ρ=0.965)
→ PaletteEdge (3B, ρ=0.937) / CAM-PQ (6B, varies) → Scent (1B, ρ=0.937)
YAML card → 23D vector → ThinkingStyle(36) → FieldModulation(7D) → ScanParams
→ MUL assessment → NARS type → semiring selection → 16 strategies → elevation
- 7 HDR semirings (blasgraph): XorBundle, BindFirst, HammingMin, SimilarityMax, Resonance, Boolean, XorField
- 1 SPO truth semiring (spo/): HammingMin with frequency/confidence
- 1 palette semiring (bgz17): PaletteCompose with 256×256 distance table
- 1 planner semiring (planner): TruthPropagating with NARS deduction/revision
- 1 attention semiring (bgz-tensor): AttentionTable + ComposeTable
- 5 contract semiring choices: Boolean, HammingMin, NarsTruth, XorBundle, CamPqAdc
- Fingerprint/BitVec: 4 copies (ndarray canonical)
- ZeckF64: 3 copies (ndarray canonical)
- ThinkingStyle: 4 copies (contract canonical, not yet adopted)
- Base17: 3 copies (bgz17 canonical)
- NARS InferenceType: 3 copies (contract canonical)
- CSR adjacency: 5 implementations (different purposes)
WHO DEPENDS ON lance-graph-contract:
in-tree — planner, callcenter, smb-bridge (the BINDING consumers; symbiont ⊘ DEPRECATED 2026-08-18, operator no-go — dormant excluded crate, never live surface)
ladybug-rs — Planner + CamPq + OrchestrationBridge
(crewai-rust / n8n-rs — EVICTED 2026-06-21, operator-directed; superseded by
ladybug-rs + the in-tree thinking-engine. NO LONGER binding consumers — the
contract evolves without a crewai/n8n multi-repo bump. Scattered "replaces
crewai-rust's X" doc-comments are historical provenance; StepDomain::{Crew,N8n}
stay reserved-dormant. See EPIPHANIES E-CREWAI-N8N-EVICTED.)
WHO WE DEPEND ON:
ndarray — Fingerprint, CAM-PQ, CLAM, BLAS, ZeckF64, HDR cascade, JIT
lance — columnar storage, versioning, vector search
datafusion — SQL query engine
arrow — columnar memory format
SIBLING REPOS:
/home/user/ndarray/ — The Foundation (BLAS, Fingerprint, CAM-PQ, CLAM, jitson)
/home/user/crewai-rust/ — The Agents (agent cards, thinking styles, YAML templates)
/home/user/n8n-rs/ — The Orchestrator (workflow DAG, step routing, compiled styles)
/home/user/kuzudb/ — Reference (column-grouped CSR adjacency model)
.claude/knowledge/signed-session-findings.md — BF16 tables, gate modulation, quality checks
.claude/knowledge/phi-spiral-reconstruction.md — φ-spiral, family zipper, stride/offset, Zeckendorf, VSA
.claude/knowledge/primzahl-encoding-research.md — prime fingerprint, Zeckendorf vs BF16 vs prime encoding
.claude/knowledge/bf16-hhtl-terrain.md — BF16-HHTL correction chain, 5 hard constraints, probe queue
.claude/knowledge/zeckendorf-spiral-proof.md — φ-spiral proof (scope-limited, see header before citing)
.claude/knowledge/two-basin-routing.md — Two-basin doctrine, representation routing, pairwise rule, attribution
.claude/knowledge/encoding-ecosystem.md — MANDATORY: full encoding map, synergies, read-before-write checklist
.claude/knowledge/membrane-tiers.md — DOCTRINE: the 3+ tier abstraction law (T0..T3+R2IL), the compile-through/entropy rule, the agent→membrane map, and the T2→T3 leak ledger
.claude/knowledge/folding-doctrine.md — WORKING-MODEL: the map is not the city — fold coordinates by default, materialize only when total cost (routing + control + interpretation + access, per tier) is lower; compile-time maps; crypto folds must be public; READ BEFORE any shuffle/transpose/layout/canonicalize step
.claude/knowledge/frankenstein-checklist.md — Composition failure modes (VibeTensor §7), boundary test matrix
.claude/knowledge/lab-vs-canonical-surface.md — MANDATORY before touching REST/gRPC/Wire DTO/endpoint/shader-lab (prevents "add another REST endpoint" hallucination)
.claude/knowledge/autoattended-multiagent-pattern.md — MANDATORY before planning a wave with ≥4 parallel workers; 4-savant taxonomy (PP-13/14/15/16), worker iron rules, atomic-consolidation pass
.claude/knowledge/ndarray-vertical-simd-alien-magic.md — MANDATORY before writing SIMD code in any consumer crate OR filing a PR against `adaworldapi/ndarray` `src/simd_*`; canonical reference for the wave W1a (5 ndarray primitives) + W1b (5 consumer migrations) + W1.5 (3 sigker primitives, gated on jc Pillar 11) plan
.claude/knowledge/core-first-transcode-doctrine.md — MANDATORY before any C++→Rust transcode / codegen / AST-DLL / "port Tesseract" / DO-adapter work; the Core-first inversion (a generated layer is only as clean as the OGAR Core it targets) + the OGAR movable-parts assume-contract + the unicharset adapter-parity falsifier. Carried by the core-first-architect / adapter-shaper / core-gap-auditor ensemble.
.claude/knowledge/ogar-consumer-preflight.md — MANDATORY before any consumer (woa-rs/medcare-rs/smb-office-rs) classid/bridge/codebook work; the consumer-side spellbook (pull via *Port::class_id / contract::ogar_codebook::canonical_concept_id; NEVER construct a *Bridge or copy the codebook). Inverse of OGAR's SURREAL-AST-TRAP-PREFLIGHT; operational mirror of docs/CONSUMER-BRIDGE-DEPRECATION.md (#589/#590).
.claude/knowledge/compilation-vs-runtime-substrate.md — MANDATORY before filing a cross-repo issue or writing any seam/lowering design that pairs a consumer repo with SoA/temporal.rs/NARS/RBAC/mailbox vocabulary: contracts compile types; codegen emits into consumer repos; cargo builds them; the running engine's internals never gate a build or a typed-value construction (the door-knocking-compiler test). Born from OGAR #208 (closed hallucinated). Carried by layer-boundary-warden / codegen-flow-cartographer.
.claude/knowledge/assembler-vs-storage-substrate.md — MANDATORY before assigning responsibility across the OGAR↔lance-graph boundary or naming any "ingest" API: OGAR = the V3 assembler substrate (IR/mint/codegen); lance-graph = spine (contracts+query); Lance = calcification, never an ingest endpoint. Ownership quick-map + failure signatures from the 2026-07-14 #691/#208 chain. Carried by layer-boundary-warden / codegen-flow-cartographer.
.claude/knowledge/split-tunnel-sparse-append-resident-fold.md — PATTERN (MEASURED in a consumer): write = sparse append, one Lance version per batch, never compacted; read = fold over resident records; Lance read once, at replay. History 0.72 ms vs 336 ms scanning Lance. Read before designing any write path, history/diff read, or a hot-path Lance read
.claude/CALIBRATION_STATUS_GROUND_TRUTH.md — OVERRIDE: read BEFORE any SESSION_*.md
.claude/PLAN_BF16_DISTANCE_TABLES.md — 5-phase plan for BF16 distance tables
.claude/TECHNICAL_DEBT_SIGNED_SESSION.md — 56% useful, 44% bypass (honest review)
.claude/CODING_PRACTICES.md — 6 patterns from EmbedAnything + quality checks
P0 Rule: .claude/knowledge/encoding-ecosystem.md must be read BEFORE any
codec, encoding, distance, compression, or representation work. This is the
map of all 8+ encoding representations, their crate locations, their invariants,
their synergies, and their FINDING/CONJECTURE status. Never guess architecture.
P0 Rule: .claude/knowledge/lab-vs-canonical-surface.md must be read BEFORE
any work that mentions REST, gRPC, Wire DTOs, /v1/shader/* endpoints, the
shader-lab binary, OrchestrationBridge, UnifiedStep, codec research ops,
or "external API". The canonical consumer surface is UnifiedStep via
OrchestrationBridge — the REST/gRPC server and per-op Wire DTOs are
LAB-ONLY scaffolding. Adding another /v1/<thing> endpoint is the
Kahneman-Tversky System-1 easy path and is nearly always wrong; extending
the canonical bridge is the System-2 correct move. See the Decision
Procedure in that doc before writing a single new handler.
Best practice (P0 for transcode work): .claude/knowledge/core-first-transcode-doctrine.md
must be read BEFORE any C++→Rust transcode, codegen, AST-DLL, "port Tesseract",
or DO/DTO-adapter work. The Core-First inversion: a generated layer (AST /
adapters / codegen'd Rust) is only ever as clean as the Core it targets, so the
OGAR Core is shaped first, deliberately — never treated as the residue of
"what we couldn't codegen." Emit thin classid-keyed adapters that ASSUME the
Core (identity = classid; state = SoA value tenants per the #511
SoaMemberSpec calibration; relations = EdgeBlock (the 16-byte block is canon; its 12+4 reading is
V1-legacy — resolve ClassView::edge_codec_flavor);
composition/inheritance = classid → ClassView; invocation = UnifiedStep),
and treat the ruff_cpp_spo SPO harvest (has_function / inherits_from /
virtually_overrides) as the ClassView method-resolution manifest — the
harvest and the codegen are two halves of ONE system, not orthogonal. Never
build a parallel Tesseract-rs object model, never let an adapter carry its
own state (a Core gap → extend the Core deliberately, never hack the adapter),
and never force intrusive/stateful methods into the adapter mold (route them
to raw-pointer hand-port — Frankenstein flattening guard). Holds for
mechanical/data-shaped leaf methods only; CONJECTURE until
PROBE-OGAR-ADAPTER-UNICHARSET runs byte-parity green. Carried by the
core-first-architect / adapter-shaper / core-gap-auditor ensemble.
Best practice (consumer-side): .claude/knowledge/ogar-consumer-preflight.md
is the consumer mirror of OGAR's SurrealQL-AST trap. Read it BEFORE any consumer
crate (woa-rs / medcare-rs / smb-office-rs) pulls a classid, migrates off a
*Bridge, or touches the OGAR codebook. The consumer trap is the inverse of the
producer trap: re-implementing the Core locally — a *Bridge construction, a local
*_CODEBOOK copy, a parallel registry — instead of pulling via
*Port::class_id (spine) / contract::ogar_codebook::canonical_concept_id
(membrane, BBB-safe), then stamping the OGAR#95 app prefix. Five questions, 90
seconds. Carried by integration-lead / baton-handoff-auditor /
core-first-architect.
Every .claude/knowledge/ document has a READ BY: header listing which agents
MUST load it before producing output in that domain. When a knowledge trigger fires
(see .claude/agents/BOOT.md § Knowledge Activation Protocol), the relevant
knowledge docs are loaded BEFORE the agent responds.
Critical process rule: .claude/knowledge/bf16-hhtl-terrain.md contains a
probe queue with CONJECTURE/FINDING status for each architectural claim. Any agent
proposing changes to HHTL cascade, γ+φ placement, Slot D/V layout, or bucketing
strategy MUST check the probe queue first. If the relevant probe is NOT RUN, the
next deliverable is the probe, not more synthesis.
Insight update cycle:
Claim → Probe defined (pass/fail criteria) → Probe written (example file)
→ Probe run → Result recorded in knowledge doc → CONJECTURE promoted to FINDING or corrected
No knowledge doc should contain unmarked conjectures. Label everything.
P0 Rule: grep FINDS, reading DECIDES (operator, 2026-09-16: "when you grep, only use it for finding and read after"). A grep result is a claim about a PATTERN, never about the tree. Use it to locate candidates, then open the file and read before concluding anything — especially before concluding that something is ABSENT.
Measured 2026-09-16, three false claims in ONE document, all from grep-as-verdict, all caught before commit only because a later read contradicted them:
| grep said | the truth | what reading found |
|---|---|---|
| planner→loco has "no dependency edge" | lance-graph-ogar is a workspace member depending on BOTH sides |
its Cargo.toml (ogar-loco at :137, contract at :86) |
CapabilityAuthority is "unimplemented" |
it is implemented AND production | the impl is written fully-qualified — impl lance_graph_contract::hotplug::CapabilityAuthority for OgarAuthority — so impl.*CapabilityAuthority missed it |
| the kanban seam is "unwired both directions" | the seam is built; only one edge is missing | recipe_vocab.rs's module doc states the design ("neither may import the other… so it lives in a consumer that already depends on both") |
The third is the instructive one: the grep was CORRECT (those planner-side hits really are doc comments) and the CONCLUSION was still wrong, because the file that would have explained why was never opened. A correct grep can support a false conclusion.
Two corollaries:
- A negative result is the weakest thing grep produces. Absence under one pattern is not absence in the tree — fully-qualified paths, re-exports, macros, aliases, and line breaks all defeat a reasonable-looking regex. Before writing "X does not exist", open the place X would live.
- Never count grep hits as evidence without reading them. The same session
nearly reported 20
BatchWriter::castcall sites; reading showed ~17 were ractor's unrelatedActorRef::cast(SupervisorMsg::…)and only 3 were real.
Cross-ref: the sibling rule below (Read before Write) protects FILES from a blind write; this one protects CONCLUSIONS from a blind read.
The full rule set lives in ONE place: .claude/knowledge/FIRST-HAND-SOURCE-LAW.md.
The measured table above is why the rule exists; that file is the rule —
what may be claimed from which operation (search is navigation, never
evidence), the auto-deepen triggers, the paging rule (a partial Read is not
evidence for a whole-file claim), and context exhaustion must reduce SCOPE,
never evidence quality. Worker-side mechanics stay where they already are:
.claude/v3/knowledge/sonnet-worker-guardrails.md §1/§5 and
.claude/knowledge/tiered-agent-execution-protocol.md. Read it before the
first search of a task; do not restate it anywhere.
It also carries the one rule with no other home: human authorization is
PROVENANCE, NOT VALIDATION. A person chooses direction, scope, policy,
naming and acceptable risk — "the user chose X" never becomes "X is
technically true" without independent evidence. So new canonical material
does not use operator-ruled / operator-pinned / operator-locked /
operator-confirmed as a technical status; it uses an evidence-bearing state
(MEASURED with its command, VERIFIED-IN-CODE with its location,
TEST-PINNED, CURRENT-CONTRACT, WORKING-MODEL, HYPOTHESIS, OPEN,
SUPERSEDED, REJECTED-BY-FALSIFIER), and records a real decision as
DECISION / SCOPE / BASIS / REVISIT WHEN. Historical files keep their
wording; the PreToolUse guard blocks only an edit that INTRODUCES one of
the four, and lets a supersession note quote it.
P0 Rule: Read before Write, always. Before calling Write on any path
that may already exist, run Read (or git status for committed files).
The Edit tool is the default for modifying existing files; Write is only
for new files or genuine full rewrites the user explicitly asked for. This
rule applies to the model's own prior commits in the same session — "I just
wrote this" is not a license to overwrite it without checking state.
Diagnostic signature of the failure mode: a git diff showing ~N insertions / ~N deletions on a file of size N — same magnitude, same shape,
virtually every line different — means the file was regenerated from prompt
instead of built from state. If you see this on your own commit, you just
overwrote committed work. Revert with git restore <path> and use Edit
for any genuine refinement.
P0 Rule: the destructive-prepend one-liner is PROHIBITED — never open a
file for writing in the same expression/pipeline that still reads it
(open(p, "w").write(x + open(p).read()), sort f > f). Mandatory
post-check after every ledger write: wc -l — an append-only file that got
SHORTER is always a defect. Full law, incident receipts (#1081/#1082),
falsifier and consequences:
.claude/knowledge/never-truncate-a-file-you-still-need-to-read.md
(locked 2026-08-30; board entry
E-DESTRUCTIVE-PREPEND-TRUNCATES-BEFORE-READ-1, census trap 10).
Tool-reach reminder for deferred tools. AskUserQuestion, TodoWrite,
WebSearch, WebFetch are namechecked in the Claude Code system prompt but
sit behind ToolSearch in Opus 4.6 — their schemas are not loaded by default.
Do not treat "not in the current schema list" as "not available." Reach for
ToolSearch with select:<name> when the situation calls for them
(multi-step tracking, user clarification on ambiguous denials, web lookups).
Upstream regression filed:
anthropics/claude-code#46861
documents the pattern observed in this workspace (Opus 4.6 reproducer: post-
commit Write-over-self without Read; deferred-tool reach failure for the
tools listed above). Treat that issue as the canonical reference if a future
session asks why this section exists. The 172/171 diff that triggered the
filing was on .claude/prompts/arxiv.md in this repo, branch
claude/risc-thought-engine-TCZw7.
Model Base Tokenizer Vocab Hidden Act Status
───── ──── ───────── ───── ────── ─── ──────
Jina v5 small Qwen3 Qwen3 BPE 151K 1024 silu GROUND TRUTH (safetensors + ONNX on disk)
Reranker v3 Qwen3 Qwen3 BPE 151K 1024 silu SAME BASE as v5 (listwise, cross-encoder)
ModernBERT-large OLMo OLMo BPE 50K 1024 gelu ONNX on disk (GeGLU, code-friendly)
BGE-M3 XLM-R SentencePiece 250K 1024 gelu baked u8 lens (multilingual)
Jina v3 XLM-R SentencePiece 250K 1024 gelu baked u8 lens (LEGACY, not ground truth)
Qwopus 27B Qwen2 Qwen2 BPE 151K 5120 silu 305 tables in Release v0.1.2
Reader-LM 1.5B Qwen2 Qwen2 BPE 151K — — in Release, not baked
CRITICAL: Reranker v3 = Qwen3 base (NOT v2 XLM-RoBERTa).
Same tokenizer as Jina v5. Same architecture. Same silu gate.
Baked reranker lens was built from Qwen2 GGUF → needs rebuild with Qwen3 tokens.
Tokenizer sharing:
Qwen3 BPE (151K): Jina v5, Reranker v3
Qwen2 BPE (151K): Qwopus, Reader-LM (DIFFERENT from Qwen3!)
XLM-RoBERTa (250K): Jina v3, BGE-M3 (LEGACY)
OLMo (50K): ModernBERT
Core: engine.rs, bf16_engine.rs, signed_engine.rs, role_tables.rs
Composition: composite_engine.rs, dual_engine.rs, layered.rs, domino.rs
Calibration: cronbach.rs, ground_truth.rs, reencode_safety.rs (x256 proven)
Encoding: spiral_segment.rs, prime_fingerprint.rs (VSA bundle perturbation)
Patterns: pooling.rs, builder.rs, auto_detect.rs, tokenizer_registry.rs
Sensors: jina_lens.rs, bge_m3_lens.rs, reranker_lens.rs, sensor.rs
Cognition: cognitive_stack.rs, ghosts.rs, persona.rs, qualia.rs, world_model.rs
Bridge: l4_bridge.rs, bridge.rs, semantic_chunker.rs, tensor_bridge.rs
Examples:
jina_v5_ground_truth.rs — end-to-end pipeline (tokenize → ground truth)
end_to_end_signed.rs — BF16/i8 smoke test (CDF collapse confirmed)
dual_signed_experiment.rs — u8 vs BF16 comparison across 3 lenses
calibrate_lenses.rs — Spearman ρ + ICC (real Qwen3 tokenizer)
stream_signed_lens.rs — 5-lane encoder from GGUF (BF16 stream)
stream_hdr_lens.rs — u8 CDF HDR lens from GGUF
Data on disk (gitignored, download from HF or Releases):
jina-v5-onnx/ model.safetensors (1.2 GB) + model.onnx (2.3 GB) + tokenizer
modernbert-onnx/ model.onnx (1.5 GB) + tokenizer
jina-reranker-v3-BF16-5lane/ 5-lane encoding (u8/i8/γ+φ, 1.1 MB)
docs/UNIFIED_INVENTORY.md — Master index, LOC census, crate map, dep graph
docs/TYPE_DUPLICATION_MAP.md — Every duplicated type with file:line precision
docs/CODEC_COMPRESSION_ATLAS.md — Full→ZeckBF17→BGZ17→CAM-PQ→Scent chain
docs/THINKING_ORCHESTRATION_WIRING.md — End-to-end thinking pipeline (9 layers)
docs/SEMIRING_ALGEBRA_SURFACE.md — All 15 semirings across all repos
docs/ADJACENCY_SYNERGY_MAP.md — 6 CSR models, BLAS×PQ×BGZ17, KuzuDB
docs/METADATA_SCHEMA_INVENTORY.md — 4096 surface, 16Kbit, Lance persistence, Arrow
docs/INTEGRATION_DEBT_AND_PATHS.md — Strengths, weaknesses, epiphanies, 7 paths
docs/ORCHESTRATION_IS_GRAPH.md — Capstone: orchestration AS graph traversal
docs/CONSUMER_WIRING_INSTRUCTIONS.md — How to consume lance-graph-contract
src/cache/— 7 modules, 39 tests:kv_bundle.rs: HeadPrint=Base17 (from ndarray), AttentionMatrix 64×64/256×256candidate_pool.rs: ranked candidates, Phase (Exposition→Coda)triple_model.rs: self/user/impact × 4096 heads, DK, Plasticity, Truth=NarsTruthlane_eval.rs: Euler-gamma tension, DK-adaptive, 4096-head evaluationnars_engine.rs: SpoHead, Pearl 2³, NarsTables (causal-edge hot path), StyleVectorsconvergence.rs: AriGraph triplets → p64 Palette layers → CognitiveShaderkv_bundle.rs: VSA superposition store
src/strategy/chat_bundle.rs: AutocompleteCacheStrategy (Strategy #17)src/serve.rs: Axum REST server, OpenAI-compatible /v1/chat/completionsAUTOCOMPLETE_CACHE_PLAN.md: full implementation plan with 6 agent scopes
src/hhtl_cache.rs: HHTL cache with RouteAction (Skip/Attend/Compose/Escalate), HipCache k=64src/hydrate.rs: --download/--reindex/--verify with feature flags (qwen35-9b/27b-v1/v2)data/manifest.json: SHA256 for all 41 shards- GitHub Release v0.1.0-bgz-data: 41 bgz7 assets, 685 MB
- lance-graph-planner → ndarray (hardware: Base17, read_bgz7_file)
- lance-graph-planner → causal-edge (protocol: CausalEdge64, NarsTables)
- lance-graph-planner → p64 + p64-bridge + bgz17 (convergence highway)
- ndarray = hardware acceleration (SIMD, no thinking logic)
- causal-edge = protocol (CausalEdge64, NarsTables = precomputed NARS as lookup tables)
- lance-graph-planner = thinking (NarsEngine, AutocompleteCache, Styles)
- p64 = convergence point (both repos meet, no circular deps)
- AriGraph (lance-graph core) cannot be planner dep (circular) — use p64 convergence instead
EMPA, InstCache, Semantic Caching, C2C, ContextCache, Krites, Thinking Intervention,
ThinkPatterns, Thinkless, Holographic Resonance, DapQ, Tensor Networks, PMC Attention Heads,
LFRU, Illusion of Causality, NARS Same/Opposite, KVTC, CacheSlide.
All findings in .claude/knowledge/session_autocomplete_cache.md.
611M SPO lookups/sec. 17K tokens/sec. 388 KB RAM. 100% information preservation.
Operator-locked this session. Append-only. Wrapper
NodeGuid(#480) is audited against THIS, never the reverse. No RFC-9562 ceremony in the hot key.
⊘ SUPERSEDED — MIGRATION MANDATORY (operator, 2026-07-04). The
10..13 family (u24)/13..16 identity (u24)tail below — two contiguous u24 bit-groupings (family:u24 ++ identity:u24) — is V1-LEGACY and forbidden for new units. A flat u24 has no axis: it cannot carry a rail (X:Y), so it is a structurally retired shape, not a width variant. Every new unit is the V3 content-blind 4+12 facet (classid(4) + 12-byte payload, operator-lockedE-V3-FACET-4-PLUS-12, 2026-07-02; rulingE-V1-TAIL-FORBIDDEN-V3-IS-CONTENT-BLIND-1,.claude/board/EPIPHANIES.md). The 12B is a dumb byte register the ClassView projects — it holds every sanctioned reading at once, carved per.claude/v3/soa_layout/le-contract.md§3 as6×(u8:u8)rails /4×(u8:u8:u8)SPO triplets /3×(u8:u8:u8:u8)odoo quads (6·2 = 4·3 = 3·4 = 12).u8:u8= two separate bytes, NEVER widened to u16 or u24. Reads of the u24 tail on existing V1 rows survive unchanged (I-LEGACY-API-FEATURE-GATED); only new mints are forbidden — route them throughmint_for(classid_read_mode(c).tail_variant, …), neverNodeGuid::new(V1). Append-only: the pin below is NOT deleted; read it as the retired V1 tail. Live residue tracked in.claude/board/ISSUES.mdISS-V1-TAIL-RESIDUE.
Node = 4096 bit = 512 byte: key(16) | edges(16) | value(480).
(The stride is CANON and survives V3 unchanged; it is the KEY's u24 tail and
the EDGE block's 12+4 reading that are V1-legacy — see the two ⊘ notes.)
Key (16 byte, little-endian):
0..4 classid (u32) 8 hex — prefix-routable; default 0x0000_0000
4..6 HEEL (u16) ┐
6..8 HIP (u16) ├ 3 cascade tiers (HHTL path)
8..10 TWIG (u16) ┘
10..13 family (u24) ┐ V1-LEGACY tail — read-only; new units mint the
13..16 identity (u24) ┘ V3 4+12 facet (see ⊘ supersession above)
local_key() = bytes 10..16 (family ++ identity), the only discriminator once
the prefix is resolved. [V1-LEGACY — reads only; new mints use the V3
content-blind facet.]
Edge block (16 byte): always reserved (zeroed when unused), never shrunk;
a class opting out of edges is resolved via classid → ClassView, never by a
stride change.
⊘ V1-LEGACY READING — the "12 in-family + 4 out-of-family, one byte per slot" carving is NOT the layout (marked 2026-08-04). The 16-byte reservation and the 512-byte stride are CANON and are REUSED unchanged by V3 (
.claude/v3/COMPONENT-MAP.md:NodeGuid/EdgeBlock/NodeRow16|16|480 = REUSE — CANON, const-asserted;.claude/v3/soa_layout/le-contract.md§316: the 512-byte row "stays authoritative"). Do NOT shrink, widen, or re-stride the block on the strength of this note.What is V1 is presenting 12+4 one-byte slots as THE reading. Under V3 it is one interpretation among several, selected per class:
EdgeCodecFlavor::{CoarseOnly, CoarseResidue, Pq32x4}viaClassView::edge_codec_flavor.CoarseOnly— each byte a palette/centroid index, i.e. the 12+4 block read literally — is merely the zero-fallback default;Pq32x4reads the SAME 16 bytes as 32 × 4-bit product-quantizer codes, andCoarseResiduecarries a per-dimension signed-4-bit residue in the reserved value slab. Every flavor leavesNODE_ROW_STRIDEuntouched, so adopting one needs noENVELOPE_LAYOUT_VERSIONbump.Consequence for a session reading this block: never assume a node's edge bytes mean "12 in-family + 4 out-of-family" — resolve the flavor through the class's
ClassViewfirst. Kernels:ndarray::hpc::edge_codec; per-flavor fidelity:ndarray::hpc::reliability(edge_codec_compare). Append-only: the V1 line is regraded in place, not deleted.
⊘ 2026-09-17 — the TYPE is retired too (operator ruling,
E-THE-SECOND-FACET-IS-NOT-AN-EDGE-BLOCK-1): "It's forbidden for the edge block to even know it's an edge block — it's just another content blind facet cascade."EdgeBlockis nowpub type EdgeBlock = FacetCascade;— bytes 16..32 are the same4 + 12facet as the key, and thein_family/out_familyfields no longer exist. A regraded paragraph does not retire a reading while a struct still spells it. Readers that still split at 12:ISS-EDGE-BLOCK-WAS-A-SECOND-TYPE-FOR-THE-SAME-FACET.
Zero-fallback ladder (monotonic — zero = fall through to the broader default):
classid == 0x0000_0000→ default class, no prefix routing (dormant)family == 0x00_0000→ default basin, no neighborhood grouping (dormant)- ⇒ while both are zero,
identity(24 bit) ALONE discriminates — the bootstrap address. 16.7M identities per default basin; mint a non-zero family to expand.
RESERVE, DON'T RECLAIM: a zero tier means not consulted, never compacted
away. classid(4B) and family(3B) keep fixed offsets so a non-zero mint later
wakes routing/basin binding with ZERO ENVELOPE_LAYOUT_VERSION change. Mint path
must debug_assert identity uniqueness while in the default basin.
No UUID ceremony: no version nibble, no variant bits, no namespace/kind. The
dash-groups are the only semantics; the tail is plain family|identity.
Reference impl: canonical_node.rs (NodeGuid / EdgeBlock / NodeRow, with
const _ size asserts at 16/16/512 and is_default_class / is_unbasined /
is_bootstrap_address guards). The types are live and V3-current; what is
V1-legacy is the reading of two fields — NodeGuid's u24 tail (mint via
mint_for, never NodeGuid::new) and EdgeBlock's 12+4 carving (resolve via
ClassView::edge_codec_flavor, never assumed).