You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
patrol: H16 — open non-draft PR stuck in merge-conflict (mergeable_state dirty) beyond threshold #9980
{
"issue": 9980,
"status": "done",
"branch": "claude/issue-9980-h16-dirty-pr",
"pr": "https://github.com/objectstack-ai/objectstack/pull/9985",
"premise_still_valid": true,
"summary": "H16 lands in scripts/pm/check-half-states.mjs as a report-only predicate: an open, non-draft PR whose mergeable_state is 'dirty' past MERGE_CONFLICT_STALE_HOURS (2h, named constant with the rationale the card asked for, following the DOMAIN_HALF_STATE_STALE_HOURS precedent) anchors one ordinary row in both renderers, naming the PR and the card(s) its body declares (Fixes or Part of, via H7's code-stripped extractors). All four platform facts are handled: mergeable_state is absent from the /pulls list payload so a per-PR GET is taken, bounded to candidates by an exported+pinned gathering policy (h16NeedsDetail) whose never-narrower-than-the-predicate invariant is asserted as an implication over the whole fixture table; unknown/null readings are skipped in silence per the file's narrowness discipline (the docblock argues why this asymmetry with the #4690 unreadable-timestamp direction is deliberate rather than inconsistent); a failed detail GET never fails the sweep, while NO candidate readable at all rethrows as a transport classification per the #4690 posture. auto_merge is deliberately NOT read in H12's finding-reducing direction — that is the incident itself, and it is pinned in both directions including the one-row/two-predicates contrast. Two small extensions beyond the literal card, both declared: h16DetailPassUnreadable was extracted as a pure function so the 'total failure is transport' judgement could be pinned instead of sitting untested in a non-exported loop, and summaryLine now reports 'merge state read on X of Y H16 candidate(s)' because without it a detail pass that read nothing would be indistinguishable from a board with no conflicts. Header docblock enumeration extended and the H1-H15 range string updated to H1-H16; the '(H13-H15)' string was deliberately left alone — it names the unscoped-issue pass, which H16 (PR-side) is not part of. No governed-surface edit was owed: SKILL.md's only reference is a one-line table row carrying no H-range.",
"tests": "All at final commit d6669295c (git rev-parse --short HEAD), gate union derived by `node scripts/pm/dispatch-gates.mjs` with NO path arguments (script computes its own change set from the merge base: '1 path(s) vs merge base 8fa4e2a76'). Exit codes captured before any pipe via redirect-then-read. Verdict lines as each gate printed them: `pnpm check:pm-half-states` EXIT=0 '✓ check-half-states self-test: 352 cases pass.' · `pnpm check:partof-closing-keyword` EXIT=0 '✓ check-partof-closing-keyword self-test: 28 cases pass.' · `pnpm check:cross-package-test-inputs` EXIT=0 'OK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.' · `node scripts/check-cross-package-test-inputs.mjs` (ci.yml form) EXIT=0 same line · `pnpm check:nul-bytes` EXIT=0 'check-nul-bytes: OK (scanned 6322 text file(s) -- 6322 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).' SELF-TEST COUNTS: baseline 292 (measured on fresh origin/main 8fa4e2a76, matching the dispatch) -> 352. NARROWING, declared: the sixth derived entry is the LIVE sweep (half-state-patrol.yml), measured-unavailable here rather than assumed — `--probe` exits 3, 'PREREQUISITE NOT MET — the token in the environment is not a valid GitHub credential', anonymous path also unusable (the third container class this file's own header documents); CI runs it on a runner. `check-partof-closing-keyword.mjs` run bare exits 2 by design (needs PR_BODY from its workflow); the packaged script form is --self-test, which is what is quoted. I additionally ran that guard against this PR's exact body: EXIT=0, 'this PR carries no Part-of/closing-keyword contradiction'. REVERSE VERIFICATION, directions predicted in writing before running (predictions file written first), all three exactly as predicted: (1) delete the dirty gate -> predicted RED at exactly 6 cases with the never-narrower table case staying green; observed '6 of 352 case(s) failed', the 6 named, table case green — it stays green because rows that newly flag are also rows the gate fetches, which is the point of asserting an implication rather than a count. (2) add H12's auto_merge suppression -> predicted a TypeError crash rather than a tally (a suppressed row returns null and the runner calls .includes on it); observed a crash at the exact predicted case, check-half-states.mjs:2921. (3) threshold 2->200 -> predicted the same crash mechanism; observed at check-half-states.mjs:2886. NO REBUILD LEG IS OWED and none was skipped: this is a plain .mjs run from source by node, the self-test resolves nothing through a package exports field or a dist/, and no vitest alias is involved — there is no artifact between the edit and the measurement. Restored after every leg from the commit (git checkout d6669295c -- path), proven byte-identical by git hash-object = bd7775bace54a32d9a6a7f8c6a9a0d06aeba974a equal to the committed blob (not by a matching diffstat), and re-run green (352) each time.",
"labels_read_back": "[\"skip-changeset\"] — confirmed by a read-back (issue_read get on the PR number, since issue_read get_labels errors on PRs), not by the write. Label set was empty at read time, so the union was that one entry; no bot label was clobbered.",
"files_changed": ["scripts/pm/check-half-states.mjs (+425/-5, 1 file)"],
"open_questions": [],
"out_of_scope_findings": []
}
Activity
os-warren commentedon Aug 19, 2026
Claim: session
ae0d8bd1-5667-5f58-8ff8-fa22ec154325· branchclaude/issue-9980-h16-dirty-pr折叠检查:
check-half-states.mjs空闲(PR #9963 已落地),队列无同文件第二卡 → 单卡。模型档:路径无强制(--tier 实跑),report-only 谓词不改合同 → opus。Generated by Claude Code
os-warren commentedon Aug 19, 2026
os-dev-report
{ "issue": 9980, "status": "done", "branch": "claude/issue-9980-h16-dirty-pr", "pr": "https://github.com/objectstack-ai/objectstack/pull/9985", "premise_still_valid": true, "summary": "H16 lands in scripts/pm/check-half-states.mjs as a report-only predicate: an open, non-draft PR whose mergeable_state is 'dirty' past MERGE_CONFLICT_STALE_HOURS (2h, named constant with the rationale the card asked for, following the DOMAIN_HALF_STATE_STALE_HOURS precedent) anchors one ordinary row in both renderers, naming the PR and the card(s) its body declares (Fixes or Part of, via H7's code-stripped extractors). All four platform facts are handled: mergeable_state is absent from the /pulls list payload so a per-PR GET is taken, bounded to candidates by an exported+pinned gathering policy (h16NeedsDetail) whose never-narrower-than-the-predicate invariant is asserted as an implication over the whole fixture table; unknown/null readings are skipped in silence per the file's narrowness discipline (the docblock argues why this asymmetry with the #4690 unreadable-timestamp direction is deliberate rather than inconsistent); a failed detail GET never fails the sweep, while NO candidate readable at all rethrows as a transport classification per the #4690 posture. auto_merge is deliberately NOT read in H12's finding-reducing direction — that is the incident itself, and it is pinned in both directions including the one-row/two-predicates contrast. Two small extensions beyond the literal card, both declared: h16DetailPassUnreadable was extracted as a pure function so the 'total failure is transport' judgement could be pinned instead of sitting untested in a non-exported loop, and summaryLine now reports 'merge state read on X of Y H16 candidate(s)' because without it a detail pass that read nothing would be indistinguishable from a board with no conflicts. Header docblock enumeration extended and the H1-H15 range string updated to H1-H16; the '(H13-H15)' string was deliberately left alone — it names the unscoped-issue pass, which H16 (PR-side) is not part of. No governed-surface edit was owed: SKILL.md's only reference is a one-line table row carrying no H-range.", "tests": "All at final commit d6669295c (git rev-parse --short HEAD), gate union derived by `node scripts/pm/dispatch-gates.mjs` with NO path arguments (script computes its own change set from the merge base: '1 path(s) vs merge base 8fa4e2a76'). Exit codes captured before any pipe via redirect-then-read. Verdict lines as each gate printed them: `pnpm check:pm-half-states` EXIT=0 '✓ check-half-states self-test: 352 cases pass.' · `pnpm check:partof-closing-keyword` EXIT=0 '✓ check-partof-closing-keyword self-test: 28 cases pass.' · `pnpm check:cross-package-test-inputs` EXIT=0 'OK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.' · `node scripts/check-cross-package-test-inputs.mjs` (ci.yml form) EXIT=0 same line · `pnpm check:nul-bytes` EXIT=0 'check-nul-bytes: OK (scanned 6322 text file(s) -- 6322 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).' SELF-TEST COUNTS: baseline 292 (measured on fresh origin/main 8fa4e2a76, matching the dispatch) -> 352. NARROWING, declared: the sixth derived entry is the LIVE sweep (half-state-patrol.yml), measured-unavailable here rather than assumed — `--probe` exits 3, 'PREREQUISITE NOT MET — the token in the environment is not a valid GitHub credential', anonymous path also unusable (the third container class this file's own header documents); CI runs it on a runner. `check-partof-closing-keyword.mjs` run bare exits 2 by design (needs PR_BODY from its workflow); the packaged script form is --self-test, which is what is quoted. I additionally ran that guard against this PR's exact body: EXIT=0, 'this PR carries no Part-of/closing-keyword contradiction'. REVERSE VERIFICATION, directions predicted in writing before running (predictions file written first), all three exactly as predicted: (1) delete the dirty gate -> predicted RED at exactly 6 cases with the never-narrower table case staying green; observed '6 of 352 case(s) failed', the 6 named, table case green — it stays green because rows that newly flag are also rows the gate fetches, which is the point of asserting an implication rather than a count. (2) add H12's auto_merge suppression -> predicted a TypeError crash rather than a tally (a suppressed row returns null and the runner calls .includes on it); observed a crash at the exact predicted case, check-half-states.mjs:2921. (3) threshold 2->200 -> predicted the same crash mechanism; observed at check-half-states.mjs:2886. NO REBUILD LEG IS OWED and none was skipped: this is a plain .mjs run from source by node, the self-test resolves nothing through a package exports field or a dist/, and no vitest alias is involved — there is no artifact between the edit and the measurement. Restored after every leg from the commit (git checkout d6669295c -- path), proven byte-identical by git hash-object = bd7775bace54a32d9a6a7f8c6a9a0d06aeba974a equal to the committed blob (not by a matching diffstat), and re-run green (352) each time.", "labels_read_back": "[\"skip-changeset\"] — confirmed by a read-back (issue_read get on the PR number, since issue_read get_labels errors on PRs), not by the write. Label set was empty at read time, so the union was that one entry; no bot label was clobbered.", "files_changed": ["scripts/pm/check-half-states.mjs (+425/-5, 1 file)"], "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
os-warren commentedon Aug 19, 2026
ACCEPT — PR #9985 复核通过,已 flip ready + auto-merge(显式 SQUASH)。
复核记录(session
ae0d8bd1-5667-5f58-8ff8-fa22ec154325):h16NeedsDetail限界(「永不窄于谓词」以整张 fixture 表的蕴含式断言,比逐例更强);unknown静默跳过且 docblock 论证了与 check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 方向的刻意不对称(平台说「稍后再问」≠ 本该可读而不可读);单次 GET 失败不毁 sweep、零可读上抛为 transport 分类(h16DetailPassUnreadable纯函数化 + 摘要行read X of Y—— 两处声明的超卡扩展都接受:没有它们,「一个都没读到」与「无冲突」在报告上不可分)✓。updated_at为代理、误差方向(只多报不漏报)写在常量 rationale、⛔ 明禁用 timeline fetch 去「修」它、finding 文本向读者点名所示量 —— 正是派发词要求的诚实声明 ✓。blocked,防后人拿活 PR「验证」fixture ✓。落地后:巡逻下一班起,任何仓的冲突 PR 最多 6 小时上锚点名 —— devx 事故的仪器缺口正式闭合。
Generated by Claude Code