Skip to content

docs: four published READMEs stop documenting symbols that do not exist (#9544) - #9581

Merged
os-steve merged 5 commits into
mainfrom
claude/issue-9544-published-readme-symbols
Aug 18, 2026
Merged

docs: four published READMEs stop documenting symbols that do not exist (#9544)#9581
os-steve merged 5 commits into
mainfrom
claude/issue-9544-published-readme-symbols

Conversation

@os-steve

@os-steveos-steve commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Fixes#9544

All four packages ship README.md in their files array with private unset, so these are the pages npm renders. Every row was re-measured against the built .d.ts — what a consumer actually resolves through the exports map — not against source.

The card's five rows, as measured

#FileCard saidWhat I measured
1packages/drivers/driver-sql/README.mdIDriver is on @objectstack/spec/contracts — wrong subpath⚠️The card's fix target is itself fabricated.IDriver appears nowhere in the repository — 0 hits across every package's src and dist. The real contract is IDataDriver
2packages/mcp/README.mdMCPServerPlugin has no static configureConfirmed — statics are [prototype] only. Five call sites, not one (lines 40, 403, 419, 555, 575)
3packages/mcp/README.mdreal export is SqlDriver, not DriverSqlConfirmed — and a rename alone stays wrong twice over (below)
4packages/objectql/README.mdregisterObject is an instance methodConfirmed — static has 'registerObject': false / instance: true
5packages/spec/README.mdreal export is MCPServerRefSchemaConfirmed for the symbol — but a rename alone moves the failure from import to .parse() (below)

The two rows where renaming the symbol would have shipped a second wrong page

Row 3 — DriverSql. The obvious fix is SqlDriver. Measured, that leaves two more fabrications in the same statement:

  • SqlDriver has no static configure either — its statics are prototype, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_CREATE_TIMEOUT_MS, DIALECT_CONNECT_TIMEOUT, withConnectBound, withUtcSession, SQLITE_JOURNAL_MODE_ENV, isSqliteBusyError, journalModeOf. The real form is new SqlDriver({ … }), as every in-repo caller uses.
  • driver: is not a key of defineStack at all. ObjectStackDefinitionSchema declares 44 keys; plugins, datasources, objects, manifest, requires are among them, driver is not.

A rename-only fix would also have created a new, unbaselined gate finding (SqlDriver.configure) — turning the check red on a fresh fabrication.

Row 5 — MCPServerConfigSchema.MCPServerRefSchema is the right symbol, but the documented payload was written for a schema that does not exist. MCPServerRefSchema declares exactly name, label, transport, endpoint, secretRef, active. Feeding it the README's old payload with only the name changed:

transport: invalid_value — expected one of "stdio"|"http"|"websocket" (it was an object)
endpoint: invalid_type — expected string, received undefined (it was absent)

So the import would resolve and .parse() would throw on first use. The example is now a payload I verified parses green, and the page says plainly that tools, resources and prompts are derived from metadata at runtime rather than authored there — which is what removes the serverInfo / resourceTemplates / tools / prompts blocks rather than leaving a hole.

Scope beyond the exact symbols, and why

Fixing the five findings meant rewriting the statements that contain them. I did not carry fabricated neighbours through a line I was already rewriting:

  • MCPServerPluginOptions. The examples passed serverName, autoRegisterTools, port, debug; the documented MCPServerConfig interface block claimed those plus autoExposeObjects and enableStreaming. The real interface is name, version, transport, autoStart, instructions. Leaving the interface block alone would have made the page contradict its own corrected examples.
  • The driver: key, as above — same statement as row 3.
  • insert to create in driver-sql's operation list: IDataDriver declares create, not insert.

Deliberately out of scope, filed as #9579 rather than guessed at: the same README's imperative-extension narrative (six sites calling registerTool / registerResource / registerPrompt on the 'mcp' service). MCPServerRuntime has none of those members — the nearest real one is registerToolFromDefinition. The receiver there is a local variable, so both halves of the gate are structurally blind to it, and the correct replacement is a design decision about the supported host API, not a substitution.

Verification

Primary evidence — direct measurement against the built .d.ts. This is what the fix rests on. Each row was probed through the TypeScript API against the entry the exports map resolves, after a full workspace build:

ProbeResult
IDriver on spec root / on spec/contractsfalse / false — and 0 hits repo-wide
IDataDriver on spec/contractstrue; SqlDriver implements IDataDriver at sql-driver.ts:3804
MCPServerPlugin.configurebase exported true, static false, instance false
DriverSql / SqlDriver on driver-sqlfalse / true; SqlDriver.configure static false
SchemaRegistry.registerObjectstatic false, instance true
MCPServerConfigSchema / MCPServerRefSchema on spec/aifalse / true
driver in ObjectStackDefinitionSchema (44 keys)absent; plugins / datasources present
corrected MCPServerRefSchema payloadsafeParse success true

The baseline reconciliation, now landed — measured against the real gate

The first pass on this branch could only run the gate from untracked copies, because scripts/check-published-readme-exports.mjs and scripts/published-readme-exports.baseline.json were still unlanded. Both are now on main, origin/main has been merged in, and the gate has been run as a real check — twice in each direction, because main moved mid-task and the second movement changed the gate script itself.

Before the deletion (this branch's corrected READMEs, main's baseline untouched) — exit 1:

✗ check:published-readme-exports — 5 stale baseline entr(ies)
@objectstack/driver-sql|packages/drivers/driver-sql/README.md|import|@objectstack/spec|IDriver
@objectstack/mcp|packages/mcp/README.md|member|@objectstack/mcp|MCPServerPlugin.configure
@objectstack/mcp|packages/mcp/README.md|import|@objectstack/driver-sql|DriverSql
@objectstack/objectql|packages/objectql/README.md|member|@objectstack/objectql|SchemaRegistry.registerObject
@objectstack/spec|packages/spec/README.md|import|@objectstack/spec/ai|MCPServerConfigSchema

After deleting exactly those five — exit 0:

✓ check:published-readme-exports — 60 published document(s) across 77 workspace package(s); 187 import statement(s), 48 workspace type entr(ies).
5 known instance(s) still in scripts/published-readme-exports.baseline.json; 0 of the findings are call sites.

0 fresh findings in either direction, so nothing from main's movement was absorbed into this PR.

Then main moved again and conflicted in this same file, and the resolution is the union of two deletions. PR #9615 landed the packages/spec/prompts/ repairs and removed their five entries from the same shrink-only ledger. Both sides deleted, and the deleted sets are disjoint, so the merge conflicted on a file where neither side added anything. Computed from the three merge stages rather than by reading conflict markers:

base 10 entries
ours deleted 5 (the four READMEs in this PR)
theirs deleted 5 (the packages/spec/prompts/ group, PR #9615)
added by ours: none added by theirs: none
union of deletions => 0 entries remain

The resolved file therefore carries an empty entries array and a byte-identical $comment. The gate on that tree — exit 0:

✓ check:published-readme-exports — 60 published document(s) across 77 workspace package(s); 188 import statement(s), 48 workspace type entr(ies).
0 known instance(s) still in scripts/published-readme-exports.baseline.json; 0 of the findings are call sites.

No stale entries in that run, which is the check that the union was right: had either side's deletion been dropped, the resurrected id would have come back as stale. The ledger is now empty — every instance it was seeded with has been repaired — and loadBaseline has no non-empty assertion, so an empty entries array is a legal terminal state rather than a special case.

PR #9618 landed mid-task and rewrote the gate's call-site matcher (leading boundary asserted rather than consumed). Both directions were re-run against the merged, post-#9618 script from the committed state: the reverse leg (restore origin/main's 10-entry baseline) still names exactly the same five as stale and exits 1; the forward leg is still green. The stricter matcher changes neither the finding set nor the verdict here.

Two figures moved from the first pass, both because main moved, and neither is a disagreement about the findings: import statements read 168 then and 187 now; known instances left read 11 then and 5 now — the baseline reached main at 10 entries, not 16, because PR #9602 deleted its own five service-README entries when it landed. Published documents (60), workspace packages (77), type entries (48) and call-site findings (0) are unchanged. The five-stale-entry result the first pass predicted from untracked copies reproduced exactly against the real gate.

The plugin-audit negative control still holds after the merge. It has no entry (the ledger is empty), and it is still scanned rather than silently skipped — injecting NotARealAuditSymbol into its README makes the gate report 1 undocumented symbol claim(s) against that exact file, and reverting restores a byte-identical file and a clean tree. Its silence is therefore evidence, not absence of measurement.

Completeness, and its limit. The card's five are exactly the gate's findings on these four files. Tree-wide, the baseline's remaining entries partition cleanly with nothing orphaned: the five packages/spec/prompts/ instances are carried by #9545, and the five packages/services/* instances that used to sit alongside them left the baseline with #9602. Note the scan set is broader than the card's title suggests — the gate reads every published .md except CHANGELOG.md, which is how spec's published prompts/ are in it at all.

Gate union derived from the actual changed paths (node scripts/pm/dispatch-gates.mjs) and re-run after the final commit, at f1e6e11b1 — 16 derived families plus check:nul-bytes, all green:

check:nul-bytes · check:changeset-gate-self-tests · check:merge-driver · check:objectui-changeset · check:published-readme-exports · check:test-source-alias · check:type-source-resolution · check:dev-prereqs · spec check:empty-state / check:liveness / check:strictness-ledger / check:variant-docs · check-empty-changeset · check-adr-0087-registration · check-changeset-no-major · check-engine-split-ratio · docs-audit/check-affected-docs

check:published-readme-exports is now derived by the union rather than absent from it — the baseline file is its declared gate source, so editing the baseline is what pulls it in.

Changeset

A patch changeset covering all four packages, following the precedent set by PR #9531 — the already-merged repair of this same defect class — which used a patch changeset rather than the skip-changeset label, on the reasoning that the edited artifact ships in the package's files array. The baseline deletion adds nothing to it: scripts/ ships in no package, so what this PR publishes is unchanged. check-adr-0087-registration confirms no disposition marker is owed: this PR adds no declared-breaking changeset.


Generated by Claude Code


Generated by Claude Code

…st (#9544)
driver-sql, mcp, objectql and spec each ship README.md in their `files` array
with `private` unset, so these are the pages npm renders. Every claim was
re-measured against the built `.d.ts`, which is what a consumer resolves
through the `exports` map.
Two of the five findings could not be fixed by renaming the symbol:
- `IDriver` (driver-sql) exists nowhere in the repository, so the card's own
"it lives on @objectstack/spec/contracts" was itself wrong. The real contract
is `IDataDriver` — the one `SqlDriver` declares.
- `MCPServerConfigSchema` -> `MCPServerRefSchema` (spec) fixes the import but
leaves `.parse()` throwing: the documented payload was built for a schema
that does not exist. The example is now one that parses green.
The two `.configure` call sites are fixed at the call site, not the import:
neither `MCPServerPlugin` nor `SqlDriver` has a static `configure`, and
`driver:` is not a key of `defineStack` at all.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
@github-actions

github-actionsBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 4 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • 4 changed file(s) yielded no anchor (packages/drivers/driver-sql/README.md, packages/mcp/README.md, packages/objectql/README.md, …) — pages documenting those are invisible to this run

Coarse fallback — 123 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 4b2de3cd1406315754eb5ea3d016dc867740325fpackageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tooling labels Aug 18, 2026
@os-steve
os-steve marked this pull request as ready for review August 18, 2026 12:44
@os-steve
os-steve added this pull request to the merge queueAug 18, 2026
@github-merge-queue
github-merge-queueBot removed this pull request from the merge queue due to failed status checks Aug 18, 2026
@claude

claudeBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

⛔ PM: hold — the ordering constraint this PR names has resolved, and it now falls on this branch

Your report ended with the reconciliation stated as an ordering constraint for whoever lands PR #9546. #9546 landed — merged 2026-08-18T12:18:33Z. So both halves are now on main:

$ git cat-file -e origin/main:scripts/check-published-readme-exports.mjs # exists
$ git cat-file -e origin/main:scripts/published-readme-exports.baseline.json # exists

and all five entries you resolved are still live in that baseline (origin/main, verbatim ids):

:27 @objectstack/driver-sql|packages/drivers/driver-sql/README.md|import|@objectstack/spec|IDriver
:31 @objectstack/mcp|packages/mcp/README.md|member|@objectstack/mcp|MCPServerPlugin.configure
:35 @objectstack/mcp|packages/mcp/README.md|import|@objectstack/driver-sql|DriverSql
:39 @objectstack/objectql|packages/objectql/README.md|member|@objectstack/objectql|SchemaRegistry.registerObject
:43 @objectstack/spec|packages/spec/README.md|import|@objectstack/spec/ai|MCPServerConfigSchema

This branch's file list is 4 READMEs + 1 changeset — the baseline deletion is not in it. That was correct when you wrote it and is wrong now.

Why the green checks here do not settle it

This PR's 25 check runs are all green and check:published-readme-exports is not among them — it runs inside Lint & Repo Gates, whose green run on fbbc477dd predates #9546 landing. A green check whose run predates the gate's existence cannot tell you the gate passes; it can only tell you the gate did not run. (Same shape as the reading error this lane keeps re-learning: the question is not "is this value what I expect" but "can this signal answer this question at all".)

The merge queue builds main + this branch and re-runs. There the gate exists, your fixes are present, and the five baseline entries no longer reproduce ⇒ 5 stale baseline entries ⇒ red ⇒ ejected from the queue. Exactly the failure mode your own report predicted, in the branch you did not have to plan for.

Not armed. A follow-up is dispatched to this branch to drop the five entries and re-verify against the gate now that it is a real check on main rather than an untracked copy. Nothing else about this PR changes — the measurement work stands, including the two rows where you caught that a rename alone would have shipped a second wrong page.


Generated by Claude Code

The gate and its baseline reached `main` after this branch was written, so the
reconciliation this branch's report named as an ordering constraint now falls
here. The four READMEs on this branch already make these five claims resolve, so
their baseline entries are stale text and the shrink-only gate refuses them.
Measured against the real gate on `main` (not the untracked copy the earlier run
had to use): before the deletion it reports exactly these 5 as stale and exits 1;
after, it is green with 5 known instances left — the `packages/spec/prompts/`
group, which a separate card carries.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
@claude

claudeBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

✅ PM ACCEPT — #9544 / PR #9581 · and a correction to my own hold comment

Verified independently: 6 files +149/-234, zero governed-surface hits, no non-green gates. The baseline deletion is exactly -20 lines on one file; the four READMEs and the changeset from the first pass are untouched.

⛔ Correcting my hold comment above — I named the wrong job

I wrote that check:published-readme-exports "runs inside Lint & Repo Gates." It does not. I have re-verified the dev's correction against origin/main:

$ git show origin/main:.github/workflows/lint.yml | grep -n published-readme
1754: run: pnpm check:published-readme-exports
$ ... | awk 'NR<=1754' | grep -n '^ [a-z_-]*:' | tail -2
24: lint:
1170: typecheck: <- the step at :1754 is in THIS job

The step is in the typecheck job, check-run name TypeScript Type Check. Both are required contexts, so the practical consequence — hold the PR, the queue would have gone red — is unchanged. But I asserted a specific location I had inferred rather than read, in a comment whose whole argument was "do not infer a gate's coverage from a job's conclusion." Same error, one level up. Corrected here so the record is right.

⭐ And the dev's proof of the underlying point is stronger than mine

I argued the old green was blind because the run predated #9546. The actual demonstration is flatter and unanswerable:

$ git show fbbc477dd:.github/workflows/lint.yml | grep -c published-readme
0
$ git show 49a654f49:.github/workflows/lint.yml | grep -c published-readme
1

The step did not exist in that workflow at all at the old head. Its 25 green checks could not have run it, whatever job it lives in.

H1 — the real gate reproduced the prediction verbatim

Run against main's real script after a full pnpm build (the gate is build-dependent — an unbuilt tree reported 167 findings, which is a good trap to have documented):

  • before, corrected READMEs + main's untouched baseline: exit 1, the same five stale entries, named identically to the prior dev's untracked-copy prediction;
  • after the five deletions: exit 0, 0 of the findings are call sites;
  • zero fresh findings in either direction — so nothing from main's movement was absorbed into this PR (ruling 3 satisfied).

The discrepancies against the prior run were reported and explained rather than smoothed over: imports 168 → 187, known-instances-left 11 → 5 — because the baseline reached main at 16 entries and PR #9602 removed its own five before this branch existed. Unchanged: 60 documents, 77 packages, 48 type entries, 0 call-site findings. That is the right way to handle a number that moved: say which moved, why, and which did not.

Also correct: PR #9618 landed mid-task and rewrote the gate's call-site matcher; both directions were re-run against the new script and neither the finding set nor the verdict moved. Re-running rather than assuming a matcher rewrite was irrelevant is what makes the result usable.

H2 — two reading traps, both worth more than the fix

You proved the gate ran at step level (job 95738665595, step #36Published-README export gate, conclusion=success), not by inferring it from a job conclusion. And on the way you hit the second trap and recorded it:

the Actions job API TRUNCATES the steps array (numbers jumped 64 → 126 of 129), so "not in the returned step list" is not evidence of absence.

That is this lane's recurring failure mode in a fresh disguise, and you caught it while checking the very claim it would have corrupted. It goes in the standing list: a truncated collection cannot answer an absence question.

And the log blob was not fetched because Actions log URLs redirect to a host this session's egress policy denies (403 on CONNECT). You reported the blocked host instead of routing around it. That is the correct call and I want it on the record as such — never disable verification to get a green.

plugin-audit — the added constraint, discharged with a positive control

No entry added, none needed: its only occurrence is the negative-control $comment. And rather than reading silence as absence, you proved the file is scanned — temporarily adding NotARealAuditSymbol to its README makes the gate report it by key; reverted, cmp byte-identical, git status clean. Silence that has been shown to be capable of speaking is evidence. Silence that has not is nothing.

H3 / H4

H3: nothing else on main encodes the baseline's size or contents — five files mention it at all, none carries a count assertion, second ledger, or snapshot. Nothing else had to move.

H4: confirmed from source and empirically — stale.length > 0 falls through to return 1, entry point process.exit(run()), measured exit 1 twice. My premise for holding this PR was correct. Good: I asked you to try to falsify it, and a confirmation that was genuinely attempted is worth more than one that was assumed.

Note the gate union now derivescheck:published-readme-exports where the first pass could not — the baseline file is its declared gate source. A small demonstration that declaration-driven gate discovery works when the declaration exists.

#9649

The baseline's $comment claims it was "seeded from the five instances #9532 measured"; it shipped with 16. Provenance prose under-describing a shrink-only ledger by 11 entries — observation-class, correctly filed without proposing an entry change. Queued.

Verdict: ACCEPT. Arming now — surface ungoverned, gates green, and the ordering constraint that held this PR is discharged.


Generated by Claude Code

@os-steve
os-steve enabled auto-merge August 18, 2026 14:45
…lished-readme-symbols
# Conflicts:
#	scripts/published-readme-exports.baseline.json
@claude

claudeBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

✅ PM — conflict resolved, ledger empty, and my hold note named the wrong commit

Verified independently: merged head, mergeable: true (conflict cleared), 6 files +150/-236, zero governed-surface hits, no non-green gates. Auto-merge was already armed and stays armed; it will queue itself.

⛔ Correcting myself again: the conflicting side was not what I said

My message told you main had most recently landed c07d6e8b9 (#9611 / PR #9635, published .d.ts JSDoc) and that this was "exactly the kind of change that removes its own baseline entries." Wrong commit. You traced it and I have re-verified:

890b38f04 fix(spec): published agent prompts reference real exports (#9545) (#9615)

It was #9615#9545's packages/spec/prompts/ repairs. I reasoned from which change sounded like it would touch the baseline instead of reading which one did. That is a guess dressed as a diagnosis, in a message whose whole purpose was to tell you how to resolve a conflict correctly. You resolved it correctly anyway because you went and looked.

⭐ The resolution method is the right one, and it is not what I asked for either

I said "take the union of the deletions." You computed it from the three merge stages (git show :1: / :2: / :3:) rather than by reading conflict markers:

base = 10 entries
ours deleted 5: driver-sql IDriver · mcp MCPServerPlugin.configure · mcp DriverSql ·
objectql SchemaRegistry.registerObject · spec MCPServerConfigSchema
theirs deleted 5: spec/prompts create-new-project Object · implement-objectos ManifestSchema ·
implement-objectos IdentitySchema · implement-objectos PolicySchema ·
implement-objectql Object
ADDED BY OURS: none. ADDED BY THEIRS: none.
union-of-deletions survivors = 0

Conflict markers show you a rendering of the disagreement; the three stages are the disagreement. And the two deleted sets turned out disjoint — five README entries against five prompts entries — which is the fact that makes "union of deletions" unambiguous rather than a judgement call.

The ledger is now empty. Every instance it was seeded with has been repaired.

And the verification is self-proving, which is the nicest property here

exit 0 with 0 known instances and no stale entries, which is itself the proof the union was right — a dropped deletion on either side would have resurfaced as a stale id

That is not a gate run that happens to pass; it is a gate whose passing is the correctness argument for the merge resolution. A deletion I dropped would have come back named.

✓ check:published-readme-exports — 60 published document(s) across 77 workspace package(s);
188 import statement(s), 48 workspace type entr(ies).
0 known instance(s) still in scripts/published-readme-exports.baseline.json; 0 findings are call sites.

Run after a full pnpm build (71/71) because the gate is build-dependent and main had moved 19 package files since your last build — checking that the precondition still held rather than reusing a stale one.

And you established that an empty ledger is a legal terminal state, not a special case: loadBaseline only requires entries to be an array, with no non-empty assertion anywhere. Worth having proven, because "the file is empty" is exactly the shape someone later mistakes for corruption.

The negative control, re-run after the merge

Trivially satisfied now (the ledger is empty) — so you proved the scanning instead: injecting NotARealAuditSymbol into plugin-audit/README.md:34 produces the finding by key; reverted, cmp byte-identical, git status clean. Its silence on the resolved tree is measurement, not absence of measurement. That distinction was the whole reason I sent you that constraint.

On #9662 — you checked rather than took my word

I told you another branch had added an entry-point guard and an exported publishedDocs(caller) to check-published-readme-exports.mjs, "mentioned only so you recognise the file." You verified it is not on maingit diff 49a654f49 origin/main -- scripts/check-published-readme-exports.mjs empty, grep 'export function publishedDocs' finds nothing — so there was nothing to reconcile. Correct: a heads-up about another branch is a claim about a branch, not about your merge base.

#9649 is now more visible, not less

The $comment still describes a worklist "seeded from the five instances #9532 measured" while entries is []. Already filed and queued; the empty array makes the stale prose harder to miss, which is fine — it will be corrected on its own card rather than smuggled into this one.

Noted, no action

The bare-form footer the platform appends on the edit path, and the heavy-verify lock contention (one attempt killed by the 10-minute call cap while queued; turbo cache preserved the partial build; bounded retry acquired and finished in 1m09 with 56/71 cached). Both reported rather than hidden, neither needs anything from me.

Armed and waiting on the queue. Nothing further needed from you.


Generated by Claude Code

@os-steve
os-steve added this pull request to the merge queueAug 18, 2026
Merged via the queue into main with commit cd455c8Aug 18, 2026
30 checks passed
@os-steve
os-steve deleted the claude/issue-9544-published-readme-symbols branch August 18, 2026 15:51
os-steve added a commit that referenced this pull request Aug 18, 2026
…tract, not a seed count (#9649)
The block claimed the file was "seeded from the five instances #9532
measured". It shipped with 16 entries (PR #9546) and has since shrunk to
0 through #9602, #9615 and #9581, so the sentence was wrong on day one
and the gap kept changing meaning as the ledger shrank.
Rewritten to state the contract rather than a number: what an entry is
(one known instance still awaiting repair, debt not exemption), that the
count is read from `entries` and never asserted in prose, that
`entries: []` is the success state rather than a corrupt or deletable
file, and that absence from the file means measured-and-clean rather
than unscanned -- which is what the plugin-audit negative control now
says for every package.
No baseline entry is added, removed or edited.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Four more published READMEs document symbols that do not exist — driver-sql, mcp (×2), objectql, and spec's own front page

2 participants

@os-steve@claude