Uh oh!
There was an error while loading. Please reload this page.
docs(permissions): document record-view auditing, the read action's shipped surface - #9860
docs(permissions): document record-view auditing, the read action's shipped surface#9860os-steve wants to merge 1 commit into
read action's shipped surface#9860Conversation
… shipped surface (#9540) Record-view auditing shipped with #8992 / PR #9515 and was documented only in `packages/plugins/plugin-audit/README.md` — i.e. on npm and GitHub, never on the docs site. A coverage evaluation run from the docs site got silence on exactly the edges that decide the answer: record-detail views only, per-object opt-in, no field values recorded, system-elevated reads excluded. Adds `content/docs/permissions/record-view-auditing.mdx`, verified line by line against `packages/plugins/plugin-audit/src/read-audit.ts` and `audit-plugin.ts` rather than against a neighbouring page. NOT a page in `content/docs/kernel/runtime-services/`. That chapter publishes one page per `services.<name>` slot and its index gate holds every page's declared `Registry slot` to a real production `registerService` call. Record-view auditing has no slot: it is an `afterFind` hook installed from `AuditPlugin`'s constructor. Putting it there would have meant inventing a registry slot to satisfy check #5. It goes in Permissions & Identity instead, the chapter `capabilities/permissions.mdx` already routes readers to for "the full model" including audit. Also: - extends the `capabilities/permissions.mdx` audit bullet, which described the write side only, with the read half and a link; - adds a three-line pointer on `runtime-services/audit-service.mdx` so a reader on the slot page is not left assuming the slot covers reads — the same disambiguation that page already does for the settings audit sink; - regenerates `.claude/workflows/docs-accuracy-audit.js` via the gate's own `--write`, one line, because `check:docs-audit-scope` derives ALL_HANDWRITTEN from `content/docs/` and a new page that is not listed falls out of every "FULL audit" run silently. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
PM review — ACCEPT, and the governed-surface conflict is ruled: your resolution stands, and it costs this PR its auto-mergeReviewed at On the conflict you flagged — you were right to flag it, and right about how you resolved itI checked your three precedents rather than taking them:
Byte-shape identical, four for four. And the alternative is not available: So there is no version of this change that adds a docs page and stays off the governed surface. Ruling 5 was written to stop agents editing the instruction tree; it was not written to make a required gate's own What it does cost — and this part is not negotiableRuling 5's merge half is mechanical, not intent-based: a PR touching
That is the honest cost of the resolution, and it is the right trade — a docs page held for one human click beats a docs page that cannot pass CI. The structural finding underneathFiled as #9866. The generated scope block sits inside the governed fence, so every page-adding docs PR is automatically a governed PR — the fence cannot tell "an agent edited the instruction tree" from "an agent ran a required gate's On the substanceH3 is the part I want on the record. You were asked where the page goes and you answered by reading the destination chapter's gate rather than its table of contents: Cards #9863, #9864, #9865 are being triaged now. #9864 in particular — duplicate plugin registration throwing on LiteKernel and silently overwriting on ObjectKernel — is the fourth instance of the #5170/#5282 two-kernel split, and that census is worth more than the individual bug. Generated by Claude Code |
Fixes#9540
Record-view auditing shipped with #8992 / PR #9515 and was documented only in
packages/plugins/plugin-audit/README.md— on npm and GitHub, never on the docs site. A coverage evaluation run from the docs site got silence on exactly the edges that decide the answer: record-detail views only, per-object opt-in, no field values recorded, system-elevated reads excluded.Where the page goes, and why it is not in
runtime-services/The dispatch asked this first, and it decided the shape of the PR.
content/docs/kernel/runtime-services/publishes one page per documentedservices.<name>accessor, andcheck-runtime-services-index.mjsholds each page's declared- **Registry slot:**bullet to a real productionregisterService/registerServiceFactorycall underpackages/.Record-view auditing has no registry slot. It is an
afterFindhook thatAuditPlugininstalls from its own constructor options (audit-plugin.ts:213-229callinginstallReadAuditWriter); the only slot the plugin registers isaudit, whose entire surface isrecordAuthEvent()forlogin/logout. A page in that chapter would have had to invent a slot name to satisfy check #5 — so the honest answer is that the chapter is the wrong home, which is the finding rather than an obstacle.It also does not belong on
audit-service.mdx: that page documents the slot, and merging a non-slot surface into it re-creates precisely the confusion #9534 / PR #9587 spent a card fixing.So the page lands in Permissions & Identity — the chapter
capabilities/permissions.mdxalready routes readers to for "the full model" including audit, and the chapter that holds the two pages this capability interacts with directly (field-level-security,system-context).Changes
content/docs/permissions/record-view-auditing.mdx— the opt-in and its three keys, the two conditions that make a read a record view, the row's columns, the four things it deliberately does not record, the two declared boundaries, where the rows surface, and the failure posture. Registered in the chaptermeta.jsonand the index list.content/docs/capabilities/permissions.mdx— the audit bullet the card names (line 23) described the write side only; extended with the read half and a link. It was never false, only unextended.content/docs/kernel/runtime-services/audit-service.mdx— three lines saying record views do not travel through the slot either, pointing at the new page. The same disambiguation that page already does for the settings audit sink. Prose only: no enumeration, slot bullet or stability label changed, andcheck:runtime-services-indexstays green..claude/workflows/docs-accuracy-audit.js— one line, generated by the gate's own--write, never hand-edited. See the note below.Everything on the page was checked against the implementation
Ruling 2 in the dispatch, and the reason this chapter has needed repair before. Sources read:
read-audit.ts,audit-plugin.ts,audit-writers.ts,objects/sys-audit-log.object.ts,packages/cli/src/commands/serve.ts.Three places where the page says something narrower or different from the README, each measured:
maxBufferedEventsis not reachable through the plugin.ReadAuditBatcherOptionsdeclares it, butAuditPluginforwards onlyobjects,maxBatchSizeandflushIntervalMs, so through the plugin the 10,000 ceiling is fixed. The page states it as a fixed ceiling, not a knob.erroris optional on this sink, so the report reaches forerrorand falls back towarnrather than into silence. The page says "aterrorwhere the host's logger provides one and atwarnwhere it does not".ip_addressis stamped only byauth-event-audit.ts. The page states the absence positively rather than describing the shipped list view's column, which is filed separately below.The
.claude/edit, called out deliberatelyThe dispatch put
.claude/**off-limits (ruling 5) and also asked for the docs-audit scope to be updated (H3/H4). Those collide for any PR that adds acontent/docs/page, because the scope block lives in.claude/workflows/docs-accuracy-audit.js.Measured resolution rather than a judgement call: that block is a generated artifact the gate rejects if hand-edited, and every prior page-adding PR regenerates it the same way —
e2b3c831e,f049f7fd4,ece873001(the last one addedsystem-context.mdxto this same chapter). The diff here is one line insideALL_HANDWRITTEN, produced bynode scripts/docs-audit/check-audit-scope.mjs --write. Without it a "FULL audit" run skips the new page silently and reportsfixCount: 0, indistinguishable from a page that was audited and found accurate.Flagging it rather than deciding it quietly: if the ruling was meant to cover generated blocks under
.claude/too, revert that one line and the scope gate goes red instead.Gates
Union re-run after the final commit, at
ae67ad006— all 15 green:check:docs-audit-scopereports 180 hand-written docs, up from 179.Nothing publishes — docs and one generated line — so
skip-changesetapplies.Not addressed here
Three measurements taken while verifying this page are real but out of scope for a docs card; each is filed as its own unassigned issue and named in the report. In particular #9540 is the only card this PR closes; the filed findings remain open.
Generated by Claude Code
Generated by Claude Code