D-ACR-1 + D-ACR-7: the attention basis is a REUSE, and the 59..63 reading contract that reads through it - #981
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_5195811c-dcf3-4926-8623-aaf292020510) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 274b80219e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if depth as usize > CASCADE_UNITS { | ||
| None | ||
| } else { | ||
| Some(Self { facet, depth }) |
There was a problem hiding this comment.
Normalize ignored suffix bytes in prefix focuses
When two calls use the same class, depth, and significant prefix but different bytes after depth, the resulting focuses mutually cover each other and therefore denote the same wildcard, yet the derived Eq and Hash treat them as different because this constructor retains the entire facet. This can create duplicate logical focuses in hash sets/maps and inconsistent cache keys; zero the unconsulted suffix here, as common_prefix already does, or implement equality and hashing over only the significant prefix.
Useful? React with 👍 / 👎.
The deliverable called RowFocusMask "the one missing primitive". Half of that
is right, and the wrong half is the more useful one.
THE ATOM ALREADY EXISTED, EXACTLY. contract::facet::FacetCascade is
facet_classid(4) | 6x(8:8) = 16 B under CascadeShape::G6D2 -- literally the
6 x 2 x u8 shape asked for, with index/group_of/level_of/shift shipped,
tier_bytes() ordered coarse-first, and two readings to copy the pattern from
(awareness_facet::SpoFacet, tekamolo_facet::TekamoloFacet). Zero new bytes were
needed and none were added: no tenant, no bit, no ENVELOPE_LAYOUT_VERSION bump.
WHAT WAS ABSENT is narrower: a composition that is not a bitset union. Every
union/intersect in the crate is a bit op over FIELD POSITIONS -- FieldMask
(u64, MAX_FIELDS=64), WideFieldMask (u8 positions, capped at 256 with a loud
UniverseExceedsSocCap), StepMask, rbac. None composes addresses, and a bit-OR
of two addresses is a third address neither side ever visited. That is now a
test: OR-ing 0b01 and 0b10 gives 0b11, and the union must not contain it.
The right composition was already in the canon one type over.
NiblePath::is_ancestor_of is coarse->fine prefix containment with an EXPLICIT
depth. Reusing the rule gives `covers`; reusing the explicit-depth discipline
avoids a real trap, since inferring the wildcard boundary from zero bytes
collides with the zero-fallback ladder where 0 is a dormant tier, not a
terminator. depth therefore lives OUTSIDE the 12 bytes and the wire shape stays
exactly 6 x 2 x u8.
That is also the >256-rows answer: the u8 per level bounds AXIS RESOLUTION,
never population. A depth-2 focus is measured covering 65,536 addresses across
only the two units varied, and the container holds 1000 entries where FieldMask
stops at 64 and WideFieldMask at 256 -- no cap transfers, because the container
does not index rows at all.
CONTENT-BLINDNESS, defended twice. A first draft named the axes
Heel/Hip/Twig/Leaf/Family/Identity, baking the cascade reading into the
low-level type -- exactly what FacetCascade's own contract forbids ("only the
CONSUMER projects meaning onto the bytes"). Corrected after the operator raised
a second candidate reading (six ontology scopes: disease / anatomy / process /
substance / evidence / context). FocusAxis is now Axis0..Axis5, a position, and
BOTH readings appear only in a test over byte-identical input, proving the
projection is free. The lesson: once a second plausible reading exists, any name
in the substrate is a premature commitment to the first -- this would have been
the fifth homonym collision of the arc, and the first one we minted ourselves.
Vertical stacking was considered and rejected: six fixed rows inside one atom
would mint a second addressing system for a dimension facet_classid already
carries (plan §3: same NodeGuid, different thinking-table row, sparse
occupancy), which HTT §2.2 withdrew. One atom, one (classid, rail).
Deferred and named: difference() keeps a partially-overlapped entry whole,
because subtracting a subtree from a prefix means enumerating siblings --
inventing addresses never visited. Composability with WideFieldMask stays §6
Y2's parked basis collision (positions <= 256 vs an unbounded population), per
D-ACR-0's measurement.
Does not, and structurally cannot, touch cognitive-shader-driver's
attention_mask* -- the dependency edge runs the other way.
14 new tests, 1194 contract tests green, clippy clean, fmt clean.
Board hygiene in the same commit: EPIPHANIES prepend, LATEST_STATE contract
inventory, STATUS_BOARD D-ACR-1 -> Shipped.
…lan) Two arcs were being built separately -- the alpha-channel attention overlay and the DisMech Hole. This plan is the claim that they are one loop, and that exactly one fibre of it is missing. THE FENCE, MEASURED TWICE. "Expanding CE64 59..63" cannot mean widening: layout.rs:93-111's _LAYOUT_COVERAGE const-asserts all 64 bits covered exactly once, and dismech-causality-v3-v1.md:503 states verbatim "Not in CE64 -- it has zero free bits." The operator's own notation is the answer: ^n is STACKING, the canon's "scale is the next cascade level, never field-widening" applied to the awareness axis. Three stages, none of them a bit: readable (D-ACR-7's reading contract, spanning CausalEdge64 AND CausalEdgeV3) -> discriminating (WitnessKind -> Hole) -> granular (HoleV3). THE MISSING FIBRE. Every other link is shipped or designed: the pothole opens via QueryReference::at, the stamp is with_reasoning_band (the only writer), locating is RowFocusMask (shipped today), exploring is the 14 delta_conf-capable recipes, closing is Revision + span, rewiring is plasticity at bits 50-52. Handover is neither -- D-ACR-16 is NOT DESIGNED with zero precedent. This plan's contribution is naming what handover IS so it has a shape to be designed against: a Hole is a kanban card for a missing link, an owned row moving between mailboxes -- never a message, never a shared log. Self-organization then follows from existence-not-command, not from a scheduler. BLOCKER STATED AS A PREREQUISITE, NOT A QUEUE POSITION. HoleV3 = ValueTenant 16 is blocked on BoardAggregates = 15 resolving, because the discriminant to VALUE_TENANTS index requires contiguous descriptors. GROUND TRUTH STATED HONESTLY. The public DisMech corpus marks its own gaps, but only 27 named intermediates match an actual graph node (113 have a real 2-hop path). A supervised evaluation has 27-113 usable cases, not thousands -- the gap count says how much work exists, the match count how much is checkable today. The handover doc is cold-start: it carries D-ACR-0's audit result (do not build on attention_mask -- it is a rename register file, EXISTS-UNCALLED), D-ACR-1's reuse finding (the atom already existed; what was missing was a composition that is not a bitset union), the mid-flight council state (v3 NOT ratified, reviewers 1 and 3 outstanding, and the rule that they see draft v2 only), the CausalEdgeV3 scope correction no savant could have caught, and the ogar-loco measurement -- already the same 6x2x8bit format, deliberately mirrored with a documented reason to stay separate, so do NOT "fix" it by importing. Board hygiene same-commit: INTEGRATION_PLANS prepend, STATUS_BOARD D-KUH-1..4.
…space, logarithmic path; stacking multiplies exponents while paths add; the pothole is the descent selector). Radix half graded [G], descent-selector half carried by D-KUH-1 as design intent.
…esign input)
Handover = ownership transfer IN PLACE of the shared classid+6x2x8bit atom.
Verified against the substrate: zero-copy is not an optimization but the
compliance condition -- the V3 tombstone ruling removed every inter-mailbox
handoff type ("nothing is serialized or transmitted between mailboxes"), so a
copying handover would be forbidden, not slow. The classid IS the briefing
(ClassView resolves the reading at the receiver; no protocol negotiation).
The narrow gap, measured: SoaEnvelope::mailbox_owner exists
(soa_envelope.rs:195) but NO ownership-transfer operation exists anywhere --
ownership is static today. The design therefore reduces D-KUH-1 + D-ACR-16
from "design a handover protocol" to "design the owner-change operation":
format, self-description and zero-copy already exist.
One open detail named rather than smoothed: prefix depth lives outside the 16
bytes (D-ACR-1's explicit-depth rule), so a raw handover would silently read as
depth-12 -- every wildcard focus would look like a pinpoint claim. The depth
byte's home in the Hole row's value slab is D-KUH-1's to fix.
STATUS_BOARD D-KUH-1 row updated in the same commit.
…ver is a focus entry in the next rung layer Operator correction: "kein Owner-Wechsel, nur Focus der Aufmerksamkeit ueber rung levels mit Alpha layer fuer thinking about thinking." §9 point 4 had read the static ownership as the gap; that was backwards. Static ownership is the design -- an owner change would be a substrate mutation, the command-shaped intervention existence-not-command deleted and the contamination boundary exists to prevent. Handover = the appearance of an AttentionFocusFacet entry in the NEXT rung layer of the alpha overlay, at the same address. The Hole never moves. Rung n+1 writes its own layer (one-writer holds trivially). Escalation is a second-order read plus an own-layer focus entry -- exactly D-ACR-4's read path. Collapses three things: the remaining work is an overlay operation (RowFocusMask::insert, shipped today) rather than a substrate one; the depth detail dissolves (depth travels in the overlay entry, raw 16-byte transport never happens); and D-ACR-16's cascade IS the stack of rung layers, the card being the focus entry, never the row. Point 4's measurement stays true (no transfer op exists) but regrades GAP -> CONFIRMS: its absence is the design. Handover doc + STATUS_BOARD D-KUH-1 corrected in the same commit, append-only.
…ature Operator refinement interrupting the prior push: "in dynamischem Substrat in place mit Lance versioning, in statischem Ontologie-Substrat Alpha layer." The first correction made the overlay THE mechanism everywhere; refined: static ontology -> alpha-layer entry at the same address (contamination boundary, overlay discardable whole); dynamic substrate -> in-place write by the row's one owner, with Lance versioning as the residue carrier -- episodic = Lance versions (E-MARKOV-TEMPORAL-STREAM-1), rung n+1 reads "where rung n looked" as a version-range read via QueryReference::at(v, rung): a projection, zero copies, replayable (alpha-plan §3c said it: a read at a version, never a stored history column). One invariant, two implementations: attention leaves a replayable trace without contaminating what it observed. Static side: the trace is a separate layer, because the substrate must not move. Dynamic side: the trace is the substrate's own motion, because it moves anyway and Lance keeps every version. The dynamic arm needs NOTHING built. Remaining work is solely the overlay arm's n+1-layer insert convention (RowFocusMask shipped) + lifecycle stamps. D-ACR-16's cascade is now fully shaped: rung layers over the static substrate, version-range reads over the dynamic one. Handover doc + STATUS_BOARD updated same commit, append-only throughout.
…anization: where each word cashes out The operator's closing claim, recorded with each term bound to its mechanism. Gestalt = the shallow-prefix read (a whole apprehended without enumerating members; RowFocusMask's minimal antichain as a mechanical Praegnanz operation, marked observation-not-doctrine; multistability via classid-selected readings). Meta-awareness = rung n+1 entries about rung n's at the same addresses, QueryReference::at as replayable self-history, the Hole as the metacognitive act made a row, MUL confidence-invariance as awareness of awareness's reliability. Self-organizing "durch die Architektur" made precise: the SO literature's preconditions map one-to-one onto RULINGS, not onto code that could rot -- local rules (one-writer, no scheduler), a stigmergic medium (the two-armed trace: alpha layers static, Lance versions dynamic), a gradient (potholes, one at a time), accretion (minting, never widening), terrain protection (contamination boundary). The stigmergy identification is graded [H]: exact structural match, no collective behaviour measured. The emergence claim itself stays CONJECTURE and already has its falsifiers -- D-ACR-8, D-ACR-10, D-ACR-11, D-KUH-3 ARE the emergence tests; none new needed. The preconditions are architectural invariants, the emergence is a prediction, and the prediction's tests are pre-registered.
… raised, 3 resolved
The council ran the full iron sequence: spec v1 -> 5 savants (39 findings;
code-truth 6/6 CONFIRMS) -> draft v2 -> 3 reviewers on v2 only -> Phase-4
fixes -> v3. Reviewers 1+3 were lost to a container restart and recast
against the surviving draft; their verdicts were never invented in the gap.
The three BLOCKs, each verified at source before acceptance:
1 (overclaim). "V3's bytes were never temporal" is FALSE for populated
instances: from_v1(e, target) has no provenance parameter and raw-copies
truth/spare (edge_v3.rs:117,138-139). The zero-stub comment above it is a
compile-time feature condition, not a runtime guarantee -- a v1/unknown CE64
with temporal >= 512 lifted under a v2 build carries stale band bits into V3
byte 9, indistinguishable from clean. V3Register is redefined as a caller
assertion ("minted clean"), never an inference; unstated origin = Unknown =
refuse. The v1 trap applies to BOTH carriers, on V3 transitively through the
lift. The from_v1 provenance drop is filed as a causal-edge follow-up.
2 (overclaim). G5 contradicted the total-lookup fix (split into G5a
zero-fallback / G5b must-error), and G10a was a same-function-same-input
tautology -- deleted under the falsifiability rule. G10b survives: compare
CausalEdge64::truth() vs CausalEdgeV3::truth_raw() on the same edge
post-from_v1, hosted in causal-edge (both crates' zero-dep postures hold,
measured on both Cargo.tomls), closing a measured missing test: the module
doc claims truth/spare survive the round trip and no test asserts it.
3 (firewall). Draft v2 contained zero occurrences of any board file -- the
Phase-2 consolidation dropped Savant 4's complete hygiene answer. Restored
as the spec's committed board-hygiene table.
Post-ratification operator addendum: all V3-generation carriers confirmed
unwired/planned (the contract is prescriptive by construction AND by ruling);
the temporal doctrine -- time is implicit in the epistemic pothole (Lance
versions, QueryReference::at), explicit ONLY in Rubikon revision /
CausalEdgeV3's TE byte / a future attention-v3 reading; EdgeProvenance is
layout epoch, never time. The v1 trap generalized: temporal went stale
because it lived implicitly in a reclaimable field.
Board hygiene same-commit: EPIPHANIES prepend (the from_v1 finding + the
TrustTexture x4 homonym folded in), STATUS_BOARD D-ACR-7 row (Spec RATIFIED,
gates G1..G10b), INTEGRATION_PLANS prepend, AGENT_LOG council entry
(orchestrator sole writer), handover superseded-note.
Implementation of contract::band_reading against G1..G10b is the next unit.
… measured composition The operator's target named: CE64 59..63 -> CEV3 + attention v3 x pothole x kanban x cognitive Maslow, via the supervisor's kanban_actor transparent view as meta-awareness. Every factor measured rather than assumed, with two real findings: 1. "Cognitive Maslow" is NOT a missing layer -- it is the shipped rung vocabulary: recipe_loci.rs states "the rung a recipe fires at IS a level of the operator-ruled Maslow pyramid of cognition", Maslow-monotone climb, elevate on sustained BLOCK, 70 references tree-wide. The composition consumes it as its need-axis; a pothole resisting closure at rung n escalates by the already-ruled climb signal. 2. The census loop IS the mechanical form of "transparent view as meta-awareness": five transparent reads -- phase distribution (PhaseCensus, one &self pass), attention (RowFocusMask), unknowns (pothole spans), epistemic grading (band readings, both carriers), need-level (Maslow rung) -- composed at the same addresses, feeding what gets attention next by existence, never command. No new organ minted. Gate status that makes "breakthrough" current: alpha-plan §3h (MUL over rung layers) was id-less pending three prerequisites -- RowFocusMask (shipped today), the 59..63 reading contract (ratified today), the delta_conf filter (a ratified acceptance condition inside it). All three landed or ratified; §3h moves from long-term to next-in-line after the band_reading implementation. Emergence stays CONJECTURE; §10's four falsifiers unchanged.
…9..63
Implements the RATIFIED spec `.claude/plans/dacr7-band-reading-contract-v1.md`
(5+3 council, 3×BLOCK(P0) raised and resolved in Phase 4, none argued away).
ONE reading contract, TWO carriers. `CausalEdge64` bits 59-60 (truth) / 61-63
(band) is the muscle memory; `CausalEdgeV3` bytes [8] hi-2 / [9] lo-3 via
`truth_raw()`/`spare_raw()` is the granularity, and rehydrates INTO CE64 to
reason. The reading never changes stored bytes — it declares how a consumer
projects them, resolved per `(classid, rail)` through `ClassView`, exactly like
`edge_codec_flavor` and `rail_carving`.
Provenance is the gate, and it comes FIRST — before the lens is even asked.
Council BLOCK-1: `CausalEdgeV3::from_v1` (edge_v3.rs:117) takes no provenance
parameter and raw-copies the tail (:138-139), so the v1 temporal trap — a
`temporal >= 512` aliasing a non-zero band — reaches V3 transitively. Therefore
`EdgeProvenance::V3Register` is a CALLER ASSERTION ("minted clean"), never an
inference; unstated means `Unknown` means refuse. Follow-up filed, not owned
here: `from_v1` should carry provenance in its signature.
The L1 split (Phase-4 fix): declaration lookup is TOTAL — `reading_or_default`
folds an undeclared class to `ZERO_FALLBACK`, sibling-consistent with the two
existing ClassView resolvers — while raw-bit projection is FALLIBLE and must
FAIL rather than hand back a plausible value. `get()` stays `Option` so "never
declared" and "declared Absent" remain distinguishable for audit, and
`declare()` returns true on replace so a redeclaration is visible.
`sampling_admits` filters on `Tactic::moves_confidence()` — 14 of 34 — never on
`maturity().is_production()`, which is 31 of 34 and would silently admit 17
tactics that move nothing. Asserted against the real `all_kernels()`.
G10b lives in `causal-edge` because both crates are zero-dep and neither may
import the other (contract Cargo.toml:10-17, causal-edge Cargo.toml:20-23). It
closes a measured missing test: the module doc claimed the truth/spare round
trip is byte-exact and nothing asserted it through the accessors. It fires on
nonzero ordinals surviving `from_v1` → `rehydrate`, and stays silent on zero.
Mints nothing: no tenant, no bit, no ENVELOPE_LAYOUT_VERSION bump, no cfg
feature that re-means a stored bit.
Gates: G1 1207 contract tests (+13) · G2 clippy clean · G3′ lens mismatch fails
and match resolves · G4′ V1Legacy/Unknown refuse, V2Stamped/V3Register resolve ·
G5a total fold · G5b UndeclaredClass fires · G6 14 admitted / 20 rejected ·
G7′ arity pins · G8 no with_* or CE64 mask bit-ops · G9 no cfg · G10b green.
Also: TYPE_DUPLICATION_MAP TrustTexture corrected ×2 → ×4 — the entry had two
stale line numbers and the arigraph path wrong. Arities are 4/4/5/3, so the
old "rename one to disambiguate" recommendation was incoherent; the planner's
5-variant enum cannot round-trip a 2-bit field at all. One `cargo fmt` reflow
in edge.rs is the pinned toolchain's own output on a pre-existing line.
Board hygiene same-commit: LATEST_STATE inventory, STATUS_BOARD D-ACR-7 → Shipped.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
274b802 to
b045575
Compare
This PR lands two falsifiers in `crates/causal-edge/src/edge_v3.rs`, and #981 landed a `#[test]` there before it. Neither could ever have failed in CI: no workflow names `causal-edge`. Its own PR body records the symptom without naming it — "standalone, `--manifest-path` — es steht unter `exclude`" — which is the same "green on a developer machine" shape `rust-test.yml` already describes when it closed this hole for deepnsm, supervisor and bgz-tensor. `causal-edge` is workspace-EXCLUDED but a path-dep of `lance-graph`, `lance-graph-planner`, `cognitive-shader-driver` and `sigma-tier-router`, so its LIB does compile inside gated builds. It is the TESTS that were unarmed — including this PR's. Added, both measured on the pinned 1.97.1 toolchain before landing: - `rust-test.yml`: `cargo test --manifest-path crates/causal-edge/Cargo.toml` — 75 passed, 0 failed. - `style.yml`: `cargo fmt --manifest-path crates/causal-edge/Cargo.toml -- --check` — clean today; the step keeps it that way. NOT added: a clippy gate. `clippy --all-targets -- -D warnings` returns 7 errors on this crate, every one of them pre-existing and NONE in the `edge_v3.rs` this PR touches (they sit in `edge.rs` ×7 lines, `tables.rs:37`, `v2_layout_tests.rs:20`). Gating them here would fail this PR for defects it did not introduce, so they are recorded as ISSUES ISS-CAUSAL-EDGE-CARRIES-SEVEN-PRE-EXISTING-CLIPPY-FINDINGS with their exact locations, and the crate is left with a test gate and a format gate but no lint gate — an asymmetry that is deliberate and written down rather than left to be rediscovered. The wider measurement this came out of: no workflow in this repo runs `--workspace` or `--all`, so every gate is a hand-maintained allowlist and adding a crate to `[workspace] members` adds it to nothing. Nine members plus this excluded crate were reached by no job. That is EPIPHANIES E-THE-GATE-IS-A-HAND-MAINTAINED-ALLOWLIST-NOT-THE-WORKSPACE-1 and ISSUES ISS-CI-GATE-IS-AN-ALLOWLIST-NINE-MEMBERS-UNGATED, both on the claude/hydrate-from-zip branch; the remaining eight are one operator decision (a single --workspace job, or a recorded rationale per omission), not a blind eight-job addition.
Two things, and the second is why the first was possible. ARCHIVE — the missing distribution shape `copy::hydrate_dir` hydrates a dataset that lives in the object store as a TREE of objects. That is right when the store IS the dataset's home; it is wrong for distribution, where the artifact is a versioned, checksum-pinned release: a tree has no single identity to pin, no atomic publish upstream, and its listing can interleave with a producer's write. Operator ruling 2026-08-22: "bitte als zip, nicht dass wir ein Verzeichnis mit einzelnen Dateien shippen". Zip rather than tar, concretely: a zip ends with a central directory, so entries can be enumerated and sought without a sequential scan — which is also what lets this validate the WHOLE index before extracting a single byte. `archive::hydrate_archive` composes what the crate already owns — `hydrate_file` for the pinned fetch, `publish_by_rename` + `StagingKind::Dir` for the atomic publish — and adds only the middle: expanding one verified container into private staging under a containment rule. Every entry must live under the declared root, no `..`, no absolute path; the first escaping entry rejects the whole archive, because a dataset missing one file is not a partial success but an unopenable table that `count_rows` reports as wrong-sized. BUILD — the crate did not compile at main Measured on a clean checkout of origin/main (#981): cargo build -p lance-graph-hydrate error[E0599]: no method named `get` found for reference `&dyn ObjectStore` ... 5 errors, in the LIB, not the tests `object_store 0.13.2` — already pinned in the lockfile on main, unmoved by this branch — moved `get`/`put` onto an extension trait. The fix is two `use` lines. `cargo fmt` also rewrites four files, and clippy had a live warning, so the crate was merged unbuilt, unformatted and unlinted. The finding is not the breakage; it is the mechanism that hid it. A crate with zero consumers is in nobody's build graph, so a semver-COMPATIBLE upstream change invalidated it with no gate firing. Its own lib.rs records the absence of a consumer as a cost tradeoff — it is also a verification hole. Filed as EPIPHANIES E-A-CRATE-WITH-ZERO-CONSUMERS-IS-BUILT-BY-NOTHING-AND-CAN-BE-MERGED-BROKEN-1 and ISSUES ISS-HYDRATE-CRATE-HAS-NO-BUILD-GATE, whose durable fix is the next commit on this branch: `VersionedGraph::hydrate_from`, which puts the crate into lance-graph's build graph and closes ISS-REMOTE-URI-CONSTRUCTORS-PREDATE-THE-HYDRATION-DOCTRINE at the same time. Measured, not asserted: 39 tests green (33 pre-existing, 6 new); clippy --all-targets -D warnings clean; disabling the containment check and the file counter turns exactly their two tests red and leaves the other four green, so both new guards are load-bearing. Board hygiene in this commit: LATEST_STATE contract inventory, the epiphany, the issue.
Two things, and the second is why the first was possible. ARCHIVE — the missing distribution shape `copy::hydrate_dir` hydrates a dataset that lives in the object store as a TREE of objects. That is right when the store IS the dataset's home; it is wrong for distribution, where the artifact is a versioned, checksum-pinned release: a tree has no single identity to pin, no atomic publish upstream, and its listing can interleave with a producer's write. Operator ruling 2026-08-22: "bitte als zip, nicht dass wir ein Verzeichnis mit einzelnen Dateien shippen". Zip rather than tar, concretely: a zip ends with a central directory, so entries can be enumerated and sought without a sequential scan — which is also what lets this validate the WHOLE index before extracting a single byte. `archive::hydrate_archive` composes what the crate already owns — `hydrate_file` for the pinned fetch, `publish_by_rename` + `StagingKind::Dir` for the atomic publish — and adds only the middle: expanding one verified container into private staging under a containment rule. Every entry must live under the declared root, no `..`, no absolute path; the first escaping entry rejects the whole archive, because a dataset missing one file is not a partial success but an unopenable table that `count_rows` reports as wrong-sized. BUILD — the crate did not compile at main Measured on a clean checkout of origin/main (#981): cargo build -p lance-graph-hydrate error[E0599]: no method named `get` found for reference `&dyn ObjectStore` ... 5 errors, in the LIB, not the tests `object_store 0.13.2` — already pinned in the lockfile on main, unmoved by this branch — moved `get`/`put` onto an extension trait. The fix is two `use` lines. `cargo fmt` also rewrites four files, and clippy had a live warning, so the crate was merged unbuilt, unformatted and unlinted. The finding is not the breakage; it is the mechanism that hid it. A crate with zero consumers is in nobody's build graph, so a semver-COMPATIBLE upstream change invalidated it with no gate firing. Its own lib.rs records the absence of a consumer as a cost tradeoff — it is also a verification hole. Filed as EPIPHANIES E-A-CRATE-WITH-ZERO-CONSUMERS-IS-BUILT-BY-NOTHING-AND-CAN-BE-MERGED-BROKEN-1 and ISSUES ISS-HYDRATE-CRATE-HAS-NO-BUILD-GATE, whose durable fix is the next commit on this branch: `VersionedGraph::hydrate_from`, which puts the crate into lance-graph's build graph and closes ISS-REMOTE-URI-CONSTRUCTORS-PREDATE-THE-HYDRATION-DOCTRINE at the same time. Measured, not asserted: 39 tests green (33 pre-existing, 6 new); clippy --all-targets -D warnings clean; disabling the containment check and the file counter turns exactly their two tests red and leaves the other four green, so both new guards are load-bearing. Board hygiene in this commit: LATEST_STATE contract inventory, the epiphany, the issue.
What this is
Two deliverables that turned out to be one shape, plus the plan that connects them.
D-ACR-1 —
contract::attention_facet(dd0efabc). The attention atom was already shipped: it is theFacetCascade(classid(4) | 6×(8:8)) underCascadeShape::G6D2. This PR adds the Attention reading of it — zero new bytes, no tenant, noENVELOPE_LAYOUT_VERSIONbump.D-ACR-7 —
contract::band_reading(274b8021). The reading contract for CE64 bits 59..63, ratified by a 5+3 council before implementation.D-ACR-1: the basis decision
The candidate basis (
cognitive-shader-driver::attention_mask) is an LRU rename register file, not attention focus — audited separately in #980. So the basis is a reuse, not an extension:AttentionFocusFacet— the cascade read as focus, with an explicitdepth: 0..=12held outside the 12 bytes. Inferring a wildcard from zero bytes would collide with the zero-fallback ladder, where0is a dormant tier, not a terminator (theNiblePathprecedent).FocusAxisisAxis0..Axis5— a position, not a meaning. The module names no axis semantics. Both the cascade reading (HEEL·HIP·…) and a candidate ontology-scope reading (disease/anatomy/process/substance/evidence/context) are ClassView-resolved projections, demonstrated over byte-identical input inthe_same_atom_reads_as_cascade_and_as_ontology_scope_without_changing_a_byte. Baking either name into the low-level type would have been the error.RowFocusMaskcomposes by prefix containment, never bit-OR:unionabsorbs into a minimal antichain,intersectyields the deeper of a covering pair,differenceis deliberately conservative. It does not index rows, so noFieldMask(64) orWideFieldMask(256) cardinality is inherited — a 1000-entry container is tested.FOCUS_AXES = CASCADE_UNITS / 2— derived, never a second literal.D-ACR-7: the reading contract
Ratified via 5+3 council (
.claude/plans/dacr7-band-reading-contract-v1.md): 3×BLOCK(P0) raised, 3 resolved in Phase 4, none argued away.One contract, two carriers.
CausalEdge64bits 59-60 (truth) / 61-63 (band) is the muscle memory;CausalEdgeV3bytes[8]hi-2 /[9]lo-3 is the granularity, and rehydrates into CE64 to reason. The reading never changes stored bytes — it declares how a consumer projects them, resolved per(classid, rail)through a newClassView::band_readingprovided method, the same registry pattern asedge_codec_flavorandrail_carving.Provenance gates before the lens does. The council's BLOCK-1:
CausalEdgeV3::from_v1(edge_v3.rs:117) takes no provenance parameter and raw-copies the tail (:138-139), so the v1 temporal trap — atemporal >= 512aliasing a non-zero band — reaches V3 transitively.EdgeProvenance::V3Registeris therefore a caller assertion ("minted clean"), never an inference; unstated meansUnknownmeans refuse.The L1 split. Declaration lookup is TOTAL (
reading_or_defaultfolds toZERO_FALLBACK, sibling-consistent with the two existing ClassView resolvers); raw-bit projection is FALLIBLE and must fail rather than hand back a plausible value.get()staysOptionso "never declared" and "declaredAbsent" remain distinguishable for audit;declare()returnstrueon replace so a redeclaration is visible.Sampling filters on capability, not maturity.
sampling_admitsusesTactic::moves_confidence()— 14 of 34 — nevermaturity().is_production(), which is 31 of 34 and would silently admit 17 tactics that move nothing. Asserted against the realall_kernels(), not a fixture.The plan commits
f2b91e18…b09a8fe8build.claude/plans/known-unknown-handover-network-v1.mdincrementally. Two operator corrections are recorded append-only rather than rewritten:§8 grades the ↑n arithmetic honestly: the radix half is
[G], the descent-selector half is design intent carried by D-KUH-1.Verification
band_reading, +14 fromattention_facet)V1Legacy/Unknownrefuse,V2Stamped/V3Registerresolve · G5a total fold · G5bUndeclaredClassfires · G6 14 admitted / 20 rejected · G7′ arity pins · G8 nowith_*calls, no CE64 mask bit-ops · G9 nocfgfeature re-meaning a stored bitcausal-edge— both crates are zero-dep and neither may import the other. It closes a measured missing test: the module doc claimed the truth/spare round trip is byte-exact and nothing asserted it through the accessors. Fires on nonzero ordinals survivingfrom_v1→rehydrate, stays silent on zero.All gates were pre-registered before any agent ran.
Also in this PR
docs/TYPE_DUPLICATION_MAP.md—TrustTexturecorrected×2→×4. The entry had two stale line numbers and the arigraph crate path wrong. The arities are 4/4/5/3, which makes the old "rename one to disambiguate" recommendation incoherent: the planner's 5-variant enum cannot round-trip a 2-bit field at all. Rewritten as per-site renaming only, never unification — the zero-dep posture of both crates makes the duplication deliberate.Follow-up, filed not owned here
CausalEdgeV3::from_v1should carry provenance in its signature. That is acausal-edgesignature change and belongs in its own PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
Generated by Claude Code