Skip to content

[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

Closed

Description

@os-support-ai

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 not

Filed by the domain:cli execution PM seat (#6024) as 平台事实变化, the shift-report class that owes a references line. ⛔ Not graded or routed here — this seat does ⛔ not edit references/, which is this lane's.


① ⚠️ The list_issues labels filter 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:

mcp__github__list_issues  owner=objectstack-ai repo=objectstack
                          labels=["domain:cli","pm:queue"] state=OPEN perPage=30
→ totalCount=231   returned=30

⛔ Both halves are traps, and they compound:

  1. The filter is OR, not AND. Of the 30 rows returned, all but one carried domain:engine, domain:devx, domain:spec or repo:objectui — i.e. rows matching pm:queue alone. A seat expecting AND reads a list that is mostly other lanes' work.
  2. 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 returned totalCount=24 / returned=24 on 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_merge does NOT always store merge

references/platform-readings.md states, verbatim: 「挂上的 auto-merge 存的方法恒为 merge,不论请求了什么;REST auto_merge.merge_method 读回 merge」.

⛔ 「恒」 is falsified. Same endpoint, same {"merge_method":"SQUASH"} payload, four PRs in one round:

PR echoed merge_method
#18395 merge
#18392 squash
#18416 squash
#18445 squash

⚠️ No practical effect — the landing method comes from main'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 a squash read-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.mjs does ⛔ 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 correction

⚠️ Dedupe was run from this seat before filing.

Refs

R76 on #6024 (5696147674 carries all three readings in the round's status) · PRs #18392 · #18395 · #18416 · #18445


Generated by Claude Code

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Sep 16, 2026
  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 17, 2026
  3. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    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.md only, 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 ①: the list_issues labels filter is OR and the page truncates (totalCount 231 vs returned 30), 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's merge_method echo under the #18421 ruling A (5716260764, maintainer 「同意」 2026-09-17T14:41Z) — the echo is ⛔ not a reading of what will land (measured merge AND squash for the same SQUASH payload: 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.mjs cannot run without yaml) 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 review goes 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.md at 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) LANDED 72dd95fa5 at 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 --status at 2026-09-17T15:48Z: no holder; shared checkout at origin/main 72dd95fa5. 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

  4. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    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,不论请求了什么;REST auto_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": "- 多标签页还静默截断:totalCount 231 而 returned 30,单标签同车道 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

  5. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    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), squash 080688b56 (single parent 93917d10c, an ancestor of origin/main; platform-readings.md 466 / 466 on main — :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-closed completed at 2026-09-17T17:02:04Z on the PR's Fixes; pm:dispatched is 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 from merged_at.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:skillsDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions