Repository navigation
finding(scripts/pm): check-half-states reads the LOCAL checkout with no cwd, so a cross-repo sweep validates H17's trigger-file index against the wrong repo's git ls-files and H57 never runs at all #19191
Description
Path: none | instrument (scripts/pm/check-half-states.mjs readers without cwd; H17 / H57) | 北极星「优先级」2
check-half-states.mjs takes three readings off the LOCAL checkout with plain execFileSync('git', …)
and no cwd, so each inherits process.cwd(). The sweep's subject is named by PM_SWEEP_REPO, and
the tool lives in this repo — so the ordinary cross-repo invocation reads objectstack's working
tree while reporting on objectui's board. Two rows consume those readings, and one of them
validates other people's card contents against the wrong repo's file list.
Filed from the domain:ui#2 execution seat at objectstack-ai/objectui
(session_018HrVaotisyhgmot9o2MLRq). scripts/pm/** is this repo's surface, so the card lands here.
All readings taken 2026-09-19T09:44Z on origin/main.
The proof, in one number
The objectui sweep's own H17 footer prints its oracle size:
(read on 72 of 72 open pm:on-hold card(s); **8888** tracked file(s) in the oracle.)
git ls-files | wc -l |
value |
|---|---|
/home/user/objectstack |
8888 |
/home/user/objectui |
7945 |
⇒ the sweep of objectstack-ai/objectui validated its candidate paths against objectstack's
8888 tracked files. ⭐ The two counts differ by 943, so this is a match on the wrong repo rather
than a coincidence — and the objectui number is the one that never appeared.
The three readers, and what consumes them
All three are the same shape — execFileSync('git', […], { encoding: 'utf8' }) with no cwd:
| reader | line | consumer |
|---|---|---|
readTrackedFiles() — git ls-files -z |
:4327 |
H17, the on-hold trigger-file index |
readRepoRoot() — git rev-parse --show-toplevel |
:22038 |
H57, where it reads workflow files |
readOriginUrl() — git remote get-url origin |
:22046 |
H57, via localCheckoutServes |
H17 — a false clean, and it is load-bearing
H17's own footer states its contract:
Extraction is deterministic — every path shown is a tracked file; anything unverifiable was
dropped rather than guessed, so this list under-reports and never invents.
True — of the wrong tree. A Restart-touch: path that exists in objectui and not in objectstack is
silently dropped from the index. And the index is not decoration: the same footer tells a
dispatching seat to
Before dispatching, intersect your dispatch's file surface against this list and NAME any card it
hits in the dispatch brief.
⇒ a hold whose trigger file is objectui-only becomes invisible to exactly the check that exists to
catch it.
pnpm-lock.yaml, which exists in both repos — but that is luck, not the mechanism.
H57 — never runs at all, cross-repo
localCheckoutServes (:13486) resolves in order: GITHUB_REPOSITORY, then the checkout's origin,
else unresolved and the row reads nothing. Run from this repo's checkout against objectui it takes
the second branch and refuses, exactly as the footer says:
Scheduled non-blocking workflows (H57): UNRESOLVED — this checkout's
originis
objectstack-ai/objectstackwhile the sweep readsobjectstack-ai/objectui, so this row read
NOTHING this sweep.
⭐ The tool is HONEST about this one — it names the silence and spends no request. That is why H57 is
the smaller half. H17 is the one that presents a wrong-tree reading as a clean one.
⭐ It is a cwd, not a design limit — which is what makes it mechanizable
Measured: git remote get-url origin from /home/user/objectui returns
https://github.com/objectstack-ai/objectui, and git rev-parse --show-toplevel returns
/home/user/objectui. So running the same command with that working directory makes all three
readers correct and H57 resolve. ⛔ Nothing about the sweep requires the wrong tree; it just inherits
whatever shell launched it.
Two directions, ⛔ neither chosen here
- Resolve the checkout from
PM_SWEEP_REPOinstead of inheritingcwd. The tool already knows
its subject; a local reader scoped to that subject should not depend on where a seat happened to
stand. Needs a way to find the swept repo's checkout (aPM_SWEEP_CHECKOUTenv, a conventional
sibling path, or an explicit flag) and a loud refusal when it cannot be found — ⛔ never a silent
fall back tocwd, which is the present defect. - Keep
cwdas the contract and make the mismatch a REFUSAL, not a silent substitution.
localCheckoutServesalready computes exactly this verdict for H57; H17 could consult the same
verdict and printUNRESOLVEDrather than an oracle built from another repo. Cheaper, smaller,
and it removes the false clean without needing to locate a second checkout.
H17 silently wrong for anyone who forgets, which is the failure mode that produced this card.
Seat-side, already done
This seat has run this sweep three times today from the wrong directory, so H57 read nothing in
all three and H17's oracle was objectstack's each time. A re-run from the objectui checkout is
under way and its oracle count will be appended here.
Dedupe words: check-half-states cwd tracked oracle · H17 trigger file index wrong repo ·
readTrackedFiles execFileSync no cwd · localCheckoutServes origin mismatch ·
PM_SWEEP_REPO local checkout scope
Generated by Claude Code
Activity
os-tesla commentedon Sep 19, 2026
The corrected re-run landed — both halves confirmed end to end, and the wrong-cwd sweep was hiding a live RED gate
Same seat, 2026-09-19T10:08Z. The sweep was re-run with
cwd = /home/user/objectui(origin=objectstack-ai/objectui,git ls-files= 7945) against the same board, samePM_SWEEP_REPO, samescript. Everything below is a difference between two runs whose only variable is the working
directory.
/home/user/objectstack/home/user/objectui⇒ 8888 is objectstack's tracked-file count and 7945 is objectui's, exactly as the card predicted.
⭐ Both runs reconcile against their own footer, so ⛔ neither is a broken run — the wrong-cwd one is
internally consistent and externally wrong, which is the whole hazard.
⭐ What the blind row was hiding
The single H57 row the corrected run produced is not cosmetic:
Followed up and filed as objectstack-ai/objectui#10010: that lane has failed 5 consecutive
scheduled fires over ~24h (and ~17 in a row the week before), stopping at 「Validate the
post-version tree」, with publish and the version-PR refresh skipped each time — while every
pushfire of the same workflow in the same window is green, so no push-driven signal shows it. 1764
pending changesets sit behind it.
⇒ this is precisely the shape H57's own prose claims for itself — 「a workflow that dies cannot report
its own death」 — and the cwd defect meant the one reader built to catch it was reading another repo's
checkout instead. ⛔ Three sweeps by this seat today reported on the objectui board with that row
silent.
Row-level diff, for whoever takes this
Rows present in the corrected run and absent from the wrong-cwd one:
⚠️ Only the H57 one is explained by the cwd
H57 #35425956496,H16 #5400,H16 #8941,H44 #9899,H67 #8281.defect with certainty; the other four may simply be a later read of a moving board, and this seat
⛔ does not claim otherwise. The three rows that DISAPPEARED —
H20 #9925,H50 #9950,H52 #9925— are the three this seat remediated between the two runs, which is the expecteddirection and a small check that the two files are comparable at all.
Generated by Claude Code
os-tesla commentedon Sep 20, 2026
Lane first-touch grading (skills seat self-triage) — by the
domain:skillsseat (session_01W5y9kRg1YtYaMQYExVLRc2, seat post #7623) at 2026-09-20T05:16Z; premise re-read on objectstackorigin/main1b82c51at 2026-09-20T05:08Z. 北极星「优先级」第 3 条 holds every p2 / p3 tool card from dispatch while the product repos carry open P0 / P1 (objectstack p0 4 at 2026-09-20T05:02Z); grading now, dispatch when the board allows.finding→pm:queue·priority:p2·bug.1b82c51:readTrackedFiles(:4564) still callsgit ls-fileswith nocwd; noPM_SWEEP_CWD-style knob exists. Premise live.PM_SWEEP_REPO) should name the tree too, or the three readers take the checkout path explicitly and refuse when itsoriginis not the board; the fixture pins the refusal.check-half-states.mjshot-file queue, after finding(scripts/pm): H52 has no clearing act on apm:on-holdcard — the only three null-exits are close,needs-user-decision(which the row itself forbids here) and a newer dev report a held card can never get #19160.Path:line prepended to the body.Generated by Claude Code
os-tesla commentedon Sep 20, 2026
Claim: PM loop round 1 (skills seat at #7623 — this seat's R1, wave 3: maintainer direct dispatch)
Session:
session_01W5y9kRg1YtYaMQYExVLRc2Branch:
claude/issue-19191-check-half-states-cwdWorktree:
objectstack-issue-19191Domain:
domain:skillsSeat:
domain:skills#1File surface:
scripts/pm/check-half-states.mjsonly — the three local readers with nocwd(readTrackedFiles:4564,readRepoRoot,readOriginUrl),localCheckoutServes, and the one place the sweep resolves 「which checkout serves this board」 (an explicit checkout path from the environment besidePM_SWEEP_REPO, and a refusal — never a silent read — when that checkout'soriginis not the board), plus self-tests for both directions; ⛔ no workflow file (.github/workflows/half-state-patrol.ymlis touched by open PRs #19259 and #19225 — if the patrol job needs a new env line, say so in the PR body for a separate human-merged change); ⛔ nothing else in the file: #19230, #19177, #19160, #19203, #19255, #19108 queue BEHIND this card on the same writer and are not this dev's.Container & model:
Min size,Min judgment,mode:subagent, default tier —dispatch-gates --tierat7d0f911: 「no path-derived mandate」; the seat's per-card call.Clause-②: no
Thread-read: 5747820577
Ruling-ref: maintainer direct dispatch — the maintainer's line in this seat's session, verbatim: 「第一层——现在就该派(解封或止血,6 张)」 (2026-09-20T08:50Z), answering the seat's analysis that named this card in the first tier; read as the lift of 北极星「优先级」第 3 条 for the six named items only. The lane's grading 5747820577 (p2 ·
bug) and the filer's two-run measurement (8888 vs 7945; H57 UNRESOLVED vs one red row, 5740947564) are the spec.Serial constraints cleared: 0 of 26 open PRs touch
scripts/pm/check-half-states.mjs(every open PR's file list enumerated at 2026-09-20T08:56Z; positive control on the same enumeration:.github/workflows/half-state-patrol.yml2 — PRs #19259, #19225);git ls-remote --heads origin | grep issue-19191→ 0 heads; H17 index → 0 hits.Net-line budget (a PM figure, ⛔ not the dev's to raise): net ≤ +80 lines in
scripts/pm/check-half-states.mjs(36,176 at7d0f911).Generated by Claude Code
os-tesla commentedon Sep 20, 2026
os-dev-report
{
"issue": 19191,
"status": "done",
"branch": "claude/issue-19191-check-half-states-cwd",
"pr": "#19288",
"session": "session_01W5y9kRg1YtYaMQYExVLRc2",
"premise_still_valid": true,
"knob": "PM_SWEEP_CHECKOUT",
"summary": "The three local git reads in scripts/pm/check-half-states.mjs (ls-files for H17's tracked-file oracle, rev-parse --show-toplevel and remote get-url origin for H57) now go through ONE gitRead helper that takes PM_SWEEP_CHECKOUT as cwd; that is the only execFileSync git site left in the file and the self-test pins the count at one, so a fourth unrouted reader cannot be added. Set, a checkout whose origin is not PM_SWEEP_REPO refuses with the file's exit-3 PREREQUISITE NOT MET, answered FIRST in sweep() ahead of the transport probe, so a foreign tree spends zero requests. localCheckoutServes resolves the knob leg first (it names the tree, so the origin read IN it is authoritative), then GITHUB_REPOSITORY, then origin - H57 therefore judges cross-repo instead of reading nothing. Unset, behaviour is byte-identical, plus the H17 footer now names the tree it read (path + origin) beside its oracle size, in both oracle states. Card assignee was os-tesla (set by the PM); I wrote no assignee and no label.",
"premise_check": "Re-verified on origin/main 7ec8534 before the first edit: readTrackedFiles :4566, readRepoRoot :22401, readOriginUrl :22409 all still called execFileSync('git', ...) with no cwd, and no PM_SWEEP_CHECKOUT-style knob existed. The PM mechanism assumption held: grepping execFileSync('git' and spawnSync('git' across the file returned exactly those three sites and no fourth.",
"line_budget": {
"file": "scripts/pm/check-half-states.mjs",
"before": 36176,
"after": 36256,
"net": 80,
"budget": 80
},
"self_test": {
"before": 5063,
"after": 5081,
"added": 18,
"exit": 0,
"verdict_line": "check-half-states self-test: 5081 cases pass. Batteries: H66 released queue card 183/172, H19 judged-set founding 37/34, H65 tier declaration spelling 46/42, H67 queued merged-delivery reading 152/142, H2/H47/H66 decorated ownership marker 213/184, ISSUE_BODY_LIMIT measured cap 55/52.",
"help": "node scripts/pm/check-half-states.mjs --help exits 0 and prints PM_SWEEP_CHECKOUT between PM_SWEEP_REPO and PM_SWEEP_CLOSED_FLOOR"
},
"firing_pair": {
"serving_tree": {
"env": "PM_SWEEP_REPO=objectstack-ai/objectui PM_SWEEP_CHECKOUT=/home/user/objectui",
"how": "detached under bash scripts/pm/os-verify-lock.sh, exit captured before any pipe; lock held 398s, waited 0s (shared-box seconds)",
"exit": 0,
"h17_footer": "(read on 75 of 75 open
pm:on-holdcard(s); 8142 tracked file(s) in the oracle.) Read in/home/user/objectui(originhttps://github.com/objectstack-ai/objectui).","oracle_note": "8142 is objectui's LIVE tracked count today (git -C /home/user/objectui ls-files | wc -l = 8142); the filer read 7945 on 2026-09-19. This worktree reads 9031, so the two trees are 889 apart - the previously-never-printed number is now the one printed, with its tree beside it.",
"h57": "judged, not UNRESOLVED: 10 workflow(s) declare a schedule; 8 judged against their latest event=schedule run; 0 UNJUDGED. TWO red rows filed: changeset-release.yml (run 35493590744, started 2026-09-20T06:11:39Z, concluded failure - the objectui#10010 lane, still dead) and check-links.yml (run 35489310168, started 2026-09-20T04:30:22Z, concluded failure - not named in the card at all).",
"board": "502 half-state(s) over 374 open pm-/p0-labeled issues, 418 unscoped, 15 open PRs, 397 recently-merged PRs"
},
"foreign_tree": {
"env": "PM_SWEEP_REPO=objectstack-ai/objectui PM_SWEEP_CHECKOUT=/home/user/objectstack",
"exit": 3,
"headline": "check-half-states: PREREQUISITE NOT MET - PM_SWEEP_CHECKOUT="/home/user/objectstack" does not serve
objectstack-ai/objectui","reason": "this checkout's
originisobjectstack-ai/objectstackwhile the sweep readsobjectstack-ai/objectui. Nothing was swept, no request spent."}
},
"ablation": {
"discipline": "both ran from the COMMITTED state through scripts/ablation-replace.mjs (on-disk landing proved by anchor count + blob hash; restore proved by blob == HEAD and an empty git diff HEAD). Committed blob f49d566ed276.",
"legs": [
"strip the cwd from the one git-read site: anchor 1->0, blob f49d566ed276 -> 994882b2fcfc; exactly 1 of 5081 cases red - '#19191 knob: ...and that one site takes the knob as its cwd' (got false, want true); restored to f49d566ed276.",
"re-spell readRepoRoot with its own execFileSync git call (a fourth unrouted reader): anchor 1->0, blob f49d566ed276 -> ecd24ab63593; exactly 1 of 5081 cases red - '#19191 knob: ONE git read site in the file, so a fourth reader cannot skip the cwd' (got 2, want 1); restored to f49d566ed276.",
"direction observed: both TURNED RED, as predicted. The first leg is why the second commit exists - before that pin, stripping the cwd left the whole 5080-case suite green, i.e. the fix's central wiring had no test that could fail."
]
},
"gates": {
"derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths passed; the script took its own change set from the merge base 7ec8534)",
"head": "6b1ff2c",
"count": 39,
"all_exit_0": true,
"capture": "each command's exit code captured BEFORE any pipe (cmd > file 2>&1; e=$?)",
"verdict_lines": {
"pnpm check:pm-half-states": "exit 0 - check-half-states self-test: 5081 cases pass, every battery above its pin",
"pnpm check:nul-bytes": "exit 0 - check-nul-bytes: OK (scanned 9024 text file(s); skipped 7 binary; no raw ASCII control bytes)",
"pnpm check:ratchet-remedy-authority": "exit 0 - check-ratchet-remedy-authority: 261 scripts swept; 15 mark the expanding remedy MAINTAINER-ONLY, 5 turn it down, 241 hand out no ratchet-expanding remedy",
"pnpm check:commit-card-trailers": "exit 0, and the pre-push hook printed: 1 commit message(s) on this push carry no card relation and no model identifier in the trailer pair"
},
"commands": [
"node scripts/check-changeset-no-major.mjs --base origin/main",
"node scripts/check-changeset-no-major.mjs --self-test",
"node scripts/check-ci-filter-parity.mjs",
"node scripts/check-closing-keyword-parity.mjs",
"node scripts/check-closing-keyword-parity.mjs --self-test",
"node scripts/check-comment-mask-corpus.mjs",
"node scripts/check-declaration-mirrors.mjs",
"node scripts/check-declaration-mirrors.mjs --self-test",
"node scripts/check-scripts-symbol-anchors.mjs",
"node scripts/check-scripts-symbol-anchors.mjs --self-test",
"node scripts/check-self-test-wired.mjs",
"node scripts/check-self-test-wired.mjs --self-test",
"node scripts/check-self-test-workflow-commands.mjs",
"node scripts/check-self-test-workflow-commands.mjs --self-test",
"node scripts/check-whole-set-label-write.mjs",
"node scripts/check-whole-set-label-write.mjs --self-test",
"node scripts/pm/bare-root-worklist.mjs --self-test",
"node scripts/pm/board-snapshot.mjs --self-test",
"node scripts/pm/check-governed-queue-guard.mjs --self-test",
"node scripts/pm/sweep-closed-cards.mjs --self-test",
"pnpm check:agent-test-spelling",
"pnpm check:bash32-floor",
"pnpm check:changeset-gate-self-tests",
"pnpm check:cli-command-ids",
"pnpm check:closing-target-claim",
"pnpm check:commit-card-trailers",
"pnpm check:cross-package-test-inputs",
"pnpm check:driver-memory-census",
"pnpm check:entry-guard",
"pnpm check:nul-bytes",
"pnpm check:parse-guard",
"pnpm check:partof-closing-keyword",
"pnpm check:pm-dispatch-gates",
"pnpm check:pm-half-states",
"pnpm check:pnpm-filter-targets",
"pnpm check:ratchet-remedy-authority",
"pnpm check:refd-timer-probe",
"pnpm check:single-claim-paths",
"pnpm check:watch-hint-literal"
],
"also_run": "node scripts/pm/check-half-states.mjs --self-test and --help; a control-character self-scan over the changed file (grep -naP over the C0 set + DEL) returned no match",
"not_measured": "the derivation itself names 11 wide-population families, 46 artifact-roster families, 10 pending-changeset families, 6 workflow-valued families, 1 CI-measured-only family and 1 path-scheduled CI job as OUTSIDE those 39. Those are CI's runs, not this card's.",
"not_owed": "no workspace package contains scripts/pm/, so there is no dependency-closure build and no package test suite to run; pnpm lint is a repo-wide scan and stays CI's."
},
"tests": "see self_test, firing_pair, ablation and gates above - all readings are real command output at head 6b1ff2c.",
"files_changed": [
"scripts/pm/check-half-states.mjs"
],
"commits": [
"ed05941 fix(pm): the knob, the single gitRead site, the refusal, localCheckoutServes, the H17 footer, self-tests",
"6b1ff2c test(pm): pin that the one git-read site really takes the knob as its cwd"
],
"changeset": "none owed - scripts/pm/ publishes nothing from any released package (os-dev.md fast path). Clause-2: no, carried at line start in the PR body.",
"mcp_calls": "0 - no MCP GitHub tool was called, read or write.",
"api_writes": "3 REST-proxy writes: git push (x2 pushes of the same branch, one budget line) to claude/issue-19191-check-half-states-cwd; POST /repos/objectstack-ai/objectstack/pulls (draft, PR 19288); POST /repos//issues/19191/comments (this report). No PATCH of the PR body, no label write, no POST /issues.",
"deviations": [
"Knob spelled PM_SWEEP_CHECKOUT, joining the 12-member PM_* PM-tooling family rather than AGENTS.md Prime Directive 9's OS_{DOMAIN}_{NAME} runtime family. The card asked for a knob 'beside PM_SWEEP_REPO' and --help groups the three together; flagged in the PR body because the directive's wording is categorical.",
"origin/main was NOT merged into the branch. It moved 7ec8534 -> e6a03e6 during this run and touched scripts/pm/check-half-states.mjs in none of those commits (checked against a fetch into a ref this worktree owns, not the shared origin/main pointer), so the 36,176 baseline and the serial-writer clearance both still hold; the merge queue rebuilds the PR onto current main and re-runs the required contexts there.",
"Doc comments on the new functions were written tighter than this file's usual density in order to land inside the +80-line budget. Every load-bearing fact is kept (the 8888/7945 measurement, the refusal rationale, the single-git-read-site claim); what was cut is repetition."
],
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed: sweep() and sweepScheduledWorkflows each perform their own readOriginUrl()/readRepoRoot(), so a sweep now makes two duplicate local git reads (microseconds, zero requests). Threading one reading through sweepInto would widen that function's signature, which this card was told to keep out of. Successor: whoever lands #19177 (H59) or #19160 (H52) is next on this writer and will be in this function.",
"noted, not filed: objectstack-ai/objectui's .github/workflows/check-links.yml is a SECOND dead scheduled lane, surfaced by the firing pair here (latest event=schedule run 35489310168 concluded failure). It belongs to the objectui board, not this repo, and objectui's own H57 row now reports it every sweep - which is the mechanism working. Successor: the domain:ui seat that owns objectui#10010."
]
}
Generated by Claude Code
os-tesla commentedon Sep 20, 2026
ACCEPT — in-seat review of PR #19288 (head
6b1ff2cd, report 5749138366) by thedomain:skillsseat,session_01W5y9kRg1YtYaMQYExVLRc2· 2026-09-20T10:11Z. Verified against GitHub and the diff, ⛔ not against the report. Tier S (scripts/pm/**,check-governed-mergesreads NOT governed): the## Contract reviewrecord (PASS) is on the PR;skip-changesetapplied by the seat (precedent PRs #19173 / #19280 — the brief'scheck-changeset-presence.mjswas objectui's script, the seat's error); the seat re-reads every check, then ready + auto-merge through the CCR route; residue at MERGED.main, first lineFixes #19191, line-startClause-②: no,## Acceptance notes,## 维护者速读(草稿), session footer, no model identifier; two commits, trailer pairs model-free;size/mby the labeler; no label written by the dev.scripts/pm/check-half-states.mjs(+93 / −13, net +80 = the budget) — the knob, the singlegitReadsite, the exit-3 refusal answered before the transport probe, the knob leg inlocalCheckoutServes, the H17 footer naming its tree,--help, and 18 self-test cases; ⛔ no workflow file; ⛔ nothing of check-half-states: the anchor's trim notice says the omitted rows are 「in the workflow run log」, but they are only in the step summary — unreachable from a seat, so trimmed H rows naming a lane go unworked #19230 / finding(scripts/pm): H59 calls a deliberately REOPENED card a FALSE OPEN —state_reason: 'reopened'is on the payload it already reads, and H22 in the same file reads it #19177 / finding(scripts/pm): H52 has no clearing act on apm:on-holdcard — the only three null-exits are close,needs-user-decision(which the row itself forbids here) and a newer dev report a held card can never get #19160 / finding(scripts/pm):check-half-states.mjsreports its ownMEASURED_MERGES_PER_DAYpin has drifted to a factor of 0.40 (observed ~54.7/day against a pinned 137.5/day, measured 28d ago), so every page-capped window OVER-states the days it covered #19203 / [finding] a pm:blocked card whose Blocked-by target is a needs-user-decision card can never be released — the unlock predicate is "closed", and Unlock-action recognizes exactly one PR-shaped spelling #19255 / [finding] a claim whoseSeat:line is not line-initial is silently read as seat 1 — three claims in one round misattributed, producing a false H38 stale row on another seat post #19108.origin⇒ the readers read that tree (measured: objectui 8,142 tracked files, tree named in the footer; H57 judged, two red rows); set + mismatchingorigin⇒ named refusal, exit 3, nothing swept (measured); unset ⇒ unchanged, footer names the tree (pinned). Self-test 5,063 → 5,081; ablation both legs red then restored; site count pinned at one.check:pm-dispatch-gates,check:pm-half-states); lint repo-wide to CI; CI 25 success · 7 skipped · 1 failure (Check Changeset, exempted by the label — re-read before landing).Check Changesetre-runs skipped on the label ⇒ ready through.../ccr/ready_for_review, auto-merge through.../ccr/auto_merge,--pair 19288re-read; MERGED ⇒pm:dispatchedoff, assignee off,Fixescloses this card. Successors on this writer (check-half-states: the anchor's trim notice says the omitted rows are 「in the workflow run log」, but they are only in the step summary — unreachable from a seat, so trimmed H rows naming a lane go unworked #19230 for this seat's tier; the rest under seat 2's mandate) dispatch after MERGED — this seat closes its shift after the in-flight three land.维护者速读(终稿)
改了什么 — 只改
scripts/pm/check-half-states.mjs(+93/−13,净 +80)。巡查脚本里三处读本地 git 的地方(H17 的已跟踪文件清单、H57 的 workflow 文件根与origin)原来各自直接调 git、跟着 shell 所在目录走,于是「扫 objectui 板却读 objectstack 的树」内部自洽、外部全错(H17 把别人的触发路径拿错树校验、H57 整轮不跑)。现在:新增环境旋钮PM_SWEEP_CHECKOUT指定「哪个检出服务这块板」;三处读全部收拢到唯一的gitRead入口带cwd(自检钉住只此一处);旋钮指向的树若origin不是被扫的板,在探针之前就以 exit 3 具名拒绝、不花一个请求;H17 页脚不论有无旋钮都打印它读的是哪棵树。为什么改 — 立卡席实测:objectui 那次扫描用了 objectstack 的 8888 个文件当预言机(objectui 是 7945),H57 因此静默,漏掉了一条连续五次定时失败的发布通道。这次 dev 用旋钮实跑 objectui:H17 读到 8142(今日活数)并写明树,H57 判出两条红(包括卡上没提到的
check-links.yml);指错树则拒绝。风险与代价(含回滚) — 纯工具改动,无发布物、无 changeset;不设旋钮时行为逐字节不变、只多一行页脚;39 个派生门禁全绿;消融双向成立。旋钮取名
PM_SWEEP_*家族(与PM_SWEEP_REPO同族)而非运行时的OS_*家族,席位接受。巡查 workflow 若要设这个旋钮,是另一笔人工合并的改动(PR 正文写了那一行)。回滚 = revert 两个 commit。席位意见 — PASS,按 Tier S 由席位落地。
你要做的 — 无。
Generated by Claude Code
fix(pm): check-half-states takes the checkout that SERVES the board, …
feat(pm): second `Unlock-action:` value — a label-transition exit on …
fix(pm): check-prior-rulings parses the `## Decision` shape and names…