DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path change-requests/cr-2026-130-upload-content-reaches-memory-v0_1.html

CR-2026-130 — Upload Content Reaches Memory

Version. 0.1  ·  Date. 2026-07-01
Status. Drafted, not executed. Completes Room 1 (Memory) intake. Base: main @ 2abcfd1 (post-CR-2026-129). Number 130 confirmed free at staging.
Grounded on. seed v0_12 (§Memory line 43 — intake commitment), manifest v0_72, upload-pathway ground-truth v0_1 (loomworks-record 7138184).

Plain-language summary

You can upload files and images today — they store, and images are even interpreted by the vision skill. But the interpretation gets dropped: it never becomes a Memory assertion, so you can't confirm it, recall it, or reason over it. An uploaded photo of Fenwick's leaf produces a description that goes nowhere.

This CR wires the last connection: an uploaded image's description (and a document's extracted content) becomes a held assertion you confirm — flowing through the same capture→confirm→commit grammar as a spoken note. Upload a photo → the machine describes it → proposes it as a held note ("I see a Monstera with a new fenestrated leaf — save this?") → your confirm commits it to Memory. The file is stored AND its content becomes recallable memory.

This completes Room 1's intake: Memory can now take in what you hand it, not only what you speak.

The seed already commits to this (grounding)

Seed §Memory line 43: a contribution carries how it arrived — "typed, spoken, extracted from a document, described from an image." The seed already names described-from-image and extracted-from-document as first-class contribution kinds with automatic lineage. Line 45: "A correction is a contribution. A retraction is a contribution. Both are preserved" — the append-only assertion model.

So this CR does NOT introduce a new commitment — it closes the gap between the seed's standing commitment (intake includes described-from-image / extracted-from-document, as contributions) and the current Rail-B code (which interprets but drops the result at event grain). We make the code honor what the seed already says. No seed conflict; the seed mandates the target.

The mechanism (how extraction/description becomes a held assertion, the routing, storage) is specification-level, governed by the comprehensive specification — this CR builds the mechanism for the seed's commitment.

What already works (reuse as-is — from the ground-truth investigation)

The one substantive net-new piece

Wire Rail B's interpretation output → held assertion. Today uploads.py:661 hardcodes assertions_drafted=[], and no consumer converts the interpretation into an assertion — the description lives only as an object-store blob + an upload_event_received row, unreachable by recall (recall reads committed assertions only).

The fix: when an upload is interpreted (vision describes an image, extraction summarizes a document), call add_assertion with the interpretation as content, producing a held assertion with provenance recording the "how" (described-from-image / extracted-from-document, per seed §Memory line 43) and lineage to the source file. It enters the capture→confirm→commit loop: proposed as held, the Operator confirms (machine describes → proposes → human approves — Operator-authority). Mirror Rail A (image_description.py / contributions.py:280) as the reference implementation.

The supporting fixes

  1. Default image upload to vision. Today an image matches three skills (vision/ocr/metadata); with no message the executor's disambiguation scores all three 0.0 and returns needs_clarification BEFORE running anything (the "0% picker" / blank "I think this is —"). Fix: an image with no explicit skill request defaults to vision (describe) — the common case — rather than dead-ending at disambiguation. OCR/metadata remain available when explicitly requested. (Consistent with "only show what is available" — removes a dead-end picker rather than adding one.)
  2. Vision key for dev. Vision resolves its key from DB (system_config.loomworks_llm_key / engagement key), not an env var. Confirm it's populated so vision can run in dev; if absent, the failure must surface truthfully (transformation_failed with a clear message), NOT silently produce no description. (Truthfulness — same discipline as Finding 3.)
  3. MinIO availability in dev. put_blob → 503 if no live MinIO. Ensure a dev MinIO is available or the failure surfaces truthfully. (Environment, not code — confirm/document.)

Deferred (recorded, not in this CR)

What must NOT change

Tests

Pass condition

An uploaded image or file becomes a held assertion (machine describes → proposes → Operator confirms) that is recallable Memory, with provenance recording it as described-from-image / extracted-from-document. The file is also stored. Failures surface truthfully. Verified at runtime by uploading a real image and confirming it enters the held tray, commits on confirm, and recalls. Suite green.

After this lands — Room 1 (Memory) is complete

Room 1's intake works: Memory takes in files, folders, and images (with interpreted descriptions), not only spoken/typed notes. Combined with the four conformance findings (120/127/128/129), the Memory room does its full job — accumulate with provenance, from every intake path — and is genuinely done.

Then the queue (unchanged): semantic-meaning foundation (recall + correction-recognition + routing substrate), content-to-engagement routing consistency, held-tray robustness edges (incl. dismiss-verb/number-resolution, over-eager-capture), wide-net reduction, boundaries arc.

DUNIN7 — Done In Seven LLC — Miami, Florida · Loomworks — CR-2026-130 — Upload Content Reaches Memory — v0.1 — 2026-07-01