Skip to content

D79 Wave 1: the structure stage — deterministic skeleton, sanity check, anchor fallback (#165) - #169

Merged
fazpu merged 2 commits into
mainfrom
feat/d79-structure-stage
Jul 28, 2026
Merged

D79 Wave 1: the structure stage — deterministic skeleton, sanity check, anchor fallback (#165)#169
fazpu merged 2 commits into
mainfrom
feat/d79-structure-stage

Conversation

@fazpu

@fazpu fazpu commented Jul 28, 2026

Copy link
Copy Markdown
Member

Wave 1 of 3 for #165 — the D79 structure stage, per plan/designs/e0_files_design.md §4.1 and D79 + amendments.

What ships

  • Blockizer heading metadata (raw level + NFKC-normalized title on heading blocks, blockizer-2026.07b bump) with the chunk grid proven byte-identical two ways: the golden-digest lock AND a packing byte-equivalence regression under mutated metadata. Stale pre-metadata sidecars re-derive via blocks_from_sidecar instead of dead-lettering queued work.
  • Deterministic skeleton parser over canonical heading blocks; §4 output contract unchanged; placement null until Wave 2 (P3 type-default per the design's degraded path).
  • The skeleton sanity check: normative stat schema (d79-v2), budget-bounded flash judge (REMEMBERSTACK_SKELETON_CHECK_MODEL, default glm-4.7-flash) with anomaly-exemplar-first deterministic sampling under a hard 16K ceiling, one closed verdict enum, check_outcome separating outages from verdicts, fail-open as a non-authority guard.
  • String-anchor LLM fallback replacing the one-shot offsets route (REMEMBERSTACK_STRUCTURER_MODEL narrows to this seat); every fallback tree faces the terminal judge — gate demotions included — degrading to the synthetic root on terminal incoherence. No cycles.
  • Role pass: deterministic title rules → bounded title-only classifier (REMEMBERSTACK_ROLE_MODEL) → explicit body; failure degrades, never retries.
  • Provenance: five-generation split, immutable generations + current pointer seeded from route + selected-tree hash (a checker bump mints nothing unless the route flips), D52 append-only per-document check records with route tags, legacy backfill (migration p1_04_0019), D53 recorded N/A, hard-forget covering both new tables explicitly with scrub verification.
  • D66 docs: project-status truthful for the shipped route; deployment page + .env.example document the three structure seats.

Review trail

Codex (gpt-5.6-sol, xhigh) implemented; Grok-4.5 (3 MAJOR / 9 MINOR) and Opus (4 MAJOR / 11 MINOR) reviewed independently, both REQUEST-CHANGES; the second commit applies every finding — including Opus's measured quadratic prompt renderer (~5s CPU at 6K headings, now linear) and the generation-identity rule both reviewers caught from different angles. Final review and adjustments by Claude.

Gate

ruff clean, pyright 0 errors, 986 passed including the Postgres-gated suites (migration round-trip, backfill, forget scrub, P3 leak test). Benchmarks and the tool catalog untouched — engine-side only.

fazpu and others added 2 commits July 28, 2026 19:37
Use a dedicated flash-class title-only role seat because role assignment has an independent generation/version and bounded title-only contract; sharing the fallback seat would couple configuration and provenance.
Both reviews REQUEST-CHANGES; every finding applied:

- Generation identity seeds from route + selected-tree hash, never the
  checker version: a checker bump over an unchanged route derives the same
  id (ON CONFLICT no-op — no minted generation, no pointer churn), a route
  flip or different fallback tree genuinely appends. Two-run test locks it.
- blocks_from_sidecar (blockizer-owned, D57): a stale pre-metadata
  blocks.json re-derives blocks from document.md instead of dead-lettering
  queued STRUCTURE/CHUNK work; both handlers use it; produce-side
  validation stays strict. Tested with a genuine legacy sidecar.
- Hard-forget explicitly deletes document_structure_generations then
  document_skeleton_checks (FK order), verifies both in the scrub query,
  and the forget test seeds + asserts them.
- Every fallback tree faces the terminal judge: density/leaf gate
  demotions enter the same fallback -> terminal-check sequence (shared
  helper); generation rows now uniformly describe the SELECTED tree while
  check records describe candidates; design state machine clarified.
- Checker prompt rendering is linear (was quadratic: full re-render per
  candidate, ~5s CPU at 6k headings); sampling tag bumped to sample-v2.
- check_outcome hygiene: not_run_short renders no prompt and records no
  hash (nullable column); ValueError classifies as invalid_response for
  non-OpenRouter seats; provider_unavailable stays distinguishable in the
  failure envelope.
- level_jump_count uses raw heading levels only (d79-v2 stats): pairs
  missing a level are excluded, all-anchor trees report null — never the
  structurally fake zero the design warns about; checker lines render
  level=null honestly.
- Packing-vs-heading-metadata byte-equivalence regression; multi-section
  legacy backfill coverage; a non-current generation with a poison section
  provably never leaks into P3; migration downgrade documented one-way;
  out-of-scope ruff exclusion reverted.
- D66 same-PR docs: project-status describes the shipped parser -> check ->
  fallback route; deployment page + .env.example document the three
  structure seats and the narrowed STRUCTURER meaning.

Gate: ruff clean, pyright 0 errors, pytest 986 passed incl. Postgres.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKENhTLJg1HqhbdwCmmkbc
@github-actions

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  src/rememberstack/adapters
  openrouter.py
  src/rememberstack/core
  __init__.py
  blockizer.py 246, 252, 254
  chunker.py
  structure_skeleton.py 341, 343, 345, 450, 601, 603, 666
  src/rememberstack/model
  __init__.py
  blocks.py 41, 47
  documents.py
  model_provider.py
  sections.py
  src/rememberstack/profiles
  selfhost.py 387-393, 421-422
  src/rememberstack/spine
  catalog_contract.py
  chunk_catalog.py
  document_catalog.py 412
  src/rememberstack/spine/migrations/versions
  p1_04_0019_d79_structure_generations.py
  src/rememberstack/workers
  __init__.py
  e0.py 784-800, 860, 950, 953, 1077, 1142, 1224, 1259
  e1.py
Project Total  

This report was generated by python-coverage-comment-action

@fazpu
fazpu merged commit 7c5cb47 into main Jul 28, 2026
8 checks passed
@fazpu
fazpu deleted the feat/d79-structure-stage branch July 28, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant