Repository navigation
Commit e37ea4d
Fixes #19301
Clause-②: no
## What this changes
One sentence, inside the single `effae80` entry of
`packages/spec/CHANGELOG.md`. Nothing else in that entry moves, and no
other entry is touched.
**FROM** — "`undoable` now has its anchor — the patch names exactly the
fields whose prior values are captured."
**TO** — "`undoable` now has its anchor — the merged write bag, `patch`
UNDER the collected `params`, names exactly the fields whose prior
values are captured."
The replacement wording is the one the settled `ActionSchema.undoable`
description already uses, so the entry, the schema description and the
executor now say one thing.
## The entry was contradicting itself
The single entry for `effae80: feat(spec): a row action gets the
declarative single-record field write` stated BOTH capture sets, four
lines apart — the sentence corrected above, against "`undoable` captures
the prior values of exactly the fields written" in the same entry's
executor-contract paragraph.
## Which of the two shipped — measured at `3c10091`
The written set, on four independent readings:
1. `declarativeUpdateWrite` (`packages/runtime/src/action-execution.ts`)
builds the write bag as `{ ...patch, ...params }`.
2. `executeDeclarativeUpdateAction` keys `undoData` off
`Object.keys(data)` over that same bag, so on any params-carrying action
the capture is strictly wider than `patch` names.
3. `packages/runtime/src/action-declarative-update.test.ts` pins exactly
that: "`undoable: true` carries the prior values of EXACTLY the fields
written".
4. The entry's own `patch` bullet, four lines above the corrected
sentence, already says the static values are "merged UNDER the values
`params` collects (a param of the same name wins)".
So the two sentences were never two phrasings of one set, and the
corrected one was wrong on the day it was written — it is not a record
of behaviour that later changed. Correcting it makes the record agree
with the release it describes rather than rewriting shipped history.
**The entry documents 17.3.0, not 17.4.0.** It sits under the `##
17.3.0` heading; the file ships inside the current `17.4.0` tarball
because `CHANGELOG.md` accumulates. The published surface is real either
way — this note only keeps the version attribution straight.
## Why a PR at all, and why this shape
`AGENTS.md` (Documentation Guardrails) rules the route for this exact
case: a `packages/*/CHANGELOG.md` is RELEASE-OWNED and never edited in a
code PR, and "Factual error in a released entry → **amend that entry in
a dedicated docs-only PR**, ⛔ never an erratum in a later entry and
never a rider on code changes". This is that dedicated docs-only PR: no
code rides along, the amendment is in place, and no later entry carries
an erratum.
No mechanical gate forbids the edit. `packages/spec/CHANGELOG.md` is on
no governed-surface row (Prime Directive 14 names `docs/adr/**`,
`docs/NORTH-STAR.md`, `.claude/**`, `skills/**`, `AGENTS.md`,
`CLAUDE.md`), and the standing red line names `content/docs/releases/`,
a different path.
## Changeset — measured, not assumed
`patch`, not `skip-changeset`.
- `packages/spec` is published: `private` unset, version `17.4.0`.
- `CHANGELOG.md` is named in its `files[]`, and `npm pack --dry-run
--ignore-scripts` on the package lists 277 files with `CHANGELOG.md`
among them. The bytes this PR changes ship inside the tarball.
- `AGENTS.md` Post-Task Checklist step 3: `skip-changeset` "is for a
diff that publishes nothing from any released package". This diff
publishes changed bytes from a released package, so that label would be
a false declaration.
- Repo precedent agrees — prose-only corrections inside published
packages take `patch` here.
No labels are written by this PR: the dispatch named none, and
`skip-changeset` is measured above as not applicable.
## Verification
Gate families were derived in this worktree rather than carried: `node
scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
--commands` at `3c10091` names **61**. All 61 were run, each exit code
captured to a file before any pipe, and reconciled with `--ran`: **57
exit 0, 4 NOT MEASURED**.
The four are `check:dts-closure`, `check:dual-build-cjs-loads`,
`check:lean-entry-closure` and `check:sourcemap-no-sources-content`.
Each exited **3 — PREREQUISITE NOT MET**, because no package carries a
`dist/` in this worktree. They read built output across the whole
workspace; this diff contains no TypeScript, so nothing it changes can
reach a `dist/`. CI's `Build Core` covers them.
Package level, through the shared verify lock:
- `pnpm --filter @objectstack/spec test` — exit 0, 511 files passed / 1
skipped, 14951 tests passed.
- `pnpm --filter @objectstack/spec typecheck` — exit 0.
- `pnpm --filter @objectstack/spec exec vitest run
src/system/compliance-families-retirement.test.ts` — exit 0, 10 tests.
That suite walks `CHANGELOG.md` files and skips this filename by name.
`pnpm lint` narrows to nothing here, and the narrowing is measured
rather than assumed: every `files:` block in `eslint.config.mjs` targets
`{ts,tsx,mts,cts,js,jsx,mjs,cjs}` and no markdown processor is
configured; `eslint --no-inline-config --format json` over both changed
paths returns 2 file results, each carrying only "File ignored because
no matching configuration was supplied.", with 0 errors and 0 rule
warnings. The diff holds no file in eslint's population, so no untouched
file's verdict can move.
Not measured locally, with its reason: the two cross-package
`action-owner-key-single-source.test.ts` suites (`packages/runtime`,
`packages/objectql`) fail to resolve `@objectstack/objectql`'s entry in
an unbuilt worktree. Neither can be moved by this diff by construction —
their `SCANNED_EXTENSION` is `.ts`, and both `CHANGELOG.md` and
`.changeset/` are ruled exclusions in their `NOT_A_STALE_MENTION` table.
## Acceptance notes
Noted, not filed, and deliberately not fixed here — fixing it would turn
this into a code PR, which the route above forbids:
- `packages/runtime/src/action-execution.ts`, in the comment directly
above the `undoData` loop, reads "EXACTLY the fields written — the patch
names them". The first clause is right; the second carries the same
retired patch-only phrasing, immediately above a loop that iterates the
merged bag. Internal only — `@objectstack/runtime` ships `dist`,
`README.md` and `CHANGELOG.md`, so `src/` never reaches the tarball. No
carrier PR or person is known for that file.
---
_Generated by [Claude
Code](https://claude.ai/code/session_013RDBh5DqXd2xnLwvHLgLFr)_
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: os-support-ai <318092878+os-support-ai@users.noreply.github.com>
1 parent b971924 commit e37ea4d
2 files changed
Lines changed: 36 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3915 | 3915 | | |
3916 | 3916 | | |
3917 | 3917 | | |
3918 | | - | |
| 3918 | + | |
3919 | 3919 | | |
3920 | 3920 | | |
3921 | 3921 | | |
| |||
0 commit comments