Skip to content

pm-dispatch: three measured readings — the statesTheSet census, the enqueue instant, and the battery's cap-sized runtime - #18287

Merged
claude[bot] merged 3 commits into
mainfrom
claude/issue-18248-platform-readings-fold-2
Sep 15, 2026
Merged

claude[bot] merged 3 commits into
mainfrom
claude/issue-18248-platform-readings-fold-2

Conversation

@claude

@claude claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #18248
Fixes #18274
Fixes #18283

One folded dispatch of three cards, all on the same cell of the seat's readings
ledger: .claude/skills/pm-dispatch/references/platform-readings.md. Each card is
one commit; each row is checkable by its own control word. Three rows are
rewritten in place (a rewrite buys no lines) and one row is added, so the ledger's
ceiling moves 465 to 466 with a single ruledRaises record — the SEVENTEENTH —
quoting the standing one-file exception verbatim and untranslated.

Rows

card line bytes what the row now says
#18248 396 (rewritten) 92 to 117 the ledger's mustName declares statesTheSet, so it must equal the required-context registry exactly, and a registry row enrolled without following this table is red
#18248 397 (rewritten) 71 to 108 a green gate IS the reading that the name list is right; only the COUNT WORD stays unpinned prose, hand-followed
#18274 58 (added) 117 the squash commit's committer date is the enqueue instant and the fast-forward does not move it, so a landing instant is read from merged_at or the merged event, never from git log
#18283 428 (rewritten) 117 to 119 the battery is cap-sized on one box (430 to 450 s) rather than over the cap, the cap belongs to the caller's container, and the detached prescription stands

Ledger: 465 lines before, 466 after; every row at or under 120 bytes; no issue
number in operative text.

Why each row moved

The mustName pair. Both rows were true on the tree they were written
against. The platform-readings.md entry of INSTRUCTION_SURFACES in
scripts/check-required-contexts.mjs now declares statesTheSet: true — an
entry that must name the registry EXACTLY, count and membership, with every
literal present verbatim in the ledger's own prose. So the old row's conclusion
("a seventh enrolment cannot redden this surface") is the opposite of what the
gate does. What survives is narrower and is recorded as a residual in that
gate's own header: the numeral that introduces the list is ordinary prose, and
pinning it needs the arbitrary-literal recognition that scan measured as out of
reach. Both halves are proved below rather than argued.

The enqueue instant. In a merge-queue repository the queue writes the squash
commit onto its own queue ref at enqueue and later fast-forwards main onto the
same object, so the commit's committer date never moves: it is the ENQUEUE
instant. merged_at, the merged timeline event and removed_from_merge_queue
carry the fast-forward instant instead, identical across one merge group. The
card carries the table of eight landings this seat measured, where the gap ran
15 to 26 minutes. The 120-byte line rule does not hold all of that, so the row
carries the mechanism and the prescription; the table stays on the card, which
is this file's convention for provenance.

The battery row. Its stated basis — the battery EXCEEDS the container's
600-second foreground cap — is contradicted by five runs on one box: 433.3 s,
432.4 s and 435.7 s from one session, 434.8 s from another, and 450.2 s from
this branch with a second agent running the same battery in a sibling worktree
(1730 cases pass). None was a cap-kill. The basis is conditional, not false, so
the row is re-conditioned rather than deleted: cap-sized, with the cap a
property of the caller's container and the margin a property of how contended it
is — the 432 to 450 spread IS that contention, measured. The prescription is
unchanged, because it is right either way.

Dedupe, per card

Each subject was grepped on origin/main with a lit control word before
anything was written.

card subject grep on origin/main lit control verdict
#18248 statesTheSet 0 hits under .claude/; mustName, 排他 and 手跟改 hit only the two rows being rewritten required checks lit at :393 candidates 2 / rewritten in place 2 / landed 0 / already present 0 / refused 0
#18274 committer date 0 hits under .claude/; 入队时刻 0 hits; 快进 hits only dispatch-runbook.md, in the unrelated sense of fast-forwarding a local checkout merged_at lit at ledger :22 and SKILL.md :489; git log lit at ledger :152 :155 :281 candidates 1 / landed 1 / already present 0 / refused 0
#18283 check:pm-dispatch-gates, 600 and detach hit only the row being rewritten tail --pid lit at .claude/agents/os-dev.md :342 and guard-process-kill.sh :74 candidates 1 / rewritten in place 1 / already present 0 / refused 0

Nothing was duplicated, and no fact already carried elsewhere was restated.

Reverse verification

Control words. Each touched row greps back exactly once by a word unique to
its new text, and every superseded phrase greps to zero in the file and in the
repository: statesTheSet 1, 数量词未钉 1, 贴调用方容器上限 1, 入队时刻 1;
不要求排他 0, 门绿不是本行已对的读数 0, 计数行只能手跟改 0, 逾容器 600 秒前台上限 0.

Three ablation legs, each mutating a file on disk with the mutation proved by
an occurrence count and a git hash-object reading, each restored by
git checkout HEAD -- path under an EXIT INT TERM trap and each restore proved
by git diff HEAD empty plus a hash equal to the HEAD blob. Direction predicted
before the run in every case.

leg mutation predicted observed
A — proves :397 the count word 七个 to 六个, every literal left listed GREEN (the numeral is not pinned) check-required-contexts exit 0
B — proves :396 one required literal deleted from the ledger's prose RED, naming the missing context exit 1: "platform-readings.md no longer names the required context 'Governed Surface Queue Guard'"
C — proves :396 directly an EIGHTH context enrolled in REQUIRED_CONTEXTS, the ledger left unfollowed RED on the exclusivity half exit 1: "declares statesTheSet: true, so its mustName must be the required set EXACTLY — it lists 7 name(s) against a registry of 8"

Restores: leg A and leg B back to blob d9bd0fd, leg C back to blob 90f3993,
each equal to its HEAD blob, with a post-restore control run at exit 0. No test
file and no fixture is left behind.

Gates

Derived on the changed paths with node scripts/pm/dispatch-gates.mjs --commands
(no hand-written path list: the tool took the change set off the merge base) and
reconciled with --ran. Exit codes were captured by redirect before any pipe.

family verdict
check:pm-skill-ratchet green — "platform-readings.md is 466 lines (ceiling 466; headroom 0)"; the cross-file move still balances: +11 against a net source decrease of 20, less 141 lines of ordinary ruled raise
check:required-contexts green — "7 required context name(s) pinned across 3 workflow(s); 6 instruction surface(s) scanned"
check:pm-skill-id-lint green — "27 file(s) clean"
check:pm-governed-prose green — "2 instruction surface(s) name all 5 registered governed surfaces"
check:skill-frame-sync green — the one declared copy of the decision frame is coherent
check:nul-bytes green; plus a hand scan of both changed files for the other control bytes, zero hits
check:pm-governed-merges green
check:pm-dispatch-gates ran DETACHED and waited for with tail --pid: 450.2 s, "dispatch-gates self-test: 1730 cases pass"
the other 30 derived families green
@objectstack/lint check:doc-formula-expressions NOT MEASURED — exit 3, PREREQUISITE NOT MET (it imports the compiled @objectstack/formula, which is not built in this worktree); nothing in this diff reaches it

Reconciliation verdict, verbatim:

✓ dispatch-gates --ran: 39 derived famil(ies) accounted for — 38 run, 1 NOT-MEASURED (⛔ a FLOOR — 1 derived from exit 3; 1 of 39 recorded no exit code).

The one family with no exit code is the battery itself: it was started detached,
so its shell status was not captured. Its criterion is the verdict it printed,
which is the reading this repository prescribes over a bare code.

skip-changeset: nothing published moves. Both changed paths are outside every
package's files[] — one is a .claude/ reference under the ratcheted PM
surface, the other a scripts/pm/ gate source.

Acceptance notes

  • Noted, not filed: scripts/pm/check-dispatch-gates.mjs :17 and
    scripts/pm/dispatch-gates.mjs :25 both still open with the pre-memoisation
    clause "on an agent container that makes a full run longer than the container's
    foreground command cap". Neither was touched. The first file's NEXT section
    already carries the corrected basis in the words this PR's row now uses — "The
    battery now fits inside a quiet container's cap with room to spare" and "The cap
    is a property of the CALLER's container and the margin is a property of how
    contended it is" — and it opens by marking the earlier section as written
    against the old battery, so the header states the cap as the container's
    property already and the card's conditional edit does not fire. The sibling
    tool's copy is outside this claim's declared file surface. Carrier: the skills
    seat, which owns both headers and lands this PR.
  • The chain head's claim cites comment 5675816113 under Thread-read:; that id
    answers 404. The correction comment on the card names 5675921529 as the one
    meant, and that is the comment that was read. Recorded as NOT MEASURED for the
    cited id rather than as an absence of evidence.

维护者速读(草稿)

改了什么 — 派发台账 platform-readings.md 的三行按实测改写、一行新增:①
mustName 那两行原说本表不排他、加一个必查项不会让门禁变红,而 statesTheSet
普查落地后恰恰相反,改写成门禁今天真正做的事,只把「数量词」这半句留作手跟改;②
新增一行:合并队列仓里 squash 提交的 committer date 是入队时刻,落地时刻要读
merged_at 或 merged 事件,不能读 git log 的日期;③ 那条说 check:pm-dispatch-gates
超容器 600 秒上限的行,五次实测都在上限之内(432–450 秒),改写成「贴上限、上限
归调用方容器」,detach 的处方原样保留。台账上限 465 → 466,一行一条记账。

为什么改 — 台账是席位下判断的事实表,三条里两条的依据已被实测推翻(一条被落
地的门禁推翻,一条被五次计时推翻),留着会让下一个席位按错的理由行动;第三条是缺
口:整个车间今天按 git log 日期记落地时刻,系统性早了 15–26 分钟。

风险与代价(含回滚) — 纯文本改动,零已发布面,故 skip-changeset。风险只有一
个方向:台账行写错会误导席位,故每行都用唯一控制词反查一次、被替换的旧话全仓归零,
并做了三条消融腿(改数量词→绿、删一个必查名→红、加第八个必查项→红)。回滚 = revert
这三个 commit,台账与上限一起回到 465,无迁移、无生成物。

席位意见 — (留空,待 contract-tier 审查填写)

你要做的 — 这是 references 层加 scripts/pm/**,按分层规则由 skills 席位审查后
自行落地,不需要维护者点击;若你想复核,最值得看的是三条消融腿的方向是否与行文一致。


Generated by Claude Code

…ded statesTheSet census

The two rows said the ledger's `mustName` is not exclusive, so a seventh
registry row could not redden this surface, and concluded that a green gate
vouches for nothing here. Both were true before the census landed: the
`platform-readings.md` entry of `INSTRUCTION_SURFACES` in
`scripts/check-required-contexts.mjs` now declares `statesTheSet: true`, so
that array must equal the required-context registry EXACTLY — count and
membership — and every literal in it must appear verbatim in this file. An
enrolment that does not follow this table is red on the enrolling PR.

What survives is narrower and measured: the COUNT WORD introducing the list is
ordinary prose and is not pinned — the gate's own header records the reading
(the numeral reverted while every literal stays listed runs green), so it stays
hand-followed. Line-neutral: two rows rewritten in place, 117 B and 108 B.

Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
Co-authored-by: Claude <noreply@anthropic.com>
…t, not the landing

One row added to the readings ledger's merge-queue block, beside the rows about
the squash commit the queue lands. In a merge-queue repository the queue writes
that commit onto its own queue ref at ENQUEUE and later fast-forwards `main`
onto the same object, so its committer date never moves: it is the enqueue
instant. `merged_at`, the `merged` timeline event and `removed_from_merge_queue`
carry the fast-forward instant instead — identical across one merge group, and
measured 15 to 26 minutes later on eight landings. A landing instant is
therefore read from `merged_at` or the `merged` event, never from `git log`.

The ceiling moves 465 to 466 for that one line, recorded as the SEVENTEENTH
`ruledRaises` record under the standing one-file exception, quoted verbatim and
untranslated as every record before it does; the accounting comment beside the
ceiling names the added row and the three in-place rewrites, which buy nothing.

Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
Co-authored-by: Claude <noreply@anthropic.com>
…easured

The row said the battery EXCEEDS the container's 600-second foreground cap and
prescribed running it detached with `tail --pid`. Measured on one box, under
sibling load, on merged heads: 433.3 s, 432.4 s and 435.7 s from one session,
434.8 s from another, and 450.2 s from this branch with a second agent running
the same battery in a sibling worktree — five verdicts (1730 cases pass), none
a cap-kill. The stated basis is conditional rather than false: since the
battery's discovery pass was memoised it is CAP-SIZED, not over the cap.

The prescription is unchanged and stands on the corrected basis: the cap is a
property of the CALLER's container and the margin a property of how contended
it is — the spread from 432 s to 450 s is that contention, measured — neither
of which the battery can see, and an agent box runs several agents at once. So
detached is still the form that cannot be cut off, and a timeout remains a
non-reading. No fleet reading is taken and the row claims none. Line-neutral,
119 B.

Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
Co-authored-by: Claude <noreply@anthropic.com>
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 15, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 15, 2026
@claude

claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 14737be92bf3ad0f80df34cf3fd8ee8c51509995

Reviewing seat: domain:skills, in-seat review at the contract-review tier — get_session read at 2026-09-15T07:15Z: configured_model = session_context.model = last_served_model, the constant's tier, no fallback notice this round. Fold of three cards (#18248 chain head · #18274 · #18283), claims 5676935525 / 5676935780 / 5676936047 (the five fold gates and the serial check on the chain head's), report 5677287698; Clause-②: no on every claim; default-tier build, seat review at tier.

① Derived judgments

② Semver level

Not applicable — nothing published moves; skip-changeset measured.

③ Boundary flags

open_questions: none. Four declared deviations, each answered: (1) the range widened to 430–450 s on the branch's own measurement — accepted, a row must not be falsified by its own PR. (2) check-dispatch-gates.mjs not edited — accepted, its header already carries the corrected basis in a later section (the card's condition did not fire); its sibling dispatch-gates.mjs :20–:28 does NOT, filed as #18288. (3) the battery's exit not captured — accepted, the verdict line is the reading. (4) three commits amended and force-pushed with lease BEFORE the PR existed, on a branch only this dev had pushed — accepted for this run; the fold's shared branch is named for the chain head and the seat had not fetched it, so no one's checkout was invalidated; once a PR exists, no rewrite. Out of scope, recorded: the chain-head claim's Thread-read id was the seat's slip, corrected on the card at 2026-09-15T08:12Z. Landing: in-seat once every check on 14737be9 is green — ready through the CCR route, auto-merge SQUASH, the enqueue event read (and the queue ref re-measured under refs/heads/gh-readonly-queue/*), provenance on this PR; the squash closes the three cards, residue stripped after the two landing readings.

Implemented-by: claude/issue-18248-platform-readings-fold-2
Reviewed-by: session_01HZfg2AwVX191qCizp88gQr

VERDICT: PASS


Generated by Claude Code

@claude

claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Landing provenance — skills seat, session session_01HZfg2AwVX191qCizp88gQr, 2026-09-15T09:00Z. References-tier + scripts/pm/** landing (no rules-layer file; #17950 tiering): review of record 5677334553 PASS on head 14737be92bf3ad0f80df34cf3fd8ee8c51509995, ACCEPT 5677335133 on the chain head #18248; every check on that head read green at 2026-09-15T08:59Z (24 success / 11 skipped / running none / failed none); the seat's own detached battery on this head: ✓ dispatch-gates self-test: 1730 cases pass.. The seat flipped the PR ready through POST …/pulls/18287/ccr/ready_for_review and armed auto-merge SQUASH through PUT …/pulls/18287/ccr/auto_merge; the added_to_merge_queue event reads 2026-09-15T08:59Z. Queue-ref reading right after the enqueue under refs/heads/gh-readonly-queue/*: 1 ref(s) served through this proxy (PR #18286, enqueued at 2026-09-15T08:49Z, read 0 as well) — the timeline event stays the reading of record. Landing is confirmed by the two readings (merged_at + git log origin/main carrying (#18287) single-parent) at the next wake; the squash closes #18248 · #18274 · #18283 by Fixes, then each card's residue is stripped and the landing records posted.


Generated by Claude Code

Merged via the queue into main with commit bda3a60 Sep 15, 2026
37 checks passed
@claude
claude Bot deleted the claude/issue-18248-platform-readings-fold-2 branch September 15, 2026 09:20
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 17, 2026
… sibling does (objectstack-ai#18291)

Fixes objectstack-ai#18288

## What changed

`scripts/pm/dispatch-gates.mjs`'s header comment, in the "## Run
--self-test
DETACHED on an agent container" section, stated the pre-memoisation
basis for
the detach prescription: the battery "makes the full run longer than the
container's foreground command cap, which SIGTERMs a run past it" — true
before the family-discovery memoisation, no longer the measured basis
today.

The clause now matches the corrected basis its sibling
`check-dispatch-gates.mjs`
carries at :43-:48 (added after objectstack-ai#18201 collapsed the battery's own
tree-discovery to one pass per process): the battery is cap-SIZED on a
quiet
box — the cap belongs to the CALLER's container and the margin to how
contended it is, neither of which this file can see, and an agent box
runs
several agents at once. The prescription is unchanged: detach and poll
the
log (`tail --pid` or otherwise); a timeout is not a reading.

Section shape, the `nohup`/`tail` example command, and the `objectstack-ai#14281`
reference
are all kept as-is; only the outdated basis clause is rewritten.

## Comment-only, no behaviour change

git diff origin/main -- scripts/pm/dispatch-gates.mjs | grep -E '^[-+]'
| grep -v -E '^(\+\+\+|---)' | grep -v -E '^[-+]\s*\*'

prints nothing on this branch — every changed line is a ` * ` comment
line.

## Measured

This run's own `pnpm check:pm-dispatch-gates`: 434.5s, 1730 cases pass,
no
cap-kill — one more point alongside the six already on the register row
this
reading is drawn from (432.4 / 433.3 / 434.8 / 435.7 / 447.4 / 450.2s,
all
verdicts, none a cap-kill; see PR objectstack-ai#18287's fold of
`platform-readings.md`).

---
_Generated by [Claude
Code](https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr)_

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment