Skip to content

Say what a read-only run actually does - #488

Merged
MongLong0214 merged 1 commit into
devfrom
prd-writes-wording
Aug 8, 2026
Merged

Say what a read-only run actually does#488
MongLong0214 merged 1 commit into
devfrom
prd-writes-wording

Conversation

@MongLong0214

Copy link
Copy Markdown
Owner

Closes #473. Documentation only.

The promise was false, and a test found it

§8.2 said zero writes. Writing §11's read-only test strictly is what found it: a plain run touches index.db-shm, and --fix creates that and -wal.

Those are SQLite's bookkeeping for a WAL database — created by opening one at all, for readers as much as writers — and they hold no committed data.

Two ways to close it, and why this one

Making the run literally write-free means opening the index outside WAL for doctor, which trades a documentation problem for the concurrency one #420 was about.

So the document moves instead, and states the invariant that carries the meaning: index.db is byte-identical after a plain run, including under failure, and nothing else in the repository changes but those two sidecars.

The §11 acceptance row moves with it. A table still saying "zero writes" while the test asserted something narrower would leave the next reader to discover which one to believe.

Why not just scope the test

The document is what a reader checks the code against. A test quietly narrower than the promise it implements is the arrangement this milestone exists to remove.

Three read-only invariant cases pass against the amended wording.

Stated

The exception is named for SQLite specifically — a future dependency that touches the filesystem on open needs its own line. And --fix creates the -wal file a plain run does not, so the two paths differ in what they leave behind even though neither writes data.

Section 8.2 promised zero writes. Writing section 11's read-only test strictly
is what found the promise false: a plain run touches `index.db-shm`, and `--fix`
creates that and `-wal`. Those are SQLite's bookkeeping for a WAL database,
created by opening one at all, for readers as much as writers, and they hold no
committed data.

Two ways to close the gap. Making the run literally write-free means opening the
index outside WAL for doctor, which trades a documentation problem for the
concurrency one #420 was about. So the document moves instead, and states the
invariant that carries the meaning: `index.db` is byte-identical after a plain
run, including under failure, and nothing else in the repository changes but
those two sidecars.

The acceptance row moves with it. A table that still said "zero writes" while
the test asserted something narrower would leave the next reader to discover
which one to believe.

Limit: the exception is named for SQLite specifically, so a future dependency that touches the filesystem on open would need its own line rather than being covered by this one
Ruled-out: opening the index outside WAL so the promise becomes literally true | it reintroduces the concurrency failure #420 fixed, to make a sentence accurate
Ruled-out: leaving §8.2 and scoping only the test | the document is what a reader checks the code against, and a test quietly narrower than the promise it implements is the arrangement this milestone exists to remove
Warn: `--fix` creates the `-wal` file that a plain run does not, so the two paths differ in what they leave behind even though neither writes data
Blast: local
Undo: easy
Certainty: firm
Verified: the three read-only invariant cases pass against the amended wording, asserting `index.db` equality and a filtered inventory rather than an unqualified zero
Provenance: authored
Record-Id: r-prdwrites
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

CommitLore — record lint

Trailers: clean — 1 commit in origin/dev..afd48df9b69868fa7084e625414ecb505cc138a8
Active constraints: 3 limits · 9 ruled-out · 3 warnings — from 3 records over 1 changed path

Active constraints for the paths this PR touches

Limits (3)

  • r-prdwrites afd48df — the exception is named for SQLite specifically, so a future dependency that touches the filesystem on open would need its own line rather than being covered by this one
  • r-adr32rev 6955e81 — documents only -- src/ and test/ are untouched, and the two checks this revision specifies (notes-availability, capture-liveness) do not exist yet
  • r-adr32doc f35921e — this lands the model and the specification only; no check changes behaviour and the shipping report is byte-identical until the registry work begins

Ruled out (9)

  • r-prdwrites afd48df — opening the index outside WAL so the promise becomes literally true | it reintroduces the concurrency failure Concurrent hooks make half the injections fall back to a full scan, because no SQLite busy timeout is set #420 fixed, to make a sentence accurate
  • r-prdwrites afd48df — leaving §8.2 and scoping only the test | the document is what a reader checks the code against, and a test quietly narrower than the promise it implements is the arrangement this milestone exists to remove
  • r-adr32rev 6955e81 — keeping "SPEC forbids doctor exiting 3" | spec/SPEC.md line 274 names an unfetched notes mirror and shallow history as code 3's own examples, so the prohibition claim was false and saying so plainly beats softening it
  • r-adr32rev 6955e81 — degrading the aggregate on every non-optional skip | doctor.ts lines 628, 699 and 942 skip on ordinary healthy repositories, which made ok permanently unreachable
  • r-adr32rev 6955e81 — a capture-recency heuristic to close the produced-then-stopped case | SPEC line 155 makes a record per commit optional, so recent recordless commits are not evidence of breakage; the gap is named open in PRD §2.2 instead of guessed shut
  • r-adr32rev 6955e81 — dropping --only and --category as the review suggested | they are filters over registry data feeding the partial-honesty rule, not new code paths, and the disagreement is recorded in the ADR's Rejected section with that reason
  • r-adr32doc f35921e — a manual status, as the Swift reference has | it exists there for operator attestations the OS cannot query, and every CommitLore remediation is a command, so a status nothing emits is dead contract surface
  • r-adr32doc f35921e — the reference's 0/1/2/3 strict exit mapping | SPEC §10 fixes 2 as "could not run" and 3 as "could not see everything" for every command, and RELEASE-GATE §4 plus init's doctor --fix depend on warn exiting zero
  • r-adr32doc f35921e — per-surface profiles, for now | omitting checks to make a surface faster is the doctor reports a healthy install on a repository where every capture has been silently dropped for 8 days #458 shape, and --only/--category cover the subset uses until a measurement shows the full set is too slow

Warnings (3)

  • r-prdwrites afd48df (claim)--fix creates the -wal file that a plain run does not, so the two paths differ in what they leave behind even though neither writes data
  • r-adr32rev 6955e81 (claim) — the earlier revision claimed init depends on doctor's exit code; init.ts line 104 branches on needsAttention and ignores the exit code, so do not reintroduce that claim when next touching §7
  • r-adr32doc f35921e (claim)blocked_by is the one new field that can hide a real defect if it ever suppresses a row rather than annotating it, so the invariant belongs in a test before the first collapse ships

Trailer violations fail this check. Active constraints are informational — they are what the repository already decided, not a verdict on this PR.

@MongLong0214
MongLong0214 merged commit 5ffa5c0 into dev Aug 8, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant