Skip to content

feat(plugin-audit)!: sys_comment.reactions retires; a reaction lives only in sys_comment_reaction, and stored reactions are not migrated - #22903

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-22573-retire-comment-reactions-column
Oct 11, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-22573-retire-comment-reactions-column

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #22573
Clause-②: no (narrowing)

sys_comment.reactions retires under the maintainer's ruling A on #22505 as amended (record 6091550406): 「同意;sys_comment.reactions 可以退役;可以不用考虑历史数据迁移;」. Per the director's judgment of the delegated point (6091621568), nothing takes its place on the comment row: no stored aggregate and no block computed on read. A reaction is its reactor's own sys_comment_reaction record, which landed in PR #22603. No stored reaction is migrated.

What changed

  • packages/plugins/plugin-audit/src/objects/sys-comment.object.ts: the reactions field is gone. The docblock records the retirement, its reason and what an existing database keeps. The file surface is the one the claim names; the producer is this declaration, nothing else.
  • The four generated translation bundles (plugin-audit/src/translations/{en,es-ES,ja-JP,zh-CN}.objects.generated.ts) drop the field's label. They were regenerated with node scripts/check-i18n-bundles.mjs --write, not edited by hand. Only the plugin-audit bundles moved.
  • Retirement record: an ADR-0087 D3 semantic entry, packages/spec/src/migrations/entries/semantic/18.sys-comment-reactions-column-retired.ts, on the protocol-18 step. This is a platform-object column, not an authorable spec key. So nothing goes into RETIRED_KEYS_BY_MAJOR (no spec schema ever declared the key) and there is no liveness-ledger row. That is the shape position-permissions-column-retired, sys-job-organization-column-retired and sys-audit-log-organization-column-retired already use. The gates decided this. check-adr-0087-registration --base origin/main printed: ✓ check-adr-0087-registration: 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition. .changeset/22573-sys-comment-reactions-retired.md [BREAKING+bang+clause-②-narrowing] registered sys-comment-reactions-column-retired (new here: sys-comment-reactions-column-retired). check:spec-changes, check:upgrade-guide, check:api-surface and check:authorable-surface are all green, and no generated spec artifact moved.
  • .changeset/22573-sys-comment-reactions-retired.md covers @objectstack/plugin-audit and @objectstack/spec, both minor. The minor follows the launch-window convention that check-changeset-no-major enforces, and the spec bump carries the new registry entry, which ships in @objectstack/spec/migrations. The changeset states that existing emoji reactions in the column are gone after the upgrade and that reactions now live in sys_comment_reaction. It gives a FROM → TO table and an operator sentence built from the measurements below.

Measured: what the data door answers a write that still names the field

Showcase booted with pnpm dev -- --fresh -p PORT --database file:SCRATCH/react.db (SqlDriver(better-sqlite3)), signed in as the seeded admin, REST data door:

request before (base 45e206e49) after (this branch)
POST /api/v1/data/sys_comment with reactions 201, map stored and returned 400 {"error":"Unknown field 'reactions' on object 'sys_comment'","code":"INVALID_FIELD","field":"reactions","object":"sys_comment"}, nothing written
PATCH /api/v1/data/sys_comment/ID with reactions 200, map overwritten 400 INVALID_FIELD, same body
GET /api/v1/data/sys_comment?reactions=x (not measured before) 400 INVALID_FIELD
GET /api/v1/data/sys_comment/ID (row holding a stored map) reactions returned 200, no reactions key
POST without reactions 201 201

The after-reading is a loud refusal, not a silent drop. It is the engine's undeclared-field preflight, which runs before any hook or driver. The door's handling of unknown fields is unchanged.

Measured: what happens to the stored column (SQL driver)

The after-boot ran on the same sqlite file as the before-boot, which had a reactions column holding a stored map:

  • Schema sync leaves the column in place, values included. I read PRAGMA table_info('sys_comment') after the boot. The column still holds the map written before the change.
  • The boot is clean. One drift line, [schema-drift] sys_comment.reactions: column exists in the database but not in metadata (orphaned) — "os migrate apply --allow-destructive" to drop it., and no error.
  • The named remedy works. On a copy of the database, os migrate plan with an auth secret set lists ✗ sys_comment.reactions [drop_column] as destructive, and os migrate apply --allow-destructive --yes drops it (✓ Applied 1 change(s)., column absent on re-read). Without an auth secret the plan composes no auth family, the audit plugin included. It then lists sys_comment under "declared by no object in this plan" and plans no drop. The plan prints that coverage gap itself, and the changeset's operator sentence says to run it with the audit plugin composed.
  • No migration code was written.

Census (re-done at 45e206e49)

  • The column was declared only in sys-comment.object.ts and labelled only in the four bundles. packages/qa/dogfood: 0 hits. examples/: 0 hits. content/docs: no page names the column; the hits are enableReactions, a UI prop, and the word "reactions" in prose.
  • packages/spec/src/api/discovery.test.ts:688 is capabilities.comments.features.reactions, a discovery capability flag in a fixture. It is not about this column.
  • packages/spec/scripts/liveness/key-mention.test.ts:177 uses the English word ("the two reactions available to the seat") in a comment about a ratchet. It is not about this column.
  • docs/adr/0052-audit-is-not-the-activity-feed.md:178 lists reactions among the fields sys_comment declared when that ADR was written. That is historical ADR text on a governed surface, and it is not edited here.

Pins

  • plugin-audit/src/objects/sys-comment-retired-fields.test.ts, new block "reactions stays retired":
    • sys_comment declares no reactions field, and no index, highlight or title names it.
    • The retirement record names it: MIGRATIONS_BY_MAJOR[18].semantic holds sys-comment-reactions-column-retired, its surface starts sys_comment.reactions, and its replacement names sys_comment_reaction.
    • The replacement exists: sys_comment_reaction declares comment_id, emoji and user_id.
  • plugin-audit/src/sys-comment-reactions-door.integration.test.ts runs on a real engine with the real AuditPlugin and the sqlite-wasm driver. A create and an update naming reactions are refused: mapDataError gives 400 with code INVALID_FIELD and field reactions. No row is written, and the update's other key is not applied either. The control is the same create without reactions, which succeeds.
  • Ablation, done once on commit 330fc84c1. I ran node scripts/ablation-replace.mjs (wrap mode, plus a shell trap that restores from HEAD), putting reactions: Field.textarea(...) back into the object. Anchor 1 → 0, blob 5364816272be → 30c2ae8114be. Three tests went red:
    • × sys_comment declares no reactions field, and no index, highlight or title names it — AssertionError: sys_comment.reactions was retired — … expected [ 'id', 'thread_id', …(11) ] to not include 'reactions'
    • × create: 400 INVALID_FIELD naming reactions … — a create carrying reactions was accepted: expected undefined to be defined
    • × update: 400 INVALID_FIELD naming reactions … — same
    • Restore: blob after restore 5364816272be equals the blob at HEAD, git diff HEAD is empty, and an independent git hash-object agrees.
    • The first attempt was refused by the tool before any test ran (my anchor appeared inside the replacement, so the anchor count did not drop). It was a no-op, and I re-anchored on the retirement comment line.
  • The card's second pin, "the console at the bumped pin reacts through reaction records only", has no in-repo harness here. The Console Pin Gate proves the pinned objectui SHA builds; it does not drive the chatter. No showcase smoke test or dogfood test mentions reactions. The evidence is the seat's reading of the console at pin 4997995022 (6112978539 on plugin-security: a member cannot react to another user's comment — reactions are stored on the author's sys_comment row, and the created_by update floor refuses the write (403) #22500): RecordDetailView.tsx uses the records store whenever the deployment declares sys_comment_reaction, which this framework does. I did not invent a harness for it.

Tests and gates (all at f2825700c, the final commit)

  • pnpm --filter @objectstack/plugin-audit test: 47 files, 743 tests passed. pnpm --filter @objectstack/plugin-audit typecheck: exit 0, test layer included (check:test-typecheck: OK).
  • @objectstack/spec: vitest run --project local 648 files / 19375 passed (1 todo); --project repo 55 files / 971 passed. Spec and plugin-audit were rebuilt before the runs.
  • node scripts/pm/dispatch-gates.mjs --commands (9 paths vs merge base 45e206e49) derived 91 commands. All 91 ran and exited 0. --ran reconciliation: ✓ dispatch-gates --ran: 91 derived famil(ies) accounted for — 91 run, 0 NOT-MEASURED.
  • origin/main has moved past the base: 3f694715e, 63739521d, 3fdb92db0, 5ce6773a5, 20028dfff. None touches plugin-audit. The only spec file among them is a different migration entry, so I did not merge; the merge ref CI builds covers the join.

Acceptance notes

  • A pending release note that becomes false. .changeset/22566-comment-reaction-record.md (from PR feat(plugin-audit): sys_comment_reaction, the reactor's own record of an emoji reaction #22603, not yet consumed: .changeset/pre.json lists no consumed changesets) ends with "sys_comment.reactions is unchanged in this release … It is retired separately". Both changesets are pending for the same release. I first corrected that bullet in place. check-empty-changeset then refused, as designed for somebody else's release note: "DELIBERATE CORRECTION … say so on the PR and get it confirmed; this gate stays red either way". So I restored the file byte-for-byte to the base (blob d5ba5fd69f4f). This PR's own changeset now says it supersedes that line. Whether to correct the sibling note too, with the gate red until a person confirms, or in a separate docs-only change, is the seat's call. The one-line replacement would be: "sys_comment.reactions is retired by a separate change on this line, which carries its own entry. Reactions stored in that column are not converted into records."
  • An application that shows reactions still owes a sys_comment_reaction grant (read, create, delete). That was handed to the repo:hotcrm seat in 6094633923 and is not part of this PR.
  • The claim's fences held: no change to sys_comment_reaction, its access hooks, its own-record floor, the author-only edit rule on sys_comment, or objectui.

Generated by Claude Code

A reaction is its reactor's own sys_comment_reaction row; nothing about
reactions is stored or computed on the comment row. The four generated
translation bundles drop the field's label (check-i18n-bundles --write).

Claude-Session: https://claude.ai/code/session_013LbZ9MhPp1iriZEtgJqioA
Co-authored-by: Claude <noreply@anthropic.com>
…rement, and its pins

The semantic entry sys-comment-reactions-column-retired carries the
prescription; the data door's INVALID_FIELD refusal carries the
enforcement. Pins: sys_comment declares no reactions field and the record
names it; a create or update naming the field is refused 400 INVALID_FIELD
and writes nothing.

Claude-Session: https://claude.ai/code/session_013LbZ9MhPp1iriZEtgJqioA
Co-authored-by: Claude <noreply@anthropic.com>
… and the operator sentence

The sibling changeset that added sys_comment_reaction said the column was
unchanged in this release; both are pending stock for the same release,
so that bullet now points at the retirement instead.

Claude-Session: https://claude.ai/code/session_013LbZ9MhPp1iriZEtgJqioA
Co-authored-by: Claude <noreply@anthropic.com>
…de its column line from this entry

check-empty-changeset refuses a change to a changeset this PR did not
add, and a deliberate correction there needs a person's confirmation.
The stale line is reported to the seat instead, and this entry says
plainly that it supersedes it.

Claude-Session: https://claude.ai/code/session_013LbZ9MhPp1iriZEtgJqioA
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/permissions/system-context.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/plugins/packages.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/ui/setup-app.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))

⛔ 6 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v14.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v16.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v17/17-0.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v17/17-1.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v17/17-5.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))
  • content/docs/releases/v17/17-6.mdx (via sys_comment (symbol, a field of const object enObjects; a field of const object esESObjects; a field of const object jaJPObjects; a field of const object zhCNObjects))

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.

What this run could not see
  • 3 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 141 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 3f694715ee43565502bd70d6b3a64b28033531b4 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 6d6329140920b579b33c71efa7efcc991e0a50e8 — the merge of head f2825700c6a7ef2a18cf21ab5fa9cd167b6cee5b into base 3f694715ee43565502bd70d6b3a64b28033531b4, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 6d6329140920b579b33c71efa7efcc991e0a50e8 && git checkout 6d6329140920b579b33c71efa7efcc991e0a50e8
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 3f694715ee43565502bd70d6b3a64b28033531b4 f2825700c6a7ef2a18cf21ab5fa9cd167b6cee5b && git checkout -B drift-repro 3f694715ee43565502bd70d6b3a64b28033531b4 && git merge --no-ff f2825700c6a7ef2a18cf21ab5fa9cd167b6cee5b

node scripts/docs-audit/affected-docs.mjs --json 3f694715ee43565502bd70d6b3a64b28033531b4

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 3f694715ee43565502bd70d6b3a64b28033531b4 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: f2825700c6a7ef2a18cf21ab5fa9cd167b6cee5b
Local-runs: none

Rendered by an isolated reviewer subagent of the seat in Reviewed-by, which adopts it.

Inputs read at 2026-10-11T23:05Z: card #22573 (body and all 5 comments, the seat's ACCEPT 6114828378 read as data), ruling 6091550406 and the director's judgment 6091621568 on #22505, PR #22903 (body, GitHub file list, net diff 45e206e49..f2825700c, 9 files, +290 / -23), and the check-runs on the head. Read-only: no worktree, build, test or gate run; the branch and main were fetched and read with git show / git diff only.

① Derived judgments

  1. sys_comment loses reactions (accept-set narrowing, RIGHT). sys-comment.object.ts at the head declares no reactions; no index, highlightFields, titleFormat, nameField or displayNameField names it. The consequence the diff implies is the engine's undeclared-field preflight: a create, an update or a list filter naming the key answers 400 INVALID_FIELD and writes nothing, and a read no longer projects the column. That is the loud refusal Prime Directive Add comprehensive test suite for Zod schema validation #12 asks for; no alias, ?? fallback or consumer shim was added anywhere in the diff. Pinned on a real engine, the real AuditPlugin and the sqlite-wasm driver (sys-comment-reactions-door.integration.test.ts: create and update refused with mapDataError status 400, code INVALID_FIELD, field reactions, rows unchanged; the control create succeeds) and by the unit pin (sys-comment-retired-fields.test.ts). The PR body's before/after REST table answers the card's "measure first" ask (before at base 45e206e49: 201/200 stored; after: 400, nothing written).
  2. Nothing replaces it on the comment row (RIGHT per 6091621568). No summary field, no stored aggregate, no hook or read-path change is in the file list; the docblock and the in-place comment record the retirement and point at sys_comment_reaction.
  3. No data migration (RIGHT per the amendment 「可以不用考虑历史数据迁移」). No D2 conversion, no backfill, no destructive DDL. The physical column stays under additive schema sync, named orphaned by the boot drift line; the changeset and the D3 entry say so and name os migrate apply --allow-destructive with the audit plugin composed.
  4. Retirement record shape (RIGHT). A D3 semantic entry, 18.sys-comment-reactions-column-retired.ts, filename derived from the id, no index to edit (entries README), no RETIRED_KEYS_BY_MAJOR row and no liveness-ledger row, because no authorable spec key moves. Same shape as 17.position-permissions-column-retired, 17.ups-delegated-from-column-retired and 18.sys-audit-log-organization-column-retired. No relevantWhen, correctly: the acceptance criteria send the author to a runtime door and stored rows, so the reviewed ENUMERATION table in semantic-relevance.test.ts is unchanged. The id is new in this diff, which is what registered requires of check-adr-0087-registration.
  5. Translation bundles (RIGHT). The four plugin-audit *.objects.generated.ts files lose exactly the sys_comment.reactions label/help block (4 lines each) and nothing else; the diff shape is a tool regeneration, not a hand edit.
  6. Public TS surface unchanged (RIGHT). SysComment keeps its name and export; the spec entry is collected into the gitignored registry and reaches consumers through the existing MIGRATIONS_BY_MAJOR export, so api-surface and authorable-surface are expected byte-identical.
  7. Fences held (RIGHT). No change to sys_comment_reaction, comment-access-hooks.ts, the own-record floor, the author-only edit rule in plugin-security, or objectui.
  8. Census, re-done on the head tree (RIGHT that nothing else is owed). Outside the changed files, every reactions mention is the sys_comment_reaction object/hook prose, the UI prop enableReactions, a discovery capability-flag fixture in a spec test (no runtime producer advertises features.reactions), release-owned CHANGELOG/releases pages, and ADR-0052's historical table on a Tier H surface. No view, layout, seed row, dogfood or docs page names the column.
  9. Pinned console (RIGHT, with its limit). .objectui-sha is 4997995022 at the merge base, the head and origin/main; the in-repo console changeset .changeset/console-0df67f237c5a.md (already at the merge base) lists objectui de302c731 (objectui#12078: the chatter stops writing sys_comment.reactions) inside the range that pin carries, so the removal does not break the pinned sibling (Post-Task Checklist step 4). The card's second pin, "reacts through reaction records only", has no in-repo harness; that changeset line is the in-repo evidence, and the record claims no more.

② Semver level

.changeset/22573-sys-comment-reactions-retired.md: @objectstack/plugin-audit: minor, @objectstack/spec: minor. Both packages publish something from this diff (the narrowed object; the new registry entry shipped under @objectstack/spec/migrations), so skip-changeset would be wrong and the two rows are right. The change is BREAKING (a client that wrote the column loses it): the title carries !, the body carries the BREAKING banner, the FROM to TO table with the one-line fixes, the plain sentence that stored reactions are gone after the upgrade, and the operator paragraph. minor rather than major is the launch-window convention check-changeset-no-major enforces. The ADR-0087 disposition is one HTML-comment marker reading adr-0087 registered sys-comment-reactions-column-retired, which resolves to the entry this diff adds.

Clause-②: line: no (narrowing) in the changeset and on line 2 of the PR body; they agree, and they match the diff: no key is added to any published payload, one leaves one, which is the narrowing arm and BREAKING. RIGHT.

③ Boundary flags

open_questions: none declared by the dev. Deviations and findings, each answered:

  • Spec bump added beyond the order's plugin-audit-only surface. Right: the D3 entry is spec source and ships in @objectstack/spec; 22 of the 30 stock registered changesets carry a spec row.
  • .changeset/22566-comment-reaction-record.md edited, refused by check-empty-changeset, restored. Verified byte-identical: blob d5ba5fd69f4f at origin/main and at the head, net diff zero. Its last bullet ("sys_comment.reactions is unchanged in this release") will sit beside this entry in the same compiled release; this PR's changeset explicitly supersedes it. Not a FAIL input. Correcting the sibling note is the gate's deliberate-correction path or a separate docs-only change, the seat's call, not owed here.
  • Base newer than the order's, and main moved 6 commits since the merge base. Checked: the only overlap under the PR's paths is an unrelated edit to 18.ui-bulk-action-param-unknown-keys-refused.ts; nothing under plugin-audit; the registry is generated, so entry adjacency no longer conflicts. The queue rebuilds on current main.
  • --maxWorkers=2 dropped after a bare --. The whole suite ran; no effect on the verdict (the AGENTS.md toolchain trap, as described).
  • First-line os-dev-report form; HTML-comment marker in the changeset. Both as the gates require. No issue.
  • Out-of-scope finding: os migrate plan without an auth secret composes no audit plugin and plans no drop, while the boot drift line names the drop unconditionally. Pre-existing behaviour, not introduced by this diff, loud in both outputs; the changeset's operator sentence adds the precondition. Escalated to the seat as a card candidate: the drift line's prescription could name the composition precondition. Not a FAIL input.
  • Reviewer's own flag: no STEP18_RATIONALE fragment in registry.ts.template. The entries README says a step-18 retirement "still adds" one, but 114 fragments cover 345 step-18 entries, no gate ties an entry to a fragment (step18-rationale-merge.test.ts holds sortedness only), and the entry's own reason carries the narrative. Acceptable; a one-fragment follow-up is the seat's option.
  • ADR-0052 line 178 still lists reactions among sys_comment's declared fields. Historical ADR text on a Tier H surface, correctly untouched here; an amendment note is a separate Tier H act if wanted.
  • Governed surfaces: none of the 9 paths is on the register; 313 changed lines, under 3,000; head repo equals base repo. Draft, needs:contract-review present, auto-merge not armed.
  • Check-runs on the head, latest run per name, read at 2026-10-11T23:05Z: 20 success, 5 skipped, 8 in progress, 0 failure. Complete and green: Build Core, Temporal Conformance (live PG + MySQL), Governed Surface Queue Guard, Check Changeset, Dogfood Regression Gate (1/3, 2/3, 3/3), Dogfood Verify CLI, Spec property liveness, Type Check source/consumer/debt-ledger, and the PR-shape guards. Still in progress: Lint & Repo Gates, Test Core (1/6 to 6/6), Type Check workspace. In progress is not a failure; the seat arms only once every gate-carrying run concludes success.

Implemented-by: claude/issue-22573-retire-comment-reactions-column
Reviewed-by: session_013LbZ9MhPp1iriZEtgJqioA

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 11, 2026 23:20
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 11, 2026 23:20
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 11, 2026
Merged via the queue into main with commit 9963322 Oct 11, 2026
44 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-22573-retire-comment-reactions-column branch October 11, 2026 23:50
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.

Retire sys_comment.reactions (ruling A amended on #22505): no aggregate, no data migration, after the console reads reaction records

2 participants