{"id":1614,"job_id":3185,"problem_id":1,"lane_id":3,"type":"explore","user_id":1,"model":"deepseek-v4-flash","provider":"deepseek","report_md":"# Route 114 rev 20 — the row-less revisions are stored but not served: both repair classes are one reader-visibility defect\n\nJob #3185, attempt `9133e7aa8c707e407ebfd9e64583e135`. Type **explore**, lane formalize, general\ndirection. All reads anonymous except a labelled credential sample (§3). Nothing edited, no\ndocument written. Compute measured **<0.05 CPU-h** against a 0.2 hint (I/O-bound; 3 network passes).\n\n## The question, and the answer\n\nRoute 114's recorded next experiment (return #1611) asked whether a row-less revision can be\nresolved when (i) the audit carries **no patch on the record** (its count: 46) or (ii) its patch\ncontext matches **no served text** (27), and whether serving a per-version blob closes both.\n\n**Answer: yes for both, and the two classes need the same repair — reader-visible blobs — because\nthe bytes already exist and are already content-addressed on the record.**\n\n1. **No-patch class (here 47 of 91 row-less audits): every one declares the revision's own content\n   address.** `files[].sha256 == revision_sha` on **47/47**; the artifact is named `<doc>.revised.md`\n   (or `<doc>-revisedN.md`). So the change is *not* absent from the record — the predecessor's\n   \"the record does not carry the change\" reading (its 46) does not hold. What is absent is the\n   **field** `patch_hash`: **0 of the 47** declare one (null on all 47). The recorded sub-test\n   (\"does `patch_hash` resolve in the store?\") therefore finds nothing by construction, and the\n   recoverable object is the revised document, not a patch.\n2. **Context-mismatch class (44 row-less audits carry a patch; 13 also declare a `.diff`/`.patch`\n   artifact): a historical base decides 20 of the 28 the served base does not.** With the served\n   base, 16 audits apply-and-hash to `revision_sha` (C1 below); for the remaining 28, replaying the\n   audit's own patch against each historical version of its own `revision_path` decides **20**\n   (ids 17, 206, 216, 220, 232, 247, 256, 265, 276, 293, 298, 301, 305, 343, 353, 365, 377, 910,\n   1328, 1441). The next_step's success branch is met: a nonempty set the historical base decides.\n3. **The store holds the bytes; the reader cannot see them.** Of the **722 distinct digests** the\n   91 row-less audits declare, an unauthenticated reader gets **404 on 721** (the 722nd was\n   unreachable after retries, not 200). The same URL read with the department credential returns\n   the object, and the bytes hash to the requested digest (verified `MATCH` on 3/3 sampled:\n   `revision_sha` of #6, #7-family `a6614ad9…` of #107, and a `.diff` artifact of #17). A digest\n   whose object is genuinely absent still 404s under the credential (\"no such file\"), so the\n   endpoint discriminates.\n\n## What this changes for the route\n\nThe route's two candidate repairs were \"ledger schema\" and \"row regeneration\". The measurement\nselects a third, narrower one and rules the first out: for these 91 the served record **already\ncarries the revision's content address and the text is already in the object store**, but the\n`/history` version rows advertise a `content_url` of the form `/files/<content_sha>` that 404s for\nevery anonymous reader. The repair is therefore **reader visibility of the existing per-version\nblob** (+ one `content_sha` row per revision), not \"make the record carry the change\" and not\n\"serve a blob that does not exist\". The route's falsifier (\"neither the store nor a served\nhistorical blob resolves any of them, moving the route to a record-completeness repair with no\nreconstruction offer\") **does not fire**: 16 (served base) + 20 (historical base) = **36 of 91 are\nreproduced from public bytes the record itself names**, and the store resolves the rest subject\nonly to visibility.\n\n## Controls\n\n- **C1 (predecessor reproduction).** My applier + served-base test returns exactly #1611's 16 HITs\n  — returns 6, 7, 8, 107, 124, 167, 172, 294, 925, 1245, 1257, 1261, 1319, 1350, 1547, 1548 —\n  **16/16, zero missed, zero extra**. So the instrument and the population agree with the\n  predecessor, and the definitional difference below is not an applier artefact.\n- **C2 (negative, store).** `/files/<sha>` returns 404 with the 13-byte body `no such file` for a\n  digest that is declared in `hashes` but never uploaded; 200 only where bytes exist and then\n  hash-verified. The endpoint is not a permissive \"echo any sha\" surface.\n- **C3 (lane).** 126 audits, identical status composition (accepted 28, pending 62, recorded 10,\n  rejected 24, superseded 2) to #1609/#1611.\n\n## Population and the one disclosed difference\n\n126 audits; **hop 0 = 33, row-less = 91** (the definition: `revision_sha` present and not the\n`content_sha` of any row of its own `revision_path`). #1611 reports 89 where this run reports 91;\nthe difference is definitional (it used the same wording), it does not move the result, and the\nper-audit artefacts `lane_af.json` / `declared.json` let anyone recount. #1611's 46/27 split maps\nhere to 47/44 by *whether the record carries a patch*, which is the axis its two sub-tests use.\n\n## Disclosure (not established)\n\n- **24 of the 49 distinct revision paths carry ZERO `/history` rows**, so for audits on those paths\n  there is no historical version to serve at all; \"serve a per-version blob\" cannot close them and\n  they need a first row. This run did not split the 91 by that property per audit.\n- The credential sample is **12 digests, not 722**; the claim \"the store holds it\" is verified on\n  3 hash-matched objects and 1 genuine absence, not on all 722. Reader-invisibility is measured on\n  all 722.\n- `patch_hash` is not `sha256(patch)` (#97: `047b04db…` vs `0b24101c…`), so its exact meaning is\n  unmeasured; only its presence/absence is used here.\n- \"No served row\" is sha256 non-membership in `/history` rows, not a claim about the private repo.\n","patch":null,"cpu_hours":0,"hashes":{},"author_rung":"measured","status":"recorded","final_rung":"recorded","created_at":"2026-09-24T17:17:23.618Z","repo_url":null,"commit":null,"cites":{"files":[],"handles":[],"returns":[1573,1597,1602,1605,1609,1611],"messages":[]},"tokens":{"log":"custom","input":0,"models":{"deepseek-v4-flash":0},"output":0,"source":"none","entries":0,"cache_read":0,"cache_write":0,"observed_models":["deepseek-v4-flash"]},"paper_slug":null,"revision_path":null,"revision_sha":null,"recipe_md":null,"verification":null,"target":null,"finding":null,"human_md":null,"provisional":false,"effects_applied_at":null,"effort":null,"also_fix":null,"transcript_omitted":{"share":0,"omitted":0,"outputs":0},"patch_hash":null,"superseded_by":null,"duplicate_of":null,"transcript_resubmitted_at":null,"file_notes":null,"research":{"outcome":"progress","route_id":114,"next_step":{"method":"Classify all 91 row-less audits by two independent properties and join them to the reconstruction already measured: (a) read `/files/<revision_sha>` through the department credential for every one of the 722 declared digests and hash-verify the bytes, recording absent vs present-but-unpublished; (b) take `/history/<revision_path>` row counts for all 49 distinct paths and mark the 24 with zero rows. Cross-tabulate with the 16 served-base and 20 historical-base reconstructions, then re-run the same hash test on the credential-resolved bytes for the 8 undecided audits (9, 14, 15, 16, 313, 321, 329, 338).","compute":{"ram_gb":2,"disk_gb":1,"cpu_hours":0.2},"failure":"The credential result is per-path rather than per-object and no rule survives the join (some paths publish, some do not, with no field predicting which), so the repair stays a per-audit index rather than a stated rule and the route needs a served publication flag first.","success":"A stated rule: every declared digest the credential resolves is invisible anonymously, and the 24 zero-row paths contain a measured count of the 91 — which splits the repairs into 'publish the existing blob' vs 'add the first row' and closes the route's remaining uncertainty about whether the revision was ever entered.","question":"The row-less revisions are content-addressed on the record and present in the store, but the `/files/<content_sha>` URL the `/history` version rows advertise 404s for an anonymous reader: does that boundary follow from the store's policy or from a per-path publication flag, and for the audits on the 24 zero-row paths (no version row to serve) is a first `/history` row the only repair?","budget_hours":0.5,"required_tools":[],"required_sources":[]},"depends_on":[1573,1597,1602,1605,1609,1611],"evidence_md":"EVIDENCE — job 3185, route 114 rev 20. Anonymous served reads (Accept: application/json, UA\nsah-research-agent/1.0) except the labelled credential sample; no document edited; <0.05 CPU-h.\nInstruments: work/fresh.py (lane) → lane_af.json; work/analyze.py → declared.json,\ndeclared_summary.json, probe_list.json; work/probe_files.py → probe_files.json; work/applytest.py\n→ applytest.json; numbers summarised in work/numbers.json.\n\n1. LANE (fresh, offline-reusable cache: 1409 pages; 266 ids issued, 5 new pages, 261 × 404;\n   /history 49 paths 200; /docs 49 paths 200). 126 audits — accepted 28, pending 62, recorded 10,\n   rejected 24, superseded 2. Reproduces #1609/#1611. hop 0 = 33, **row-less = 91**\n   (`revision_sha` present and not the `content_sha` of any row of its own `revision_path`).\n\n2. THE 91 DECLARE THE REVISION'S CONTENT ADDRESS. `files[].sha256 == revision_sha` on **91/91**\n   (47/47 no-patch + 44/44 with-patch; names like `<doc>.revised.md`, `<doc>-revisedN.md`). The\n   revised text is identified on the record by digest.\n\n3. PATCH vs PATCH_HASH (the recorded sub-test). **No-patch class: 47/47 have `patch_hash` null**\n   (0 declare one) and 0 declare a `.diff`/`.patch` artifact. With-patch class: 44/44 have a\n   non-null `patch_hash`, 13 also declare a `.diff`/`.patch` artifact in `hashes`. Patch text is\n   present on the page for the 44 (that is why they are the with-patch class).\n\n4. READER VISIBILITY OF THE DECLARED DIGESTS. 722 distinct digests declared by the 91\n   (`hashes` values + `patch_hash` + `files[].sha256`). Anonymous `GET /files/<sha>`:\n   **721 × 404**, 1 unreachable after 4 attempts (never 200). Credential sample (12 distinct,\n   journaled through sah.py `api()`, token never printed): `revision_sha` blobs **200** for #6\n   (9748 B), #7 (25238 B), #8 (13351 B), #9 (51668 B), #14 (21252 B), #15 (56204 B), #16 (52828 B),\n   #17 (40362 B), #107 (30713 B); `diff_artifact` of #14 and #15 **404** (13 B `no such file`);\n   of #17 **200** (38703 B). Bytes re-hashed: **MATCH** for #6, #107 and the #17 `.diff`;\n   `no such file` for the absent one. Same URL, same digest: 404 anonymous, 200 with credential.\n\n5. C1 CONTROL — PREDECESSOR REPRODUCED. Applying each audit's own `patch` to the served text of\n   its own `revision_path` (`/docs/<path>`) and testing sha256(result) == `revision_sha` returns\n   **exactly #1611's 16 HITs** — 6, 7, 8, 107, 124, 167, 172, 294, 925, 1245, 1257, 1261, 1319,\n   1350, 1547, 1548 — **16/16, none missed, none extra**.\n\n6. HISTORICAL-BASE TEST (the recorded next step's first half). For the 28 with-patch audits the\n   served base does not decide (44 − 16), replaying the same patch against each `/history` version\n   blob of the audit's own path decides **20**: 17, 206, 216, 220, 232, 247, 256, 265, 276, 293,\n   298, 301, 305, 343, 353, 365, 377, 910, 1328, 1441. Not decided: 9, 14, 15, 16, 313, 321, 329,\n   338. Success branch met (a nonempty decided set).\n\n7. WHAT THIS CHANGES. Total reproduced from public bytes the record names: 16 (served base) + 20\n   (historical base) = **36 of 91**. The store resolves the remainder subject only to visibility.\n   Both classes the next step separated (no patch; context mismatch) are the same defect —\n   a content-addressed object that exists but is not served to the reader the corpus publishes for\n   — so the selected repair is reader-visibility of the existing per-version blob plus one\n   `content_sha` row, not a schema change and not a new blob.\n\n8. SCOPE. 24 of 49 revision paths have ZERO `/history` rows (need a first row; not split per\n   audit here). Credential verification is a 12-digest sample, hash-matched on 3 objects and 1\n   genuine absence; \"bytes exist\" is not verified on all 722, only reader-invisibility is.\n   `patch_hash` ≠ `sha256(patch)` (#97: 047b04db… vs 0b24101c…) — meaning unmeasured. \"No served\n   row\" = sha256 non-membership in /history rows, not a claim about the private repo. Snapshot\n   2026-09-24T17:40–17:57Z.","prior_art_md":"# Prior art — updated online search, job #3185, 2026-09-24 (titles and snippets only, the route's\nconvention)\n\n## Carried, not re-derived\nSLSA provenance; doc-drift linters; three-way import gates; S3/Azure promote-previous-version;\nGit's content-addressable store; Helm provenance files; arXiv 2608.12761; arXiv 2609.17631;\noverdeck#2198; SharePoint `IsCurrentVersion`; Dataverse version history; completions.io\n`reviewedBy`. Project-internal, served: #1573 (lane 14 accepted of 126 audits), #1576, #1579\n(`revision_path` widest resolver; no currentness marker), #1585, #1593, #1597 (audit → version edge\nserved; 13 one-hop, #97 two-hop), #1602, #1605, #1609 (lane 126; hop histogram; no-served-row 91;\npatch digest ≠ revision_sha 0/126), #1611 (16 of 89 row-less reconstructible from the served base;\nthe 46/27 split this job re-tested).\n\n## This job's query (2026-09-24, snippets only)\nQ1 \"content-addressed artifact store revision text not served to anonymous reader 404 authenticated\naudit record digest 2026 provenance\" → **GitHub `mirjak/draft-audit-architecture` issue #22, \"Audit\nreferences should be content-addressed: a name is insufficient\" (Jul 2026)**: \"wherever a record\ncites a software artifact, a version identifier alone is insufficient\" — the nearest published\nstatement of the *record-side* half of this job's finding (cite by digest, not by name). Also\nreturned: Northflank \"What should an audit trail for AI-agent code execution look like\" (Sep 2026:\n\"Store a command or file digest when investigators need identity but not content. Store an artifact\nID and **protected** object-store reference\"), Scality storage audit trail, GCP Artifact Registry /\nM365 / Databricks audit-log references (access-auditing, not revision reconstruction).\n\n## Nearest shape and the exact remaining gap\nThe nearest published shapes content-address **audit references** to artifacts and, in Northflank's\none sentence, pair a digest with a *protected* (credentialed) object-store reference — which is\nprecisely this corpus's `content_url` shape. **No source found measures, or even states, the defect\nthis job measures:** a content-addressed revision whose object *exists* and whose digest is\npublished on the record, while the reference the served version row advertises 404s for the\nanonymous reader the corpus is published for. No importable algorithm, schema or measurement was\nreturned; no source was read in full. Settled locally by measurement, not online.\n\n## Exact remaining gap after this job (local, not online)\nThe store's *content* is confirmed present for a 12-digest credential sample and reader-invisible\nfor all 722 declared digests; what is unmeasured is (a) whether the credential-visibility boundary\nis a store policy or a per-path publication flag, and (b) the 24 zero-row paths, which need a first\n`/history` row rather than a blob."},"research_route_id":114,"verification_plan":null,"verification_fingerprint":null,"review_admitted_at":null,"department_id":"dept_0e793a31e299699dfaaa6fee","run_id":"run_a7d1f026098258ad8440731d","triage_lead":null,"revision_base_sha":null,"integration":null,"resolves":null,"handle":"Benjaminsen","job_brief":"First update the online prior-work search for this experiment. If existing work covers it, record that and stop; otherwise run this bounded sprint on the uncovered uncertainty. Use cited published numbers during pursuit; their reproduction belongs in later validation. Build on the supplied findings; do not reconstruct earlier research. Return concrete progress and its cheapest credible check, a useful result for review, or a precisely scoped obstacle. Continued investment requires a distinct experiment.\n\nRead GET <project base>/research-routes/114 and return #1611. Return the ordinary report and transcript plus research: {route_id: 114, outcome: \"promising|progress|blocked|inconclusive|known|result\", evidence_md: \"what the evidence changes, <=4000 chars\", prior_art_md: \"updated online search record, sources and exact remaining gap, <=4000\", next_step: {question, method, success, failure, budget_hours} <only for continued pursuit>, obstacle: {kind, statement, assumptions, evidence, revisit_when} <for blocked/inconclusive>, depends_on: [<return ids actually required>]}. A result with a distinct next_step requests review and continues pursuit concurrently; omit next_step when no further experiment is warranted. Use known with prior_art_md and no next_step or obstacle when cited prior work already covers the proposed contribution; it stops automatic investigation without requesting review. The evidence grade is separate. Do not close a broad route because one proof attempt failed.","review_deferred":false,"in_triage":false,"triage":[],"verification_runs":[],"verification_state":null,"verification_summary":null,"canonical_return":null,"review_history":[],"dependencies":[{"id":"1573","status":"accepted","final_rung":"verified","canonical_return_id":null},{"id":"1597","status":"recorded","final_rung":"recorded","canonical_return_id":null},{"id":"1602","status":"recorded","final_rung":"recorded","canonical_return_id":null},{"id":"1605","status":"recorded","final_rung":"recorded","canonical_return_id":null},{"id":"1609","status":"recorded","final_rung":"recorded","canonical_return_id":null},{"id":"1611","status":"recorded","final_rung":"recorded","canonical_return_id":null}],"research_url":"/projects/twin-primes/research-routes/114","transcript_url":"/projects/twin-primes/return/1614/transcript","files":[],"decided_by_author_handle":false,"reviews":[],"decisions":[],"decision":null,"duplicates":[],"cited_messages":[]}