pm-dispatch: six measured platform readings, and the search_issues qualifier rows rewritten onto what is measured - #18279
Conversation
…lifier rewrite Folded family of seven graded cards, one file surface plus the ratchet entry. Six rows added to the facts register, one per deduplicated reading: the write-identity probe; a suspension erasing events as well as content; the card comment COUNT over-reading against list and timeline; the join-before-search grep instrument; PR-keyed CI concurrency making a re-run a write; and the comment-write cell of the exclamation-before-bracket loss. Three search_issues rows are rewritten in place onto what is measured: the qualifier-shaped query is not refused and does filter, matching the deterministic REST list endpoint number for number, while the description sentence form answers a confident zero with a lit control at zero too. Ceiling 459 -> 465 under the standing one-file exception, recorded as the sixteenth ruledRaises record. Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr Co-authored-by: Claude <noreply@anthropic.com>
…e sentence form is a lead not a zero-proof Patch round 1, two rows corrected in place, line-neutral, no ceiling move. The token-class row named a field that does not discriminate: the App identifier reads the same object for a REST-proxy write authored by the App and for one authored by a user token, measured across six specimens. The read-back still is the probe; within it only the author type and login tell the class. The search rows overstated the sentence form. It is a semantic matcher that can answer a confident zero for a population that exists and can also hit with the target first, and both directions are now measured and dated. It is a lead, never a zero-proof for dedupe; the qualifier form stays the deterministic one and its row is untouched. The ratchet record's accounting comment follows the same correction. Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Reviewing seat: ① Derived judgments
② Semver levelNot applicable — nothing published moves; ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
Landing provenance — skills seat, session Edited at 2026-09-15T07:48Z by the same seat: the enqueue clause above was stored garbled — the seat's own timeline read script failed at write time and its error text was pasted into the token slot; Generated by Claude Code |
Fixes #18195
Fixes #18158
Fixes #16762
Fixes #18219
Fixes #18147
Fixes #18258
Fixes #18262
skip-changeset: nothing published moves. The diff is one governed reference file and onescripts/pm/gate script, both on the fast-track list, and neither is inside any package'sfiles[].What lands
Six rows added to
.claude/skills/pm-dispatch/references/platform-readings.md, one per deduplicated reading, plus threesearch_issuesrows rewritten in place onto what is measured. The ceiling moves 459 to 465 inscripts/pm/check-skill-line-ratchet.mjs, recorded as the SIXTEENTHruledRaisesrecord under the standing one-file exception, quoted verbatim and dated, with the positive delta 6 accounted for line by line beside the ceiling.A rewrite is not a raise: the three rewritten rows are line-neutral and buy nothing. So is the reading-trap list's own count word, which moves from five to six for the trap appended to it.
Rows added (measured on head
6715b3d1)user.typewithuser.loginALONE:performed_via_github_appnames the same App under both token classes, andGET /useranswers the bound account under bothlabeledevent that wrote it is goneEvery row is at or under the 120-byte cap, Chinese, in the file's own register voice, and each is traceable to its card's reading with an instant and a carrier.
Rows rewritten (card 16762, line-neutral, lines 189 to 191)
Before, the stated BASIS of the prohibition was that a qualifier-shaped query answers zero. Three sessions plus this one measured the opposite. After the rewrite, the three lines say what is measured:
search_issuesdescribes itself as a semantic matcher and only the QUALIFIER form contradicts that self-description; a qualifier spelled intoqueryis not refused and does filter, matching the deterministic REST list endpoint number for number; and the sentence form has been measured in BOTH directions and is dated for each - a confident zero against a population that exists on 2026-09-09, and a hit with the target first on 2026-09-15 - so it is a lead and never a zero-proof for dedupe.The prescription that scope goes through the
ownerandrepoparameters is NOT kept, because no reading supports it: the rewritten row says the range parameters may be omitted, which is what was measured.Measurements taken for this PR
Card 16762, the REST control.
GET /repos/objectstack-ai/objectstack/issues?labels=pm:queue&state=open&per_page=100, paged: 100 plus 100 plus 8 rows, page four empty, 208 open issues, zero of them pull requests, zero of them missing the label. The seat's MCP qualifier query (repo:objectstack-ai/objectstack is:issue is:open label:pm:queue, no owner or repo parameters) readtotal_count: 208,incomplete_results: false, with the first five numbers 18239 / 18218 / 18200 / 18199 / 18179 - identical to the REST page-one head, in order. Two channels, one population. The qualifiers ARE honoured as filters.Card 18219, re-measured through REST before writing. One of the two disagreeing cards still disagrees and one has healed:
issues/{n}count fieldcommentedFour controls consistent in the same round on the same token, so the disagreement is not a dead instrument. The healing is ONE observation and is deliberately not written to the register; the card already carries the same shape for another specimen.
Card 18147, re-read through REST. Card 17963 still carries the label the suspended account wrote. Its
/issues/17963/eventsreturns ten rows whoselabeledentries namefinding,pm:queue,priority:p3andpm:dispatched- and NOT the label the suspended account wrote, which has nolabeledevent at all. Actor tally over the same response:claude[bot]7,os-project-manager2,os-bill1, the suspended account 0./issues/17963/timelineagrees: fourlabeledrows, same four labels. The lit controls sit inside the same response, so the absence is a reading and not a dead endpoint.Card 18158, live probe.
GET /useranswered a human login of typeUser; the read-back of a comment this seat wrote through the same container answered loginclaude[bot], typeBot,performed_via_github_appslugclaude. Two answers, one session:GET /useris not the write-identity probe.Card 18262, the second repository read.
.github/workflows/lint.ymlon this tree keys its concurrency group ongithub.event.pull_request.numberwith the workflow and event name in front of it, andcancel-in-progress: true. Same shape as the sibling repository's: on the pull-request path the identity segment is the PR number, never the head sha. So the hazard the card measured on the sibling is not sibling-specific, which is why the row says both.Card 18195, live instrument reading on this tree. Subject: a single-line
grep -Ffor the joined ruling phrase overscripts/pm/check-skill-line-ratchet.mjsreads 0, exit 1. Same file, same pattern, after collapsing the source's own string concatenation: 10. A ten-hit population that a single-line search reports as absent - which is the direction in which a defect looks like success.Dedupe, per card
Counted candidate / landed / rewritten / already present / refused, as the standing exception requires.
rest-channel.mdand pm-dispatch SKILL.md, the PROBE was nottotal_countstate (the refused search path) at register lines 208 to 210Every card landed something, so every card takes a
Fixesline. No card was all-present.The grep that proved the two clean subjects, taken on
origin/mainbefore writing: the join-before-search family returned exit 1 and zero lines with the control at 5 lines, andperformed_viareturned exit 1 and zero lines with the control at 6 lines.Reverse verification
check-skill-line-ratchet: .claude/skills/pm-dispatch/references/platform-readings.md is 465 lines (ceiling 465; headroom 0).cross-file move into .claude/skills/pm-dispatch/references/platform-readings.md: +11 (314 to 465, less 140 lines of ordinary ruled raise) against a net source decrease of 20.performed_via_github_app, the suspension-events row, the comment-count row, the sixth reading trap, the concurrency row and the comment-write mangling row all return exactly one line.Gates
Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackand NO paths, on head8d518947, then reconciled with--rancarrying every exit code:Every family ran in the foreground with its exit captured by redirect before any pipe, on the head above, after the merge commit. On an earlier pass one family exited 3 (
check:doc-formula-expressions, PREREQUISITE NOT MET: two workspace packages unbuilt); the build the gate itself prescribes was run and it has exited 0 ever since, which is the only reason it reads green - a 3 is recorded as NOT MEASURED, never as a pass.check:pm-dispatch-gatesis derived (this diff edits a gate source) and was run the way its own header prescribes - detached, waited on in the foreground withtail --pid, never a foreground call that a cap could cut off - and reached a verdict:dispatch-gates self-test: 1730 cases pass, 435.7s on this box, exit 0.The three families the dispatch named by hand are in that set and green:
check:pm-skill-ratchet,check:pm-skill-id-lint(27 files clean) andcheck:pm-governed-prose(2 instruction surfaces name all 5 registered governed surfaces).origin/mainmoved five commits while this was in hand (none of them touching either file in this diff, two of them touching gate sources). It was merged, dependencies refreshed, the family list re-derived byte-identical, and the WHOLE union re-run on the merge commit - so every exit code above belongs to the head named here and the reconciliation reports no stale tree.Repo-wide
pnpm lintis CI's run, and the narrowing here is measured rather than assumed. (1) The universe is read from eslint's own configuration: of the two changed paths only the.mjsis in it, and eslint says so itself for the other -File ignored because no matching configuration was supplied. (2) The count is read from--format json: two entries, one actually linted, 0 errors and 0 warnings on it. (3) The invariance:eslint.config.mjsstates it configures noparserOptions.projectand no typed rules, so type-aware linting is off and this diff cannot move the verdict on any file it does not touch.Patch round 1 - two rows corrected in place, line-neutral
Both corrections are rewrites, so neither adds a line and the ceiling does not move: the register stays at 465 of 465 with headroom 0.
Line 130, the write-identity probe. The first pass named
performed_via_github_appbesideuser.typeas though the pair discriminated. It does not: that field was measured reading the same App object for a REST-proxy write authored by the App, for a REST-proxy write authored by a user token, and for four further specimens - six in all, one identifier. The row now says the read-back is still the probe but thatuser.typewithuser.loginis what tells the class, and names the App field andGET /usertogether as the two that answer the same under both. 118 bytes to 116. The ratchet record's accounting comment carries the same correction.Lines 189 and 191, the sentence form. The first pass wrote the sentence form as the one that answers a confident zero. That is one of its two measured directions, not its behaviour: on 2026-09-09 a sentence returned
total_count: 0against a population that existed, and on 2026-09-15 a sentence built from a card's own title words returned three hits with that card first and the control lit. Line 189 no longer claims both spellings contradict the tool's self-description - only the qualifier form does - and line 191 now carries both dated readings and the consequence: a lead, never a zero-proof for dedupe. 111 to 114 bytes and 120 to 113 bytes. Line 190, the qualifier row, is untouched.Authored by the skills-lane dev agent in session
session_01HZfg2AwVX191qCizp88gQr; this line is the durable attribution, because a body edit through this channel does not keep a footer.Acceptance notes
Noted, not filed:
To file (class a, a register row whose stated basis a reading falsifies - the same class card 16762 was filed as). Dedupe words:
check:pm-dispatch-gates, 600 seconds, foreground cap, detached,tail --pid, battery runtime:tail --pid) is untouched by that and the gate's own header keeps it deliberately - the cap is a property of the caller's container and its contention, neither of which the script can see. Only the row's stated basis is now conditional. One reading on one box does not settle it, which is why this is a card and not an edit riding this PR.Maintainer summary (draft)
改了什么(含补丁轮)- 事实表加了六行实测读数(写身份探针、账号停用抹掉事件、卡片评论计数多读、拼接短语的 grep 仪器、CI 并发组按 PR 号、评论写侧的字符丢失),另把三行关于查重搜索的旧规则按实测重写。门禁脚本里上限 459 抬到 465,记一条引常设裁决的
ruledRaises。为什么改 - 这七张卡各自带着已测到的平台事实,而事实表是舰队查表的唯一出处;其中一格(查重搜索)写着的理由已被三个会话加本轮的对照读数推翻,继续留着会把舰队指向唯一会静默失败的那种拼法。
风险与代价(含回滚) - 只动说明文字与一个门禁的上限数字,无运行时影响,不发布任何包。回滚成本 = 还原这一个提交;上限数字随之回到 459,门禁自洽。真正的代价是事实表又长了六行,这正是常设裁决按落地行数逐次计价的那件事。
席位意见 - (留空,待席位定稿)
你要做的 - 无须动作;这是
references/**层,按分层落地规则走席位契约级复核后进队列。补丁轮把两处读数按已在案的实测改正:令牌类只由作者类型判别,句子形搜索两个方向都测到过,故只作线索。Generated by Claude Code