Status: Adversarial Layer: Projection
§Scope
No purpose statement is recorded for this subsystem; the scope below states what it covers.
materializer/** and the promoted docs/ it renders
§Start here
amanuensis_materializer/core.py; renderers.py; readback.py
§Structure
What the survey recorded as claims about this subsystem, grouped by what each one states. Every claim is bound to the revision it was asserted at and to the evidence attached to it; a superseded claim is not shown here.
§Other claims
| Claim | Subject | Statement | Epistemic kind | Asserted at |
|---|---|---|---|---|
B-04/projection/a-refusal-leaves-the-previous-output-untouched | B-04 | Every way this renderer can fail leaves the published projection as it was. A missing required view refuses before the plan is built; an unknown nav group refuses before a byte is written; a renderer exception records the traceback and clears ok; a read-back mismatch clears ok; and clean publication renders into a staging directory, promotes only on a green summary, and removes the stage otherwise. The one destructive step — replacing the output directory — is additionally refused while the output holds a file no prior manifest claims. | Observation | c0734040022f |
§Vocabulary
- page plan — The list of pages the current store requires, computed once per render and used four times over: to decide what to write, what to link, what to navigate, and what the read-back must find.
§Known defects here
2 defects here are open or awaiting verification. Each one's full record, with its evidence, is on Open findings.
- The projection read-back's per-row stale-marker expectation set is empty for every real conspectus, so a projection that drops every stale marker still passes that part of the state axis; and the index page's stale reading is drawn from the same dead source. — B04-R1 · Medium · Open
- A clean publish can go red on the read-back's coverage axis with dangling anchors whose only distinguishing property is the length of the record prose beside them: shortening five long rationales returned all seven missing anchors and the next publish was green on all three axes. — B04-R2 · Medium · Open
§Standing
Adversarial — Candidate conclusions are being challenged; treat them as provisional. It cannot justify that the challenge pass has finished.
- Files read
- 24 of 94 ledger rows
- Files in scope, not yet read
- 0 of 94
- Files excluded from the survey obligation
- 70 of 94
- Ledger rows the repository has changed under
- 64 of 94
- Active concerns with a disposition recorded here
- 12 of 12 — 1 confirmed-bug, 8 confirmed-acceptable, 1 ruled-out, 2 out-of-scope
- Findings by resolution state
- 2 open
- Seams assessable from both sides
- no seam names this subsystem
§Survey record
§File ledger
| Path | Classification | Why in scope | Examined at |
|---|---|---|---|
materializer/.gitignore | examined | Local build state kept out of the tree. | c0734040 |
materializer/README.md | examined | The contract the renderer states for itself: what it produces, the three source kinds, and the self-contained HTML requirement. | c0734040 |
materializer/amanuensis_materializer/__init__.py | examined | The package surface: one exported class. | c0734040 |
materializer/amanuensis_materializer/core.py | examined | The orchestrator: the page plan, the diff-aware render decision, the global xref pass, the HTML projection, the retirement of orphaned pages, and the post-xref read-back. | c0734040 |
materializer/amanuensis_materializer/db.py | examined | The read-only open and the REQUIRED_VIEWS probe with the one fix it names — the reason an older store is refused rather than rendered short. | c0734040 |
materializer/amanuensis_materializer/diagrams.py | examined | The topology surfaces, and the atlas-not-graph rule: with no recorded edges the page says so and renders a subsystem atlas rather than asserting a dependency graph. | c0734040 |
materializer/amanuensis_materializer/html_projection.py | examined | The diff-aware materializer: the Python projection of the store. | 410d769b |
materializer/amanuensis_materializer/lint.py | examined | The orientation-prose lints: survey-status assertions shaped as assertions rather than matched as bare words, and the composite-index rule. | c0734040 |
materializer/amanuensis_materializer/manifest.py | examined | The per-page source-hash record, the version bump that invalidates everything, and prune_retired. | c0734040 |
materializer/amanuensis_materializer/readback.py | examined | The diff-aware materializer: the Python projection of the store. | ec5824bc |
materializer/amanuensis_materializer/renderers.py | examined | The diff-aware materializer: page renderers, read-back axes, and the HTML projection. | a521e28 |
materializer/amanuensis_materializer/slugs.py | examined | The deterministic routing every page and every xref target is derived from. | c0734040 |
materializer/amanuensis_materializer/vocabulary.py | examined | The diff-aware materializer: the Python projection of the store. | 410d769b |
materializer/amanuensis_materializer/xref.py | examined | The global cross-reference pass: code fences and existing links stashed, self-references rendered bold rather than linked, and every candidate path verified inside the output root. | c0734040 |
materializer/materialize.py | examined | The CLI: the three modes, the unmanaged-file refusal that protects a human's files from clean publication, and the stage/backup/promote sequence that leaves the prior output untouched on a red run. | ec5824bc |
materializer/pyproject.toml | examined | The ruff configuration the regression list runs. | c0734040 |
materializer/test-history-and-disagreements.py | examined | The diff-aware materializer: the Python projection of the store. | 410d769b |
materializer/test-ledger-freshness.py | examined | The diff-aware materializer: the Python projection of the store. | 410d769b |
materializer/test-lens-pages.py | examined | The diff-aware materializer: the Python projection of the store. | 410d769b |
materializer/test-materializer.py | examined | The diff-aware materializer: the Python projection of the store. | ec5824bc |
materializer/test-overview-truthfulness.py | examined | The diff-aware materializer: the Python projection of the store. | 410d769b |
materializer/test-readback.py | examined | The diff-aware materializer: the Python projection of the store. | 410d769b |
materializer/test-search-index.py | examined | The diff-aware materializer: the Python projection of the store. | 410d769b |
materializer/test-unmeasured-coverage.py | examined | The diff-aware materializer: the Python projection of the store. | a521e28 |
docs/.manifest.json | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/.projection-contract.json | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/architecture.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/architecture.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/concern-checklist.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/concern-checklist.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/concerns.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/concerns.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/contradictions.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/contradictions.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/diagnosticity.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/diagnosticity.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/disagreements.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/disagreements.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/entry-point.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/entry-point.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/field-notes.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/field-notes.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/files.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/files.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/findings.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/findings.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/hot-spots.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/hot-spots.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/how-to-read.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/how-to-read.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/index.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/index.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/master-plan.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/master-plan.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/not-yet-surveyed.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/not-yet-surveyed.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/onboarding-report.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/onboarding-report.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/open-questions.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/open-questions.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/resolution-history.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/resolution-history.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/resolved-findings.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/resolved-findings.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/resolved-leads.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/resolved-leads.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/seams.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/seams.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/search-index.js | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/sessions.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/sessions.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/stale.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/stale.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/subsystems/b01-survey-methodology-and-agent-contracts.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/subsystems/b01-survey-methodology-and-agent-contracts.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/subsystems/b02-mcp-core-persistence-and-lifecycle.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b02-mcp-core-persistence-and-lifecycle.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b03-knowledge-tools-and-workflow-api.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/subsystems/b03-knowledge-tools-and-workflow-api.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/subsystems/b04-diff-aware-materializer.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b04-diff-aware-materializer.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b05-packaging-installer-validation-and-product-docs.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b05-packaging-installer-validation-and-product-docs.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b06-report-interface-design-and-validation-studies.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b06-report-interface-design-and-validation-studies.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b07-embedded-research-surveys-and-platform-trials.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b07-embedded-research-surveys-and-platform-trials.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b08-activation-evidence-and-release-readiness.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b08-activation-evidence-and-release-readiness.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b09-conspectus-design-lanes-their-drivers-and-receipts.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/subsystems/b09-conspectus-design-lanes-their-drivers-and-receipts.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | 50abc288 |
docs/vocabulary.html | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
docs/vocabulary.md | generated-ignore | materialize_docs renders these pages and dev/promote-docs.mjs checks them in; they are the projection's output, not its source. | a7f9384d |
materializer/uv.lock | generated-ignore | uv writes this lockfile; it is resolver output. | a7f9384d |
§Concern review
AT-1
- Verdict
- Accepted behavior
- Evidence
- Code verified
- Linchpin dependency
- 🔗
Rationale
AT-2
- Verdict
- Out of scope
- Evidence
- Code verified
Rationale
CC-1
- Verdict
- Confirmed defect
- Evidence
- Code verified
Rationale
entries, a table no code path writes: readback.py:687's per-row stale-marker expectation set and renderers.py:696's index reading. The freshness strip beside them was migrated onto the ledger (B04-2's repair), so the page now shows a live count while the axis that is supposed to verify its markers computes an empty expectation set. Filed as B04-R1.CR-1
- Verdict
- Accepted behavior
- Evidence
- Code verified
- Linchpin dependency
- 🔗
Rationale
EP-1
- Verdict
- Accepted behavior
- Evidence
- Code verified
Rationale
IF-1
- Verdict
- Accepted behavior
- Evidence
- Code verified
- Linchpin dependency
- 🔗
Rationale
RL-1
- Verdict
- Accepted behavior
- Evidence
- Code verified
- Linchpin dependency
- 🔗
Rationale
SC-1
- Verdict
- Accepted behavior
- Evidence
- Code verified
- Linchpin dependency
- 🔗
Rationale
SI-1
- Verdict
- Out of scope
- Evidence
- Code verified
Rationale
SI-2
- Verdict
- Accepted behavior
- Evidence
- Code verified
- Linchpin dependency
- 🔗
Rationale
TB-1
- Verdict
- Accepted behavior
- Evidence
- Code verified
Rationale
TR-1
- Verdict
- Ruled out
- Evidence
- Code verified
Rationale
§Survey artifact
§B-04 — Diff-aware materializer
Structural account, read at c073404. Scope: materializer/** — the only Python in the product and the only reader-facing surface. docs/ is its output and is generated-ignore.
§Observed
One plan, four consumers. core.py:_plan computes the page list from the store; rendering, the HTML shell's navigation, the reader's-guide route table and the read-back's expected-path set all read it. A page cannot exist in one and not the others.
Diff-aware by source hash. .manifest.json records per page the identifiers it was rendered from (db:, prose:, synthetic:) and their hashes; a page is rewritten when a source hash changes, when its own content hash changes, when the file is missing, or when MATERIALIZER_VERSION moves. Pages whose generator disappeared are retired — file and manifest entry both.
Two formats, one source, read back independently. HTML is derived from the finished post-xref Markdown, and ProjectionVerifier checks state, coverage and content on each format separately, so a healthy Markdown cannot mask damaged HTML.
Refusal preserves the prior output. Absent required view, unknown nav group, renderer exception, red read-back, unmanaged file in the output directory — each leaves docs/ as it was. Clean publication stages, verifies, then promotes.
Derived predicates are generated, not restated. OBLIGATION_BEARING_SQL and the evidence-quality ladder come from the generated vocabulary module, so the renderer, the server and the lint cannot disagree about what carries an obligation or which rung is strongest.
§State containers
None held across calls. Manifest and Summary are per-run dataclasses; the SQLite connection is opened mode=ro and closed in a finally. Claimed as an explicit negative.
§Seam contracts from this side
memory.db— readmode=ro, never written. This side depends on the two viewsREQUIRED_VIEWSnames and refuses by name when they are absent.<storage>/docs/— written here, promoted bydev/promote-docs.mjs(B-09) to the repository's checked-indocs/.reporting-style.md(B-01) — specifies the typed projections this implements; nothing compares the two.
§Open
readback.py:687 and renderers.py:696 still read entries, a table no code path writes. Recorded as B04-R1.