Skip to content

Commit 53fc099

Browse files
docs(plugin-audit): the published README stops documenting an API, a row shape and an action vocabulary that do not exist (#9517) (#9531)
The README is in the package's published `files` array with `private` unset, so it is what the npm package page renders. It documented twelve `auditService.*` methods that exist nowhere in the repo, a `PluginAudit.configure({...})` entry point that does not exist, an `IAuditService` spec contract that was never declared, a row shape `sys_audit_log` does not have, action values outside its enum, and six `/api/v1/audit/*` routes — all under a banner claiming SOC 2 / HIPAA / GDPR readiness. The compliance paragraph is deleted rather than softened or relocated: it is a company-level claim needing an accountable owner, and does not belong in a package README. The replacement documents only what the code can be pointed at — the real exports, the real columns, the seven-value action enum with the writer for each value, the credential masking, and the subtract-an-exclusion-list coverage model. It also states three gaps the old README obscured (reads, failed operations, and the auth-events-only client fingerprint), and names two dependency boundaries with their degraded behaviour per the access-recipes.mdx pattern. Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5126e79 commit 53fc099

2 files changed

Lines changed: 245 additions & 347 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
"@objectstack/plugin-audit": patch
3+
---
4+
5+
docs(plugin-audit): the published README stops documenting an `auditService` API, a row shape and an action vocabulary that do not exist (#9517)
6+
7+
<!-- adr-0087: not-required (no-migration-prescription) Documentation only. No
8+
authorable property is added, renamed, retired or tombstoned; no schema, type or
9+
runtime behaviour changes. The only edited artifact is the package README, which
10+
ships in the package's `files` array. -->
11+
12+
`packages/plugins/plugin-audit/README.md` is in the package's published `files`
13+
array and `private` is unset, so it is **what the npm package page renders**. It
14+
documented an API surface with no implementation anywhere in the repo, under a
15+
banner claiming SOC 2 / HIPAA / GDPR readiness.
16+
17+
**Measured against `origin/main` before anything was rewritten**, and the drift
18+
was wider than the ledger of it:
19+
20+
- **Every `auditService.*` method the README called is absent from the repo**
21+
`getFailedActions`, `logAdminAction`, `logDataAccess`, and also
22+
`getRecordHistory`, `getUserActivity`, `searchLogs`, `getRecordSnapshot`,
23+
`generateReport`, `archiveLogs`, `purgeLogs`, `logDataDeletion`,
24+
`logDataExport`. Twelve methods, zero implementations. A reader following the
25+
README wrote code that could not compile.
26+
- **`PluginAudit` does not exist**, and neither does the `.configure({...})`
27+
static it was called through — no class in this repo exposes one. The export is
28+
`AuditPlugin`, a `Plugin` class registered as `kernel.use(new AuditPlugin())`
29+
and taking **no configuration at all**. The documented config object
30+
(`trackObjects`, `trackFields`, `retentionDays`, `autoArchive`, `excludeUsers`,
31+
`trackSystemEvents`) was fabricated in full.
32+
- **`IAuditService` is not in `@objectstack/spec/contracts`** — the README's
33+
"Contract Implementation" section named an interface the spec has never
34+
declared.
35+
- **The row shape was not the shipped one.** The README declared `timestamp`,
36+
`userName`, `userEmail`, `recordName`, `changes`, `sessionId`, `status` and
37+
`errorMessage`. `sys_audit_log` declares none of them.
38+
- **The action values were outside the enum.** `'insert'`, `'auth:login'`,
39+
`'security:password_reset'`, `'workflow:approval'` and `'user_role_change'` are
40+
not forms this object accepts; the namespaced-colon spelling never was one.
41+
- **The object name was wrong**`audit_log`, not `sys_audit_log`.
42+
- **The REST namespace does not exist.** Six `/api/v1/audit/*` routes were
43+
documented; the object declares `apiMethods: ['get', 'list']` and is read over
44+
the ordinary object API.
45+
46+
The compliance paragraph is **deleted, not softened or relocated**: a
47+
regulatory-readiness claim is a company-level statement needing an accountable
48+
owner, and it does not belong in a package README. The three external
49+
SOC 2 / GDPR / HIPAA links that existed only to support that framing are gone
50+
with it.
51+
52+
The replacement documents only what the code can be pointed at: the real exports;
53+
the real `sys_audit_log` columns; the seven-value action enum **with the writer
54+
for each value**, so a reader can check any row of it; the credential masking on
55+
`old_value` / `new_value`; and the coverage model, which is
56+
**all objects minus an exclusion list** rather than the fabricated per-object
57+
`trackObjects` config — subtraction, because the object universe is open and an
58+
enumerated allow list would silently stop auditing everything registered after
59+
boot.
60+
61+
Three things are now stated that the old README obscured, all of them gaps a
62+
reader could otherwise mistake for coverage:
63+
64+
- **reads and views are not on the ledger** — no writer emits a read action;
65+
- **failed operations are not on the ledger** — there is no success/failure
66+
column, and the writers fire only on `after*` events, i.e. only on operations
67+
that succeeded, so `getFailedActions`-style "security monitoring" had no
68+
mechanism behind it in the first place;
69+
- **`ip_address` / `user_agent` are populated on auth events only** — the
70+
record-level writer does not stamp them, so a null client fingerprint on a CRUD
71+
row does not mean the request had none.
72+
73+
Two dependency boundaries are **named with their degraded behaviour** rather than
74+
left silent, following the `access-recipes.mdx` pattern: hierarchy-relative
75+
permission scopes need `@objectstack/security-enterprise` and **fail closed to
76+
`own`** without it, so a grant written to let managers read their reports' audit
77+
rows shows them only their own on an open build; and `lifecycle.archive` needs a
78+
registered `archive` datasource, **failing closed to retention** without one —
79+
nothing is ever deleted and the table grows, which is the safe direction for a
80+
ledger but not the documented one.

0 commit comments

Comments
 (0)