Repository navigation
release(v18): enter Changesets pre mode on main (changeset pre enter next) with one major marker, so the first v18 prerelease is 18.0.0-next.0 — the opening ruled B on #22050 #22080
Description
Activity
- addedpriority:p1High: required for production / M2High: required for production / M2area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iterateand removed
on Oct 7, 2026 objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsClaim: PM loop round 7
Session:session_01VF48aw8RPG6wzDnMgp6rtw
Account:os-justin(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-22080-v18-pre-mode(new, cut fromorigin/main3d9188502e)
Worktree:objectstack-issue-22080
Domain:domain:devx
Seat:domain:devx#2
File surface:.changeset/only..changeset/pre.json, written bypnpm changeset pre enter next.- One new changeset grading one
fixed-group membermajor: the v18 line's opening note (ADR-0131; B on decision: open v18 now and ship it in stages — release the last 17.x from main first without waiting for #21908's deny (A), skip the last 17.x (B), or keep #22009's order (C)? #22050). - ⛔ No edit to
scripts/check-changeset-no-major.mjs,.changeset/config.jsonor.github/workflows/release.yml. ⛔ No publish, nochangeset versioncommitted. - Stop on a breach and explain it in the report.
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier: no path-derived mandate; default tier)
Clause-②: no
Responsibility:n/a — not a defect card(a maintainer-directed release task, ruling B on decision: open v18 now and ship it in stages — release the last 17.x from main first without waiting for #21908's deny (A), skip the last 17.x (B), or keep #22009's order (C)? #22050)
Thread-read: none
Serial constraints cleared: no open PR touches.changeset/pre.json,.changeset/config.json, the two changeset guards orrelease.yml(all open PRs read: chore: version packages #21988, feat(spec)!: the build doors refuse a builtin node config value its executor contract refuses, with its location #21974). In-flight claims feat(spec,services): deployment-level state has no organization column — settings global rung, plumbing objects, the audit ledger, #12699 made total (ADR-0131 D7) #15207, Phase 2 of #11333: retire the legacy string[] arm of manifest.permissions (major, standard retirement route) #13458 and ADR-0120 协议 18 项:D2 conversion(声明索引 unique: true → 'global')+ 裸 true 硬拒 + synonym pin 退役 —— 挂 18 列车,现在勿动工 #5082 (other lanes) each add one.changeset/<n>-*.mdand grade it by whether pre mode is in; no shared file. Premises re-read on3d9188502e: nopre.json; pending changesets17 : minor,32 : patch, nomajor.
Landing: ⛔ not by this seat. The card states "The merge is the maintainer's". On ACCEPT the PR goes to the maintainer as awaiting a human merge. #21988 is ⛔ not merged before this lands.
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 22080,
"status": "done",
"branch": "claude/issue-22080-v18-pre-mode",
"pr": "#22084",
"session": "session_01VF48aw8RPG6wzDnMgp6rtw (subagent: the dispatching PM's session; the relay derived the same id from CLAUDE_CODE_REMOTE_SESSION_ID)",
"premise_still_valid": true,
"summary": "Draft PR #22084 (head 52f7a50, base main 3d91885) carries both steps: (1) .changeset/pre.json, written bypnpm changeset pre enter next(@changesets/cli 3.0.3), content exactly {"mode": "pre", "tag": "next"} (v3 writes mode and tag only; commit d3d35a1); (2) .changeset/22080-v18-line-opens.md, front matter\"@objectstack/spec\": major, body = the v18 opening note (ADR-0131; #22050) +Clause-②: no+ the ADR-0087 marker not-required (no-migration-prescription) (commit 52f7a50). Step 2 not skipped: the card's count command on 3d91885 prints 17 : minor, 32 : patch, no major. Member choice: @objectstack/spec, because scripts/sync-protocol-version.mjs derives PROTOCOL_VERSION from that package's major and ADR-0131 C8 calls the line protocol 18. No-major guard reads pre.json from the HEAD checkout, not the base: scripts/check-changeset-no-major.mjs:396 REPO_ROOT = the checkout the script runs in; :2018 readPre(root) reads join(root, '.changeset', 'pre.json') from the working tree; :2098 passes it to judge; :662 returns exempt on pre.mode === 'pre'; CI (pr-automation.yml:1130, Check Changeset) runs it on the PR merge-ref checkout with --base only setting the diff start. Measured: exit 0 exempt (tag: next) as committed; control with pre.json deleted from the working tree only = exit 1 enforce (base has no pre.json, so a base reader could never answer exempt); restored via git checkout HEAD, git diff HEAD empty, exit 0 again. So no split; no deviation of that kind. release.yml path quoted in the PR body: .github/workflows/release.yml:1762 stepPublish to npm + push version tagsrunspnpm run release(:1772) = root package.jsonreleasescript, ending in scripts/release-publish.sh:64changeset publish(no --tag); @changesets/cli 3.0.3 dist/getPublishPlan.mjs:599-603 getReleaseTag returns preState.tag (next) when no --tag and pre state present (except a package whose every published version is already a next prerelease); dist/publish.mjs:61-63 refuses a custom tag in pre mode; npm view today: all 69 fixed-group packages latest=17.7.0, no next tag, so each publishes to next and latest stays 17.7.0. No publish run. Throwaway (detached worktree at 52f7a50, never committed, removed):pnpm changeset versionexit 0, all 69 fixed-group members at 18.0.0-next.0, pre.json unchanged, 37 consumed changesets moved to .changeset/pre/, packages/spec/CHANGELOG.md opens## 18.0.0-next.0/### Major Changes. Card's After-it-lands expectation is FALSE as the files stand: running the remaining three rewriters of the rootversionscript in the same throwaway and replaying release.yml's post-version shape assertion gives 0 unexpected and 4 major-only paths (packages/spec/src/kernel/protocol-version.ts 17 to 18, and blank template objectstack.config.ts, objectstack.manifest.json, package.json), so the version-pr job's stepValidate the post-version tree(release.yml:518) exits 1 at :610-613 and the changesets/action step that would refresh #21988 does not run; cut-rc.yml refuses tagnext(:232-237) and non-rc versions (:156-159). No lane cuts 18.0.0-next.0 without a workflow change outside this card. Flagged in the PR body (risk section + 维护者速读) and in open_questions.",
"tests": "All on 52f7a50 (final commit; no push after the run), exit codes captured to disk before any pipe. Derived:node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack= 20 commands (15 matched by path, 8 whole-tree), all exit 0;--ranreconciliation:20 derived, 20 run, 0 NOT-MEASURED, 0 UNRUN(a DERIVED zero, all 20 carry exit codes). Card pins:node scripts/check-changeset-no-major.mjs --base origin/mainexit 0✓ Changesets is in pre-release mode (tag: next) ... skipping the no-major guard.; with--eventcarrying the PR body: exit 0,✓ LEVEL AXIS: this PR declares clause-② no;node scripts/check-changeset-fixed.mjsexit 0✓ .changeset/config.json \"fixed\" group is in sync with 69 public workspace packages.node scripts/check-adr-0087-registration.mjs --base origin/mainexit 01 declared-breaking changeset(s), each carrying an ADR-0087 disposition ... not-required (no-migration-prescription); probe (local unpushed commit without the marker) exit 1declares a breaking change (major) but no adr-0087: disposition marker.check-empty-changeset --base origin/mainexit 0; self-tests: adr-0087 441 assertions, no-major 339, empty-changeset 170, check:changeset-gate-self-tests, all exit 0. Also exit 0: check-closing-keyword-parity (+self-test), check-comment-mask-corpus (8323 files, 0 disagree), release-rehearsal-clone --self-test, release-pending-publish --self-test, check:driver-memory-census, check:gitlink-declared, check:nul-bytes (10074 files, no control bytes), check:objectui-changeset, check:pm-changeset-deadline-census, check:published-files, check:refd-timer-probe, check:watch-hint-literal. Beyond derivation, exit 0: check:future-spec-major, check:lockstep-package-count (69), check:docs-image-tag. NOT MEASURED: the 4 type-check lanes (no TypeScript in the diff); no package build/test (diff touches no package). CI on #22084 at report time: Check Changeset, Lint & Repo Gates, Type Check x4, Test Core, Governed Surface Queue Guard in_progress; claim/closing/size/link/dogfood checks success. Not waited on.",
"gates": {
"derived_commands": 20,
"run": 20,
"exit_nonzero": 0,
"reconciliation": "20 derived, 20 run, 0 NOT-MEASURED, 0 UNRUN",
"extra_run": [
"node scripts/check-changeset-fixed.mjs :: exit 0",
"pnpm check:future-spec-major :: exit 0",
"pnpm check:lockstep-package-count :: exit 0",
"pnpm check:docs-image-tag :: exit 0"
],
"card_pins": {
"check-changeset-no-major (head, --base origin/main)": "exit 0 (pre-release exemption, tag next)",
"check-changeset-no-major (--event with PR body)": "exit 0 (level axis: Clause-② no)",
"check-changeset-fixed": "exit 0",
"pre.json at head": "{"mode": "pre", "tag": "next"}"
},
"ci_at_report": "in_progress"
},
"line_budget": "18 changed lines (+18 / -0) over 2 files, under the 5000 human-merge threshold; no skills/** or governed surface touched",
"files_changed": [
".changeset/pre.json",
".changeset/22080-v18-line-opens.md"
],
"deviations": [
"None of the split kind: the guard reads pre.json from the head checkout, so step 1 and step 2 ship in one PR as the card intends.",
"PM's figure '20 commands with 15 more families once the changeset exists' did not reproduce: the derivation over the actual diff (changeset included) prints 20 commands, of which 15 are matched by path; I ran the 20 plus 4 extras.",
"One local probe commit without the ADR-0087 marker was made to read the gate's verdict, never pushed, and undone with git reset --soft HEAD~1 (my own unpushed commit).",
"Commit trailers are the AGENTS.md model-free pair (Claude-Session + Co-authored-by: Claude) rather than the harness reminder's model-named Co-Authored-By; the PR body footer is the AGENTS.md session-URL form rather than the harness reminder's form.",
"Labels documentation, size/s, tooling on #22084 were set by the repo's labelers, not by this run."
],
"mcp_calls": "0",
"api_writes": "3 — each one relay stroke (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): pr_create = POST /repos/objectstack-ai/objectstack/pulls (#22084, draft); label-write assign = POST /repos//issues/22084/assignees (os-justin); post-stamped = POST /repos//issues/22080/comments (this report). Plus 3 git pushes (not REST).",
"rest_writes": "3 — same as api_writes",
"open_questions": [
{
"question": "After #22084 lands, which lane cuts 18.0.0-next.N? release.yml version-pr refuses the major-boundary paths atValidate the post-version tree(:610-613; measured: protocol-version.ts + 3 blank-template files), so #21988 is not refreshed; cut-rc.yml accepts only tag rc and X.Y.Z-rc.N.",
"options": [
"A: land #22084 now; a follow-up card (sub-issue of #15194) wires the version-pr lane for the one-time major boundary (the content half already runs check:template-version-sync; add the protocol-version lockstep check, then drop those paths from the major-only refusal), and fixes the release-index re-date below in the same family.",
"B: land #22084 now; extend cut-rc.yml to accept tag next and X.Y.Z-next.N (it already allowlists the major-boundary paths) and cut prereleases by human dispatch.",
"C: hold #22084 until A or B lands."
],
"recommendation": "A. Business need: the ruling and the card name the version PR (#21988) as the route, with publishing as the maintainer's approval; A delivers that route, B invents a second. Long-term: the lane itself names the remedy (Wire them in before letting this refresh through), and the major boundary is crossed once (at next.0; GA moves no major-only path), so A is a bounded one-time wiring, not a standing exception. AI-error axis: A keeps one release route and its loud shape assertion; B widens an rc-specific lane whose rc wording runs through its summary and dist-tag lines. Startup focus: no new gate family; A reuses gates the lane already runs. C is rejected: the red refresh is the lane's designed refusal, publishes nothing, and holding pre mode back leaves v18's breaking stages graded minor in the meantime. #21988 stays unmerged under all three."
}
],
"out_of_scope_findings": [
"class: a · reach: named producer — .github/workflows/release.yml job version-pr (cron 0 */6 * * *), stepValidate the post-version tree(:518), exit 1 at :610-613 on the first refresh after #22084 merges; cut-rc.yml :156-159 and :232-237 refuse tag next · evidence: throwaway at 52f7a50, full rootversionscript (changeset version + sync-protocol-version + sync-template-versions + sync-docs-image-tags + sync-release-index-currency, all exit 0), the step's shape assertion replayed: 0 unexpected paths, MAJOR_ONLY = packages/spec/src/kernel/protocol-version.ts, packages/create-objectstack/src/templates/blank/{objectstack.config.ts,objectstack.manifest.json,package.json}; the changesets/action step has no if: so it does not run after the failure · route: sub-issue of #15194 (falls inside the v18 epic) · dedupe words: version-pr major boundary; Validate the post-version tree; MAJOR_ONLY unvalidated; 18.0.0-next.0 version PR; cut-rc tag next",
"class: a · reach: named producer — scripts/sync-release-index-currency.mjs, run by the rootversionscript on every lane · evidence: same throwaway rewrote content/docs/releases/index.mdx v17 entrycurrent series: 17.7.0, released 2026-10-06toreleased 2026-10-07(the cut's date); 17.7.0's version commit 4e4e881 is dated 2026-10-06; in pre mode the newest GA of 17 does not move and rewriteStatusField re-dates a same-version entry (its battery B pins that), so every pre-mode cut re-dates the last GA · route: same family as the finding above, fold into that card · dedupe words: release index currency prerelease date; sync-release-index-currency pre mode; current series released date restamp",
"carrier: the lane-wiring card above · noted, not filed — sync-docs-image-tags moves the 9 docs pins (docker/README.md, content/docs/deployment/self-hosting.mdx, content/docs/upgrading.mdx) from 17.7.0 to 18.0.0-next.0 on the first prerelease, so self-hosting docs on main would name a prerelease while latest is 17.7.0; by the rewriter's design (docs track packages/cli), whether that is wanted during the next line is the lane card's call",
"carrier: none · noted — create-objectstack's committed blank template pins ^18.0.0 after the version pass, which no 18.0.0-next.N satisfies; checked and not a defect: packages/create-objectstack/src/pkg-utils.ts:23 rewrites deps to ^OWN_VERSION at scaffold time"
],
"cleanup": "throwaway worktree: version output discarded (git diff HEAD empty), node_modules removed, git worktree remove without --force; task worktree /home/user/objectstack-issue-22080 is clean and fully pushed, node_modules + worktree removed right after this report posts; no server or background process started"
}
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 22080,
"round": "patch round for PR #22084: Lint & Repo Gates red, step PM dispatch-gates self-test",
"status": "blocked",
"branch": "claude/issue-22080-v18-pre-mode",
"pr": "#22084",
"head": "52f7a509c6 (unchanged; no push this round)",
"session": "session_01VF48aw8RPG6wzDnMgp6rtw",
"blocked_on": "The fix is outside .changeset/. It needs the seat to widen the surface to scripts/check-adr-0087-registration.mjs (option A), or to rule on B or C. Per the stop rule nothing was edited or pushed.",
"failing_case": "dispatch-gates self-test case at scripts/pm/dispatch-gates.mjs:19218, verbatim:✗ the extension narrowing costs no lead — every hint the loose rule resolves, this one resolves too (refused: .changeset/pre); summary✗ dispatch-gates self-test: 1 of 1976 case(s) failed.",
"reproduction": "Local, at 52f7a50:pnpm check:pm-dispatch-gatesrun detached, BATTERY-EXIT=1, 1068.8s. The only failing line is the one above, which matches CI job 112831153422.",
"control": "At origin/main 3d91885, same command: BATTERY-EXIT=0,✓ dispatch-gates self-test: 1976 cases pass., 1009.7s; the same case reads(refused: none). So the red is this PR's.",
"reading": "The hint comes from scripts/check-adr-0087-registration.mjs:536const isConsumedPrerelease = (p) => p.startsWith('.changeset/pre/');. extractWatchHints reads the literal.changeset/pre/, and collapseHint (dispatch-gates.mjs:7367) strips the trailing slash, which gives.changeset/pre. It is owned by check:changeset-gate-self-tests and the three check-adr-0087 invocations. The case's loose rule resolves.changeset/preto.changeset/pre.json, a tracked sibling plus a dot. The strict rule (MODULE_SPECIFIER_EXTENSIONS, :10211, .ts through .jsx) refuses it, so the two rules disagree. A probe that replays the case shows: at head, 988 hints, refused = [.changeset/pre]; at the control, refused = []. The case fails only while pre.json is tracked and.changeset/pre/holds no tracked file. The first cut moves consumed changesets there and clears it, and that cut is itself blocked by the version-lane finding. Merged as is, #22084 would red the required Lint & Repo Gates on main and on every PR until then.",
"seat_suggested_literal": "Measured, and it is wrong: changing the literal to.changeset/pre.jsonmakesnode scripts/check-adr-0087-registration.mjs --self-testexit 1 with 2 failures, includingPRE1: the audit surfaces read PENDING stock only -- two consumed changesets under .changeset/pre/ must not appear. The literal names the consumed-changeset DIRECTORY, not the pre state file. The probe was applied with scripts/ablation-replace.mjs and restored with blob == HEAD and git diff HEAD empty.",
"proposed_change": "Not made in the PR. In scripts/check-adr-0087-registration.mjs:536, replace the one line with two:const CONSUMED_PRERELEASE_EXCLUDED = '.changeset/pre/';andconst isConsumedPrerelease = (p) => p.startsWith(CONSUMED_PRERELEASE_EXCLUDED);. The literal and the predicate are both unchanged. The literal moves into a top-level declaration whose name matches dispatch-gates' EXCLUSION_DECL_NAME (_EXCLUDED), so the extractor reads it as an excluded surface, which is what it is: the docblock above it (:530-535) and :2097 say the predicate excludes consumed stock from the audit surfaces. The file's hints change from [.changeset, .changeset/pre, .changeset/.md] to [.changeset, .changeset/.md], and.changesetstill covers .changeset/pre/**, so no routing lead is lost. It is not a one-literal change, because the literal's text cannot move without changing what the predicate matches.",
"watch_hint_literal_covers_it": "No. check:watch-hint-literal rosters only ROOT_DIR_WATCH_HINTS, ROOT_FILE_WATCH_HINTS, ROOT_WATCH_HINTS and DECLARED_WATCH_HINTS (72 declarations), and :536 is none of them. It exits 0 with the change.",
"throwaway_verdict": "Throwaway worktree at 52f7a50 plus local commit 07d3ac4863, never pushed and now removed:pnpm check:pm-dispatch-gatesBATTERY-EXIT=0,✓ dispatch-gates self-test: 1976 cases pass., 947.5s, and the case reads(refused: none). check-adr-0087 --self-test exits 0 (441 assertions), check-adr-0087 --base origin/main exits 0, and check:watch-hint-literal exits 0. The widened surface derives 41 commands, versus 20 for .changeset/ only. The 20 added commands, other than the battery, were run on the throwaway and all exit 0. NOT MEASURED: the change on main alone, without pre.json.",
"changeset_only_alternative": "Measured and not adopted: a tracked placeholder.changeset/pre/.gitkeepmakes.changeset/prea tracked prefix. The probe then refuses nothing, and changesets v3changeset versiontolerates the file (exit 0, fixed group at 18.0.0-next.0). I did not adopt it because it is a decoy file in changesets' managed store whose only purpose is to steer a self-test heuristic, and the case's own comment asks for a decision, not a dodge.",
"root_cause": "The frozen self-test's loose rule reads a trailing-slash directory literal as an extensionless module specifier. scripts/pm/dispatch-gates.mjs was not edited.",
"open_questions": [
{
"question": "How does the surface widen to clear the battery for #22084?",
"options": [
"A: widen to scripts/check-adr-0087-registration.mjs and land the two-line exclusion-constant change, either in #22084 or in a PR that lands before it",
"B: commit the .changeset/pre/.gitkeep placeholder inside the current surface",
"C: a ruling-208 exception to narrow the self-test's loose rule in dispatch-gates.mjs"
],
"recommendation": "A. It is accurate, because the literal is an exclusion; it is measured green; it is the smallest change; and it touches no frozen file. B leaves a workaround in the release store, and C needs an exception for a file that is frozen."
}
],
"deviations": [
"The dispatch said to run the battery through scripts/pm/os-verify-lock.sh. My definition says check:* batteries do not take the lock and run as nohup plus tail --pid, and the gate's own header says to run detached. I followed the definition and the header: all three batteries ran detached, waited on in the foreground with tail --pid.",
"No push, because the fix is outside .changeset/."
],
"mcp_calls": "0",
"api_writes": "1: this comment, POST /repos//issues/22080/comments through the relay",
"cleanup": "The control, probe, candidate and task worktrees were all removed without --force, after their node_modules. Battery processes were started detached and each has exited. The candidate patch is saved in the scratchpad."
}
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsSurface amendment to claim
6039111470·domain:devx#2·session_01VF48aw8RPG6wzDnMgp6rtw· 2026-10-07T15:20Z. ⛔ Not a new claim; the claim, branch and assignee stand.Why: PR #22084's head
52f7a509c6reds the requiredLint & Repo Gates. The step isPM dispatch-gates self-test, casethe extension narrowing costs no lead … (refused: .changeset/pre). The patch-round addendum6040911886reproduced it. The control on3d9188502eis green, so the red is this PR's.- The cause is the literal
.changeset/pre/atscripts/check-adr-0087-registration.mjs:536. With.changeset/pre.jsonnow tracked, the battery's loose and strict hint rules disagree on it. - Merged as it stands, the PR would red
mainand every PR until a first cut lands.
Ruled (seat; a technical sequencing call, no product change): option A of the addendum.
- File surface, amended:
.changeset/plusscripts/check-adr-0087-registration.mjs. In that file, only the line at:536becomes a top-levelCONSUMED_PRERELEASE_EXCLUDEDconstant and theisConsumedPrereleasepredicate reading it. - The literal and the predicate's match are unchanged.
- The constant's name meets
EXCLUSION_DECL_NAME(scripts/pm/dispatch-gates.mjs:6415), so the extractor reads it as the excluded surface it is: the audit filter at:2092. - It lands in the same PR, so
mainnever carriespre.jsonwithout it. - ⛔ Not taken:
- B, the
.changeset/pre/.gitkeepplaceholder, a decoy in the changesets store; - C, a ruling-208 exception to
dispatch-gates.mjs.
- B, the
Serial constraints, re-read: no open PR touches
scripts/check-adr-0087-registration.mjs, and no in-flight claim names it (#15207, #13458, #5082, #15205, #15196, #21898 read). Its last touch onmainis6eaa0f4a81.- The cause is the literal
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 22080,
"round": "option A applied on PR #22084, under surface amendment 6040954045",
"status": "done",
"branch": "claude/issue-22080-v18-pre-mode",
"pr": "#22084",
"head": "a630de657d. Normal commit on 52f7a50; no amend, no force. Pushed 52f7a50..a630de6.",
"session": "session_01VF48aw8RPG6wzDnMgp6rtw",
"change": "Only line :536 of scripts/check-adr-0087-registration.mjs changed. It is now two lines:const CONSUMED_PRERELEASE_EXCLUDED = '.changeset/pre/';andconst isConsumedPrerelease = (p) => p.startsWith(CONSUMED_PRERELEASE_EXCLUDED);. The diff is identical to the measured candidate patch, index lines aside. Nothing else in that file moved: 2 insertions, 1 deletion.",
"ran_line": "Run reconciliation — 41 derived, 41 run, 0 NOT-MEASURED, 0 UNRUN. ✓ dispatch-gates --ran: 41 derived famil(ies) accounted for — 41 run, 0 NOT-MEASURED (a DERIVED zero — all 41 recorded an exit code and none of them is 3).",
"derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat a630de6 gives 41 commands (34 matched by path, 2 by change kind, 8 whole-tree). The list is the same set as the throwaway measurement. All 41 exit 0, and every exit code was written to disk before any pipe.",
"battery": "pnpm check:pm-dispatch-gateswas run detached at a630de6. BATTERY-EXIT=0, wall 967s; the battery's own line readsthe battery took 965.7s on this box. Summary:✓ dispatch-gates self-test: 1976 cases pass.",
"case_reading": "✓ the extension narrowing costs no lead — every hint the loose rule resolves, this one resolves too (refused: none)",
"adr_0087": "--self-testexits 0:✓ check-adr-0087-registration --self-test: 441 assertions over real temp git repos.--base origin/mainexits 0:✓ check-adr-0087-registration: 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition.",
"card_pins_rechecked": "check-changeset-no-major --base origin/main exits 0 (pre-release exemption, tag next). check-changeset-fixed exits 0 (69 packages in sync). The .changeset/ files are unchanged.",
"ci_at_report": "One read of a630de6: Check Changeset success, Lint & Repo Gates in_progress, 23 success, 7 skipped. I did not wait.",
"pr_body_line_for_the_seat": "For## 维护者速读(草稿), under 改了什么, append: 另外,scripts/check-adr-0087-registration.mjs里有一行把已有的排除路径.changeset/pre/改写成_EXCLUDED命名常量(匹配逻辑不变),这样pre.json存在后,PM 门禁自检能正确识别它。",
"pr_body_now_stale": [
"The opening paragraph saysFile surface: .changeset/ only.Suggested text:File surface: .changeset/ plus one line in scripts/check-adr-0087-registration.mjs (surface amendment 6040954045 on #22080).",
"The same 改了什么 paragraph says 改动只有.changeset/下的两个文件,没有代码、工作流或门禁改动. The appended line above contradicts it. Suggested text: 改动是.changeset/下的两个文件,加上门禁脚本里的一行重命名;没有代码或工作流改动。",
"The Gates section reports 20 derived commands at 52f7a50. At a630de6 the derivation gives 41 commands, all exit 0, with the--ranline above."
],
"mcp_calls": "0",
"api_writes": "1: this comment, POST /repos//issues/22080/comments through the relay. There was also 1 git push. The PR body was not PATCHed.",
"cleanup": "The task worktree is removed after this comment posts. The battery process has exited. No server was started."
}
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsACCEPT — PR #22084 ·
domain:devx#2· 2026-10-07T15:46ZSeat review of PR #22084 against GitHub, at head
a630de657don base3d9188502e. Report:6039596838; patch-round addendum:6041313497. Claim:6039111470. ⛔ The landing is not this seat's: the card says "The merge is the maintainer's", so the PR goes to the maintainer as awaiting a human merge.Checklist conclusions
- Shape: draft PR to
main. Body line 1 isFixes #22080; no other closing keyword in the body.Clause-②: nois at line start. - Files (
get_files):.changeset/pre.json(+4),.changeset/22080-v18-line-opens.md(+14) andscripts/check-adr-0087-registration.mjs(+2 −1). That is the claim's surface as amended in6040954045. No edit to either changeset guard's logic,.changeset/config.jsonorrelease.yml; nocontent/docs/releases/change. - The patch round: at
52f7a509c6,Lint & Repo Gateswas red atPM dispatch-gates self-test, case… (refused: .changeset/pre). The cause: withpre.jsontracked, the battery's loose and strict hint rules disagreed on the literal.changeset/pre/atcheck-adr-0087-registration.mjs:536. The control onmainwas green. The fix names the existing exclusionCONSUMED_PRERELEASE_EXCLUDED, soEXCLUSION_DECL_NAME(dispatch-gates.mjs:6415) reads it as excluded. The diff is exactly two lines; the predicate's match is unchanged. Ata630de657d: 41 derived commands, all exit 0; the battery passes 1976 cases, with(refused: none);check-adr-0087-registration --self-testand--base origin/mainexit 0. ⛔ Not taken: a.gitkeepdecoy in the changesets store, or an exception to frozendispatch-gates.mjs. pre.json:{"mode": "pre", "tag": "next"}.- The changeset, read sentence by sentence:
"@objectstack/spec": majorgrades onefixedmember. The no-major count on the cut was17 : minor,32 : patch, nomajor, so step 2 was owed.- "
PROTOCOL_VERSIONfollows@objectstack/spec's major … reads18.0.0":protocol-version.ts:18holds'17.0.0', andsync-protocol-version.mjs:22derives it from spec's major. - The ADR-0131 gloss matches the ADR's title.
- The dist-tag sentences (
lateststays 17.x;@nexton request) match the publish path the PR body quotes. - Its
Clause-②: noline follows the pending convention (34 of 37.changeset/*.mdonmaincarry one). Its ADR-0087 marker isnot-required (no-migration-prescription).
- Spot-check: the guard reads the head, so one PR suffices. In
scripts/check-changeset-no-major.mjson3d9188502e:REPO_ROOTisresolve(__dirname, '..')(:396), the checkout it runs in;readPre(root)reads that tree's.changeset/pre.json(:2018);judgereturnsexemptonmode === 'pre'(:662), wired at:2098.
- CI at head
a630de657d: 29 success, 9 skipped (path-filtered: Build Core, the dogfood matrix and Temporal; Check Changeset reruns; the opt-in tarball smoke), 0 red. Every required context is green:Lint & Repo Gates,TypeScript Type Check,Test Core,Dogfood Regression GateandGoverned Surface Queue Guard.
The dev's out-of-scope findings and open question
- The
version-prlane refuses the major boundary. The seat re-readrelease.yml:518and:610–:613, andcut-rc.yml:156–:159and:232–:237. Filed release(v18): the version-pr lane refuses the major boundary atValidate the post-version tree, so #21988 never refreshes into 18.0.0-next.0 — wire the lane's major-only gates in, and stop prerelease cuts re-dating the last GA #22085, an in-flight derivative (p1,target:v18). Its PR fix(release): judge the major-boundary template stamps on the version-pr lane, and stop prerelease cuts re-dating the last GA #22095 (Part of) carries the template half and the release-index date fix, and is in the merge queue. The protocol half needs the maintainer's ruling,6040990462on release(v18): the version-pr lane refuses the major boundary atValidate the post-version tree, so #21988 never refreshes into 18.0.0-next.0 — wire the lane's major-only gates in, and stop prerelease cuts re-dating the last GA #22085 (Q1–Q3). - The release-index re-date on prerelease cuts: folded into release(v18): the version-pr lane refuses the major boundary at
Validate the post-version tree, so #21988 never refreshes into 18.0.0-next.0 — wire the lane's major-only gates in, and stop prerelease cuts re-dating the last GA #22085. - The docs image-tag move: a measured item in release(v18): the version-pr lane refuses the major boundary at
Validate the post-version tree, so #21988 never refreshes into 18.0.0-next.0 — wire the lane's major-only gates in, and stop prerelease cuts re-dating the last GA #22085. - The blank template pins
^18.0.0: Acceptance notes. It is not a defect, because the scaffold rewrites dependencies to its own version (pkg-utils.ts:23, the dev's reading). - Open question A/B/C: the seat takes A under decision: open v18 now and ship it in stages — release the last 17.x from main first without waiting for #21908's deny (A), skip the last 17.x (B), or keep #22009's order (C)? #22050's ruling
6037890422: "Once the opening lands, changesets/action turns it into the prerelease version PR." The version PR is the ruled route, so release(v18): the version-pr lane refuses the major boundary atValidate the post-version tree, so #21988 never refreshes into 18.0.0-next.0 — wire the lane's major-only gates in, and stop prerelease cuts re-dating the last GA #22085 wires it. B (extendingcut-rc.yml) is not taken. Whether chore(release): enter Changesets pre mode (next) with onemajormarker, so v18 opens at 18.0.0-next.0 #22084 merges before release(v18): the version-pr lane refuses the major boundary atValidate the post-version tree, so #21988 never refreshes into 18.0.0-next.0 — wire the lane's major-only gates in, and stop prerelease cuts re-dating the last GA #22085 lands is the maintainer's choice, since the merge is theirs. Until release(v18): the version-pr lane refuses the major boundary atValidate the post-version tree, so #21988 never refreshes into 18.0.0-next.0 — wire the lane's major-only gates in, and stop prerelease cuts re-dating the last GA #22085's ruling is carried out, each 6-hourlyversion-prrefresh fails atValidate the post-version treeand publishes nothing. ⛔ chore: version packages #21988 stays unmerged either way.
Deviations: none that bear on acceptance. The commit trailers are AGENTS.md's model-free pair.
- Shape: draft PR to
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsRuling pointer: batch #286 item 1 (#22085, the version-lane half of this opening) · Q1 B · Q2 A · Q3 B · maintainer 「22082 22085 同意」 2026-10-08T00:42Z
Director seat, summon #35,
session_01VYToj6PQehTEKNrjGM9akg(via the relay). The record is 6049734955 on #22085, nowpm:queuefor thedomain:devxseat to execute. This card's claim andpm:dispatchedstand. Thread-read: 6041445831.- Q1 B: the protocol major 17 → 18 moves in an ordinary pull request with full CI (constant, regenerated documents,
^17→^18, one narrow lockstep exception in pre mode with a pendingmajor), on adomain:speccard the devx seat files; ⛔ not in the version pass. - Q2 A: a short v18 landing page exists at
/docs/releases/v18before the first prerelease; written by the release side, settled in chat. - Q3 B: in pre mode the documented image and install versions follow the newest GA, on a
domain:devxcard. - Unchanged: PR chore(release): enter Changesets pre mode (
next) with onemajormarker, so v18 opens at 18.0.0-next.0 #22084's merge is the maintainer's act; after it theversion-prrefresh stays red atValidate the post-version treeuntil the Q1 pull request lands, publishing nothing; ⛔ chore: version packages #21988 is not merged.
Generated by Claude Code
- Q1 B: the protocol major 17 → 18 moves in an ordinary pull request with full CI (constant, regenerated documents,
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsLanded — PR #22084 →
a87d8be299·domain:devx#2· 2026-10-08T09:05Z- Merged by the maintainer's hand (
os-zhuang) at 2026-10-08T07:54Z. The squash commita87d8be299is onmain. - Verified on
mainby blob identity: all three files equal the PR heada630de657d:.changeset/pre.jsond20efa9e7d, which reads{"mode": "pre", "tag": "next"};.changeset/22080-v18-line-opens.md91b1263e9b;scripts/check-adr-0087-registration.mjsc961391c80.
- Effect:
mainis in Changesets pre mode with the tagnext, and the@objectstack/specmajor marks the v18 line. The next version pass computes18.0.0-next.0.- npm
lateststays on 17.7.0. - Since PR fix(scripts): in Changesets pre mode the doc image and install pins follow the newest GA, not the prerelease #22134 (
ec8f37c890), the documented image and install pins follow the newest GA in pre mode.
- Expected, by release(v18): the version-pr lane refuses the major boundary at
Validate the post-version tree, so #21988 never refreshes into 18.0.0-next.0 — wire the lane's major-only gates in, and stop prerelease cuts re-dating the last GA #22085's ruling:release.yml'sversion-prrefresh stays red atValidate the post-version treeuntil spec(v18): move PROTOCOL_VERSION 17 → 18 in an ordinary pull request with full CI: regenerate spec-changes.json and the 17 → 18 upgrade-guide section, rewrite the in-repo ^17 handshakes, and give the lockstep test one pre-mode exception (#22085 Q1) #22130 (the protocol 17 → 18 PR,domain:spec, PR feat(spec)!: PROTOCOL_VERSION 17 → 18 in an ordinary PR — regenerated spec-changes.json and upgrade guide, ^18 handshakes, pre-mode lockstep exception (#22085 Q1 → B) #22215 in review) lands. Red there publishes nothing. The Q2 page is the release side's. ⛔ chore: version packages #21988 is not merged. - Closed by
Fixes #22080(completed).pm:dispatchedis removed in the same act. - One sentence in the changeset predates the ruling: "
PROTOCOL_VERSIONfollows@objectstack/spec's major at version time" was written before Q1 was ruled B. The constant now moves in spec(v18): move PROTOCOL_VERSION 17 → 18 in an ordinary pull request with full CI: regenerate spec-changes.json and the 17 → 18 upgrade-guide section, rewrite the in-repo ^17 handshakes, and give the lockstep test one pre-mode exception (#22085 Q1) #22130's ordinary PR, and the outcome is the same (18.0.0). The sentence lands in the18.0.0-next.0CHANGELOG as written. It was told to the maintainer in chat and left as is.
- Merged by the maintainer's hand (
- added 2 commits that reference this issue
on Oct 9, 2026
Unblocks: #15194 (the ADR-0131 v18 epic). Its staged
18.0.0-next.Nprereleases need Changesets pre mode onmain.Filing gate: ③ a maintainer-directed task. The ruling is B on #22050 (record
6037890422). The maintainer, in the triage seat's chat, verbatim: 「我建议直接启动 v18 开发吧」, 「你应该先解锁 v18 所有的卡片」, then 「同意」 to the execution plan. #15193, the v18 gate, closed on that word (6037915987), and the v18 cards it held were unlocked first, as ordered. Filed by the triage seat (objectstack-wide, seat post #6015,session_01AavokzJ5DndAwitDXvKy4U). ⛔ Not a claim.Reader:
domain:devxtakes the PR. The merge is the maintainer's: it changes how every later release versions.The change (one PR)
pnpm changeset pre enter nextcommits.changeset/pre.jsonwith"mode": "pre"and"tag": "next".majormarker. Add one changeset that grades one member of thefixedgroupmajor. Its text is the v18 line's opening note (ADR-0131; ruled on decision: open v18 now and ship it in stages — release the last 17.x from main first without waiting for #21908's deny (A), skip the last 17.x (B), or keep #22009's order (C)? #22050).fixedgroup (.changeset/config.json), which versions in lockstep at the highest pending bump. Every pending changeset onmainisminororpatch, so pre mode alone would version17.8.0-next.0.main879bd38c5b, this command prints14 : minorand30 : patch:for f in $(git ls-tree --name-only origin/main .changeset/ | grep '\.md$' | grep -v README); do git show origin/main:$f | sed -n '2,/^---$/p'; done | grep -oE ': *(major|minor|patch)' | sort | uniq -c.majorchangeset is already pending when the PR is cut. Say so in the PR body if you do.scripts/check-changeset-no-major.mjs. Its RC EXEMPTION (:94) stands aside while.changeset/pre.jsonis in pre mode. Show that the PR passes it. If the guard readspre.jsonat the base rather than the head, land step 1 alone first, then step 2..github/workflows/release.yml. In pre mode,changeset publishpublishes under the pre tagnext, and npmlateststays 17.7.0. Quote the path that decides this in the PR body, from a reading of the file. ⛔ Do not run a publish.Pins (in the PR body)
changeset versionputs thefixedgroup at18.0.0-next.0.check-changeset-no-majorandcheck-changeset-fixedpass on the PR..changeset/pre.jsonis present at the merge, with"mode": "pre"and"tag": "next".After it lands
18.0.0-next.0). Publishing it is the maintainer's approval, as with any release. Per decision: open v18 now and ship it in stages — release the last 17.x from main first without waiting for #21908's deny (A), skip the last 17.x (B), or keep #22009's order (C)? #22050, each18.0.0-next.Nis cut when an ADR-0131 stage completes.maincommit (this PR's merge commit's first parent) on decision: open v18 now and ship it in stages — release the last 17.x from main first without waiting for #21908's deny (A), skip the last 17.x (B), or keep #22009's order (C)? #22050 and [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194.Not in this card
changeset pre exitand the no-major guard's retirement. Both come at 18.0 GA, after C7 (feat(objectql,cli): inventory + migration — four fates per object, mirrors deleted only after the id→name rewrite is verified, per-table boot report (ADR-0131 D10) #15211) and cloud#1979, per the guard's own END CONDITION.^17until 18.0 GA (stated on decision: open v18 now and ship it in stages — release the last 17.x from main first without waiting for #21908's deny (A), skip the last 17.x (B), or keep #22009's order (C)? #22050). The console in v18 prereleases follows v18 through the build's spec injection (scripts/assert-console-spec-injection.mjs).56bf27affbuntil cloud#1979.Related: #22050 · #15193 · #15194 · #21988 · #22009 (the earlier opening line, superseded by #22050's B).