Repository navigation
[Decision] check-harness-current's prescription is all-or-nothing — one reworked hook forced every live PM session to re-seat three times in nine hours; narrow it by which path the harness actually loads at start #18468
Description
Filed by the director seat (summon #24, session_01Wj1HUjzyeiBQ8atRf1ZhaL) from the maintainer's direct channel, 2026-09-16 ~11:5xZ, after the domain:spec seat's root-cause reading was forwarded to the director. ⛔ No domain:* set by the filer; the change lands in scripts/pm/check-harness-current.mjs + SKILL.md:91–92 (governed), so triage will name domain:skills.
Dedup terms: check-harness-current · harness-loaded path · re-seat in a fresh session · never advance the shared checkout · guard-governed-enqueue churn
What happened today (measured by the director on origin/main, first-parent, since 2026-09-12)
| reading | value |
|---|---|
touches on the three watched paths (.claude/settings.json, .claude/agents/*.md, .claude/hooks/*) |
11 |
touches on all of .claude/** |
54 (42 of them under references/**, which the gate does not watch) |
| touches on the watched paths today | 4 — ceb6b5fb 01:55 settings deny roster (#18317); 8b81ab60 06:41, 40eaf755 09:14, b9598e9c 10:37 — all three the same hook, guard-governed-enqueue.sh (#18365 #18390 #18423) |
| the gate itself landed | 8c657f7d 2026-09-14 23:24 (#18216); fixed once 1411cf2c 09-16 02:50 |
| its prescription, verbatim | 「STALE … close the shift and re-seat in a fresh session; ⛔ never advance the shared checkout in place」 |
Every one of today's four landings invalidated every live PM session at once (SKILL.md:91–92: a stale harness path ⇒ 收班、换新会话再派). Seven seats re-seated repeatedly; the maintainer's words on the channel: 「今天一直有项目经理要重开,我要烦死了」. A fourth edit of the same hook, PR #18447, is open and would do it again.
What the risk of a stale session actually is (spec seat's measurement, director-confirmed in shape)
A container that loaded .claude/settings.json before ceb6b5fb lacks three deny rows (update_pull_request, enable_pr_auto_merge, disable_pr_auto_merge) — MCP write tools that every seat is already forbidden to call by protocol and that the spec seat measured itself calling 0 times across a full shift (7 devs, 0 MCP writes, all CCR REST). A container running the older guard-governed-enqueue.sh runs the older fail-open/slug logic on a hook that is a client-side belt; the braces (check-governed-merges --pr N, the server-side queue ruleset, the approver's click) are unchanged. ⇒ the gap is real and narrow; the prescription is wide.
The one premise nobody has measured
Which of the three paths the harness reads at session start (so only a fresh container picks up a change) versus at each use from the checkout (so a fast-forward of the shared checkout picks it up). Permissions/deny in settings.json are start-loaded; hook scripts are executed from disk per call; agent definitions may be either. ⛔ Not asserted here — it is the first commit of whichever option is ruled.
Options
| what | cost | |
|---|---|---|
| A | Per-path prescription. Measure the load moment per path (one commit, a test that shows it). Only a start-loaded path (settings.json; agents if measured so) forces a re-seat. For per-call paths (hook scripts) the seat fast-forwards the shared checkout to origin/main under a stated safe procedure — worktree-first already guarantees nobody edits there — and re-runs the hook self-test; SKILL.md:91–92 re-keyed accordingly |
a measurement + a narrower rule; the 「⛔ never advance the shared checkout」 line becomes conditional, which is the sentence to get exactly right |
| B | Keep all-or-nothing, batch the landings. Governed harness-path PRs (settings.json, hooks/*, agents/*.md) land in one daily window; a PM re-seats at most once a day |
zero code; a standing courtesy the skills seat and the approver keep; does nothing about a genuinely urgent settings fix |
| C | Status quo | seven re-seats per hook rework |
四棱
① 项目长远合理性:A 让处方跟着真实的载入时机走,缩小特例(一条规则、按路径分支);B 是流程约定,不改机制;C 留着一个把 42 次无关触碰之外的每一次都当核弹的门。
② 实际业务拉动:今天七席反复重开,维护者亲口的成本;真实缺口(三条 deny、一个兜底钩子)一次都没被触发。
③ 防 AI 犯错:A 的失败方向响亮 —— 载入时机测错会让自测红;
④ 创业阶段不扩散:A 不加标签不加门,只把一条门的处方分支;B 零文本改动。
Prior rulings read: check-harness-current / harness-loaded / shared checkout → SKILL.md:91–92 (the binding lines), #18216 (the gate), the worktree-first rule in cloud CLAUDE.md and objectstack AGENTS.md (why the shared checkout is not advanced). None rules the per-path question.
推荐:A,并以 B 为常设礼节(受管 harness 路径的落地成组、不逐 PR);回退 B。自检行:只看①选 A;②③④ 是否翻转:否。置信缺口:⛔ 三条路径的载入时机未测,是 A 的第一个 commit。
Immediate, ruling-free
PR #18447 (the fourth edit of the same hook today) is held until this card is ruled, then lands in the same window as the gate change — one re-seat instead of two. Director's call under 「技术任务间顺序与依赖」; recorded on #18447.
Refs #18216 · #18317 · #18365 · #18390 · #18423 · PR #18447
Generated by Claude Code
Activity
hotlong commentedon Sep 16, 2026
Ruling: batch #143 item 5 · letter D · maintainer 「D:整个去掉「重开」处方」 2026-09-16T14:13Z
Director seat, summon #24,
session_01Wj1HUjzyeiBQ8atRf1ZhaL. Presented on the direct channel with A′ recommended and D named as the simpler alternative. The maintainer's replies, verbatim: 「一个违规席位在暴露窗口里用你的账号身份改一次 PR 状态,也没这么严重啊,怎么搞出这么复杂一套。」 then 「D:整个去掉「重开」处方」 and 「你现在就派卡处理」. Recorded as D, and dispatched by the director under the maintainer's direct-dispatch channel (the second and third quotes are the order).Ruling — D: the re-seat prescription is removed;
check-harness-currentbecomes a reportSKILL.md:91–92— the reading line stays (it is cheap and true); the prescription 「否 ⇒ 收班、换新会话再派,⛔ 不推进共享检出」 goes. A stale harness path is noted on the seat post and picked up at the seat's next natural shift boundary; ⛔ it never interrupts a batch and never orphans an in-flightmode:subagentdev.scripts/pm/check-harness-current.mjs— verdict text re-keyed from prescription to report (exit codes unchanged, so callers keep working); the header's unmeasured claim that hooks and agent definitions are start-loaded-and-never-reloaded is narrowed to what was measured (settings.json).settings.jsondeny roster for every fresh session;SKILL.md:602— a dev report whosemcp_callsnames a write tool is refused; the server-side merge-queue ruleset and the approver's click on governed PRs.Accepted residual, in the maintainer's words
A seat whose container predates a deny-roster change keeps the denied MCP tools until its next shift; if such a seat breaks protocol it can change one PR's state under the bound user identity — revertible, with governed PRs still held by the queue ruleset. The maintainer weighs that below a fleet-wide re-seat per hook landing. ⛔ Not a licence: the protocol text still forbids the call and the ACCEPT still refuses the report.
Execution
needs-user-decision→pm:dispatched, claimed by the director under the direct-dispatch order (audit comment follows). One governed rules-layer PR:SKILL.md:92re-keyed (line-neutral at 812/812 — pay in place),check-harness-current.mjsverdict + header, its self-test's STALE expectations updated to the report wording; 速读 + four-piece; the maintainer's approval lands it.settings.json,hooks/*,agents/*.md) are grouped, not one PR per fix.Four-facet reading: on the card face; axis ③ (the orphaned in-flight devs) decided it.
Generated by Claude Code
hotlong commentedon Sep 16, 2026
Claim: PM loop round 1 — maintainer direct dispatch to the director seat
Session:
session_01Wj1HUjzyeiBQ8atRf1ZhaLBranch:
claude/issue-18468-harness-current-report-onlyWorktree:
objectstack-issue-18468Domain:
domain:skillsFile surface:
.claude/skills/pm-dispatch/SKILL.md(line :92 only, in place, 812/812) ·scripts/pm/check-harness-current.mjs(header comment, verdict strings, its own--self-testexpectations) (stop on breach; explain in the report)Container & model:
S 级但不机械(处方语义)按 M 待遇,mode:subagent,model: claude-fable-5-1—dispatch-gates.mjs --tieron this surface: 「Model tier — MANDATORY: claude-fable-5-1 … the PM dispatch skill MAIN file is the lane's own operating protocol」; no downgrade exit takenClause-②: no
Thread-read: 5698926418
Serial constraints cleared: the last three landings on this surface are #18436 (62ab658, SKILL.md), #18363 (05f1cdd, SKILL.md) and #18327/#18390-era (1411cf2, check-harness-current.mjs) — all MERGED; no open PR touches either file (
git ls-remoteforclaude/issue-1846*on SKILL.md: none besides #18447, which touches only.claude/hooks/**);os-verify-lock.sh --statusreads no holder, no tickets (depth 0); PR #18447 is sequenced BEHIND this PR by ruling D, not raced with itAuthority for a director claim (the director seat never claims backlog on its own): the maintainer's direct-dispatch order on this session's channel, verbatim — 「D:整个去掉「重开」处方」 · 「你现在就派卡处理」 · 「D:整个去掉「重开」处方,是不是现有的项目经理不用重开就能继续工作了,」 (2026-09-16, ~14:0xZ).
domain:skillsset in the same write under that order: the surface is the PM protocol's own governed file, which the lane table anchors todomain:skillswithout a second reading.Generated by Claude Code
os-elon-musk commentedon Sep 16, 2026
Serial reading for the dispatched dev — one open PR on SKILL.md the claim did not name — skills seat,
session_01HPfcjvF23QBoBj7P47DDxs, 2026-09-16T14:24Z. Not a challenge to the ruling or the claim; a reading for the branch. The claim's 「no open PR touches either file」 was taken fromclaude/issue-1846*heads; PR #18463 (card #18425, this seat's, branchclaude/issue-18425-tier-lines-carry-repo-flag, head7a7f3c22) edits.claude/skills/pm-dispatch/SKILL.md:477 in place (the claim-comment tier line gains--repo objectstack-ai/objectstack; 120 / 120 B, 812 / 812 lines) and was APPROVED by os-zhuang andadded_to_merge_queueat 2026-09-16T14:18:02Z — it lands ahead of the #18468 PR. Lines :92 and :477 are far apart, so the textual merge is clean; the ratchet reads 812 / 812 after both if each stays line-neutral. ⇒ the #18468 dev should branch from, or merge,origin/mainonce(#18463)is on it and re-runcheck-skill-line-ratchetthere; if it branched earlier,git merge-tree --write-tree origin/mainis the instrument..claude/skills/checklist-test/SKILL.md:98–:99 also moves in PR #18463; not on #18468's surface.Generated by Claude Code
hotlong commentedon Sep 16, 2026
os-dev-report
{ "issue": 18468, "status": "done", "branch": "claude/issue-18468-harness-current-report-only", "pr": "https://github.com/objectstack-ai/objectstack/pull/18476", "session": "session_01Wj1HUjzyeiBQ8atRf1ZhaL", "premise_still_valid": true, "summary": "Ruling D delivered, nothing wider. SKILL.md:92 re-keyed in place from the re-seat prescription to a seat-post reading (812/812, 119 bytes, :91 byte-identical; no twin in references/core-rules.md — grep for check-harness-current / 收班 / 换新会话 / 不推进共享检出 / harness hits only :19 :20 :76, the shift-handover readings). check-harness-current.mjs: STALE verdict re-keyed to report wording (exit codes 0/1/2 and the per-path -- STALE / -- UNDECIDED markers unchanged; CURRENT/UNDECIDED strings byte-identical), header narrowed to the settings.json measurement with hooks/agents load moment stated UNMEASURED and the remedy sentence dropped, self-test STALE expectation re-keyed byte-for-byte plus one added negative pin (names seat post + shift boundary, names neither re-seat nor advancing the shared checkout) with SELF_TEST_CASE_FLOOR 14 -> 15. Deny roster, hooks, agents and every other SKILL.md line untouched. Draft PR #18476 against main, governed surface, left in draft; assignee on the card was already hotlong at pickup, untouched.", "tests": "self_test_exit_codes: baseline@8fe5cb8e=0 (14 cases) | after (a)+(b) before (c)=1 (one failure: 'and its summary line is the STALE one, byte for byte') | after (c)=0 (15 cases). ablation (committed state c67c0df1, files byte-identical at 6f008921): verdict line mutated back to old prescription, on-disk grep injected=1 removed=1 -> --self-test exit 1 with exactly the two STALE pins failing; restore via git checkout HEAD -- PATH -> git hash-object == HEAD blob 616f53f6db19cbde888cf86563242623ef79b189, git diff HEAD empty, git status --porcelain empty; control run exit 0 15/15; trap-guarded, absolute path, no build/dist involved (plain node script). gates: node scripts/pm/dispatch-gates.mjs --commands (no paths, merge-base changeset) = 40 families, all run with exit redirected to a file before any pipe; --ran with per-command exit codes: '40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN' (DERIVED zero). first run of 'pnpm --filter @objectstack/lint run check:doc-formula-expressions' = exit 3 PREREQUISITE NOT MET (unbuilt @objectstack/formula, @objectstack/lint) -> built under os-verify-lock.sh -c (VERDICT command-exit 0, held 194s, waited 0s, OS_VERIFY_LOCK_SLOT=issue-18468) -> rerun exit 0. also run: pnpm check:skill-frame-freshness exit 0 (not derived; PM asked). the 40-run was at c67c0df1; origin/main moved one comment-only commit (0fe38a92, scripts/check-bash32-floor.mjs, itself a derived family) so the branch was rebased onto 0fe38a92 and pushed with --force-with-lease=branch:c67c0df1 (unshared: claude/issue-*, created here, only this session pushed, no PR yet); re-derived at 6f008921: identical 40, no stale-tree warning; rerun at 6f008921 all exit 0: check:bash32-floor, check:pm-skill-ratchet (812 lines, ceiling 812, headroom 0; widest table row 342/342), check:pm-skill-id-lint, check:skill-frame-sync, check:nul-bytes, check-harness-current --self-test. named gates with exit codes @c67c0df1 unless noted: pm-skill-ratchet=0 pm-skill-id-lint=0 skill-frame-sync=0 skill-frame-freshness=0 nul-bytes=0 pm-dispatch-gates=0 (565s) pm-governed-merges=0 pm-governed-prose=0 pm-half-states=0 check-harness-current --self-test=0 check-self-test-wired=0 check-self-test-workflow-commands=0 doc-formula-expressions=3 then 0 after build; remaining 27 derived families all 0 (per-command record in the PR body and --ran file). control-byte self-scan of both changed files: 0 hits. line_budget SKILL.md = 812/812. needs:contract-review: absent on PR #18476; check-clause2-carriers --pair 18476 exit 0. labels: POST skip-changeset -> read-back {size/s, skip-changeset}, union minus read-back = none. PR body read back byte-identical to what was sent minus the trailing newline; one footer under a rule line; first line 'Fixes #18468'. CI not waited for: reported at local-verification completion; PR checks in_progress at report time.", "mcp_calls": "0 — no MCP GitHub tool called (read or write); ToolSearch loaded the Monitor schema once and Monitor was never invoked", "api_writes": "3 REST writes + 3 git pushes — POST /pulls (draft, #18476) x1; POST /issues/18476/labels [skip-changeset] x1; POST /issues/18468/comments (this os-dev-report) x1; PATCH /pulls x0; git push x3 (empty-branch probe, content push c67c0df1, lease-pinned rebase push 6f008921)", "files_changed": [".claude/skills/pm-dispatch/SKILL.md (+1/-1, line :92 only)", "scripts/pm/check-harness-current.mjs (+19/-9: header docblock, STALE verdict string, self-test STALE expectation + one added case, SELF_TEST_CASE_FLOOR 14->15)"], "deviations": ["the labels POST is not in the dispatch's write budget but is in the standard four-write budget of the dev file (which wins on conflict); applied additively and read back", "rebase + lease-pinned force-push before the PR existed, five unshared-branch criteria held; the 40-family run predates the rebase (upstream delta comment-only), six families rerun on the rebased head", "self-test: one negative pin ADDED and the total floor raised 14->15 — within (c), nothing deleted or weakened; the ✗-line regex at the old :238 is unchanged because the ✗ line is unchanged", "commit trailer pair is the model-free form AGENTS.md requires (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named form; pre-push trailer check green", "first --ran pass recorded no exit codes (tool reported a CLAIMED zero); redone with 'CMD :: exit N' spelled per line, tool reported a DERIVED zero"], "open_questions": [], "out_of_scope_findings": ["noted, not filed: check-harness-current.mjs keeps a single total SELF_TEST_CASE_FLOOR rather than the per-battery roster AGENTS.md's self-test section prescribes (floor raised to cover the added case; roster shape not this card's surface). 承接者:无"] }Generated by Claude Code
hotlong commentedon Sep 16, 2026
ACCEPT — director seat,
session_01Wj1HUjzyeiBQ8atRf1ZhaL, served tierclaude-fable-5-1(get_sessionthis shift) · 2026-09-16T14:49ZVerified against GitHub (PR #18476, head
6f008921, draft, 2 files +20/−10), ⛔ not against the report:.claude/skills/pm-dispatch/SKILL.md+1/−1 at line :92 only — now 「否 ⇒ 记座位贴,自然收班时换会话,⛔ 不中断批次;读数走scripts/pm/check-harness-current.mjs。」; :91 byte-identical; file 812/812 (check:pm-skill-ratchetexit 0 in the report, re-derived on head). No twin incore-rules.md(the dev's grep forcheck-harness-current/ 收班 / 换新会话 / 不推进共享检出 hits only the shift-handover readings :19 :20 :76 — accepted as the reading).scripts/pm/check-harness-current.mjs+19/−9: header narrowed to the one measured surface (settings.json), hooks/agents load moment stated UNMEASURED, the remedy sentence gone; STALE verdict re-keyed to 「note it on the seat post and pick it up at the seat's next natural shift boundary; ⛔ never interrupt a batch for it」; exit codes 0/1/2 and the-- STALE/-- UNDECIDEDmarkers unchanged; CURRENT/UNDECIDED strings byte-identical (diff read whole).SELF_TEST_CASE_FLOOR14 → 15; the report's ablation (old prescription injected back ⇒ exactly the two STALE pins fail; restored blob == HEAD blob) is the evidence the pin bites.--ran(DERIVED zero), all exit 0 after one prerequisite build;--pair 18476exit 0;mcp_calls0;api_writes3 REST + 3 pushes, all read back;skip-changesetread back.6f008921at review: 19 success · 11 skipped · 3 in progress · 0 failed.Landing (governed rules layer, ruling C): four-piece hung on PR #18476 — this record, 维护者速读(终稿),
needs-user-decision, review requested from an approver account; the PR stays draft until an authorized APPROVED, then the seat flips ready and arms auto-merge via the ccr routes. Card stayspm:dispatcheduntil MERGED.Implemented-by:
claude/issue-18468-harness-current-report-only(mode:subagent)Reviewed-by:
session_01Wj1HUjzyeiBQ8atRf1ZhaLGenerated by Claude Code
hotlong commentedon Sep 16, 2026
Landed — director seat,
session_01Wj1HUjzyeiBQ8atRf1ZhaL· 2026-09-16T15:53ZPR #18476 (head
6f008921) merged by the queue asd3c81164d1at 2026-09-16T15:52:46Z (merged_byos-zhuang, the approver who flipped ready and enqueued);git log origin/maincarries(#18476)at the tip. Governed landing by ruling C: APPROVED 5224793115 on that head, in-seat ACCEPT (stamped 2026-09-16T14:49Z), provenance on the PR. Now onorigin/main:SKILL.md:92reads 「否 ⇒ 记座位贴,自然收班时换会话,⛔ 不中断批次」 andcheck-harness-currentreports instead of prescribing — the maintainer's ruling D in text. Same act:pm:dispatchedremoved and the assignee cleared on this auto-closed card;domain:skillsstays.Generated by Claude Code
fix(pm): drop the re-seat prescription — check-harness-current and SK…
chore(hooks): remove the client-side enqueue guard hook — the merge_g…
docs(pm-skill): flip the gate asymmetry — adding a required gate/hook…