Commit ef47459
Fixes #17026
Clause-②: no — the landing surface is prose inside two already-compiled
`packages/*/CHANGELOG.md` entries plus erratum lines. No schema key, no
accepted-set change, no new exported symbol, no new key on a published
payload. Diff is markdown only; no path under `packages/**/src/**`
moves.
## The ruling this PR implements, verbatim
Director seat, decision batch #119 item 1, 2026-09-12T04:15Z.
Maintainer's own word to the batch presented as `1A·2A·3A·4D·5A`: 「同意」.
> **A: correct the two published CHANGELOG entries in the repository,
with a post-release erratum note.**
>
> 1. `packages/spec/CHANGELOG.md` and
`packages/metadata-protocol/CHANGELOG.md`: the two `Seed.locale`
sentences ("no first-party call site supplies one", "the liveness ledger
records `seed.locale` as `experimental`") are corrected to the
post-#17013 truth, each followed by **one erratum line naming PR #17013
and the correction date**.
> 2. **Before editing**, run the release tooling's dry-run (`changeset
version` on a scratch branch) and record that a manual edit inside an
already-compiled section **survives** — the triage seat's open
confidence gap; **if it does not survive, stop and report**.
> 3. `skip-changeset`: no package publishes anything from this change.
And the boundary that makes A legitimate, also verbatim:
> Immutability belongs to the **shipped npm tarball**, which this ruling
does not and cannot touch; it does not belong to the repository's
markdown.
## Step 2 first — the gate, run before any edit
Run on a local scratch branch off the same base, then discarded. Marker
inserted into the already-compiled `## 17.4.0` section of both files
(into the very paragraph this PR edits), then `pnpm changeset version`.
| reading | value |
|:--|:--|
| marker count before edit | spec **0**, metadata-protocol **0** |
| marker count after edit, on disk | spec **1**, metadata-protocol **1**
(`git diff --stat` = 2 files, 2 insertions / 2 deletions) |
| `pnpm changeset version` | `VERDICT changeset-version-exit 0` — "All
files have been updated" |
| **marker count AFTER `changeset version`** | spec **1**,
metadata-protocol **1** — **the manual edit SURVIVES** |
| where the marker ended up | spec `2451` → `5654`; metadata-protocol
`128` → `898` — pushed down, content intact |
| **lit control** — did the tool actually rewrite the files? | yes: a
new `## 17.5.0` section is prepended at the top,
`packages/spec/package.json` moves `17.4.0` → `17.5.0`, and the 250
pending changesets drop to **0** |
| restore | `git reset --hard` + `git clean -fd`; `git diff HEAD` empty,
0 marker residue, 250 changesets back, scratch branch deleted |
⇒ `changeset version` **prepends** and never rewrites an
already-compiled section. The triage seat's own stated blind spot —
"我**没有验证过手工编辑 CHANGELOG 会不会被下一次发版覆盖或冲突** …… 但我**没有测**" — is now
measured, and it does not block A.
## Step 1 — what changed, and why each corrected sentence is true of
today's tree
Both files carry the same compiled `## 17.4.0` entry for commit
`c1d8f98`, byte-identical before and after this change. The single
paragraph at `packages/spec/CHANGELOG.md:2451` /
`packages/metadata-protocol/CHANGELOG.md:128` becomes four: two
corrected paragraphs, each followed by one erratum line naming PR #17013
and the correction date 2026-09-12.
**Claim 1 — "no first-party call site supplies one".** Verified false on
this tree, not taken from the card:
- `packages/runtime/src/app-plugin.ts:1717` declares `private
resolveSeedLocale()`, reading `i18n.defaultLocale` off the bundle.
- It is threaded into all three `SeedLoaderRequest`s that plugin builds:
lines `1349`, `1434`, `1791` (`...(seedLocale ? { locale: seedLocale } :
{})`).
⇒ the corrected sentence says a first-party call site **does** supply
`config.locale` and names the producer and the three sites.
**Claim 2 — "the liveness ledger records `seed.locale` as
`experimental`".** Verified false: `packages/spec/liveness/seed.json` →
`props.locale.status` reads **`live`**, with `producer` naming
`packages/runtime/src/app-plugin.ts#resolveSeedLocale`.
**One adjacent clause corrected in the same stroke, named rather than
smuggled.** "on the default boot path the axis is inert" sits in the
same paragraph and is falsified by the same landing. Leaving it would
have left a known-false clause beside a corrected one, which defeats the
ruling's own purpose; it is corrected and called out here.
**The corrected text does not overclaim.** The ledger row's `live` is
explicitly bounded, and the correction carries that bound rather than
dropping it. Measured on this tree: three request builders outside
`AppPlugin` still build a `config` with no `locale` key —
- `packages/runtime/src/domains/packages.ts:1776` `applyPublishedSeeds`
(package apply) — `config: { defaultMode, multiPass, organizationId? }`,
zero occurrences of `locale` in the whole file;
- `packages/metadata-protocol/src/protocol.ts:17490` `applySeedBodies`
(draft publish) — same three keys;
-
`packages/cloud-connection/src/marketplace-install-local-plugin.ts:1510`
`runInlineSeed` (marketplace install) — same three keys.
And `SeedLoaderService#warnOnUnresolvedLocaleScope` still exists
(`packages/metadata-protocol/src/seed-loader.ts:2592`, called at
`:554`), so the corrected paragraph keeps the sentence about the warning
instead of deleting it.
## House convention followed rather than invented
The dispatch pointed at #16859 as the precedent. ⚠️ Read to the end,
**#16859 did not in fact edit a published CHANGELOG** — its own report
states `packages/spec/CHANGELOG.md` "was not opened for writing" and
that correction 1 was "confirmed foreclosed and left alone". So it
establishes no erratum wording.
The convention that does exist was found by measurement — three entries
already corrected in place in this repo:
- `packages/spec/CHANGELOG.md:5257` — "As published, this sentence
justified that by … that was false when written and is false now …"
closing `(Corrected after publication, #15058.)`
- `packages/spec/CHANGELOG.md:7401` and
`packages/lint/CHANGELOG.md:1214` — same shape, closing `(Corrected
after publication, #15026.)`
⇒ this PR follows that: the published sentence is quoted in place and
marked false, the correction follows in the same entry, and the last
erratum line closes `(Corrected after publication, #17026.)` naming the
card, as those three name theirs.
It is also exactly what the `packages/*/CHANGELOG.md` guardrail row now
added to AGENTS.md by #16849 prescribes: "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 PR is
docs-only, amends the entry itself, and adds nothing to a later entry.
## `skip-changeset` — measured, not asserted
| reading | value |
|:--|:--|
| diff file list vs merge base `c744c0af332` | exactly two paths, both
`CHANGELOG.md` |
| any non-markdown path | **none** |
| `.changeset/*.md` added by this PR | **0** |
| `packages/spec` `files[]` | `dist, json-schema, liveness, prompts,
llms.txt, README.md, src/**/*.zod.ts, CHANGELOG.md, api-surface,
spec-changes.json` |
| `packages/metadata-protocol` `files[]` | `dist, README.md,
CHANGELOG.md` |
⚠️ Stated precisely so neither half misleads: `CHANGELOG.md` **is** in
both packages' `files[]`, so the corrected bytes do ship inside the next
tarball either package happens to publish. What does **not** move is any
package **version**, any **API**, any `dist/`, any source file, or any
generated artifact — and because this PR adds no changeset, it schedules
no version bump of its own. That is the sense in which "no package
publishes anything from this change" holds.
## Gates
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` against the real change set, then reconciled
with `--ran`.
- **54 derived families — 50 run green, 4 NOT MEASURED, 0 unrun.**
Reconciliation verdict, verbatim: `✓ dispatch-gates --ran: 54 derived
famil(ies) accounted for — 50 run, 4 NOT-MEASURED (4 DERIVED from a
recorded exit 3).` Every exit code captured before any pipe.
- The 4 NOT MEASURED are `check:dts-closure`,
`check:dual-build-cjs-loads`, `check:lean-entry-closure`,
`check:sourcemap-no-sources-content`; all exit **3** = PREREQUISITE NOT
MET, each refusing because there is no `dist/` in this worktree ("Run
`pnpm build` first. ⛔ This is NOT a pass: nothing was measured."). They
read build artifacts only, which a markdown-only diff cannot move.
**Declared to CI**, which builds first.
- Repo-wide `pnpm lint` (`eslint . --no-inline-config`) over the
**full** population: exit **0** in 1m26s. No narrowing declared because
none was needed. A targeted run over just these two files reports `File
ignored because no matching configuration was supplied.` for both —
markdown is outside eslint's configured population here.
- `pnpm check:nul-bytes` green, plus a manual control-character sweep of
both touched files (`grep -naP` over the non-tab, non-newline C0 range
plus DEL): **no matches**, with a printable lit control on the same
files firing.
- Package test suites are **not owed and were not run**, stated rather
than silently skipped: the diff compiles into nothing and is imported by
nothing. The only test that mentions `CHANGELOG.md` as a file class is
the `action-owner-key-single-source` pair, whose scanner is fixed to
`.ts` sources.
## Acceptance notes — out of scope, noted, not filed
- `packages/core/src/plugin-contract.ts:69` carries a code comment
asserting the opposite posture for a different entry: "⚠️ `CHANGELOG.md`
is NOT a live document and is deliberately not corrected … supersedes
them BY VERSION rather than by rewriting them." That predates the
`packages/*/CHANGELOG.md` guardrail row #16849 added to AGENTS.md, which
now prescribes amending the entry. ⛔ Not touched by this PR and not
filed — it belongs to whoever next revisits that entry, and the
governing text is already the AGENTS.md row.
## Not in play
⛔ `content/docs/releases/` is untouched by this PR and by all of the
ruling's options. This is `packages/*/CHANGELOG.md`, a different
surface. Named here only so the red line is not read into a task it does
not cover.
Authored by the `domain:spec` execution lane, session
`session_01MkQhmuuJAVDjmeWNixwDDH`, on branch
`claude/issue-17026-seed-locale-changelog-erratum`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH)_
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7e74af3 commit ef47459
2 files changed
Lines changed: 14 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
128 | | - | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
129 | 135 | | |
130 | 136 | | |
131 | 137 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2448 | 2448 | | |
2449 | 2449 | | |
2450 | 2450 | | |
2451 | | - | |
| 2451 | + | |
| 2452 | + | |
| 2453 | + | |
| 2454 | + | |
| 2455 | + | |
| 2456 | + | |
| 2457 | + | |
2452 | 2458 | | |
2453 | 2459 | | |
2454 | 2460 | | |
| |||
0 commit comments