Uh oh!
There was an error while loading. Please reload this page.
docs(runtime): hand-audit the README's 30 unread call sites — 1 fabricated member, 2 wrong call shapes (#10368) - #10816
Queued
claude[bot] wants to merge 2 commits into
Queued
Conversation
… README's unread call sites (#10368) Hand-adjudicated every call site in `packages/runtime/README.md` that `check:published-readme-exports` reports under its `NOT read:` line — receivers bound to free variables, parameters and globals, which neither the gate nor a human reader can type by looking. Population, derived from the gate's own `countUnreadCalls` over the same `publishedDocs()` it runs on: 30 sites on 17 receivers (the whole-repo line reads `NOT read: 120 ... on 72 receiver(s)`). Verdicts: 24 sites resolvable and correct, 5 genuinely unadjudicable (receiver is a reader-owned illustrative object with no type anywhere), 1 fabricated member — `reply.code(429)`, which is Fastify, against a package whose HTTP contract spells the step `IHttpResponse.status(code)`. Two further sites name a real member with the wrong call shape (`engine.update` / `engine.delete`), a defect class member-existence cannot see, and three defects outside the call population turned up in the same read (`res.statusCode`, `PluginContext.logger`, `PluginContext.getKernel`). `NOT read` moves 120 -> 119 calls and 72 -> 71 receivers: the `reply` receiver is gone, and `res.status` / `res.json` were already counted in this document. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 23 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-zhuang
marked this pull request as ready for review
August 21, 2026 13:18
os-zhuang
added this pull request to the merge queueAug 21, 2026
Any commits made after this event will not be merged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#10368
Commissioned as a measurement. The deliverable is a true defect count with its denominator; the repairs are the by-product. Both are below.
The card states
packages/runtime/README.mdholds 47 unread sites on 18 receivers. Derived from the gate's own population, it holds 30 on 17.readable= import-bound +extractLocalBindingsderivations)X.ydedupNo counting convention in
scripts/check-published-readme-exports.mjsyields 47/18, and the document has not been edited since #10226 — well before the card was written, and the card quotes today'sNOT read: 120 … 72line verbatim, so it was written against this same tree.47is the number printed one line above it on the same green output —47 name(s) built from one, i.e.derivedReceivers, a whole-repo quantity. That is the likely provenance; I cannot prove it.The card's argument survives intact: this document is still by far the largest concentration, and still ~3× the next one (30 vs
packages/metadata/README.md's 10). Only the arithmetic moved. #10815 is filed on the underlying cause — the gate emits no per-document breakdown, so a reader has to transcribe from whole-repo scalars.How the site list was derived
Not by grepping the README. The population had to be the gate's, so the derivation reuses the gate's own exports —
publishedDocs(),extractImports,splitSpecifier,resolveTypesEntry,extractLocalBindings,readFences,countUnreadCalls. Only two things are re-stated:analyzeDocument'sreadablemap (it is built internally and not exported) andcountUnreadCalls' body (it returns cardinalities, not the pairs).The re-statement is checksummed against the gate rather than trusted: summed over all 60 published documents it must reproduce the printed pair, and it does —
TOTAL unread calls=120 receivers=72, equal to the gate's ownNOT read: 120 … on 72 receiver(s). After the repairs it tracks the move too:TOTAL unread calls=119 receivers=71. A drift in the derivation would move that total. (It is a whole-run checksum: it catches a systematic disagreement, not one document's worth. That limitation is #10815.)The script is not committed — this card is a read, and
scripts/check-published-readme-exports.mjsis fenced. It is reproduced in full, with its per-document output over all 60 published documents, in a comment on #10368.The verdict table — all 30 sites
Line numbers are
origin/mainat112a8c673, i.e. the population as commissioned.ctxregisterService(…)PluginContext— annotated at the parameterctxgetService(…)PluginContextctxtrigger(…)PluginContextctxhook(…)PluginContextengineinsert(…)IDataEngine—ctx.getService<IDataEngine>(…)enginefind(…)IDataEngineengineupdate(…)IDataEngineenginedelete(…)IDataEnginezobject(…)zodzstring(…)zodznumber(…)zodthischeckDatabase(…)HealthCheckPlugin, same fencethischeckCache(…)HealthCheckPluginthischeckDiskSpace(…)HealthCheckPluginserverget(…)IHttpServerserveruse(…)IHttpServerresjson(…)IHttpResponse— 2nd param ofRouteHandlerresstatus(…)IHttpResponsedbinsert(…)dbping(…)ctx.getService('database'), the README's own illustrative connectionconsolelog(…)ConsoleauditLogwrite(…)ConfigSchemaparse(…)z.object({…})— a zod schemaconnclose(…)for (const conn of this.connections.values()), values from an illustrativecreateConnectionDatenow(…)DateConstructorfactorygetInstance(…)Promiseall(…)PromiseConstructorchecksevery(…)await Promise.all([…])— an arraycacheping(…)ctx.getService('cache'), reader-owned exactly likedatabaseabovereplycode(…)Note on #29.
cacheis also a reserved core service slot (CoreServiceContracts.cache: ICacheService), andICacheServiceshipsget/set/delete/has/clear/stats— noping. But the README's sibling example registers'database'as the reader's own connection object, and this fence'sdependencies = ['http-server', 'database', 'cache']names plugins, not slots. Both readings are available and the receiver carries no type. Counted as ambiguous rather than pushed into the defect bucket, per the card's instruction.The count and the denominator, plainly
reply.code(…). That is the gate's own question, and the rate this document produces on it.Against the 1-in-70 prior: on the like-for-like question this is 1 in 30 (or 1 in 25 over adjudicable sites) versus 1 in 70. One instance either way; on a sample of 30 that is not a material difference, and it does not support re-opening the five-document sweep on member existence. The number that is new is the wrong-call-shape class: 2 more in the same document, invisible to the gate by construction, which no measurement so far has priced. Whether that re-opens anything is triage's call — it is a different sweep than the one #9870 proposed. The other decision-relevant fact for the remaining 73 sites: 1 in 6 of this document's unread sites is unadjudicable by anyone, so a hand read of the residual buys less coverage than its site count suggests.
The repairs, and the evidence for each
Six false claims, all in
packages/runtime/README.md.1–2.
IDataEngine.update/.delete— real members, wrong call shape (lines 206–207)IDataEngine(packages/spec/dist/analytics.zod-CjlbASro.d.ts:891, published through@objectstack/spec/contracts→@objectstack/core→@objectstack/runtime) declares:There is no
idparameter on either. The normative rule for identifying one row isresolveEngineUpdateDispatch(packages/metadata-core/src/engine-update-dispatch.ts, module header): a truthy scalardata.idwins, elseoptions.where.id, elseoptions.multi, else the engine rejects. The delete twin isassertEngineDeleteDispatchin the same package. As written, the README'suser.idlanded in the options bag — a call the engine rejects rather than one that silently does the wrong thing, but a reader following the page still cannot compile-and-run it.3. The
IDataEngineInterface Methods bullet list restated both wrong signatures (lines 215–216) — corrected in the same edit. A repaired example beside a bullet list that still contradicts it is not a repair. The two bullets that were incomplete rather than false (insert/findomit their optional trailingoptions?) are deliberately left alone: an omission is not a false statement, and widening the diff past the adjudicated defects is not this card.4.
reply.code(429).send({…})(line 610) — the one fabricated member.reply.code()is Fastify. This package's HTTP contract isIHttpResponse(packages/spec/dist/contracts/index.d.ts), which spells the stepstatus(code: number): IHttpResponseand whosesendtakesstring | Uint8Array | ArrayBuffer— so the original line was wrong twice: a member that does not exist, handed an argument the realsendwould reject.status(…).json(…)is the spelling this same README already uses at lines 543–546, and thedocs/HARDENING.md#rate-limitingrecipe the same section links to answers 429 through the framework's own JSON responder (return c.json({ error: 'Too many requests' }, 429)).decision.allowedanddecision.retryAfterMsare both real (RateLimitDecision,packages/runtime/dist/index.d.ts:1384) and are untouched.5.
status: res.statusCode(line 484) —IHttpResponsehas nostatusCode. Dropped from the logged object. A response's status is observed throughIHttpServer.afterResponse→HttpResponseObservation.status, not read off the response inside middleware. Outside the gate's population (a property access, not a call), found in the same read.6.
PluginContext's declared block (lines 250–251) —logger: ConsoleandgetKernel?(): any. The real contract (packages/core/dist/index.d.ts:403) islogger: Logger(spec'sLogger, not the globalConsole) and a requiredgetKernel(): ObjectKernel. The block's omissions —registerServiceFactory,replaceService,getServiceScoped,getServices— are left as they are, for the same reason as the bullets above.Changeset, not
skip-changesetpackages/runtimeis published, and itsfilesarray carriesREADME.md— a README repair ships on npm, so this owes a real changeset..changeset/runtime-readme-unread-call-site-audit.md,patch. (PR #9906 is the precedent; PR #10365 made the same call.) The diff ships user-visible published content, so the measurement-only branch does not apply here.Gate evidence
All gate results are the gate's own verdict line, with the exit code captured before any pipe (
cmd > file 2>&1; ec=$?).pnpm check:published-readme-exports, before (exit 0):after (exit 0, at
63549ad2ad):−1 call and −1 receiver, and that is the whole expected movement. The
replyreceiver is gone; its replacementreswas already a receiver in this document withres.statusandres.jsonalready counted, andcountUnreadCallsdedupesX.yper document. Nothing else in the diff touches a call site. The other five repairs are a bullet list, an interface block, a property access and two calls whose member names are unchanged — all invisible to this count. Per-document: 30/17 → 29/16.node scripts/pm/dispatch-gates.mjsderived 10 families from the change set (.changeset/runtime-readme-unread-call-site-audit.md,packages/runtime/README.md). All re-run at the final commit63549ad2ad:pnpm check:changeset-gate-self-testspnpm check:objectui-changesetpnpm check:slot-lookuppnpm check:test-source-aliaspnpm check:type-source-resolutionnode scripts/check-adr-0087-registration.mjsnode scripts/check-changeset-no-major.mjsnode scripts/check-empty-changeset.mjsnode scripts/check-plugin-teardown-shape.mjsnode scripts/docs-audit/check-affected-docs.mjspnpm check:published-readme-exports(the card's own gate)pnpm check:nul-bytesSelected verdict lines, as the gates printed them:
Both changeset gates were re-run after the commit: run against an uncommitted changeset they report
0 declaring changeset(s)and pass vacuously, which is the reading that would have been wrong.No tests run and none added: the diff is one Markdown file and one changeset entry.
Fences honoured
scripts/check-published-readme-exports.mjsis untouched — this is a read, not a recognizer change. #9870's option D (receivers bound by property access off a typed value) is not attempted; it still wants a census and its own card. #9911 and #10367 remain open and are not folded in here.Findings filed (unassigned, no
pm:queue)examples/host/,examples/msw-react-crud/,test-mini-kernel.ts, and three rootMINI_KERNEL_*.mdfiles), plus a truncated bullet with an unterminated backtick. Different defect class and different gate family from this card, so it is not a rider.check:published-readme-exportsprints itsNOT readblind spot only as whole-repo scalars — a per-document hand read must re-derive the population outside the gate #10815 — the gate prints itsNOT readblind spot only as whole-repo scalars, so a per-document hand read has to re-derive the population outside the gate, with no way to prove per-document agreement. Carries the measured per-document breakdown and the 47/18-vs-30/17 discrepancy above.Generated by Claude Code
Generated by Claude Code