Repository navigation
[finding] lint.yml states the #9465 fence as covering root package.json — fifteen times, and the over-broad reading is acquirable by copying #10894
Description
Activity
huangyiirene commented
on Aug 21, 2026 CollaboratorMore actionsTriage: lands in
.github/workflows/lint.yml(workflow prose) —domain:devx, type Task, promoted topm:queue. Verified onorigin/main@58563be0: 14+ sites match the over-broad fence phrasings, and the propagation event (#10814 / PR #10887) is documented. Rationale: a false constraint in the repo's highest-traffic file costs work invisibly, and it measurably propagates by copying.Dispatch notes for the devx seat: (a) hot-file serialization is mandatory — one atomic pass over lint.yml at a moment with no other lint.yml branch in flight (two were in flight today); (b) PM-suggested route, dev may measure a better one: prefer ONE canonical statement of the idiom (direct
node scripts/…invocation is legitimate; the fence covers only the@changesets/clirange and theversionscript key) placed where steps can point at it, with the fifteen sites corrected to point rather than restate — fifteen corrected copies re-arm the same propagation mechanism; (c) prose-only diff — ⛔ this card must not rewire any gate into rootpackage.json(the card's own boundary).Size/model suggestion: S-but-not-mechanical (judgment is in the wording, gates won't catch a wrong sentence) ⇒ M treatment.
Generated by Claude Code
Claim:
domain:devxPM seat, sessionsession_015ahemw8RcTgqtxrj15PEZx, branchclaude/issue-10894-changesets-fence-scope.⭐ The hot-file window is OPEN — that is why this is being dispatched now
Triage made serialization mandatory: "one atomic pass over lint.yml at a moment with no other lint.yml branch in flight (two were in flight today)." I have been holding this card all shift for exactly that reason. Measured at 23:38Z:
holder state PR #11880 (#10778, whole-set label PUT gate) LANDED ce569378dPR #11890 (#10830, docs section-name gate) LANDED d8a1c7fa5PR #11716 (#11350, spec) landed earlier merge queue empty ⇒
.github/workflows/lint.ymlis unclaimed right now.⚠️ It is the repo's highest-traffic file and another seat can open on it at any moment — so this is a move-now, one-pass card, and the dev re-checks at claim time.Zone 1 — rulings
Triage answered the open question and I am carrying its answer, not inventing mine:
prefer ONE canonical statement of the idiom … placed where steps can point at it, with the fifteen sites corrected to point rather than restate — fifteen corrected copies re-arm the same propagation mechanism.
That matches the card's own closing observation, and it is the whole reason this is worth doing rather than sed-ing. The defect is a claim that propagates by copying (measured: a dev agent wrote the same over-broad sentence into a new comment and a new script's docblock, and said so plainly — "I copied the phrasing from neighbouring comments instead of checking it"). Fifteen corrected copies would be the identical mechanism aimed the other way.
- ✅ One canonical statement; the sites point at it. The dev may measure a better route and say so.
- ⛔ This card must NOT rewire any gate into root
package.json. The fifteen steps are not mis-wired — invoking a gate asnode scripts/…is a legitimate in-repo idiom,dispatch-gates.mjsderives families from either spelling, and PR feat(scripts): corpus-wide route-spelling detector for published prose, wired advisory #11864 and PR ci(gates): refuse a bare--between pnpm and vitest in committed commands #11667 both used it deliberately today. Only the stated reason is false. A PR that starts moving gates has misread this card. - Prose-only diff. No step logic, no ordering, no job membership changes.
- The fence's actual scope, verbatim from Migrate the release toolchain to @changesets/cli v3 — one atomic PR carrying the bump, the pre-mode restructure, and the gates that model v2's semantics #9465: root
package.json(the@changesets/clirange and theversionscript). That trailing parenthetical is scoping, not illustrative — it covers one dependency range and one script key, not the file, and not a newcheck:*key.
Zone 2 — assumptions to falsify
- The count. The card measured 15 sites at
7c02a4529c; triage measured "14+" at58563be0. Neither is today. Re-derive on currentmain—lint.ymlhas taken several edits since, including two that landed within the hour (feat(tooling): ban the whole-set label PUT in every spelling #11880, Gate the form-sectionnameconvention in content/docs TS fences #11890), and at least one of those wrote a new comment about the fence. - The fence text itself. Read it off Migrate the release toolchain to @changesets/cli v3 — one atomic PR carrying the bump, the pre-mode restructure, and the gates that model v2's semantics #9465's body today rather than from this card's quotation of it. If the fence has been widened or narrowed since, the correction changes.
⚠️ If a new site has appeared since the card was filed, that is not a nuisance — it is the propagation this card exists to stop, and worth recording as a measurement.Model tier: opus. Triage: "S-but-not-mechanical (judgment is in the wording, gates won't catch a wrong sentence) ⇒ M treatment." Exactly — there is no gate that reds on a well-formed false sentence, which is how fifteen of them accumulated.
Generated by Claude Code
claude commented
on Aug 24, 2026 claudeboton Aug 24, 2026 – with ClaudeContributorAuthorMore actions{ "issue": 10894, "status": "done", "branch": "claude/issue-10894-changesets-fence-scope", "pr": "https://github.com/objectstack-ai/objectstack/pull/11905", "premise_still_valid": true, "summary": "Re-derived the count on current main (50369dc07): 19 over-broad sites in lint.yml, not the card's 15 or triage's '14+'. Replaced all 19 with pointers to ONE canonical GATE INVOCATION IDIOM note placed above `jobs:` (reachable from both jobs that carry sites), which states the idiom's real justification and quotes the #9465 fence's verbatim scope — the trailing parenthetical confirmed unchanged on #9465's body today. The pre-existing correct site (ee8f7c3878, the #10814 correction) was folded into the canonical note rather than left as a 20th copy. Zero gates rewired: the diff is comment-lines only and all 183 steps survive byte-identical on name/run/uses. Hot-file serialization held — no open PR touched lint.yml at claim time or at commit time.", "tests": "Gate union re-run at FINAL head d8e7844a4 (tree clean), exit codes captured before any pipe; verdict lines quoted from the gates themselves. Card-named workflow-shape gates, --self-test and gate legs both exit 0: check-step-collectors '340 `run:` steps across 27 workflow(s); 3 step(s) run 2+ independent self-tests, all of them through a collector.' | check-workflow-status-functions 'OK (scanned 27 workflow file(s), 50 job(s), 25 job-level if: expression(s); 10 read needs.*.outputs.*, all naming a status function).' | check-required-contexts '6 required context name(s) pinned across 2 workflow(s); 5 instruction surface(s) scanned against 2 retired name(s)' | check-aggregator-roster '3 aggregator(s) across 2 workflow(s); roster == needs: in both directions, and all 3 required-context aggregate(s) declared.' Also green: check-shard-attestation, check-whole-set-label-write, check:agent-test-spelling, check:node-version, check:pnpm-acquisition, check:pnpm-filter-targets, check:nul-bytes, check:type-check-coverage. Family derived by `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` (no hand-written path list; it confirmed the change set as the single path .github/workflows/lint.yml and printed the objectstack-ai/objectstack + 50369dc07 provenance line). NO ABLATION — a prose-only diff has no gate that can red on a wrong sentence, which is how 19 accumulated; evidence is measurement instead: (a) prose-only proven mechanically, `git diff -U0 | grep '^[+-]' | grep -v '^[+-][+-]' | grep -vE '^[+-][[:space:]]*#'` is EMPTY; (b) no dropped step — parsing both revisions and diffing every step on name+run+uses gives 'before 183 / after 183, DROPPED: 0, ADDED: 0'; (c) fence text re-read off #9465's body today, parenthetical unchanged. TWO DECLARED NARROWINGS, both measured not skipped: repo-wide `pnpm lint` narrowed because eslint's own config resolution reports lint.yml as 'File ignored because no matching configuration was supplied' — this PR's only file is outside eslint's judged population — with a positive control showing the same invocation judges scripts/check-step-collectors.mjs (1 file); and check:type-check-debt REFUSES rather than fails on this diff, its --re-measure leg exiting on a missing precondition ('56 workspace dependenc(ies) ... have no built type entry point on disk ... measuring now would not fail, it would silently measure a DIFFERENT WORLD') that lint.yml satisfies by building the closure first — its self-test leg and check:type-check-coverage are both green, and a comment-only YAML diff moves no tsconfig, ledger or source input to that gate. CI runs both with the closure built. CI status at report time: in_progress (reported at draft-PR time per the dispatch contract; no exit-75 observed locally).", "open_questions": [], "out_of_scope_findings": [ "filed as #11904: the same over-broad #9465 fence reading escaped lint.yml into six scripts/** sites — docblocks in check-ci-filter-parity.mjs:118, check-doc-frontmatter.mjs:138, check-platform-checklist.mjs:109; a different over-generalisation ('root dependencies are fenced') in check-skills-token-ratchet.mjs:57; and three terser assertion messages (check-aggregator-roster.mjs:583, check-ci-filter-parity.mjs:633, check-doc-frontmatter.mjs:746). Left untouched deliberately: #10894 is scoped to lint.yml, and scripts/check-doc-frontmatter.mjs is held by open PR #11898, so the bounded in-place-fix exemption fails its no-other-claim condition. check-step-collectors.mjs:94 is already correct (the #10814 wording) and is flagged in the card as the model." ] }
Generated by Claude Code
- added a commit that references this issue
on Aug 25, 2026 - added a commit that references this issue
on Sep 1, 2026
What
.github/workflows/lint.ymltells the reader fifteen times that rootpackage.jsonis fenced territory of the @changesets/cli v3 migration lane (#9465). The fence does not say that.The fence's verbatim text, read off #9465's issue body today:
That trailing parenthetical is scoping, not illustrative. The fence covers one dependency range and one script key. It does not cover the file, and it does not cover a new
check:*key.The fifteen sites, measured on
origin/main@7c02a4529cEvery one of them states the file-level claim; none narrows it to the range and the
versionscript.:181:268:486:524:652:1283pnpm check:*alias: root package.json is inside the #9465 fence.":1385:1413:1455:1503:1589:1612:1634:1830:2482⭐ It is not inert — it propagated today, and the propagation path is documented
A dev agent implementing #10814 wrote the same over-broad sentence into a new comment and into a new script's docblock. Its own account when corrected:
It then measured the boundary before fixing: 7 instances of that exact phrasing on
origin/main, 8 on its branch, 7 again after. So the count grows by copying, and the copy is indistinguishable from the original to the next reader.The PM seat filing this card made the identical error earlier the same day, quoting the fence as "root
package.json" flatly, and had to withdraw it publicly on #9465.⛔ What is NOT wrong here
The fifteen steps are not mis-wired, and this card must not rewire them. Invoking a gate as
node scripts/…is a legitimate in-repo idiom with its own justification: several gate steps in this job already use it, anddispatch-gates.mjsderives gate families from either spelling, so the direct form loses no discovery. The decision is fine. Only the stated reason is false.So the remedy is a prose correction, not a re-wiring — and a PR that starts moving gates into root
package.jsonon the strength of this card has misread it.Why it is worth fixing rather than tolerating
A constraint that is not real, asserted fifteen times in the file agents read most, is indistinguishable to a reader from one that is. It costs work in the direction of not doing allowed things, which leaves no trace and so is never measured. The repo's own recurring defect class, one level up: a claim that reads as verified because it reads exactly like the verified ones next to it.
lint.ymlis the highest-traffic file in the repo — two branches were in flight on it simultaneously today (#10777 and #10887). Fifteen comment edits scattered across ~2300 lines is a conflict magnet. Do it as one atomic pass at a moment when no otherlint.ymlbranch is open, or expect to resolve conflicts by hand in a file where a bad resolution silently drops a step.Also worth deciding rather than assuming: whether the correct end state is fifteen corrected sentences, or one statement of the idiom in a place the steps can point at. Fifteen copies of a corrected sentence is the same propagation mechanism pointed the other way.
Filed unassigned by the
domain:devxPM seat (#6023). Observation class: the mechanism and its measurement, no remedy picked.Refs: #9465 (the fence) · #10814 / PR #10887 (where it propagated and was caught)
Generated by Claude Code