Uh oh!
There was an error while loading. Please reload this page.
docs(plugin-audit): restore the published README's services.audit pointer, in a form published readers can follow - #9636
Conversation
…nter, in a form published readers can follow (#9589) PR #9531 dropped this README's "See Also" pointer to the runtime-services audit page because the page documented the settings sink (`record()` / `'set' | 'reset'`) as if it were the `audit` slot. PR #9587 rewrote the page around the real slot, so the omission's reason has stopped holding. Restored because the page carries three things this README deliberately does not: the slot's own failure posture (`recordAuthEvent` never throws; error once per process then debug; row lost, nothing retries; silent no-op with no engine or no `userId`), the event's field-by-field shape, and the settings-sink disambiguation with its `TypeError` consequence. The README's own slot section states the interface and the closed action union and stops there. The restored line is not the removed line. That one was labelled "Audit Logging Best Practices" — a guide the page has never been — and spelled `/content/docs/.../audit-service.mdx`, which resolves for neither audience a published README has: on npm and GitHub a root-relative href resolves against npmjs.com / github.com, not the docs site. The replacement uses the absolute `https://docs.objectstack.ai/docs/...` form that create-objectstack's published READMEs already use. The one pre-existing site-root-relative docs link in the same file is converted to the same absolute form; its page and heading anchor both exist, only the spelling was unfollowable off the docs site. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
📓 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 — 5 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
✅ PM ACCEPT — #9589 / PR #9636Verified independently: 2 files The verdict is RESTORE — and the reasoning is why I accept itMy dispatch said I would rather have a well-argued negative than a reflexive positive, and that restoring was justified only if the page carries something the README deliberately does not. You tested all three named candidates and all three held, with the mechanism for each:
Plus the one you added: the page carries the whole event shape ( And the check on ruling 1 was done properly: the settings sink now appears on that page only under an explicit "Not this: the settings audit sink" heading stating it is never registered as or resolved from the slot, and that ⭐ You did not restore the line that was removed, and that is the best call in this reportThe removed line was wrong twice, independently of the page defect:
A literal revert would have restored a link that was broken before the page ever was. Restoring the right link, with an annotation stating what the page adds so the next author can check the justification instead of reconstructing it, is the version of this task that stays fixed. H3 is a finding in its own right — four coexisting spellingsYou were told to match the repo's convention rather than the card's shorthand, and found there is no single convention: absolute The in-place conversion of H1 — noted, and the correction lands on my dispatchThe gate is Substance confirmed: the gate's own header says it is "deliberately NOT a docs linter", it reads fenced code blocks only, and makes one claim per import line plus one per 🔑 The baseline finding is operationally important and I am acting on it now
H2 — the gap is real and measured exhaustivelyNothing verifies a published README's docs-site link, neither page nor anchor: the lychee lane covers H4 — plugin-audit is the only oneSwept every package README for omission markers and read every Verdict: ACCEPT. Arming once the nine running gates converge. Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#9589
Verdict: restore — but not the line that was removed
The card asked for a judgment, not a revert. Both conditions the card set are met, so the link goes back; the line that carries it is new, because the removed one was wrong in two ways that outlived the reason it was dropped.
Condition 1 — the page's defect is gone (read as it stands on
main)Verified against
content/docs/kernel/runtime-services/audit-service.mdxat14935ab71, not against the title of the PR that rewrote it:packages/plugins/plugin-audit/src/auth-event-audit.ts.services.audit.recordAuthEvent(event: { ... }).action: 'login' | 'logout'.getService('audit').record({ ... })fails with aTypeError. That is disambiguation, which is the opposite of the defect PR docs(plugin-audit): the published README stops documenting an API, a row shape and an action vocabulary that do not exist (#9517) #9531 measured — nothing on the page presentsrecord()/'set' | 'reset'as the audit slot.Condition 2 — the page carries what the README deliberately does not
The card named three candidates and said a link is worth restoring only if at least one holds. All three do. The README's own "The
auditservice slot" section is lines 291-304 ofpackages/plugins/plugin-audit/README.md.recordAuthEventnever throws; a failed insert iserroronce per process thendebug; the row is lost and nothing retries; silent no-op when no engine resolves oruserIdis absentorganizationIdvisibilityreadrows written by the record-view writer. The slot section never enumerates the event's fieldsTypeErrorconsequenceconfig_changeas written byservice-settings, but never distinguishesSettingsAuditSink.record()from the slotPlus the whole event shape —
userIdmust be a realsys_userid,sessionIdlands onrecord_idwithobject_namefixed tosys_session,contextis serialized intometadata. The README's slot section stops atinterface AuthEventAuditSinkand the closed action union, so the page is the only place a reader learns what to put in the event. The link is not redundant.Why the restored line is a different line
PR #9531 removed:
Wrong twice, independently of the page defect:
filesarray withprivateunset, so it renders on npm and on GitHub, where a root-relative href resolves againstnpmjs.com/github.com. It is not a docs-site route either:apps/docs/lib/source.tsmountsloader({ baseUrl: '/docs' })overcontent/docs, so the route is/docs/kernel/runtime-services/audit-service, andapps/docs/redirects.mjshas no/contentsource to rescue it.The replacement uses the absolute form the repo already established, and its annotation states what the page adds — so the next author weighing the same omission can check the justification instead of reconstructing it.
One in-place fix, declared
packages/plugins/plugin-audit/README.md:343carried the only site-root-relative docs link in the entirepackages/tree —](/docs/permissions/permission-sets#access-depth...), added by the same PR #9531 — and it is converted to the same absolute form. Its target page and heading anchor both exist (content/docs/permissions/permission-sets.mdx:111, slugaccess-depth--readscope--writescope-adr-0057-d1); only the spelling was unfollowable off the docs site.Boundary scan behind that call:
grep -rn "](/docs" --include=README.md packages/returned exactly one hit before this change and zero after. Same file, same defect class as the link being added, mechanically pinned by the convention below — leaving it would have shipped a README with one followable and one dead docs link, in a diff whose whole subject is which of the two forms is correct. The seven links in other packages are not touched here; they are filed as #9632.PM hypotheses
H1 — does
check:published-readme-symbolshave anything to say about an outbound link? No. The expectation holds, and the gate's real name ischeck:published-readme-exports. There is no script or package.json entry named...-symbols; PR #9546 addedscripts/check-published-readme-exports.mjs(pnpm check:published-readme-exports,lint.yml:1723). It is explicitly "deliberately NOT a docs linter": it reads fenced code blocks only (typescript / ts / tsx / diff / untagged) and makes one claim per import line plus one perName.member(call site, against the built.d.ts. Its only](occurrences are in its own header prose and self-test fixtures. Measured on this diff: all four changed lines (343, 395-397) sit outside every fenced block in the file — the six fences are at 24-26, 33-37, 43-49, 164-166, 296-300, 360-387. Also worth knowing for future cards:scripts/published-readme-exports.baseline.jsonnames@objectstack/plugin-auditas the gate's deliberate negative control ("the PR that added this gate reports it clean"), so this file must stay clean rather than merely unbaselined.H2 — is there any gate that would catch a published README linking to a page or anchor that does not exist? No, and the gap is real. Measured across every candidate: the lychee lane (
check-links.yml) runs over exactlycontent/**/*.md,content/**/*.mdx,README.md,ARCHITECTURE.md—packages/**/README.mdis not in scope;check:doc-anchorstakes its sources fromcontent/**plusEXTRA_SOURCES = ['README.md', 'ARCHITECTURE.md'], the root README only;check:adr-linksis scoped todocs/adr/;check:docs-redirectstoapps/docs/redirects.mjs; andcheck:published-readme-exportsper H1. A published README can link anywhere, in any spelling, and ship to npm green. Filed as #9632 with a contained three-assertion proposal and sizing — the load-bearing one needs no filesystem lookup and cannot false-positive, and the other two reuse the resolverscheck-docs-redirectsandcheck-doc-anchorsalready have rather than growing a third.H3 — the card's shorthand was the wrong form, and the repo is inconsistent. Four spellings coexist in published READMEs: the absolute
https://docs.objectstack.ai/docs/...(create-objectstack/README.md:90and the blank template at 39, 70, 108 — the only form that works on all three surfaces, and the one adopted here);/content/docs/...(7 links, 5 packages — dead everywhere, filed as #9632);/docs/...(1 link, this file, converted above); and../../../content/docs/...(2 links,service-knowledgeandknowledge-ragflow— these resolve on GitHub and npm but land the reader on raw MDX source rather than the rendered page). So the card's/docs/kernel/runtime-services/audit-servicewas the second-rarest form in the tree and unfollowable off the docs site.H4 — no other published README records this deliberate omission. Swept all package READMEs for omission markers (
deliberately,intentionally,dropped,omitted,restore,once #,Blocked-by) and read every## See Alsosection in the tree. The hits are all unrelated (service-realtime's unimplementedhandleUpgrade,service-automation's deliberate non-duplication of the per-node reference, the spec liveness ledger's vocabulary).plugin-auditis the only README whose docs link was dropped for a wrong target page. The adjacent case —runtime-services/index.mdxpointing "Audit bridge" at the settings sink — is already open as #9588 and is a docs-site page, not a README, so it is not a duplicate of anything filed here.Verification
Local gate union, run after the final commit, at
a15cc19df:Gate set derived from the actual changed paths with
node scripts/pm/dispatch-gates.mjs packages/plugins/plugin-audit/README.md .changeset/plugin-audit-readme-audit-service-link.md, which added the four changeset families over the README-only derivation.Two gates are reasoned rather than run, both build-dependent, both with the measurement behind the claim:
check:published-readme-exports(full run) hard-errors without a builtdist/for every workspace package any published README imports, i.e. a whole-workspace build; it runs in the CI job that has already built. Its--self-testpasses, and the fence-range measurement in H1 shows this diff is outside its reading surface entirely.check:i18nis convention-triggered here becauseplugin-auditownsscripts/i18n-extract.config.ts, and it needs@objectstack/clibuilt. That config's input set is three object modules —sys-audit-log.object.js,sys-activity.object.js,sys-comment.object.js— plus the generated bundles. A markdown prose edit changes none of them.No test pins this README's content:
grep -rn "README" --include="*.test.ts"acrosspackages/returns no plugin-audit hit, and the one structural reference (packages/spec/src/kernel/plugin-structure.test.ts) uses the literal string'README.md'as a schema fixture.Not addressed here
#9632 (the seven links in five other packages, and the missing gate) remains open, and #9588 remains open — neither is in this PR's scope.
Generated by Claude Code
Generated by Claude Code