You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(devx): the clause-② declaration grows a direction arm, and three gates read it
A narrowing — "these spellings stop being accepted" — could ship to consumers
with every gate green. `check-adr-0087-registration.mjs` decided breaking-ness
from a hand-written `**BREAKING**` prose banner, so an author who did not type
it was classified non-breaking and owed no ADR-0087 disposition. Measured on
#16296 (and #14238 one surface earlier), both of which shipped that way.
The declaration now carries a closed direction arm — `(widening)` or
`(narrowing)` — read once, in `readClause2Line`, and imported by every reader:
* `scripts/pm/check-clause2-carriers.mjs` — `CLAUSE2_ARMS`, the arm reader, and
the two shapes that must fail closed: a near-arm spelling (`(narrowed)`, the
unfilled `(widening|narrowing)` menu) and the self-contradiction
`no (widening)`. Both read `malformed`, never as an absent arm.
* `scripts/check-adr-0087-registration.mjs` — signal (4). `narrowing` declares
breaking; `widening` declares nothing. The `**BREAKING**` banner is KEPT: 52
changesets in stock carry it and nothing else.
* `scripts/check-changeset-no-major.mjs` — a declared narrowing owes the same
grade a declared widening owes, because inside the launch window a breaking
change ships `minor`.
The arm is OPTIONAL, and that is a measurement: all five declarations on the
open board read `Clause-②: no` with no parenthetical, and all five read
byte-identically after this change.
AGENTS.md carries the format at net zero lines — its ratchet has no headroom —
paid for by deleting the widening-rationale clause and the CI step name the
gate prints for itself.
Maintainer ruling: director summon #17, decision batch #2 item 1, option B,
verbatim 「同意」.
Co-Authored-By: Claude <[email protected]>
Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
@@ -1860,10 +1903,24 @@ export function assertInputs({ cwd, head }) {
1860
1903
['a `**BREAKING**` body marker',"---\n'@objectstack/spec': minor\n---\n\na summary\n\n**BREAKING**: something changed\n"],
1861
1904
['a `BREAKING CHANGE:` body line',"---\n'@objectstack/spec': minor\n---\n\na summary\n\nBREAKING CHANGE: something changed\n"],
1862
1905
['a conventional-commit `!` summary',"---\n'@objectstack/spec': patch\n---\n\nfeat(spec)!: drop a key\n"],
1906
+
// #16421, signal (4) — the ARM, pinned in BOTH directions across these two
1907
+
// lists. `narrowing` here, `widening` in the inverted list below: an arm
1908
+
// reading that classified both as breaking would satisfy this list alone
1909
+
// while telling a consumer nothing, so neither fixture means anything
1910
+
// without the other. The `minor` bump and the banner-free body are the
1911
+
// point — this is the exact shape #16296 shipped in, and the three older
1912
+
// signals are all absent from it on purpose.
1913
+
['the `narrowing` ARM with no banner, no `major` and no `!` (#16421)',"---\n'@objectstack/spec': minor\n---\n\na summary\n\nClause-②: no (narrowing)\n"],
1914
+
['the `narrowing` arm beside a `yes` value — a diff that widens AND narrows',"---\n'@objectstack/spec': minor\n---\n\na summary\n\nClause-②: yes (narrowing)\n"],
1863
1915
];
1864
1916
constMUST_NOT_MATCH_BREAKING=[
1865
1917
['a plain `patch` changeset',"---\n'@objectstack/spec': patch\n---\n\nfix a typo\n"],
1866
1918
['a `minor` changeset whose prose merely contains the word breaking',"---\n'@objectstack/spec': minor\n---\n\nnothing groundbreaking here\n"],
1919
+
// The OTHER direction of signal (4). A widening is not a break.
1920
+
['the `widening` ARM — the arm reads, and reads as NOT breaking (#16421)',"---\n'@objectstack/spec': minor\n---\n\na summary\n\nClause-②: yes (widening)\n"],
1921
+
['a bare `Clause-②: no` — the shape every declaration on the board carries',"---\n'@objectstack/spec': patch\n---\n\na summary\n\nClause-②: no\n"],
1922
+
['a bare `Clause-②: yes` — a widening declared through the value alone',"---\n'@objectstack/spec': minor\n---\n\na summary\n\nClause-②: yes\n"],
1923
+
['prose merely NAMING the arm — the reader takes a token, never a phrase',"---\n'@objectstack/spec': minor\n---\n\nthis is a narrowing of nothing at all\n"],
0 commit comments