Per fox 2026-06-01: same treatment as #000071 — replace the
review-archaeology structure with what we SHOULD grow. Ticket goes
from 978 lines (original Anchor6 §§1-8 design log + dav1d-review §0
retrofit) to 498 lines of directive spec. **Joseph6 stays as the
first registered example grammar** per fox's note — concrete enough
that an implementer sees what a WorldDimensionGrammar looks like
end-to-end, not abstract enough to lose its load-bearing role.
What changed in shape:
Before: §0 dav1d verdict retrofit + §§1-8 archaeology of the
original Anchor6 spec being reviewed (validate seed source,
segmentation method, mapper choice — all decisions long
since made).
After: §1-13 forward spec. Goal · Axis split · Hard constraints
(all phases) · AnchorN primitive · WorldDimensionGrammar ·
Quantization mappers (with uint256-H₁ + no-SO(3) corrections
documented inline) · π*_w_object canonicalizer with
four-identity-hash record · **Joseph6 as worked example** ·
Phase 1 deliverables (9 items) · Pre-review empirical
bench preserved as §7 · Phase 2/3 deferred · Open questions
(3 remaining; 5 closed by bench, 4 by dav1d's review) ·
Cross-references · Five-step alignment · One-line review
history at the bottom.
What changed in content: nothing material. The corrected spec from
the prior §0 retrofit IS the body now. The original Anchor6 design
log is no longer inlined — git history preserves it at commit
`862662b` (pre-rewrite tip); readers who want the rejection-by-
rejection detail go to
docs/dav1d-reviews/000070-spatial-anchor-pi-w-object--2026-06-01.txt.
Critical technical corrections preserved inline (not as "what was
fixed", but as the directive answer):
- §3.1: uint256 for H₁ position (octree depth >8 entropy
preservation)
- §3.2: rename `map_rotation_so3` → `map_rotation_euler_ypr` (no
SO(3) overclaim — quantized Euler is not SO(3) coverage)
- §4: WorldObjectRecord carries all four identity hashes
(grammar_hash, axiom_pack_hash, manifest_hash, seed_hash) for
replayability
- §5: Joseph6 ships as one example grammar; future grammars
register through the same mechanism
TICKETS.md index row also rewritten in directive voice.
doc_counts tests still pass.
20 KiB
Ticket #000070 — AnchorN + π*_w_object: deterministic world-object canonicalization
Status: open · Phase 1 deliverable scoped · dav1d GO-with-rewrite
landed 2026-06-01 (full review at
docs/dav1d-reviews/000070-spatial-anchor-pi-w-object--2026-06-01.txt).
Opened: 2026-05-31
Goal
Implement the first executable v7-W world-object canonicalization kernel. The kernel takes:
hard_hash_32 one committed 32-byte SHA-256
spatial_anchor_seed v7-W manifest-published, dedicated
WorldDimensionGrammar frozen grammar declaring N + N mappers
world_manifest privacy class, axiom pack, version pins
and produces:
canonical_world_object_bytes deterministic byte string
world_object_hash SHA-256(canonical bytes)
object_record grammar_hash + axiom_pack_hash +
manifest_hash + seed_hash + per-dim values
A single committed hash deterministically expands into N named regions
via the HMAC-SHA-512 KDF already shipped in
arborist/substrate/anchor_prg.py (#000035). Each region drives one
quantized dimension under a registered mapper. N is grammar-decided,
not hard-coded.
Axis split (cross-ref #000071)
#000070 intra-world state instantiation
AnchorN + WorldDimensionGrammar + AxiomPack + Manifest →
canonical world-state records
#000071 inter-world treaty grammar
two chains decide whether commitments cross the gap →
agreement | translation | embassy | quarantine | no_bridge
Joseph6 (six-dimension Joseph @TrudoJo framework) is the first registered default grammar, not THE substrate ontology. See §5.
Hard constraints
- A1–A3 axioms. Canonical encoding · public quantization for proof-path state · collision-resistant hash. No new axiom.
- Quantized integer state only. Continuous floats do not enter the proof path (v7-W manifest hard rule, paper §1.2). Mappers emit integers; any continuous-domain math (e.g. Euler rotation) quantizes deterministically before commitment.
- Hard-hash family stays SHA-256 commit + HMAC-SHA-512 expansion. Soft locality indices (Morton / H3 / S2 / Hilbert / geohash) live outside the proof path per CLAUDE.md soft-hash rule.
- Domain separation from #000035. A NEW seed
spatial_anchor_seedis published in the v7-W manifest besideanchor_prg_seed; #000035 §2.4 "single-purpose — never reuseanchor_prg_seed" is honored without aPHI_PRG_VERSIONbump. - No new
audit_modetoken. π*_w_object emits commitments, not warrants. The four-rung ladder (POINTER-LINKED → ANCHOR-WARRANTED → EVIDENCE-WARRANTED → ENTAILMENT-VERIFIED) is not extended. - No SQL at Phase 1. A new
pi_star/spatial-anchor-object@v1registry entry folds intocanonicalization_version(one of the v9.8 8-dim cache_key dimensions). Persistence to aworld_state_cellstable is deferred to Phase 3. - Privacy fail-closed. Missing
privacy.classin the manifest is a HARD reject — no PUBLIC fallback. - Grammars must be FROZEN before proof-path use. Axioms MAY
select a grammar (LLM may propose candidates), only
deterministic validators may accept them. Accepted grammars
are canonicalized, hashed, KAT-tested, versioned.
grammar_hashbinds into every downstream commitment. - Topic-named, not version-prefixed (CLAUDE.md naming rule).
Lands under
arborist/world/andarborist/pi_star/, notarborist/v7w/orarborist/spatial/.
1. AnchorN — the substrate primitive
AnchorN is the generic key-derivation primitive. Given a hard hash
and a frozen grammar declaring N regions, it expands the hash into N
named 32-byte regions via HMAC-SHA-512 counter mode.
@dataclass(frozen=True)
class AnchorN:
hard_hash: bytes # 32 bytes (SHA-256 of source)
seed: bytes # spatial_anchor_seed from manifest
grammar_hash: bytes # binds region identities to a grammar
regions: tuple[bytes, ...] # N × 32 bytes
def split_anchor_n(
hard_hash: bytes,
seed: bytes,
grammar_hash: bytes,
n: int,
) -> AnchorN:
"""Generic N-region split. Counter-mode HMAC-SHA-512 over the
triple (hard_hash || seed || grammar_hash || counter_be8) yields
64-byte blocks; first 32 bytes of each block is the region.
Same construction as arborist.substrate.anchor_prg._expand;
the difference is grammar_hash binds into the expansion so the
same hard_hash under two different grammars yields disjoint
regions. Without that binding, swapping grammars at proof-path
time would silently reuse anchor bytes for new semantics.
"""
Lives at arborist/substrate/spatial_anchor.py. Substrate-level (not
under arborist/world/) because AnchorN is the generic primitive any
future world kernel may consume — v7-W is one consumer, but other
consumers may want N-region splits without the v7-W semantics.
2. WorldDimensionGrammar — frozen, hash-pinned, registry-addressable
A grammar declares N and the N region-to-mapper bindings. It is a
canonical-bytes-serializable record; its SHA-256 is grammar_hash.
@dataclass(frozen=True)
class WorldDimensionGrammar:
name: str # e.g. "joseph6"
version: str # e.g. "v1"
n: int # number of regions
region_mappers: tuple[str, ...] # registered mapper names
region_names: tuple[str, ...] # human-readable per-region label
axiom_pack_ref: str # "axiom-pack@v1" registry slot
def canonical_grammar_bytes(g: WorldDimensionGrammar) -> bytes:
"""Stable serialization. Field order pinned, integers little-endian."""
def grammar_hash(g: WorldDimensionGrammar) -> bytes:
return sha256(canonical_grammar_bytes(g))
def validate_grammar(g: WorldDimensionGrammar) -> None:
"""Raise GrammarInvalid if:
- n != len(region_mappers) != len(region_names)
- any mapper name isn't in the registry
- axiom_pack_ref isn't in the registry
- reserved-name collision (e.g. names starting with '_')
"""
Lives at arborist/world/grammar.py (new file).
3. Quantization mappers
Five registered mappers ship in Phase 1 (Joseph6's full set). Each takes a 32-byte region and returns a quantized integer record.
| mapper | input | output | notes |
|---|---|---|---|
map_octree_position() |
32 bytes | (level: uint8, cell: uint256) |
uint256, not uint64 — preserves entropy at any octree depth |
map_scale_level() |
32 bytes | uint16 |
quantized log-scale, fixed scale-ladder per grammar |
map_rotation_euler_ypr() |
32 bytes | (yaw: uint16, pitch: uint16, roll: uint16) |
NOT "SO(3)" — quantized Euler triple, no continuous SO(3) coverage claim |
map_symbol_table_index() |
32 bytes | uint64 |
modulo over a fixed-size symbol palette |
map_passthrough_hex() |
32 bytes | hex_str |
64-char hex; preserves the full region byte string for downstream interpretation |
All mappers are deterministic and registered by name@version.
Adding a mapper = bump
canonicalization_version: spatial-anchor-object@v1 → v2.
Lives at arborist/world/pi_star/object.py.
3.1 Critical correction (dav1d §16)
The original Anchor6 spec called map_octree_position() to return
uint64. That loses entropy at octree depth > 8. Use uint256:
preserves the full 32-byte region. The bench (§7) measured chi²
uniformity at L=2,3,4 only; production deployments will go deeper,
and uint64 truncation would silently bias cell selection at the bits
that get dropped.
3.2 Critical correction (dav1d §17)
The original Anchor6 spec described H₃ as "quantized SO(3) rotation."
Do not overclaim. The mapper is a quantized Euler ypr triple.
Quantized Euler is not SO(3) coverage — adjacent rotation operations
are not metrically adjacent in this quantization. Name the mapper
map_rotation_euler_ypr() so consumers don't import SO(3) semantics.
4. π*_w_object — the canonicalizer
def derive_world_object_record(
hard_hash: bytes,
seed: bytes,
grammar: WorldDimensionGrammar,
manifest: WorldManifest,
) -> WorldObjectRecord:
"""End-to-end:
1. validate_grammar(grammar) — fail-closed
2. validate_manifest(manifest) — privacy.class HARD-required
3. anchor = split_anchor_n(...) — N regions
4. per region: invoke registered mapper
5. assemble record with all four hashes
6. SHA-256(canonical(record)) = world_object_hash
"""
Output record carries the FOUR identity hashes plus per-dimension values:
@dataclass(frozen=True)
class WorldObjectRecord:
grammar_hash: bytes # which grammar produced this
axiom_pack_hash: bytes # which axiom pack the grammar pins
manifest_hash: bytes # which deployment manifest
seed_hash: bytes # which spatial_anchor_seed
dimensions: tuple[Any, ...] # length N; one per region_mapper
world_object_hash: bytes # SHA-256 of the canonical bytes
All four hashes are required for replayability across grammar
versions. A consumer presented with a world_object_hash and the
four identity hashes can re-derive the record byte-for-byte by
loading the named grammar + axiom pack + manifest + seed.
Lives at arborist/world/pi_star/object.py.
A separate registry-facing adapter at
arborist/pi_star/spatial_anchor_object.py exposes the canonicalizer
as a registered π*:
PI_STAR_NAME = "spatial-anchor-object"
PI_STAR_VERSION = "v1"
def canonicalize(raw: bytes) -> bytes:
"""Registry contract. Parses raw bytes into the (hard_hash,
seed_ref, grammar_ref, manifest_ref) tuple, dispatches to
derive_world_object_record, returns the canonical bytes."""
5. Joseph6 — the first registered grammar (example)
Joseph @TrudoJo's six-dimension framework lands as the first canonical grammar. It is an example of what a WorldDimensionGrammar looks like, not THE substrate.
JOSEPH6 = WorldDimensionGrammar(
name="joseph6",
version="v1",
n=6,
region_names=(
"position", # H₁
"scale", # H₂
"rotation", # H₃
"material", # H₄
"links", # H₅ — reserved for π*_w_relation sibling
"behavior", # H₆
),
region_mappers=(
"map_octree_position",
"map_scale_level",
"map_rotation_euler_ypr",
"map_symbol_table_index", # material palette
"map_passthrough_hex", # raw links reserved
"map_symbol_table_index", # behavior code
),
axiom_pack_ref="axiom-pack-joseph6@v1",
)
Joseph6's grammar_hash is computed at module-load time; KATs (§7)
pin it byte-for-byte. Future grammars (Joseph12, Cartesian5,
spatial+temporal-7, etc.) register through the same mechanism —
none is privileged over Joseph6 except by being chosen at
deployment-manifest level.
Why ship Joseph6 in Phase 1:
- Proves AnchorN can host a non-trivial grammar end-to-end.
- Gives the substrate-paper a concrete worked example readers can follow without inventing one.
- Lets the bench (§7) measure a real grammar's avalanche / uniformity / domain-separation properties rather than a synthetic.
6. Phase 1 deliverables
What ships:
- Substrate primitive:
arborist/substrate/spatial_anchor.py—AnchorN,split_anchor_n(),SPATIAL_ANCHOR_VERSION,PLACEHOLDER_SPATIAL_SEED
- Grammar layer:
arborist/world/grammar.py—WorldDimensionGrammar,canonical_grammar_bytes(),grammar_hash(),validate_grammar()
- Mappers + record:
arborist/world/pi_star/object.py— 5 mappers +WorldObjectRecordderive_world_object_record()
- Registry adapter:
arborist/pi_star/spatial_anchor_object.py— registered π*
- Joseph6 grammar:
arborist/world/grammars/joseph6.py(or registry-registered constant) — theJOSEPH6grammar definition + axiom-pack-joseph6@v1
- KATs:
bench/fixtures/spatial-anchor-object/known-answer-tests.jsonl— at minimum: zero-hash, max-hash, low-entropy hash, three mid-entropy hashes; expected outputs for Joseph6 grammar
- Tests:
tests/test_spatial_anchor.py— AnchorN unit + integrationtests/test_world_dimension_grammar.py— grammar validationtests/test_pi_star_spatial_anchor_object.py— canonicalizer round-trip + KAT replay
- Paper amendment:
docs/_source/merkle-agi-v7w-spatial-temporal.rst— new section citing Joseph (@TrudoJo) as the framework author; AnchorN + grammar layer as the architecture
- Status:
arborist/world/__init__.pySTATUS bumps fromnamespace_reserved→world_object_kernel_in_progress
What does NOT ship in Phase 1:
- ❌ Relation / event / place / agent_trace kernels (siblings)
- ❌ SQL
world_state_cellstable (Phase 3) - ❌ New
audit_modetoken (ever — hard) - ❌
verifier_policy_hashchange (commitments ≠ warrants) - ❌ Continuous tensors anywhere in proof path
- ❌ Runtime LLM-decided dimensionality (axioms select, validators accept, grammars freeze)
- ❌ Bench at Phase 1 over and above the pre-review empirical bench (§7) — KATs replace open-ended bench
7. Pre-review empirical evidence (already shipped)
bench/spatial_anchor_validation.py (commit 55b651f, 561 lines)
validated the HMAC-SHA-512 expansion properties before this ticket's
implementation phase. Survives the AnchorN reframe — N just
changes the loop count; the per-region properties measured are
unchanged.
Reproduce:
make bench-spatial-anchor [SPATIAL_N=10000]
| § | Bench | Result | What it proves |
|---|---|---|---|
| 1 | Avalanche (single-bit hash flip → Hamming distance over output) | mean 767.85 / 768 bits (z = -0.49) | counter-mode HMAC-SHA-512 is PRF-good; fixed-offset slicing inherits the property |
| 2 | Octree chi² uniformity (L=2,3,4) | |z| < 1 every level | map_octree_position() modulo 8^L is uniform; no LE-conversion bias |
| 3 | Birthday-bound collision ratio (L=4,6) | 0.989 / 1.038 | structural skew absent; collisions follow PRF expectation |
| 4 | Cross-region Pearson r (15 pairs of H₁..H₆) | r ∈ [-0.018, +0.012], max |r|/stderr = 1.80 | counter-mode block independence holds empirically |
| 5 | Domain separation (Arm A distinct seeds vs Arm B shared seed) | Arm A 767.91 bits independent · Arm B 0.00 bits exact collision | dedicated spatial_anchor_seed discipline is load-bearing; sharing seeds yields byte-identical anchor maps |
Result file bench/spatial_anchor_validation_results.md pinned to
the RNG seed 0xa8c90e551fd34427 — re-runs hash-stable.
The bench answers 5 of the original 10 design questions (Q1 seed source, Q2 segmentation method, Q3 octree mapper, Q8 endianness, Q9 KAT adversarial vectors). The remaining 5 are design decisions the dav1d review already resolved or paper-editorial calls (see §10).
8. Phase 2 (deferred — siblings under #000013)
When Phase 2 opens:
- Second grammar registration — proves the registry mechanism works for grammars other than Joseph6. Candidate: Cartesian5 (position-only, 5-region for 3D + 2D-affine variants).
- π_w_relation* — relation kernel sibling. Different grammar (relations don't have a single anchor), different π* registry slot.
- π_w_event / π_w_place / π*_w_agent_trace** — three more sibling kernels. Each is its own ticket.
The substrate primitive AnchorN is unchanged across siblings —
only the grammar + mappers vary.
9. Phase 3 (deferred — persistence)
- SQL
world_state_cellstable (or whatever shape mesh-replay needs) - v9.8
cache_keymay gain a new dimension if Phase 3 reveals it must (defer to bench evidence) - Cold-pack export for v7-W records (sibling of #000061 cold-pack)
audit_eventswriter for π*w* commitments (no new event_type needed; existingpi_star_emithandles this)
10. Open questions
Only the items the dav1d review left genuinely open. The empirical bench (§7) closed Q1/Q2/Q3/Q8/Q9; dav1d's review §0.7 answered Q4/Q5/Q6/Q7.
-
Q10 — substrate-paper amendment wording. The paper at
docs/_source/merkle-agi-v7w-spatial-temporal.rstneeds a new section introducing AnchorN + grammar layer (not fixed Anchor6). The technical content is in this ticket; the paper's voice, diagram style, and reading order stay for fox to set. -
Grammar registry persistence shape. Are grammars Python constants in
arborist/world/grammars/*.py, manifest-declared YAML, or hash-pinned blobs in a SQLite table? Phase 1 starts Pythonic; Phase 2 may need otherwise as more grammars land. -
Axiom pack registry vs declared inline.
axiom_pack_refis a registry slot; the axiom pack itself (the physics / math constraints the grammar pins) needs its own canonicalization and KAT discipline. May warrant a sibling ticket if axiom packs grow beyond simple shape.
11. Cross-references
- #000013 — v7-W substrate reservation. This ticket's Phase 1
flips
arborist/world/__init__.pySTATUS fromnamespace_reserved→world_object_kernel_in_progress. - #000035 — HMAC-SHA-512 KDF (
anchor_prg.py). AnchorN reuses_expandbyte-for-byte. Domain separation via dedicatedspatial_anchor_seedkeeps #000035's KAT freeze intact. - #000071 — World-bridge grammar. Bridge ChainRoots may carry
world_dimension_grammar_hashfrom this ticket's grammar layer. - #000015 — π* cross-domain composition. Eventually composes spatial π* with linguistic π* via the composition theorem.
- #000061 — cold-pack object store. Future v7-W record persistence may piggyback on the cold-pack distribution tier.
12. Five-step alignment
- Make requirements less dumb. Joseph's framework named the six-dimension axis; dav1d's review named "freeze grammars before proof-path use." Both are load-bearing requirements with people attached.
- Delete the part / process. AnchorN replaces Anchor6 — same
primitive, generalized. Joseph6 stays as the worked example.
Five mappers, not "however many feels right."
map_rotation_so3is deleted; renamedmap_rotation_euler_yprso consumers don't import the SO(3) overclaim. - Simplify and optimize. uint256 for H₁ position (no truncation
ambiguity); grammar identity binds into AnchorN expansion (no
silent reuse across grammars); manifest-published
spatial_anchor_seed(no need to bumpPHI_PRG_VERSION). - Accelerate cycle time. KATs replace open-ended bench at Phase 1. Joseph6's grammar_hash is a fixed byte string; deviations show up as KAT failures, not bench drift.
- Automate. Last. The π* registry mechanism + KAT discipline automates what the paper specifies; no automation before the grammar registry mechanism freezes.
13. Review history
- 2026-05-31 — original ticket filed (fixed Anchor6 framing,
H₁..H₆ ontology, six-dimension Joseph kernel). Full original
proposal preserved in git history at commit
55b651f/e2c8e2c(pre-rewrite tip). - 2026-05-31 — pre-review empirical bench shipped in
55b651fvalidating HMAC-SHA-512 expansion properties (§7); survives the rewrite unchanged. - 2026-06-01 — dav1d de-novo review: GO-with-rewrite. Generic
AnchorN replaces fixed Anchor6; Joseph6 is the first registered
grammar, not THE substrate. uint256 H₁ correction; no SO(3)
overclaim; canonical record carries four identity hashes;
privacy fail-closed; no SQL / new audit_mode / verifier_policy_hash
change at Phase 1. Full review (1904 lines) archived at
docs/dav1d-reviews/000070-spatial-anchor-pi-w-object--2026-06-01.txt. This ticket text is the rewrite dav1d's review requires.