Skip to content

refactor(plugin-audit)!: retire export / permission_change from the sys_audit_log action enum (#8147) - #8200

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-8147-audit-action-enum-retire
Aug 12, 2026
Merged

refactor(plugin-audit)!: retire export / permission_change from the sys_audit_log action enum (#8147)#8200
os-zhuang merged 1 commit into
mainfrom
claude/issue-8147-audit-action-enum-retire

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Part of #8147

⚠️ Part of, not Fixes — deliberately. This lands 2 of the 3 values the
2026-08-12 ruling named. The third (import) is referred back to the maintainer
because its stated premise is measurably false; see "The escalation" below.
Merging this must not close #8147.

What landed

export and permission_change are retired from the sys_audit_log.action
enum. Neither has ever been written. The repo has exactly two
sys_audit_log writers:

writer vocabulary
packages/plugins/plugin-audit/src/audit-writers.ts (generic hook writer) actionFor() maps afterInsert/afterUpdate/afterDelete to create/update/delete and nothing else
packages/plugins/plugin-auth/src/admin-import-users.ts action: 'import', run-level, record_id: null

Neither emits export or permission_change, so the shipped list views
filtering on them and the dashboard tiles counting them were permanently empty —
the visible product defect the ruling names (空 widget + 永远查不到东西的过滤器).

  • action enum: export + permission_change removed
  • auth_events list view filter: narrowed to ['login', 'logout']
  • config_changes list view filter: export dropped, config_change and import kept
  • plugin-audit translation bundles regenerated (4 locales, via check-i18n-bundles --write — not hand-edited)
  • ADR-0087 registration: semantic migration audit-log-action-enum-retired on D3 step 17, with spec-changes.json and the upgrade guide regenerated
  • new pin test sys-audit-log-retired-actions.test.ts
  • service-analytics routing fixture reseeded off permission_change

Why a semantic entry and not a D2 conversion

sys_audit_log is a platform-owned append-only object whose every field is
readonly: true. Nobody authors an audit row and nobody authors this enum, so
there is no source for the chain to rewrite — the same disposition
BatchOptions.validateOnly and the notification cursor already take in this
major. As an enum-VALUE retirement nothing lands in RETIRED_KEYS_BY_MAJOR and
the four surface ratchets are byte-identical by construction (no def and no
authorable key changed) — verified, they did not move.

The escalation: import is NOT retired

The ruling named import on the premise 无此 feature. That premise is false:

  • plugin-auth/src/admin-import-users.ts writes a real run-level audit row on
    every admin user-import run, and its docblock records the design decision
    (corrected rationale, superseding an earlier stale claim) that this row is a
    deliberate complement to the per-row rows, not a duplicate.
  • Case W4 of packages/qa/dogfood/test/admin-identity-audit-trail.dogfood.test.ts
    asserts that row exists, with record_id: null and metadata.event === 'user.import_run'.

Retiring it would make the enum deny a value the platform writes — and do it
silently: validateRecord skips readonly fields on insert, every field
here is readonly, so nothing rejects the write and nothing goes red. The result
would be written-but-not-declared, which for an audit surface is strictly worse
than the declared-but-never-written defect this card exists to fix, because the
row exists and the contract denies it. config_changes is also the only shipped
view that lists those rows.

Ablation (predicted before measured)

Restoring both values to the enum, everything else held:

surface predicted measured
new pin test RED, exactly 2 failures (the "not declared by the enum" cases); filter/dangling/import cases stay green RED, exactly 2, exactly those. 205 others passed
check:i18n (plugin-audit) RED, bundle drift RED — DRIFTED (4)
check:spec-changes / check:upgrade-guide / check:authorable-surface GREEN — nothing cross-checks the ADR-0087 entry against the enum PASS / PASS / PASS
service-analytics routing test GREEN — fixture uses delete, never validates against the object schema 1655 passed

Zero divergence. The negative arms matter as much as the red one: the ADR-0087
registration is not verified against reality by any gate
, and the
service-analytics fixture is not a detector of this retirement. The only
mechanical detectors are the new pin test and the i18n bundle ratchet — which is
precisely why the pin test is in this PR, with its expectations written as
literals so that expectation and reality do not derive from the same source.

Gates

check:nul-bytes, check-adr-0087-registration, check-changeset-no-major,
check-empty-changeset, check:migration-registry, check:spec-changes,
check:upgrade-guide, check:authorable-surface, check:api-surface,
check:liveness, check:i18n, check:adr-anchors, check:merge-driver,
check:cross-package-test-inputs, check:test-source-alias,
check:docs-audit-scope, check:engine-double-contract,
check:query-options-erasure — all PASS. check:type-check-debt PASS from the
repo root after a full build closure (no entry above its ceiling; the surplus
notes are pre-existing and in packages this PR does not touch — ledger not
lowered). plugin-audit 207 tests pass, service-analytics 1655 pass,
plugin-audit + spec typecheck pass.

Downstream, deliberately untouched

⚠️ Both are scoped as "the three retired values". If the maintainer upholds this
PR's finding, both need correcting to two — dropping import from the
console badge map would leave real, existing rows rendering without a label.

Generated by Claude Code


Generated by Claude Code

…_audit_log action enum (#8147)

Retires the two action values with no writer anywhere in the repo, per the
maintainer ruling of 2026-08-12 on #7675. Narrows the auth_events and
config_changes list-view filters, regenerates the translation bundles, and
registers the retirement under ADR-0087 as `audit-log-action-enum-retired`.

`import` is deliberately NOT retired: plugin-auth's admin user-import writes a
real run-level row with that action, pinned by dogfood case W4. Escalated on
the issue for a maintainer ruling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEVB6w7D7uCszR9Mw1BL73
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 12, 2026 8:00pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/plugin-audit, @objectstack/spec.

107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/plugin-audit, @objectstack/spec)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/plugin-audit)
  • content/docs/deployment/tenancy-modes.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/permissions/system-context.mdx (via packages/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-audit, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/apps.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

7 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-audit, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Aug 12, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review August 12, 2026 20:32
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 12, 2026
Merged via the queue into main with commit 344a22a Aug 12, 2026
27 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-8147-audit-action-enum-retire branch August 12, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

audit-log (C): retire export / import / permission_change from the sys_audit_log action enum and its in-repo consumer surfaces (ADR-0087 registration)

1 participant