Skip to content

feat(plugin-audit)!: sys_comment 的 visibility / reply_count 退役 —— ADR-0049 enforce-or-remove,两键都移除 (#4756) - #4849

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-4756-sys-comment-dead-fields
Aug 3, 2026
Merged

feat(plugin-audit)!: sys_comment 的 visibility / reply_count 退役 —— ADR-0049 enforce-or-remove,两键都移除 (#4756)#4849
os-zhuang merged 2 commits into
mainfrom
claude/issue-4756-sys-comment-dead-fields

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #4756

sys_comment 上两个「声明了但没人读、没人维护」的字段按 ADR-0049 enforce-or-remove 移除。维护者裁决:两键都移除,reply_count 明确不走 rollup hook 路线。

为什么移除 visibility

为什么 reply_count 也移除(而不是补 rollup hook)

#2755 先例逐字对照

sys_attachmentshare_type / visibility 是同构的一对:v1 建模、零运行时消费者,#2755 选择移除而非实现,理由是「attachment access is derived from the parent record」(packages/services/service-storage/CHANGELOG.mdf531a26 条目)。#4630 之后这个论证逐字迁移到 sys_comment.visibility。存量列的处置也照抄:留作 unmanaged leftover,不做数据迁移

消费方复核(裸名扫描,不是 import 扫描)

三仓扫描,读数如下 —— 没有任何真 reader:

reply_count sys_comment 语境的 visibility
objectstack 6 处命中:字段声明 1 + 四份生成 translations + docs/adr/0052 表格一行 5 处命中:字段声明 1 + 四份生成 translations
objectui(/workspace/objectui,git -C 扫描) 只有 camelCase 的 replyCount,是 FeedItem前端本地状态:RecordDetailView 回复时自己 +1,ThreadedReplies 直接 replies.length;从 sys_comment 拉行的 map 只读 id / author_name / author_avatar_url / body / created_at / updated_at / parent_id / reactions —— 不读 reply_count,create 负载也不发 0(visibility 的命中全是 view/section/tab 的 visible 条件与 record-alert 谓词,与本对象无关)
cloud 0 0(命中全是 EE 层级安全/文档,与本对象无关)

objectui 的 create 负载同样从不写 visibility

形态:这是 object field 级退役,不是 spec key 退役

kit 比 spec 轻,以实跑门禁为准,没有照搬 retiredKey():

  • 本仓没有 object field 级的墓碑机制(retiredKey() / UNKNOWN_KEY_GUIDANCE 都是 spec 属性的设施),liveness ledger 也只登记 spec 属性,没有 sys_comment 字段条目 —— 与 [attachments] v1 follow-ups: sys_file orphan lifecycle + non-admin permission matrix dogfood #2755 当时一致。
  • 因此墓碑由 pin 测试 + 源码处方注释承担:sys-comment-retired-fields.test.ts 在任一字段被复活时变红,失败信息里直接带处方。
  • translations:按配置 docstring 记录的命令用 node scripts/check-i18n-bundles.mjs --write --filter=plugin-audit 重生(merge 模式,四份 bundle 各删 11 行,手写译文全部保留),未手改生成物。plugin-audit 不产 metadata-forms bundle(其 extract 配置带 --objects-only --no-metadata-forms),platform-objects*.metadata-forms.generated.ts 与本对象无关,未被触及。
  • changeset 定级 minor(与 [attachments] v1 follow-ups: sys_file orphan lifecycle + non-admin permission matrix dogfood #2755 在 15.1.0 的处理、以及当前 17.x rc 线上其他移除类 changeset 一致),body 写明 FROM → TO 与存量列不迁移。

处方(墓碑写在哪都一致)

存量 DB 列:不迁移,以及移除后各路径的响亮程度

#2755 先例留作 unmanaged leftover。诚实地区分两条路径:

Pin 测试与 sabotage 实跑

packages/plugins/plugin-audit/src/objects/sys-comment-retired-fields.test.ts:两个字段不在 fields 里、不在 index / highlightFields / titleFormat / nameField 里,且两条处方各自的替代路径(parent_id / thread_id)仍在。

sabotage(把两个字段声明原样加回)实跑 —— 必须红,且失败信息带处方:

 ❯ src/objects/sys-comment-retired-fields.test.ts (5 tests | 2 failed) 10ms
     × visibility is not declared on sys_comment 6ms
     × reply_count is not declared on sys_comment 1ms

AssertionError: sys_comment.visibility was retired under ADR-0049 (#4756) — comment
visibility derives from the record `thread_id` points at (#4630); a per-row enum would
be a second, unenforced source of truth. An external/portal distinction must be designed
against ADR-0090 D11 `externalSharingModel` first.:
expected [ 'id', 'thread_id', …(13) ] to not include 'visibility'

AssertionError: sys_comment.reply_count was retired under ADR-0049 (#4756) — count
`parent_id` children at read time (#4756); a hook-maintained roll-up drifts through the
predicate/bulk write-hook gaps tracked by #4770 / #4778 / #4779.:
expected [ 'id', 'thread_id', …(13) ] to not include 'reply_count'

 Test Files  1 failed (1)
      Tests  2 failed | 3 passed (5)

恢复后同一文件 5 passed。

ADR-0052 的一行注记

docs/adr/0052 §5 的对比表里有一行把 reply_count 列为「已声明的字段」。决策本身不动(Prime Directive #13),只在表下加一条 > Note (#4756),说明该行记录的是决策当时的字段清单、其中 reply_count 已退役、threading 本身(parent_id)/mentions/reactions 不受影响 —— 免得后来的读者(尤其是 AI)从一张历史表里读出一个已经不存在的字段。

验证(全部实跑读数,merge origin/main 之后重跑)

  • pnpm build --concurrency=2Tasks: 71 successful, 71 total
  • pnpm --filter @objectstack/plugin-audit testTest Files 7 passed (7) / Tests 94 passed (94)
  • pnpm --filter @objectstack/plugin-audit typecheck → 无输出(clean)
  • 全仓 turbo run typecheck --concurrency=2Tasks: 122 successful, 122 total
  • pnpm check:i18nOK (9 package(s), all bundles in sync).
  • pnpm check:i18n-coverageOK (12 config(s), 660 baselined untranslated string(s), none new).
  • 受影响消费方:@objectstack/rest Test Files 38 passed / Tests 573 passed;@objectstack/metadata-protocol 31 passed / 260 passed;@objectstack/platform-objects 9 passed / 266 passed
  • 未触发 packages/spec 生成物(本 PR 不改 spec),四张 ratchet 无改动。
  • content/docs/releases/ 一个字未碰。

草稿状态,不 auto-merge、不自行 ready;入队由 PM 决定。


Generated by Claude Code

claude added 2 commits August 3, 2026 09:35
…, ADR-0049)

Both fields were declared with zero runtime consumers — nothing in this repo,
in objectui, or in cloud ever read or maintained either one. Maintainer
decision on the enforce-or-remove question: remove both. Same disposition and
the same stated reason as sys_attachment.share_type / .visibility in #2755
("attachment access is derived from the parent record").

- visibility: a security-LOOKING key with no gate behind it — not consulted by
  enforceFeedsCapability, the #4630 record-level gates, the REST layer, or
  objectui's discussion panel, so a comment marked `private` was as visible as
  a `public` one (Prime Directive #10 in its textbook shape). No replacement
  key: after #4630, who can see a comment derives from the record thread_id
  names. An external/portal meaning for `internal` needs ADR-0090 D11
  externalSharingModel first, and can return enforce-first.
- reply_count: never incremented and readonly, so every row read 0 forever.
  Deliberately NOT replaced by an afterInsert/afterDelete roll-up — the
  predicate/bulk write-hook gaps tracked by #4770 / #4778 / #4779 are exactly
  where such a counter drifts, and a drifting counter is worse than none.
  Count parent_id children at read time instead.

Existing DB columns stay as unmanaged leftovers, no migration (as in #2755).
plugin-audit's four translation bundles regenerated by the documented
extractor; a pin test fails loudly, prescription included, if either name is
re-declared.

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

vercel Bot commented Aug 3, 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 3, 2026 9:54am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/plugin-audit.

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

  • content/docs/deployment/cli.mdx (via @objectstack/plugin-audit)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/plugin-audit)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-audit)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-audit)

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.

@os-zhuang
os-zhuang marked this pull request as ready for review August 3, 2026 09:55
@os-zhuang
os-zhuang enabled auto-merge August 3, 2026 09:55
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit 04b9776 Aug 3, 2026
21 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-4756-sys-comment-dead-fields branch August 3, 2026 10:10
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.

sys_comment.visibility and sys_comment.reply_count are declared but nothing anywhere reads or maintains them (ADR-0049 enforce-or-remove)

2 participants