Skip to content

Commit 298e9dd

Browse files
os-billclaude
andauthored
docs(spec): correct the published 17.4.0 entry that restated the retired M9.2 promise (#18569)
Part of #17849 Clause-②: no The second half of #17849, split out of PR #18557 because AGENTS.md's Documentation Guardrails row for `packages/*/CHANGELOG.md` requires it: an already-published entry is amended **in a dedicated docs-only PR**, ⛔ never as a rider on code changes. This diff is exactly one file and adds no source, no schema and no export. #17323's ruling item 2 orders it: 「`packages/spec/CHANGELOG.md`: an erratum line under the entry that promised M9.2 (the #17026 shape — correct the published text, note the date), ⛔ not a rewrite of history.」 ## What was corrected, and where One entry: `ef3a138` (`feat(spec)!: an evaluated expression slot requires a non-blank source`) under the already-published `## 17.4.0`. Line numbers re-derived on this tree at `79a046f8c`, ⛔ not carried over from the card or from the earlier round: | line | published text | disposition | |--:|:--|:--| | 1096 | the blockquote quoting `EVALUATED_EXPRESSION_SOURCE_REQUIRED`, parenthetical `(the canonical persisted form of phase M9.1)` | **left exactly as shipped** — it is a faithful quote of what 17.4.0 published. A paragraph under it says what the constant reads now. | | 1103 | 「its docblock declares that `ast` becomes required in build output at phase M9.2」 | corrected in place, old words kept as a marked quotation | | 1119 | 「has no evaluable form under M9.1」 | corrected in place, old words kept as a marked quotation | One adjacent clause falsified by the same ruling is corrected in the same stroke and **named here rather than smuggled**: the bullet also read 「when AST-only evaluation lands」, which presupposes the retired promise. It now reads 「if AST-only evaluation is ever chartered」 — the wording the two pending changesets already carry. Leaving it would have left a 「when it lands」 sitting beside 「no promise of becoming required」 in one bullet. One dated erratum line closes the entry, carrying the in-repo tail this repository already uses in five places (`packages/spec/CHANGELOG.md` ×3 at `:2457`, `:2882`, `:5277`, `packages/lint/CHANGELOG.md:1214`, `packages/metadata-protocol/CHANGELOG.md:134`): ``` *Erratum, 2026-09-17 — the M9.1 / M9.2 phase promise this entry restated was retired by the ruling on #17323 (2026-09-12) … (Corrected after publication, #17849.)* ``` ⛔ No new entry at the top, ⛔ no version heading added (`git diff -U0 | grep -c '^+## '` → 0), ⛔ nothing this release published is changed. ## ⚠️ The card's grep criterion cannot be met, and the ruling is why The card sets `git grep -l 'M9\.[12]' origin/main -- packages` → 0. After this PR that file still carries **four** hits, and every one of them is required by the ruling's own 「⛔ not a rewrite of history」: ``` :1096 the as-shipped blockquote (deliberately untouched) :1109 "…becomes required in build output at phase M9.2" inside `As published, that sentence continued "…"` :1130 "no evaluable form under M9.1" inside `As published that clause read "…"` :1142 the erratum line itself, naming the retired promise ``` Not one of them is a live assertion of the promise — they are the quotation marks the #17026 shape puts around it, plus the erratum that retires it. A zero would require deleting the published words, which is precisely the rewrite the ruling forbids. ⇒ the criterion and the ruling are not jointly satisfiable, and the ruling governs. Reported rather than forced. ## ⚠️ `skip-changeset` — checked against #18375 before relying on it The label is applied. Before applying it I re-read the refusal #18375 is about, `scripts/check-empty-changeset.mjs`, and it does **not** reach this PR: - that gate has two rules and **both take the `.changeset/` diff and nothing else** — rule 1 fires on a newly ADDED empty-frontmatter changeset, rule 2 (`scanForeign()`) on a MODIFIED or DELETED changeset that exists on the merge base; - the DELIBERATE-CORRECTION text 「no label and no diff shape makes that safe」 is scoped, in its own words, to 「the note you rewrote describes behaviour THIS PR changed」 — a **pending release note**, i.e. a `.changeset/*.md`; - **this diff contains no `.changeset/` path at all** (`git diff --name-only origin/main...HEAD` → one line, `packages/spec/CHANGELOG.md`). So the label suppresses no refusal that could have fired here, and the finding's hazard is absent rather than accepted. What the label IS doing is the documented job: `Check Changeset` requires an added changeset from **every** PR, with no path filter, so `skip-changeset` is the only instrument for a diff that releases nothing of its own — the same instrument the #17026 ruling named (item 3) and PR #17896 spent for the same shape. ## Verification Exit codes landed to disk before reading, ⛔ never through a pipe. | run | verdict | |:--|:--| | derived gate families for this one path | 55 derived · **51 run green** · 4 NOT MEASURED | | `--ran` reconciliation with per-family exit codes | `55 derived famil(ies) accounted for — 51 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3)` | | `check-release-section-coverage` (plain · `--self-test` · `--strict`) | exit 0 ×3 — 7 published minors across 2 GA majors, every one still covered | | `pnpm check:release-notes`, `pnpm check:release-page-status` | exit 0 | | `pnpm lint` (`eslint . --no-inline-config`, whole repo) | exit 0 | | `pnpm check:nul-bytes` + a direct control-character sweep of the file | exit 0 / no hits | The 4 NOT MEASURED are `check:dts-closure`, `check:dual-build-cjs-loads`, `check:lean-entry-closure` and `check:sourcemap-no-sources-content` — all exit **3 = PREREQUISITE NOT MET** (they read the `dist/` of packages this tree never built). ⛔ Neither a pass nor a failure; CI's `Build Core` runs them. **No test is owed and that is measured, not assumed.** Four test files name a `CHANGELOG.md` path and **every one of them excludes it**: `compliance-families-retirement.test.ts` skips `CHANGELOG.md`, both `action-owner-key-single-source.test.ts` files list it under `covers` as 「a published CHANGELOG is the record of the removal itself」, and `template-consistency.test.ts` passes `:(exclude)**/CHANGELOG.md`. No test reads the bytes this PR moves. **The `changeset version` survival question is already answered and is not re-run here.** #17026's round measured it with a lit control: a manual edit inside an already-compiled section SURVIVES `changeset version` (marker present before and after, while the tool provably re-wrote both files — a new version section prepended, the package version advanced, 250 pending changesets consumed). That reading stands; re-running it would buy nothing. ## Acceptance notes Confirming reading for the finding recorded on #17849: `pnpm check:cross-package-test-inputs` is **green (exit 0)** on this tree, which has no `packages/spec/dist` because a markdown-only diff needs no build. Same gate, same commit base, opposite verdict from the built tree — a third independent leg for the same cause. ⛔ Not filed again; it is already #18353 and #18440. Noted, not filed: nothing else. Successor for the `M9.9b` / `M9.5` / `M9.7` ROADMAP citations elsewhere in the tree: none — no PR or person is routed to those files by this work, and the ruling names only the M9.1 / M9.2 phase promise. --- _Generated by [Claude Code](https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent e08c8b0 commit 298e9dd

1 file changed

Lines changed: 23 additions & 10 deletions

File tree

packages/spec/CHANGELOG.md

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,14 +1098,24 @@
10981098
> that is blank after trimming, would validate and register and then fault at
10991099
> run time. Write `{ dialect: 'cel', source: '…' }`.
11001100

1101+
That blockquote is `EVALUATED_EXPRESSION_SOURCE_REQUIRED` as 17.4.0 shipped it,
1102+
and the parenthetical inside it now reads "(the canonical persisted form)" —
1103+
the phase clause is gone from the constant and nothing else in the sentence
1104+
moved. The rule, the slot it reports at and the prescription it carries are
1105+
unchanged.
1106+
11011107
- **`ExpressionSchema` is NOT narrowed.** It is the persistence contract —
1102-
`source` OR `ast` — and its docblock declares that `ast` becomes required in
1103-
build output at phase M9.2. The new export `EvaluatedExpressionSchema` (and
1108+
`source` OR `ast`. As published, that sentence continued "and its docblock
1109+
declares that `ast` becomes required in build output at phase M9.2"; the
1110+
promise is retired — `ast` is accepted as an optional opaque structured
1111+
value and carries none. The new export `EvaluatedExpressionSchema` (and
11041112
its type `EvaluatedExpression`) is a sibling: the same envelope with `source`
11051113
required and non-blank, spelled once and composed by every evaluated slot, so
1106-
when AST-only evaluation lands the flip is one edit there rather than a
1107-
per-slot unwinding. The rule is worded as "an evaluated slot requires whatever
1108-
the engine can actually evaluate"; what that is today is `source`.
1114+
if AST-only evaluation is ever chartered the flip is one edit there rather
1115+
than a per-slot unwinding. (As published that clause read "when AST-only
1116+
evaluation lands", which carries the same retired promise.) The rule is
1117+
worded as "an evaluated slot requires whatever the engine can actually
1118+
evaluate"; what that is today is `source`.
11091119
- **The notion of blank is the engine's own** — `.trim()`, which
11101120
`cel-engine.ts`'s helpers already apply — not a third one beside the shape
11111121
rule's `min(1)` and `validateExpression`'s trim.
@@ -1116,17 +1126,20 @@
11161126
grew a rule of its own.
11171127

11181128
**What an author does with a refused envelope.** An assignment value that
1119-
carried only `ast` has no evaluable form under M9.1: author its `source`. A
1120-
whitespace-only `source` was never an expression: delete the entry, or write
1121-
the expression. Every envelope with a non-blank `source` is unchanged, and
1122-
nothing is renamed, retired or rewritten — the refusal itself carries the
1123-
prescription.
1129+
carried only `ast` has no evaluable form: author its `source`. (As published
1130+
that clause read "no evaluable form under M9.1"; the phase id is retired, the
1131+
prescription is not.) A whitespace-only `source` was never an expression:
1132+
delete the entry, or write the expression. Every envelope with a non-blank
1133+
`source` is unchanged, and nothing is renamed, retired or rewritten — the
1134+
refusal itself carries the prescription.
11241135

11251136
Not touched here: the `predicate` half of the same seam — `evaluateCondition`'s
11261137
silent `false` on an envelope without a `source` — is a behaviour change on a
11271138
live path with its own card, and the edge-condition schema that carries that
11281139
envelope is narrowed in a follow-up once the in-flight change to
11291140
`automation/flow.zod.ts` lands.
1141+
1142+
*Erratum, 2026-09-17 — the M9.1 / M9.2 phase promise this entry restated was retired by the ruling on #17323 (2026-09-12), which found a two-phase roadmap chartered by no ADR: `ast` is an accepted optional structured value with no promise of becoming required. Three passages above are corrected in place; the blockquote is left as shipped and nothing this release published is changed. (Corrected after publication, #17849.)*
11301143
- 68d5dfd: feat(spec): `ExecutionStepMetrics` gains an optional `failures` slot, and `FlowRunSummary.failed` is declared as the fold INCLUDING what a delegating node rolled up from its child (maintainer ruling 2026-09-06 on #15617, spec half)
11311144

11321145
Additive. Nothing an author writes is renamed, retired or narrowed; no accept

0 commit comments

Comments
 (0)