--- name: project-studium-engine description: "Canonical Studium Engine workstream tracker — build state, governing instruments, live blocker, and the chronological log of substantive moves. Established 2026-08-07 at the MEMORY.md trim, filling the gap MEMORY.md had flagged as 'no tracker file yet'; state seeded verbatim from the MEMORY.md line it replaces." metadata: node_type: memory type: project originSessionId: 033cfe63-c9d0-4fad-accf-c45de561f09a modified: 2026-08-07T15:08:08.484Z --- # Studium Engine — canonical workstream tracker **Established 2026-08-07**, at the steward-directed MEMORY.md trim. Until now the engine had *no tracker file*, so its build state lived inline in `MEMORY.md` (one 950-character line) and in per-session memories. That is two update surfaces and no canonical one — the drift shape recorded as skill-harvest proposal #183. This file is now the canonical surface; `MEMORY.md` carries only a pointer. **This file holds state. It does not hold the *why* or the *law*:** - **Why** → [[project-studium-engine-telos-chamber-of-voices]] (the telos — above the build plan) - **Law** → [[reference-studium-engine-architectural-charter]] (`studium-engine/docs/the-studium-engine-architectural-charter.md`) - **Touchstone** → `~/_Dev/studium-engine/docs/the-chamber-touchstone.md` (read at Step 0 when lost in the trees) - **How we work here** → [[feedback-studium-engine-sixtus-v-collaboration]] (Sixtus-V: build freely, surface only vision-forks) - **Tool review** → `studium-engine/docs/tool-evolution-log.md` (read its §0) --- ## Current state (as of 2026-08-07 wake) **Build:** Steps 0–7 built. Corpus CLEAN and gate-validated **13/13**. **Governing instruments:** V1 `verify-quote` + `fidelity_equivalence@3` — ratified 2026-08-05, **GOVERNING** (REVIEWED-87 placed 2026-08-06). ⚠ **`@3` is under challenge.** PENDING-111 + a full jurist package filed 2026-08-06 (`studium-engine/docs/fidelity-3-literal-asterisk-JURIST-PACKAGE-2026-08-06.md`, containment 13/13): `_MARKUP_EMPHASIS = re.compile(r"[_*]")` strips the **escaped literal** `\*`, erasing Alexander's confidence rating (two asterisks = a true invariant, one = progress, none = far from invariant; "Using this book", pp. 14–15). Measured **81 / 114 / 54** across the manifested corpus. The ruling sets the V-track course. **Verified 2026-08-07: no ruling yet** — zero occurrences of `PENDING-111` in `~/dotfiles/REVIEWED.md`. It does **not** gate N1. **Read side — the parse fix LANDED, `27b79ca`.** `retrieve.py` now accepts a sentence; the query was previously passed to `MATCH ?` where FTS5 parses it as a *query expression*, so `?` and `:` were syntax errors. Result, answer-keyed against `tests/chavruta_harness.py`: | | | |---|---| | crashes | **26 → 0** | | HIT | **0/22** ← *the number to beat* | | MISLOCATED | **0** | | FALSE-POSITIVE | **0** (across all 5 items where silence is the correct answer) | Both deciding buckets empty ⇒ the revert condition was not met. **The engine now grounds nothing *honestly*** — every question needs **13–19 terms to co-occur**. Recorded explicitly as *the number to beat* so a later pass cannot mistake silence for progress. **Test floor (the read side's first):** `tests/test_retrieve.py` (21 checks) + `tests/chavruta_harness.py`. **`test_conjunction_is_monotonic` is the tripwire** against every future answer-more change — it must stay green. **Live blocker: PENDING-97** — retrieval AND-s bare tokens and has no semantic layer. Now reachable and *measurable* for the first time (the 13–19 term conjunctions above). ⚡ **The embedding arm already scores 22/22 recall@20**, voice-scoped, on the identical 22 items where FTS scores 0/22 (`corpus/measure-rerank-voicescoped.json`, verified same id-set). Capability measured in June, **never landed**. recall@20 means the right passage is in the top 20 *alongside nineteen others* — the answer-more direction — so **V2 is the gate that makes surfacing it safe.** Landing embeddings first would be the make-the-demo-nicer move. **NEXT: N1 → V2.** - **N1** — the navigation-tree builder. Contract written: `docs/spec/n0-navigation-tree-contract.md` §1 (the tree) and §2 (the four primitives: `list-children`, `open-node`, `expand-to-parent`, `load-whole-work`), including that `open-node` refuses citable text for a non-citable node. Do not re-derive it. ⚠ **N1 will NOT move 0/22** — that is N2, where the reasoner navigates; N1 lays the ground it walks on. ⚠ **Build the tree from the READING INDEX** (`chamber-library/reading-indices/*.yaml` — Alexander: all 253, re-found *by name*, ascending order verified, sha-bound), **not by parsing headings**: heading text hits three documented OCR defects (179 misnumbered 178 → a duplicate node; 187 lost its `##`; 195 has no heading). The harness's heading regex is a working reference, not the input. - **V2** — gold set + pre-registered thresholds. Follows N1 rather than PENDING-97 for the reason above. --- ## OPEN THREADS — the stack as of 2026-08-07 (captured mid-session, before the TEI detour) *Written because the session went N1 → `@3` → R0 → TEI-decision and each step opened threads. That accumulation is the thing the steward abhors; this block is the guard.* **Owed to the steward, not startable by the executor** 1. **REVIEWED-87 amendment — DRAFTED, NOT PLACED.** `studium-engine/docs/REVIEWED-87-amendment-DRAFT-2026-08-07.md` §A is the block to place. `~/REVIEWED.md` is `[ESCALATE]`, steward's hand. 2. **Three measured findings for relay to the jurist** (same draft, §B): the package's `≡` claim is false and its own table refutes it; condition (a)'s "verdicts that may have overclaimed" has an empty referent (the risk ran the other way — false *refusals*); Q1's grounds hold on the corpus side only. Q3 census: escaped emphasis in **3 of 13** sources, not "Alexander only". 3. **The TEI ruling itself** — agreed in shape (MD+sidecar canonical, proxy trigger retired, deferral becomes a design window), **not yet recorded**. Blocked on the mechanism below. **Executor-startable, in rough priority** 4. **N2** — the agentic navigation loop + embedding entry-finder fallback; discovery emits hypothesis-labelled output. This is the next N-track station and **the one that can move 0/22**. 5. **V2** — gold set + pre-registered thresholds; the gate that makes surfacing the embedding arm safe (22/22 recall@20 measured in June, never landed). 6. **Alexander `front_matter` re-anchor** — all five anchors stale (+20/+20/+22/+26/+32). Now *mechanical*: `python3 -m engine.reading_index recover` proposes; nothing is applied. Unblocks → 7. **The "Using this book" FIX** — a composite-span misclassification, **not** a D-4 policy change. D-4's own text: *"citability is a function of **convocation**, not an intrinsic byte property"*, with `citable:false` reserved for matter that is **nobody's** quotable voice. Alexander's framing essays are his own words (the sidecar's own note says so). Partition the span; don't flip a flag. 8. **R0 emit / migration** — `reading_index emit ` renders native R0; **nothing has been written to `chamber-library`** (D-3). Steward review before any write. 9. **The collision census** — count characters ambiguous between markdown syntax and authorial content, per source. The number the TEI question will eventually turn on; deferred behind the mechanism by steward call 2026-08-07. 10. **56 regions unverified** (Mauss 23 + after-the-reply 33) — editorial/synthetic titles, so name-landing cannot test them. A content probe at the declared boundary is owed. **Not this thread:** the Seb package · the L2 design note · PENDING-109 census + PENDING-104 brief, both still **needing dates, not "later."** ## Chronological log ### 2026-09-03 — state relocated from the MEMORY.md index at the load-integrity trim ⚠ **Provenance: this entry is the verbatim MEMORY.md index line**, moved here because the index had become this workstream's sole custodian — the log below stopped at 2026-08-13 while the index carried engine state through 2026-09-01, and MEMORY.md was over its load budget and being silently truncated at wake. Relocated, not rewritten; the pointer in the index is now one line. - [Studium Engine](project-studium-engine.md) — canonical engine tracker. **N0–N2 + R0 + `voice_stamp` built**; corpus **14 sources, trilingual**, fleet **9 suites / 285 green**. **fr cell: TWO STEPS FROM CLOSING.** **REVIEWED-133 (PENDING-137) RULED + EXECUTED 2026-09-01** (`2b30425`, `496cd7e`) — the cell-constant narrowing is now a *placed amendment*: `fr.stratum_amendments` carries **REVIEWED-121 and REVIEWED-133 as siblings** (what cond. 4 turned on). `undisclosed_days_in_force` **deleted, not corrected**; `direction` recorded as **INFERENCE, never measurement** — ⚠ *the narrowing removed the markers the claim turns on, so the before-state is unrecoverable from the file that carries the disclosure.* **NEXT: PENDING-134's disclosure** (⚠ what it now requires is **NOT obvious** — read REVIEWED-133's `If AUTHORIZED` **with** REVIEWED-121 point 9 before touching the file; deliberately not guessed at the wrap), **then `ratio_A_to_B` re-derived ONCE** (REVIEWED-116 pt 5). ⚠ **PENDING-134 was ruled REVIEWED-121 on 2026-08-14** — this line said "NEXT: rule PENDING-134" for 18 days and aimed the steward at the wrong target. ⚠ **PENDING-131 (c) never bound the engine** (`chunker.py` has `char_range` since Cluster A). ### 2026-08-13 — the fence was never blocked; the fr cell all but closed **REVIEWED-118 EXECUTED** (`e51e30d`) — authorized 2026-08-10, unexecuted for three days, found by substrate-checking the `**If AUTHORIZED:**` clause rather than reading it as status. L926's instances 6/12/16 retracted. Two decisions not implied by the ruling: `mauss-phase2-spans.yaml` is **generated**, so the record went into `scripts/bind_mauss_spans.py` too (a retraction in the emitted YAML alone is erased by the next run, with no diff); and that file measures **binding**, so the binding facts stayed and a cross-reference carries the retraction. **THE (b1) IDENTIFICATION PASS RAN** (`docs/fr-reported-speech-identification-pass-2026-08-13.md`), authorized at REVIEWED-116 pt 5 on 08-10 and never executed. **Reported speech in exactly 1 of 9 fr grounded spans** (L1551). The other eight are Mauss's own terminology, three self-marked (*"comme nous proposons de les appeler"*). ⚠ **Corrects REVIEWED-116 pt 6 rather than confirming it**: Mauss's 73 inline ≥120-char spans are a different population from the grounded set, of which only L926 and L1551 were ever members — **within the grounded set P7's F4 tagging was correct and complete.** ⇒ **PENDING-134's blast radius on inherited fr gold is ONE span.** **PENDING-135 (c) → REVIEWED-119 · PENDING-136 (c) → REVIEWED-120** (`de1c34b`, both placed by the steward). Instance 8 reclassified negative-candidate, marked in place; ⚠ **sub-type name OPEN** — §7.4(i) addresses the nested voice served *as* the host's, this **fuses** both. Count fields now carry their populations; bare `distinct_spans` retired. ⚠ **REVIEWED-119 pt 4 corrects PENDING-135's own blocking claim**: option (d) is constrained by `studium/v2-gold@1` §14.2 (`lines: [a,b]`) — **engine-side, D-1** — not by the chamber-locked `studium/meta@1`. Materially cheaper route. ⚠ **I committed 136's own error while executing it**: `bound_instances_grounded` 12 by subtraction, ignoring instance 17. Correct **10**; all counts now verified by enumeration. **`voice_stamp` BUILT** (`d411034`; `engine/voice_stamp.py`, suite 22; fleet **9 suites / 285**). ⚠ **AND MOVE 1 WAS NEVER BLOCKED.** PENDING-131 (c) is real for the **sidecar** and never bound the engine — `chunker.py` has recorded `char_range` document offsets since Cluster A. **The line-granularity ceiling was an artifact of where the fence was being WRITTEN, not of what the engine can SEE.** Paragraph-scoped pairing (not line-scoped) is what makes it work on hard-wrapped sources. **Reporter, deliberately NOT wired to abstention** — verdict semantics are unruled. **fr cell as of this wrap:** 11 listed spans / **8 grounded** (1 A + 7 B) / 2 reclassified / 1 retracted / **10** grounded bound instances. **`ratio_A_to_B` VOID** — re-derived ONCE after PENDING-134 lands and all dispositions are recorded (REVIEWED-116 pt 5). ⚠ **INSTRUMENT LESSON, and it is the day's most transferable:** the nested-voice census carried **five defects** and **four escaped its own controls** — every control was drawn from Mauss, so they exercised one quotation convention and one line structure, and could not see blindness to ASCII quotes (3 sources) or to hard-wrapped text (2 sources), both of which produced **clean zeros**. Only the fifth — a regression in an already-covered case — was caught by the controls. **A control set drawn from one source establishes nothing about a corpus.** ⚠ **PENDING-134's remaining blocker is a STEWARD CLIENT RESTART, not a build.** `governance-mcp.py` builds `FILES` at import, so the four V0-lane keys registered at `4c3758e` are not yet served. Executor half discharged: selftest 54/54, and two key descriptions that had gone stale the same day were refreshed (`92d5ad2`) so the jurist's first read is not of a stale index. *Append substantive moves here at `/wrap-up` — not only to "Current state" above. A tracker with two update surfaces drifts between them (skill-harvest #183).* ### 2026-08-08 — disposition (vi) RULED (REVIEWED-97), and `voice:` is the convocation key (`824139d`) **Ruled and placed.** REVIEWED-97 (PENDING-113) disposes kind (vi): **four slots, each one job** — identity `voice:` · relation `quoted_by:` · category (`traditional` / `non-individual-origin`, held **out** of the key) · per-source prose note. Reasoning of record: `docs/voice-non-individual-origin-2026-08-08.md`. Substrate findings kept in `docs/vi-disposition-DRAFT-2026-08-08.md` (superseded in part). **The correction that mattered.** The jurist's first structure put the category pair **in `voice:`**. `voice:` is what `retrieve.py:216` filters on, so that would have made the Havámál and the Mahābhārata **one convocable speaker**. Measured before asserting: `glidden` spans **5 sources**, `weil` **2** — correct, one person each. Aggregation principle, jurist's phrasing: *individual-author voices aggregate at the person because a person is real and singular; traditional matter has no such person, so identity lives at the work.* **Refuted by measurement:** option C (omit `voice`, let the relation carry it) — omission resolves to the host via `sec.get("voice", catalog.get("voice"))`. Control 4/4. **Corrections found in filed records.** Surah **LXIV** (at-Taghābun), not CXIV — the sidecar title was wrong and had reached REVIEWED-96, PENDING-113 and memory; it voided the jurist's worked provenance note, which was built on the *"Say"* formula absent from the quoted passage. `quotation-poet-jurist` reclassified from "unnamed individual" to traditional matter by one footnote. Naming evidence for six of nine blocks sits **inside the fenced apparatus**, engine-unreachable. **Fourth defect in `118f411`.** L850 (*"M. Cahen nous signale aussi la strophe 145 :"*) is Mauss's own prose, fenced inside the Havámál block — found only because the steward corrected a framing about language. And the `body` → `body-01..13` split left **`test_navigate.py` red for a full day** (stale hardcoded node id; the containment invariant itself verified intact). **Re-run the fleet after any sidecar/corpus change** — proposed as a pre-commit hook extension. **Filed:** PENDING-114 (scripture quoted unmarked in Harrison — Mark 16:7–8 served as `voice: harrison`) → steward **AUTHORIZED (b)+(c)** → **REVIEWED-98 placed same day** (verified clean, L1080). **PENDING-115** (two step-3 blockers: `ROLE_CLASS` has no `quotation` key, so such sections are searchable while classified outside the declared scope; and the warrant scope is computed per *source*, so a sub-source voice overclaims — 191 chunks of Mauss would warrant a Havámál silence). **NEXT (steward-agreed order):** the `quotation-in` × `translation-of` **jurist package** — all twelve blocks are translated matter and `role` is single-valued, so (vi) is **decided but inapplicable** until it is ruled. Then PENDING-114 (b), validation phase first. ### 2026-08-07 night — V2 preconditions worked; the corpus answered with a bigger question **P4** censused **14 sources** (parsed, not grepped — `grep -c '^ - id:'` gives 22 and reproduces the design addendum's "21" error; 8 numeric ids live under `corpus_findings`). **P1** verified clean. **P5 → span-binding, `73dfef3`:** P5's `content_located: 6` is *byte*-locatability; Tier-2 gold needs a bound **span** — **15 of 17 bind** (11 distinct spans), each corroborated twice (verify_quote locates + line sits at `stated − 1`). `corpus/mauss-phase2-spans.yaml`. ⚠ The first pass bound **0 of 11** on a criterion inherited from Tier-1; the **control (6 known answers, 6/6)** is what corrected it. **P7, `2a45c26`:** fr tagged **1 A : 9 B** — inverting P7's own prediction — and §6.3's French method produces B *by construction*, so **~8 stratum-A pairs must be authored and nothing schedules them**. **en is NOT taggable** (no spans, only division anchors; EN divisions run **~29×** the FR spans). **P6 still 0 bytes.** **Then the corpus-wide finding.** Mauss's `body` had no `role: quotation` region, so §7.4(i)'s provenance join did not exist. Fixed G&G (`57090ab`) and Mauss (`118f411`) — **and the jurist ruled the fix the wrong instrument.** **REVIEWED-96:** D-4's convocation governs; `citable: false` is for matter that is *nobody's* voice; §4.1 case 2 keeps a non-host voice **quotable** under a relation. **Q3's rule:** a quoted span grounds the host's **reproduction**, never the quoted author's **authorship**. **Q2 deferred** — the chunk invariant is *derived*; carry provenance at the **span layer** instead. **Q4** binds borrowed authority only; **(vi) anonymous/traditional matter GATES the Mauss remediation**. **Q5** upgraded to BLOCKING. **PENDING-113** lodged with the remediation order. ⚠ **`118f411` was mislabelled `[FIX]`** — corpus-wide policy under a scoped label, overriding a ratified default on the authority of a document whose front matter forbids acting on it pre-review, and **destroying the only human-verified §7.4(i) negative** (the Havámál, identified as a gold-negative candidate six hours earlier). Commits STAND pending the ruled order: **(vi) → re-tag → only then `citable: true`.** ### 2026-08-07 — PENDING-111 RULED, `@3` corrected in place (`4be9378`) Jurist: **Q1 AUTHORIZE** (narrow to *unescaped* delimiters), **Q2 correction-in-place** not an `@4` bump (mechanism defect against standing doctrine), **Q3** census follows non-gating, **Q4** steward's. `FIDELITY_VERSION` stays `@3`; **`@4` reserved.** Implemented as one left-to-right scan, not lookbehind-plus-unescape (that form mis-reads `\\*`). Falsifier incl. the jurist's **nested** case; suite 33, fleet **153/153**; gold **6/17 before and after — no verdict moved either way**. ⚠ **The REVIEWED-87 amendment is DRAFTED, NOT PLACED** — `docs/REVIEWED-87-amendment-DRAFT-2026-08-07.md`. `~/REVIEWED.md` is `[ESCALATE]`, steward's hand; a jurist sign-off does not authorize a REVIEWED write. ⚡ **Three measured findings contradict the package's own premises** (draft §B, for relay): (1) the `COMPOST\* ≡ COMPOST\*\* ≡ COMPOST` claim is **FALSE** — old `@3` gave three distinct strings and the package's own Part I table printed the refutation; (2) so condition (a)'s "verdicts that may have overclaimed" has an **empty referent** — the real failure was false *refusals*, the opposite risk direction; (3) Q1's grounds hold on the **corpus side only** — a human's bare `COMPOST**` still normalizes to `COMPOST`. **Census: escaped emphasis in 3 of 13 sources, not "Alexander only"** (Alexander 293 · Musil 16 · Arendt 1); ratings **83/114/56 over all 253**. **Also opened by this ruling (Q4):** D-4's primary text says *"citability is a function of **convocation**, not an intrinsic byte property"* and reserves `citable: false` for matter that is **nobody's** quotable voice. Alexander's framing essays are his own words — the sidecar's own note says so — so fencing them is a **misclassification against D-4, not D-4 working**. The `frontmatter` section is a **composite span** (YAML+TOC furniture + four Alexander essays) never partitioned. ⚠ Blocked: its partition points live in the reading index's `front_matter` block, and **all five of those anchors are stale** (offsets +20/+20/+22/+26/+32; three land on blank lines) while the `patterns` block in the same file is exact 253/253 — **the 2026-06-12 re-anchor was partial** and the manifest reports one status, `RE-ANCHORED-BOUND`, for a file bound in one region and stale in another. ### 2026-08-07 — N1 BUILT `engine/navigate.py` + `tests/test_navigate.py` (32 checks) + `docs/spec/n1-navigation-tree-note.md`. Tree: **9 works · 13 expressions · 359 divisions · 5,685 spans**; four N0 primitives + a browsable CLI. Fleet **142/142**, retrieval untouched. **0/22 unchanged, as expected.** **The derivation that mattered:** every sidecar declares exactly ONE served section (Alexander's `body` = 10,832 lines, "Patterns 1-253"), so the sidecar is the *envelope* and the reading index is the *articulation*. Adapters declared per index filename; unknown shape → `UndeclaredIndexShape`. **Three defects, all caught by measurement, none by reading the code:** 455 spans orphaned in gaps between declared divisions → 314 more in the no-sidecar source → citability reimplemented and diverged from `chunker.section_is_served` (latent). In the first two `load_whole_work` would have **silently under-returned**. `test_every_drawer_is_reachable` is the invariant; red-witnessed at 1,970. **Owed / open:** ⚠ **6 of 8 indexed sources cannot be name-tested** (editorial or synthetic division titles) — reported as an OPEN GAP, a content probe at the declared boundary is owed. ⚠ **Mauss's reading index is not sha-bound** to the manifested file yet the manifest declares `VERIFIED-BOUND`. **Two constraint-candidates for the steward:** (1) Alexander's confidence rating is in the source but *not declared* by the reading index, so the tree cannot carry it without a chamber-side change — converging with PENDING-111, where `@3` erases the same semantic; (2) a manifest `role: reading-source` with no sidecar is chunked as `role: text, citable: true` — citable by absence. ### 2026-08-07 — tracker established Created at the steward-directed MEMORY.md trim. State above seeded from the `MEMORY.md` line it replaces plus `session-2026-08-06-evening-the-asterisk-that-carried-meaning.md`; nothing dropped. Substrate-verified at creation: PENDING-111 has no ruling; `engine/` contains no navigation module and the four N0 primitives appear only in docs (N1 genuinely unbuilt); the N0 contract and the Alexander reading index both exist at the paths named. ### 2026-08-06 evening — the parse fix landed; the asterisk that carried meaning `27b79ca` — 26 crashes → 0, HIT 0/22, MISLOCATED 0, FALSE-POSITIVE 0. Semantics measured unchanged (old path vs new over all 27 items, not one disagreement); whole-query phrasing rejected because it answers *less* (1 where the conjunction returns 4). Silence path reached for the first time by long questions, so a silence now names its term count and states it cannot distinguish *"the voice is silent"* from *"the terms did not co-occur"*; an unsearchable query is marked **`✗ NOT SEARCHED`**, never coverage-warranted. Then the steward's printed *A Pattern Language* exposed the `@3` asterisk defect → PENDING-111 + jurist package. Manifest fixes `41527be`, `cbd6a9b` (a disarmed absent-sidecar tripwire; a usage fact in a bibliographic field; a defect record cited at `corpus_findings[1]`, a key existing in zero files fleet-wide). Full account: [[session-2026-08-06-evening-the-asterisk-that-carried-meaning]]. ### Before 2026-08-06 Not reconstructed here. Per-session memories carry it (`session-*.md`, 2026-07-05 onward for the Stage-1 rebuild), together with `studium-engine/docs/stage-1-rebuild-plan-2026-07-05.md` and `docs/tool-evolution-log.md`. Backfill on demand rather than speculatively.