Skip to content

Commit e7ce606

Browse files
plugin-audit: correct two stale config_change comments after #30937 (#30981)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} --> _Requested by **Elon** · [project thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DJQ32N7D7QcUWJ5SjJDMCT5)_ domain:server#4 · os-elon-musk · session_016WV4d1abDZNVe9GRYCpLEn Fixes #30945 Claim: 6688172302 (full re-post with `sys-audit-log.page.ts` on the surface) Clause-②: no (comment-only) Metadata-protocol: none ## 维护者速读 - 改了什么:`plugin-audit` 三处注释。只改注释,不改任何代码行为。 - 为什么改:#30937 之后,非密钥设置的 `config_change` 审计行自己就带可读的改前值和改后值,旧注释还说它只有摘要、不带字段值。 - 风险与回滚:零运行时风险,单提交可整体回滚。 - 先看:`audit-plugin.ts` 第 277 行起;`audit-log-read-visibility.ts` 第 57 行起;`sys-audit-log.page.ts` 文件头第 14 行起。 - 需要你做的:无,席位落地。 ## What changes Three comments in `packages/plugins/plugin-audit/src/`. No code line changes. - `audit-plugin.ts` (the `pages:` comment, about :277). It said a `config_change` row's digest sits next to the CRUD mirror's row "that carries the value". After #30937, `config-change-audit.ts` writes `old_value` / `new_value` as `{ namespace, key, scope, value, digest }`, with `value` omitted only for a secret-valued key. The comment now says the record page puts the `config_change` row beside the mirror's rows about the same settings row, that a non-secret key's row carries its readable before and after itself, and that a secret-valued key's row carries only the digest. - `audit-log-read-visibility.ts` (the "Rows about no record" bullet, about :57). It said these rows carry no record's field values. A `config_change` row stored before its writer recorded the settings row has no `record_id`, but still names its store as `object_name` and still carries the setting's `value` and `digest`. The false clause is removed. A new sentence says what `redactAuditLogRows` does: it keys on `object_name` and `action`, not on `record_id`, so a `config_change` row naming `sys_setting` or `sys_platform_setting` has `value` and `digest` dropped on both sides for a reader whose field-level security masks that store's `value`, with or without a `record_id`. - `sys-audit-log.page.ts` (module header, about :14-24). It said a `config_change` row's `new_value` is a DIGEST, never the value, and that the value is one row down. It now says the row carries a non-secret key's readable before and after and only the digest for a secret-valued key, and that the page lists the `config_change` row beside the mirror's rows as the settings row's history. ## Why PR #30937 (#30923) made the row readable and added the `object_name`-keyed narrowing in `audit-log-field-redaction.ts`. These three comments still described the earlier digest-only row. Found in that PR's contract review (6685638224), filed as #30945. ## Verification `skip-changeset`: comment-only, nothing publishes a different behaviour. `node scripts/pm/dispatch-gates.mjs --ran`: 47 derived, 41 run with exit 0, 6 NOT MEASURED (exit 3, prerequisite not met), 0 unrun. - NOT MEASURED, reason: they read `dist/` of the whole workspace, which a fresh worktree has not built. `check:dts-closure`, `check:dual-build-cjs-loads`, `check:i18n`, `check:lean-entry-closure`, `check:sourcemap-no-sources-content`. CI runs them. - NOT MEASURED, reason: shallow clone cannot reach the pinned positive-control commit. `check-plugin-teardown-shape.mjs --self-test` (checker health only). CI runs it. No dogfood run, no unit test change: the diff touches no executable line. ## Acceptance notes - None. ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. - [x] 2. Every name I added uses the casing for its kind. - [ ] 3. No formatter ran; `pnpm lint` passes. (No formatter ran; lint not run locally, CI runs it.) - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. - [ ] 6. (n/a, not touched) `packages/spec` touched: its generated artifacts are regenerated and committed. - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English. - [x] The *Before Submitting* list in CONTRIBUTING.md is done. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_016WV4d1abDZNVe9GRYCpLEn <!-- signed: domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4 --> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8847e09 commit e7ce606

3 files changed

Lines changed: 21 additions & 14 deletions

File tree

‎packages/plugins/plugin-audit/src/audit-log-read-visibility.ts‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,19 @@
5454
* `config_change` row stored before its writer recorded the settings row,
5555
* an auth event that carried no session id, and an `action_invocation` row
5656
* of an action invoked with no subject record.
57-
* There is no record to judge, and none carries a record's field values
58-
* (the per-writer measurement in `audit-log-field-redaction.ts`), so they
59-
* are OUTSIDE this gate's class and are served under the ledger's own grant
57+
* There is no record to judge, so they are OUTSIDE this gate's class and
58+
* are served under the ledger's own grant
6059
* exactly as before — through a predicate on the ledger's own columns
6160
* ({@link ledgerRowAboutNoRecordWhere}), so a broad read is served whole. This is where the ledger differs from the activity
6261
* stream, which excludes every row naming no parent: the stream has no
6362
* platform producer of such rows, while these have three, and the shipped
6463
* `config_changes` list view reads `import` rows (and the older
6564
* `config_change` rows) through the data door.
65+
* The field-level redaction does not key on `record_id`: a `config_change`
66+
* row naming a settings store as `object_name` carries that setting's
67+
* `value` (readable for a non-secret key) and `digest`, and both are
68+
* dropped for a reader whose field-level security masks the store's
69+
* `value` (`audit-log-field-redaction.ts`), with or without a `record_id`.
6670
* - **A record action that names no record** — a `create` / `read` / `update`
6771
* / `delete` row with no `record_id` (the CRUD mirror stamps `null` when it
6872
* cannot derive the id): about a record the gate cannot name, so excluded

‎packages/plugins/plugin-audit/src/audit-plugin.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,10 @@ export class AuditPlugin implements Plugin {
275275
namespace: 'sys',
276276
objects: [SysAuditLog, SysActivity, SysComment, SysCommentReaction],
277277
// The ledger row's record page: its fields, and every ledger row about
278-
// the same record beside it, so a `config_change` row's digest sits next
279-
// to the mirror's row that carries the value (`sys-audit-log.page.ts`).
278+
// the same record beside it, so a `config_change` row sits next to the
279+
// mirror's rows about the same settings row (`sys-audit-log.page.ts`).
280+
// A non-secret key's `config_change` row carries its readable before
281+
// and after itself; a secret-valued key's carries only the digest.
280282
pages: [SysAuditLogDetailPage],
281283
// ADR-0029 D7 — contribute the one Audit Log entry into the Setup app's
282284
// `group_diagnostics` slot. The plugin owns sys_audit_log (K2), so the

‎packages/plugins/plugin-audit/src/sys-audit-log.page.ts‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ import type { Page } from '@objectstack/spec/ui';
1111
*
1212
* ## Why the page exists: the other rows about the same record
1313
*
14-
* A settings write records a `config_change` row whose `new_value` is a
15-
* DIGEST, never the value (`service-settings`' `config-change-audit.ts`), so
16-
* the row alone cannot answer "what was it changed to". The CRUD mirror
14+
* A settings write records a `config_change` row whose `old_value` and
15+
* `new_value` carry the setting's readable before and after for a key that
16+
* is not secret-valued, and only its digest for a secret-valued key
17+
* (`service-settings`' `config-change-audit.ts`). The CRUD mirror
1718
* (`audit-writers.ts`) writes its own row about the same write, on the stored
18-
* settings row, and that row carries the change: a non-secret value's old and
19-
* new state, a secret's only as the mirror's ledger view masks it. Both rows
20-
* name the same settings row as `record_id` (the `config_change` writer
21-
* records the id of the row the write landed on), so this page lists every
22-
* ledger row whose `record_id` is this row's: the `config_change` row and the
23-
* mirror's rows sit side by side, and the value is one row down.
19+
* settings row: a non-secret value's old and new state, a secret's only as
20+
* the mirror's ledger view masks it. Both rows name the same settings row as
21+
* `record_id` (the `config_change` writer records the id of the row the write
22+
* landed on), so this page lists every ledger row whose `record_id` is this
23+
* row's: the `config_change` row and the mirror's rows sit side by side, the
24+
* history of that settings row in one list.
2425
*
2526
* The list is the ledger itself, keyed on the pointer's id half on both sides
2627
* (`relationshipField` and `relationshipValueField` both `record_id`): the

0 commit comments

Comments
 (0)