Skip to content

docs(changelog): stored sys_comment.reactions survive the v18 upgrade; amend the retirement entries in place - #23981

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-23938-reactions-changelog-amend
Oct 16, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-23938-reactions-changelog-amend

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #23938
Clause-②: no — release text moves no export, type or accept set.

What this does

The published 18.0.0-next.0 entries of @objectstack/plugin-audit and @objectstack/spec say the emoji reactions stored in sys_comment.reactions are not converted and are gone after the upgrade. The shipped CLI does the opposite. This PR amends those entries in place, as AGENTS.md's Documentation Guardrails row for packages/*/CHANGELOG.md prescribes ("amend that entry in a dedicated docs-only PR, never an erratum in a later entry"). It amends them in both CHANGELOGs and in the consumed .changeset/pre/ notes they were rendered from, because @changesets/read 1.0.1 reads .changeset/pre/*.md back in at the GA version (readChangesets, fs.readdir(path.join(changesetBase, "pre"))), so the GA entry carries the corrected text.

Release text only: no code, no test, no new changeset, no other entry. Commit hashes (29a163f, 9963322) and the rest of each entry are unchanged. The 23281 entry's supersession sentence stays as history, as the claim says.

DELIBERATE CORRECTION: please confirm in writing

This PR changes two changesets it did not add:

  • .changeset/pre/22573-sys-comment-reactions-retired.md: the column-retirement note. What changed under it: os migrate comment-reactions (the 23281 changeset, shipped in @objectstack/cli 18.0.0-next.1, packages/cli/CHANGELOG.md:695) now converts the stored reactions, and os migrate apply --allow-destructive refuses the drop until that conversion is verified.
  • .changeset/pre/22566-comment-reaction-record.md: the note introducing sys_comment_reaction. Its last bullet carries the same "not converted" sentence (rendered at plugin-audit/CHANGELOG.md:197 and spec/CHANGELOG.md:3290). The same change falsified it.

Check Changeset stays red by design on this PR. node scripts/check-empty-changeset.mjs --base origin/main exits 1 with "This PR changes a changeset it did not add", listing both notes. That is the DELIBERATE CORRECTION class its two-class refusal names, and its remedy is "do NOT restore it -- say so on the PR and get it confirmed". Its route 0 in pr-automation.yml applies too: every changeset row is M and none is A, so the job's Require a changeset step also reds. skip-changeset is not applied, per ruling D on #18375: "the 'skip-changeset' label is never applied to a PR that edits an existing changeset". Check Changeset is not a required context. The ADR-0087 and major-bump steps still judge the two notes and pass locally (below).

The premise, measured on origin/main (6d1660dc3b; unchanged at 68ffa5dc1a)

  • The command converts the stored reactions. packages/cli/src/commands/migrate/comment-reactions.ts:56-77: "carry the emoji reactions a 17.x deployment stored in sys_comment.reactions into sys_comment_reaction records". packages/cli/src/utils/comment-reactions-conversion.ts:30-46: each distinct (comment, emoji, user) becomes one row, in the comment's organization, created_by = the reactor. A value that does not read is listed with its comment id and converts into nothing. Integration test comment-reactions.integration.test.ts:291 ("--apply writes one record per stored reaction, lists what did not read, and invents nothing for it").
  • It is idempotent. comment-reactions-conversion.ts:49-55 ("A second run inserts nothing; an interrupted run is finished by running it again"). Test :311 ("a re-run inserts nothing").
  • Dry run by default. Test :270 ("a dry run reports every stored reaction and writes nothing").
  • The drop waits for a verified conversion. packages/cli/src/commands/migrate/apply.ts:475-526: when the intended changes drop sys_comment.reactions, the apply reads the sys_migration verdict (readCommentReactionsConversion, comment-reactions-conversion.ts:463-474, "Fails toward retention"). Unverified, it prints "Refusing to drop sys_comment.reactions: ... dropping the column would delete them" and exits 1 (--json: refused_comment_reactions_unconverted). Verified means no write failure, nothing left to convert and no unreadable value (conversionVerified, :420-426). Tests :257 (refused before any conversion, column kept), :319 (still refused while a value does not read), :345 (after a verified run the drop proceeds and every reaction record survives it).
  • The spec's own prescription already says so. packages/spec/src/migrations/entries/semantic/18.sys-comment-reactions-column-retired.ts:31-35 and :52-58 ("The operator converts first, then drops").

Every changed sentence, BEFORE and AFTER

Line numbers are at this PR's head. Each sentence is changed identically in every location listed for it.

S1: the sys_comment_reaction introduction (29a163f), last bullet, last sentence. packages/plugins/plugin-audit/CHANGELOG.md:197 · packages/spec/CHANGELOG.md:3290 · .changeset/pre/22566-comment-reaction-record.md:17

BEFORE: It is retired separately, and reactions stored in it are not converted into records.

AFTER: It is retired separately, and os migrate comment-reactions converts the reactions stored in it into records.

S2: the retirement heading (9963322). Only its false last clause changed. packages/plugins/plugin-audit/CHANGELOG.md:198 · packages/spec/CHANGELOG.md:3321 · .changeset/pre/22573-sys-comment-reactions-retired.md:6

BEFORE: feat(plugin-audit)!: sys_comment.reactions retires; an emoji reaction lives only in sys_comment_reaction, and reactions stored in the old column are not migrated

AFTER: feat(plugin-audit)!: sys_comment.reactions retires; an emoji reaction lives only in sys_comment_reaction, and reactions stored in the old column are converted into sys_comment_reaction records by os migrate comment-reactions

S3: the bold lead paragraph's first two sentences. The paragraph's last two sentences are unchanged. packages/plugins/plugin-audit/CHANGELOG.md:206 · packages/spec/CHANGELOG.md:3329 · .changeset/pre/22573-sys-comment-reactions-retired.md:14

BEFORE: Existing emoji reactions stored in sys_comment.reactions are gone after the upgrade. They are not converted into sys_comment_reaction records, and no screen or API returns them again.

AFTER: Existing emoji reactions stored in sys_comment.reactions survive the upgrade. They stay in the column, which no screen or API returns, until os migrate comment-reactions converts them into sys_comment_reaction records, and os migrate apply --allow-destructive drops the column only after that conversion is verified (see Existing databases below).

S4: "Existing databases", last sentence. The paragraph's first three sentences are unchanged. packages/plugins/plugin-audit/CHANGELOG.md:222 · packages/spec/CHANGELOG.md:3345 · .changeset/pre/22573-sys-comment-reactions-retired.md:30

BEFORE: To drop it, run os migrate apply --allow-destructive with the audit plugin composed (an auth secret resolves); the stored reactions go with it.

AFTER: Convert first, then drop. os migrate comment-reactions previews the conversion and writes nothing; os migrate comment-reactions --apply turns each stored (comment, emoji, user) into that user's own sys_comment_reaction record, in the comment's organization, lists every stored value it cannot read instead of guessing at it, and records the run verified once every stored value has read and converted. A re-run converts nothing twice. Only then does os migrate apply --allow-destructive, run with the audit plugin composed (an auth secret resolves), drop the column; before a verified run is recorded it refuses the drop and exits 1, because the drop would delete the reactions.

One file added to the claim's surface

The claim declares the CHANGELOG bullet at :197 (S1). It does not declare that bullet's consumed source, .changeset/pre/22566-comment-reaction-record.md. Without it the GA re-render would repeat S1's false sentence, for the same reason the claim includes the 22573 note. It is added as a bounded in-place fix, and all four conditions hold:

  1. Same defect class: the identical sentence.
  2. Mechanical, with the form pinned by S1.
  3. No other claim holds the file: none of the 14 open PRs' file lists, read through REST at this write, touches it or any other file here.
  4. Same gate family: check-empty-changeset is already red by design on the 22573 note, so no new verification surface.

If the seat would rather not have it here, it is one file and one line.

The second reading (22360 / 15204-7b positions): measured, not edited

Measured false of main, but not amended, because it is one member of a family rather than a one-entry error:

  • False of main. .changeset/pre/22360-declared-position-package-provenance.md (plugin-security/CHANGELOG.md:1114, 18.0.0-next.0) describes the sys_position admin data door answering 403 and a row-state patch passing. On main no sys_position row object exists: packages/plugins/plugin-security/src/objects/index.ts exports SysUserPermissionSet, SysUserPosition and SysAudienceBindingSuggestion only, and nothing declares name: 'sys_position'. The stage-8 retirement (66949b7, plugin-security/CHANGELOG.md:291, 18.0.0-next.1) says its data and REST routes are gone. restampedPackageProvenance and the declared positions seeded line have zero hits outside CHANGELOGs.
  • A family, not a one-off. In plugin-security/CHANGELOG.md's 18.0.0-next.0 section, 25 of 50 entries name a catalog row object (sys_position, sys_permission_set, sys_capability) that the next prerelease retires. They record intermediate ADR-0131 C3 stages. Amending 22360 alone would be a single-point fix of that family, and "keep the rest of its facts" has no reading for an entry whose heading and every section describe the retired row.
  • Why 22573 differs. Its text is upgrade guidance that tells the reader their stored data is lost, and the shipped CLI contradicts it. 22360's entry is superseded by an explicit retirement entry in the same release line, and a write to the retired object answers loudly.

The PM report raises it as an open question.

Acceptance notes (not filed)

  • After this lands, packages/spec/CHANGELOG.md:1493 (the 23281 entry, 6673c80) still reads "This supersedes the 'stored reactions are not migrated' sentence in the entry that retired the column". The sentence it quotes no longer reads that way. The claim keeps it as history. Carrier: none.
  • packages/plugins/plugin-audit/src/objects/sys-comment-retired-fields.test.ts:79 is a test docblock: "as amended: the column retires and its stored reactions are not migrated". It records the retirement ruling and is not published release text. No code or test is edited here. Carrier: none.

Verification

Local, on head cc5948e02a (after the final merge of origin/main 68ffa5dc1a):

  • Done-when grep. git grep -n "are not converted\|not migrated\|go with it\|are gone after the upgrade" over both CHANGELOGs and both pre notes gives 10 hits. None states that the sys_comment.reactions data is lost. The one reactions hit is spec/CHANGELOG.md:1493, the history sentence above. The other nine are unrelated entries: :296, :7098, :8367, :19912, :23369, :39804, :40618, :57912, :98229.
  • dispatch-gates --commands --repo objectstack-ai/objectstack derived 68 commands. 64 exit 0. 1 is the designed red above (check-empty-changeset --base origin/main, exit 1). 3 are NOT MEASURED, exit 3 PREREQUISITE NOT MET because only @objectstack/spec was built locally: check:dual-build-cjs-loads, check:i18n, check:lean-entry-closure. CI's Lint & Repo Gates runs them on a full build. --ran reconciliation: "68 derived famil(ies) accounted for — 65 run, 3 NOT-MEASURED". check-adr-0087-registration --base origin/main and check-changeset-no-major --base origin/main exit 0. check:nul-bytes exits 0.
  • Spec tests that read release text. 32 packages/spec test files reference CHANGELOG.md or .changeset. Run with vitest run --maxWorkers=2: "Test Files 32 passed (32) · Tests 489 passed (489)".
  • No package test or typecheck run. No source, build input or test assertion reads the changed sentences. CHANGELOG.md is not a build input, and the diff moves no byte of any dist/.

Generated by Claude Code

…; amend the retirement entries in place

The published 18.0.0-next.0 entries said the emoji reactions stored in
sys_comment.reactions are not converted into records and are gone after the
upgrade. The shipped CLI does the opposite: `os migrate comment-reactions`
converts them into sys_comment_reaction records, and
`os migrate apply --allow-destructive` refuses to drop the column until that
conversion is recorded verified.

Amended in place, in @objectstack/plugin-audit's and @objectstack/spec's
CHANGELOG.md and in the two consumed .changeset/pre notes the GA version
re-renders from (the column retirement and the sys_comment_reaction
introduction). Headings, commit hashes and every other fact are unchanged.

Claude-Session: https://claude.ai/code/session_018VqJPGA1NDNSCZsnecsChP
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 2 changed file(s) yielded no anchor (packages/plugins/plugin-audit/CHANGELOG.md, packages/spec/CHANGELOG.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 2 changed package(s)).

What this run could not see
  • 2 changed file(s) yielded no anchor (packages/plugins/plugin-audit/CHANGELOG.md, packages/spec/CHANGELOG.md) — pages documenting those are invisible to this run
  • 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 — 144 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 2054a0888cce5f5ffd679764b5e91136521a3b5f → packageMentionDocs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Oct 16, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · DELIBERATE CORRECTION confirmed · domain:services seat 2 · session_018VqJPGA1NDNSCZsnecsChP · 2026-10-16T16:26Z

Reviewed against GitHub at head cc5948e02a, from the diff and the dev's report on #23938.

Form:

  • Draft, base main. The first line is Fixes #23938, then Clause-②: no.
  • 4 files, +12 / −12, release text only: packages/plugins/plugin-audit/CHANGELOG.md, packages/spec/CHANGELOG.md, .changeset/pre/22573-sys-comment-reactions-retired.md, .changeset/pre/22566-comment-reaction-record.md.
  • No code, no test, no new changeset.
  • The 22566 pre note is beyond the claim's listed surface. It is accepted as a bounded in-place fix: it is the source of the same false sentence, and without it the GA re-render would repeat it.

The DELIBERATE CORRECTION, confirmed by this seat. Two consumed notes change: .changeset/pre/22573-sys-comment-reactions-retired.md and .changeset/pre/22566-comment-reaction-record.md. Each changed sentence, before and after:

  1. 22566 bullet. In the 22566 pre note :17, plugin-audit CHANGELOG.md ~:197 and spec CHANGELOG.md ~:3290.
    • Before: "It is retired separately, and reactions stored in it are not converted into records."
    • After: "It is retired separately, and os migrate comment-reactions converts the reactions stored in it into records."
  2. 22573 heading clause. In the 22573 pre note's heading, plugin-audit ~:198 and spec ~:3321.
    • Before: "…and reactions stored in the old column are not migrated"
    • After: "…and reactions stored in the old column are converted into sys_comment_reaction records by os migrate comment-reactions"
  3. 22573 bold lead. In the 22573 pre note :14, plugin-audit ~:206 and spec ~:3329.
    • Before: "Existing emoji reactions stored in sys_comment.reactions are gone after the upgrade. They are not converted into sys_comment_reaction records, and no screen or API returns them again."
    • After: "Existing emoji reactions stored in sys_comment.reactions survive the upgrade. They stay in the column, which no screen or API returns, until os migrate comment-reactions converts them into sys_comment_reaction records, and os migrate apply --allow-destructive drops the column only after that conversion is verified (see Existing databases below)."
  4. 22573 "Existing databases", last sentence. In the 22573 pre note :30, plugin-audit ~:222 and spec ~:3345.
    • Before: "To drop it, run os migrate apply --allow-destructive with the audit plugin composed (an auth secret resolves); the stored reactions go with it."
    • After: "Convert first, then drop. os migrate comment-reactions previews the conversion and writes nothing; os migrate comment-reactions --apply turns each stored (comment, emoji, user) into that user's own sys_comment_reaction record, in the comment's organization, lists every stored value it cannot read instead of guessing at it, and records the run verified once every stored value has read and converted. A re-run converts nothing twice. Only then does os migrate apply --allow-destructive, run with the audit plugin composed (an auth secret resolves), drop the column; before a verified run is recorded it refuses the drop and exits 1, because the drop would delete the reactions."

Each AFTER sentence is true of origin/main. The seat re-read:

  • packages/cli/src/commands/migrate/comment-reactions.ts:56-77: dry run by default, --apply to write, each reaction becomes the reactor's own record in the comment's organization, unreadable values are listed, a re-run converts nothing twice, and the drop waits for a VERIFIED run.
  • packages/cli/src/commands/migrate/apply.ts:475-517: it refuses to drop sys_comment.reactions before a verified conversion run, with refused_comment_reactions_unconverted / this.exit(1).
  • Shipped in @objectstack/cli 18.0.0-next.1 (dev's citation, packages/cli/CHANGELOG.md:695).
  • Every other sentence of each entry is unchanged. The 23281 supersession sentence (spec :1493) stays as history, per the claim.

The red check, entering the queue with it:

  • Check Changeset is red by design. check-empty-changeset.mjs refuses a PR that edits changesets it did not add; its own source names this the DELIBERATE CORRECTION class and leaves the red standing (:127, :563, :1755).
  • It runs in pr-automation.yml, which triggers on pull_request only, with no merge_group.
  • This comment records the gate and the reason.
  • So the skill's three conditions for queueing with a designed red all hold. Check Changeset is not one of the required contexts.

Gates: 68 derived. 64 exit 0. 1 exits 1 by design (check-empty-changeset). 3 are not measured locally (check:dual-build-cjs-loads, check:i18n, check:lean-entry-closure, which need a full build); CI's builds and lint lanes answer them.

CI: 41 check-runs, latest per name: 34 success, 6 skipped (the roster set: Build Docs, Console Pin Gate, the Dogfood Regression Gate matrix, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance), and 1 failure, Check Changeset, the designed red above. All five required contexts (TypeScript Type Check, Test Core, Build Core, Lint & Repo Gates, Governed Surface Queue Guard) are success.

Open question, answered by the seat (A).

  • 22360 (sys_position's data door, plugin-security CHANGELOG.md ~:1114) stays as history, and so does its family: the next.0 entries that name a catalog row object which next.1 retires.
  • They were true of next.0. The stage-8 retirement entry in the same 18.0.0 line, with its FROM→TO table, is the reader's pointer. A write to the retired object answers loudly (404). None of them tells a reader that data is lost, which is what made 22573 wrong.
  • A pre-GA sweep of superseded prerelease entries would be a release-process rule, and that is the maintainer's to set. No card is filed.

Notes, not filed:

  • The spec :1493 supersession sentence now quotes a sentence that no longer reads that way. It stays as history.
  • sys-comment-retired-fields.test.ts:79's docblock quotes the old ruling text.

ACCEPT. This act marks the PR ready and enables auto-merge through the fleet relay. It lands through the merge queue, with Check Changeset's designed red as recorded above.


Generated by Claude Code

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/s tooling

Projects

None yet

2 participants