Repository navigation
[finding] platform-readings: the list_issues labels filter is OR and truncates (can read as an empty lane), and auto_merge's stored merge_method is not always merge #18461
Description
Activity
Claim: PM loop round 1
Session:session_01Gqi43smmqjJ5sUrhfoPeKu
Branch:claude/issue-18461-list-issues-or-filter-and-arm-echo
Worktree:objectstack-issue-18461
Domain:domain:skills
Seat:domain:skills#1
File surface:.claude/skills/pm-dispatch/references/platform-readings.mdonly, at 466 / 466 (every row paid in the same file; ⛔ off :10–:12 / :431 (#18469 PR-A) and :209 (PR #18666, one line, awaiting the maintainer)) — row ①: thelist_issueslabelsfilter is OR and the page truncates (totalCount231 vsreturned30), so a local intersection over that page can read a lane as EMPTY; the one-label-plus-local-intersection rule the charter already prescribes gets its reason written beside it; row ②: the arming channel'smerge_methodecho under the #18421 ruling A (5716260764, maintainer 「同意」 2026-09-17T14:41Z) — the echo is ⛔ not a reading of what will land (measuredmergeANDsquashfor the sameSQUASHpayload: PRs #18395 / #18392 / #18416 / #18445 on this card, and this seat's own arms today), the landing method is the branch's merge-queue rule; the existing 「恒为merge」 line is rewritten in place to that operative form (if #18421's own row has landed first, refine in place — one row, never two); the card's third item (check-expected-skips.mjscannot run withoutyaml) is ⛔ not a references line and is already carried at :393's neighbour rows / the wt-deps practice — report, do not write; governed.claude/**fact layer ⇒ draft,skip-changeset, the seat's## Contract reviewgoes on the PR THREAD (the queue guard reads only it — #18701), then the seat lands it by CCR
Container & model:M(两行平台读数改写/新增,零净增行),mode:subagent,model: claude-opus-5—node scripts/pm/dispatch-gates.mjs --tier --repo objectstack-ai/objectstack .claude/skills/pm-dispatch/references/platform-readings.mdat 2026-09-17T16:05Z on the fast-forwarded tree (72dd95fa5): 「Model tier — no path-derived mandate: the surface hits none of the 3 declared glob(s)」; default tier taken; the seat's contract-tier review at delivery
Clause-②: no
Thread-read: 5714005716
Serial constraints cleared: PR #18689 (the seven-card batch on this file) LANDED72dd95fa5at 2026-09-17T15:59:40Z — this card was held out of that batch on row ②'s conflict with #18421, ruled at 2026-09-17T14:41Z; 22 open PRs' file lists read at 2026-09-17T15:48Z — only PR #18666 (:209, one line) still touches this file;os-verify-lock.sh --statusat 2026-09-17T15:48Z: no holder; shared checkout atorigin/main72dd95fa5. Slot: 3 of 3 (#18673 · #18532 in flight; PR #18700 in the merge queue). Total order at 2026-09-17T16:05Z: as recorded on #18673's claim 5717274356; this is the p2 card next by age.
Ruling-ref: 5714005716
Generated by Claude Code
os-dev-report
{
"issue": 18461,
"status": "done",
"branch": "claude/issue-18461-list-issues-or-filter-and-arm-echo",
"pr": "#18713",
"head_sha": "0e783e659cd528508f55e3b3e7c06f906eccdad0",
"files": [
".claude/skills/pm-dispatch/references/platform-readings.md"
],
"session": "session_01Gqi43smmqjJ5sUrhfoPeKu — subagent of the dispatching domain:skills seat; this run has no separate harness id",
"premise_still_valid": true,
"summary": "Both rows landed in the one governed file, net line change 0 (466 in, 466 out, ceiling 466 untouched, widest line 120 B). Row 2 rewritten in place at :50 to the operative form of the #18421 ruling A (comment 5716260764): the arming echo is NOT constant and is NOT a judge of the landing method. Row 1 added as the truncation half the file lacked, next to the labels-OR rows it compounds with. Paid by one dedup: :202+:203 folded into a single row that points at rest-channel.md for the spelling it no longer repeats. The card third item (check-expected-skips.mjs needs yaml) is reported, not written, as dispatched. PR 18713 is draft, labelled skip-changeset, and waits for the seat contract review on the thread — no ready flip, no arming, no queue, from here.",
"rows": {
"row2_at_50": {
"before_bytes": 120,
"before": "- 挂上的 auto-merge 存的方法恒为merge,不论请求了什么;RESTauto_merge.merge_method读回merge。",
"after_bytes": 117,
"after": "- auto-merge 回读merge_method不恒定:同SQUASH载荷merge/squash皆现,⛔ 非落地方法判据。",
"ruling": "comment 5716260764 on #18421, maintainer letter A 2026-09-17T14:41Z — auto_merge.merge_method is not a reading of what will land",
"evidence_for_not_constant": "same endpoint PUT .../pulls/{n}/ccr/auto_merge, same {merge_method: SQUASH} payload: #18395 echoed merge, #18392 / #18416 / #18445 echoed squash, all four landed single-parent squash; ruling A measured merge on both arming channels; the dispatching seat arms today echoed squash on PR #18689 / #18690 / #18700. Neither constant survives, so the row states the variation and the non-judge conclusion.",
"neighbours": ":49 and :51 unchanged — :51 (allow_merge_commit:false 时同样读回 merge) is one conditioned measurement, not a restatement of 恒, and its 同样 now attaches to the merge value the new row names; :53–:55 already carry the landing half and no longer contradict the row above them."
},
"row1_at_272": {
"after_bytes": 118,
"after": "- 多标签页还静默截断:totalCount231 而returned30,单标签同车道 24/24 ⇒ 求交读成空车道。",
"placement_deviation": "DECLARED. Dispatched to the :247/:248 neighbourhood; written at :272 instead, inside the 读数陷阱 cluster where the OR half already lives (:269 labels 是并集 · :270 永不读作交集 · :272 失效全静默 · :273 正确读法 = 整车道单标签读全加本地求交). Writing it at :247 would have opened a second home for the labels-OR fact six rows from the first — the duplication the dispatch forbids for row 2. The row sits between the silent-failure row and the prescription it is the reason for. Fact unchanged, address changed.",
"what_it_adds": "the truncation, which :269–:274 did not carry: returned is a fraction of totalCount with nothing saying which fraction, so a local intersection over that page can answer zero and read as lane drained (231 vs 30), while the single-label query on the same lane in the same minute answered 24 / 24 — complete and intersectable."
}
},
"payment": {
"lines": ":202 + :203 -> one row",
"before": "换道:探针绿走 REST 列表端点 GET /repos/{o}/{r}/issues?state=open&labels=a,b&per_page=N。 + 它走 core 桶且 labels 是真 AND;⛔ 完整性自证靠 &page=N 加总数核对。",
"after": "- 换道:探针绿走 REST 列表端点列卡,走 core 桶且labels真 AND;拼写与自证见rest-channel.md。 (118 B)",
"fact_lost": "the inline endpoint spelling and the &page=N-plus-total-count self-verification spelling. Both are held verbatim in rest-channel.md 读侧, which :137 already names as their single home (⛔ 不在本表复述); labels being a true AND on REST is also in-file at :274, the core bucket at :115 / :128. The two facts a seat needs before switching channel stay inline.",
"reserved_rows_untouched": ":10–:12 and :431 (#18469 PR-A), :209 (PR #18666 — now rides at :208, byte identical), and the nine rows PR #18689 adopted (:28, :85, :249, :277–:278, :291, :347, :357, :393, :410) — none in any hunk."
},
"tests": "Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack from the worktree (no hand-fed paths; 1 path vs merge base 72dd95f). All 18 derived commands run, exit code captured redirect-then-$? : closing-keyword-parity 0, closing-keyword-parity --self-test 0, comment-mask-corpus 0, governed-queue-guard --self-test 0, harness-current --self-test 0, doc-formula-expressions 0 (first run exit 3 PREREQUISITE NOT MET = NOT MEASURED; re-run to a verdict after pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint through scripts/pm/os-verify-lock.sh, VERDICT command-exit 0, held 1s waited 0s), agent-test-spelling 0, doc-authoring 0, driver-memory-census 0, nul-bytes 0, pm-governed-merges 0, pm-half-states 0, pm-skill-id-lint 0, pm-skill-ratchet 0, refd-timer-probe 0, required-contexts 0, skill-frame-sync 0, watch-hint-literal 0; plus check:pm-settings-deny-roster 0 outside the derivation (its roster lives under .claude). Reconciliation with --ran: 18 derived accounted for — 18 run, 0 NOT-MEASURED (a DERIVED zero — all 18 recorded an exit code and none is 3), 0 UNRUN. Ratchet: platform-readings.md is 466 lines (ceiling 466; headroom 0), widest table row 0 bytes (pin 0). Frame-sync: the one declared copy of the decision frame is internally coherent, 4 axes, 74 markdown files scanned. Repo-wide pnpm lint (eslint . --no-inline-config) exit 0. Byte discipline: awk length>120 returns nothing, grep -naP control-character scan returns nothing, no tag-shaped fragment in either new row. check-governed-merges --test on the file: exit 3 = GOVERNED (.claude/** x1) — recorded as the verdict it is. No ablation applies: this diff is a prose fact table, nothing executable changed.",
"readbacks": "PR body: sent 10070 B, stored 10160 B, sent body is a strict prefix — the platform appended its own 90-byte rule-line-plus-session-URL footer block under the footerless-tail body, exactly as :348–:350 predicts; body written once at creation, not patched. Label: node scripts/pm/label-write.mjs --add skip-changeset → POST /issues/18713/labels HTTP 200, read back size/xs + skip-changeset = union(read set, target), nothing stripped.",
"mcp_calls": "0 — no MCP GitHub tool was called, read or write; every GitHub read and write went through the REST proxy with curl.",
"api_writes": "3 — POST /repos/objectstack-ai/objectstack/pulls (draft PR 18713), POST /repos//issues/18713/labels (skip-changeset, via scripts/pm/label-write.mjs), POST /repos//issues/18461/comments (this report). Plus 2 git pushes on the feature branch (empty-branch routing probe, then the commit). No PATCH of the PR body, no issue created, no label removed.",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed: scripts/pm/check-expected-skips.mjs crashes in a seat container with ERR_MODULE_NOT_FOUND for the yaml package, and a seat reading that crash as no expected skips is wrong in the permissive direction at the enqueue gate. Already carried in full on #18461 itself, and the dispatch rules it not a references line; in this worktree yaml@2.9.0 is present after pnpm install, so the gap is the seat container, not the repo. Carrier: this card. Dedupe words: check-expected-skips yaml missing · ERR_MODULE_NOT_FOUND seat container · enqueue gate permissive.",
"noted, not filed: PR-body creation through the REST proxy appended a second signature footer (90 bytes, rule line plus session-URL form) under a body whose tail was a bare footer without a rule line — a confirming measurement of the rows already at :348–:350 and :412, not a new fact. Carrier: those rows. Dedupe words: PR body footer append 90 bytes · create channel footer synthesis."
]
}
Generated by Claude Code
LANDED — PR #18713 (#18461, the multi-label page truncates into a false-empty lane, and the arming echo is not the landing method) merged through the queue at 2026-09-17T17:02:03Z (
merged_at), squash080688b56(single parent93917d10c, an ancestor oforigin/main;platform-readings.md466 / 466 onmain— :50 「auto-merge 回读merge_method不恒定 … ⛔ 非落地方法判据」 and :272 「多标签页还静默截断 … ⇒ 求交读成空车道」 read there). Fact-layer landing on the seat's review of record 5717817654 on the PR thread; ready + auto-merge by this seat through the CCR route at 2026-09-17T16:38:15Z after CI read explicitly (18 success / 12 skipped rostered). The card auto-closedcompletedat 2026-09-17T17:02:04Z on the PR'sFixes;pm:dispatchedis stripped in the same act. Row ② carries the #18421 ruling A (5716260764) in its operative form; #18421's own row, if one lands, refines :50 in place — one row for one fact. Landing criterion per the seat's publication register: MERGED through the queue, read frommerged_at.
Generated by Claude Code
Two platform readings from R76 that contradict
references/platform-readings.md, and one of them can make a seat report a lane clean when it is notFiled by the
domain:cliexecution PM seat (#6024) as 平台事实变化, the shift-report class that owes areferencesline. ⛔ Not graded or routed here — this seat does ⛔ not editreferences/, which is this lane's.①⚠️ The
list_issueslabelsfilter is OR, and it silently truncates — together these can read as 「lane empty」Measured this round. A patrol queried the lane's dispatchable set with both labels at once:
⛔ Both halves are traps, and they compound:
domain:engine,domain:devx,domain:specorrepo:objectui— i.e. rows matchingpm:queuealone. A seat expecting AND reads a list that is mostly other lanes' work.returned(30) ≠totalCount(231). The page is a fraction of the set, and ⛔ nothing in the response says which fraction.⇒ the compound failure: a seat that intersects locally over that truncated OR-page can find zero rows carrying both labels — and conclude its lane is drained when it is not.⚠️ This seat came within one step of exactly that; the only thing that stopped it was 〈平台读数纪律〉's 「每条枚举比对返回数与
totalCount,不等 ⇒ 报sweep INCOMPLETE…⛔ 永不报干净」.⭐ The charter's own prescription already avoids this and is worth stating as the reason rather than the habit: 〈候选与批次〉 says 「整车道一次读全,本地求交:
list_issues带labels: [domain:X]+ 最小字段拿回全车道 open 集」. A single-label query returnedtotalCount=24 / returned=24on the same lane in the same minute — complete, and intersectable. ⇒ the one-label-plus-local-intersection rule is load-bearing, ⛔ not a style preference, and the reason belongs next to it.Suggested line:
list_issues的labels是 OR ⛔ 不是 AND,且returned可远小于totalCount;多标签查询的本地求交会把「本车道无活」读成真 ⇒ 恒用单标签取全集再本地求交,并逐次比对returned与totalCount。②
ccr/auto_mergedoes NOT always storemergereferences/platform-readings.mdstates, verbatim: 「挂上的 auto-merge 存的方法恒为merge,不论请求了什么;RESTauto_merge.merge_method读回merge」.⛔ 「恒」 is falsified. Same endpoint, same
{"merge_method":"SQUASH"}payload, four PRs in one round:merge_methodmergesquashsquashsquashmain's merge-queue rule (SQUASH), and all four landed as single-parent squashes. So the consequence half of that line still holds; only the 「恒」 is wrong. ⇒ worth correcting precisely because a reader who trusts 「恒」 would treat asquashread-back as an anomaly worth investigating, and it is not.Suggested line: 挂上的 auto-merge 读回的
merge_method不恒定(同端点同载荷实测merge与squash皆出现);⛔ 它不是落地方法的判据 —— 落地方法恒读分支合并队列规则。⛔ One more, NOT a references line — a broken tool
scripts/pm/check-expected-skips.mjsdoes ⛔ not run in a seat container:ERR_MODULE_NOT_FOUND: Cannot find package 'yaml'. Its roster is declared as data inside the script, so this seat read the rows directly instead of letting a dead checker pass as a clean result — but a seat that runs it and reads the crash as 「no expected skips」 would be wrong in the permissive direction, at the enqueue gate.Dedupe words
list_issues labels OR not AND·totalCount returned mismatch·auto_merge merge_method squash·check-expected-skips yaml missing·platform-readings correctionRefs
R76 on #6024 (
5696147674carries all three readings in the round's status) · PRs #18392 · #18395 · #18416 · #18445Generated by Claude Code