DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path change-requests/cr-2026-194-loomworks-b60-provenance-to-memory-v0_1.md

DUNIN7-M4 — INFRASTRUCTURE CHANGE REQUEST

CR-2026-194 — B-60: where a document came from is shown once, then dropped (v0.1)

Version. 0.1 · Date. 2026-08-09 · Author. Claude.ai (drafting) / Marvin Percival (approving). Target. /Users/dunin7/loomworks-engine, branch main. Baseline. Engine ae58d34. CC confirms exact HEAD at Step 0. Companion to. CR-2026-181's Step 1 report, where this was found while adding spreadsheet and slide-deck ingestion; standing-notes/dunin7-build-list-v0_49 (B-60). Charter. Autonomous regime. Status. Ready for CC execution, with a read-first Step 1.


1. Summary

The upload pathway captures structural provenance during extraction — which heading a passage sat under, which page, which sheet — and returns it on the HTTP response. The Memory event then writes an empty list. So the structure reaches the screen that uploaded the document and is discarded before it reaches Memory.

This affects .docx today and .xlsx / .pptx from the moment they landed. The dropping is deliberate: the code comment calls it a v1 gap and names itself a follow-on. This is that follow-on.

Sourced, not asserted. The two sites — the response at uploads.py:468 returning list(result.per_step_provenance), and the Memory write at :956 passing [] — come from CR-2026-181's Step 1 report. CC verifies both against the code at Step 1 rather than trusting this paragraph.


2. What B-70's ratification does not cover

Historical uploads cannot gain provenance, and this CR must not try.

The ratification settled that an operational identifier which is derived, verifiable, and determined by facts already in the log may be backfilled — because the backfill computes what was always true. Extraction provenance fails every part of that test. It was observed at ingestion, from a file that may no longer exist, by an extractor whose version may have changed. Nothing in the log determines it, and recomputing it would produce a fresh observation presented as an old one.

So: this CR fixes the path forward only. Documents already in Memory keep no structure, and that is the correct outcome, not a shortfall.


3. Step 1 — read before building

CC establishes and reports:

  1. Why the write is empty. The comment calls it a v1 gap. Is that the whole reason, or is there a constraint behind it — payload size, a schema that cannot carry the shape, a serialization concern? If there is a real constraint, halt and report rather than working around it.
  2. What the event payload can carry. PerStepProvenance.details is a free-form dict, already carrying per-page PDF markers and OCR path metadata. Confirm the event schema can hold the same shape, and what it costs in payload size for a realistically large document.
  3. Who reads it downstream, if anyone. If nothing consumes provenance from Memory today, this CR makes data available that has no reader yet. That is fine — but it should be known, and it changes what "done" means.
  4. Whether the same drop happens anywhere else. One deliberate [] suggests the pattern may repeat. Report what you find; fix only what is in this path.

4. Scope

Carry per_step_provenance through to the Memory event instead of writing an empty list.

Tests. An upload of each supported type — at minimum .docx, .xlsx, .pptx, PDF — results in a Memory event whose provenance matches what the extraction produced. Not "is non-empty": matches, since an empty-vs-populated assertion is the vacuity shape this project keeps catching.

Observe the failure. Per the standing note, revert the change and confirm the tests fail, with messages naming the invariant.


5. Out of scope


6. Seed-mutability impact

B-69 applies. Extraction provenance is a record of how something entered Memory; if any part of it reads or derives from seed state, record the contact point with its Kind label. Likely Kind C — record it as one if so.


7. Build steps

| Step | What | Mode | |---|---|---| | 0 | Pre-flight. | Auto | | 1 | Read per §3. Report all four. Halt if a real constraint sits behind the empty write. | Auto, conditional halt | | 2 | Carry provenance through to the Memory event. | Auto | | 3 | Tests per §4, observed failing first. | Auto | | 4 | Full engine suite; ruff 0; mypy at/below baseline. | Auto | | A | Checkpoint. | Checkpoint | | 5 | Tag cr-2026-194-b60-provenance-to-memory. Push. | Auto |


8. Acceptance gate

  1. An upload's structural provenance reaches the Memory event and matches what extraction produced, for every supported type.
  2. Historical uploads are unchanged, and the completion record says so as a deliberate outcome with §2's reasoning.
  3. Payload-size cost for a realistically large document reported, whether or not it is a concern.
  4. Step 1's four findings recorded, including if nothing downstream reads provenance.
  5. Full suite green, both gates clean. Seed-mutability check recorded, including as a null finding.

9. Kickoff prompt


Execute CR-2026-194 v0.1 at ~/Downloads/cr-2026-194-loomworks-b60-
provenance-to-memory-v0_1.md. Confirm the CR number against the ledger
first.

B-60: extraction captures structural provenance, the HTTP response
returns it, and the Memory write passes an empty list. So the structure
reaches the uploading screen and is dropped before Memory. Affects
.docx today and .xlsx/.pptx since they landed.

§1's two file references come from your own CR-2026-181 Step 1 report.
Verify them against the code rather than trusting my paragraph.

Step 1 asks why the write is empty. The comment calls it a v1 gap —
find out whether that's the whole story. HALT if a real constraint sits
behind it (payload size, schema shape, serialization) rather than
working around one.

§2 matters: B-70's ratification does NOT cover this. Provenance is not
derived-and-recomputable — it was observed at ingestion, from a file
that may not exist now, by an extractor whose version may have changed.
Historical uploads keep no structure and that's correct, not a
shortfall. Do not backfill.

Tests assert provenance MATCHES what extraction produced, not that it's
non-empty. Non-empty is the vacuity shape.

Report if nothing downstream reads provenance from Memory. That's fine
but it should be known — it means this makes data available with no
reader yet, which is a build-list item rather than a reason to stop.

DUNIN7 — Done In Seven LLC — Miami, Florida CR-2026-194 — B-60 provenance to Memory — v0.1 — 2026-08-09