Repository navigation
Skills optimization flight — skills/objectstack-pm-dispatch: RESTRUCTURE (≈ −4,255 tok, −29%) — monorepo-only lore inert in a customer project, the report JSON printed twice, and four drifts from the internal dev contract (report double-channel, premise_still_valid, the stash ban, the Session: line) #14300
Description
Member card of the skills catalog optimization program #14292 (maintainer mandate 2026-09-02, verbatim: 「审核所有的 skills,进行全面的优化。」). Filed by the skills lane seat (session session_01LraLgQVGq8egUwfYZpbYt1). Read-only audit at objectstack origin/main a59f78d. The full findings table is the audit record: the dev posts it verbatim as the first comment on this card at claim time (seat scratchpad audit/objectstack-pm-dispatch/findings.md).
.claude/skills/pm-dispatch/** and .claude/agents/os-dev.md are a separate corpus under audit #13597 — read them only as the comparison oracle, ⛔ never edit them in this flight, ⛔ never in the same PR.
Audit summary
One file, SKILL.md, 1,086 lines, 14,549 tokens, headroom 0 — 7.7% of the bundle, the 2nd-largest published SKILL.md, 1.75× the other process skill. Teaches no ObjectStack surface (0 TypeScript fences). Customer decision points covered: 5 (label state machine; safe claim; dispatch with a binding template; review-against-GitHub and land; escalate vs decide) ≈ 2,900 tokens per decision. Customer-inert or duplicated text measured at 4,445 tokens (30.6%) before any restructure. Verdict RESTRUCTURE: zero progressive disclosure, zero evals, two blocks duplicated inside the file (the report JSON at 869-882 / 894-908; the sanitizer trap at 346-365 / 884-888), a 2,376-token verbatim paste-block paid in every session, and a second job (upstream reporting) restating objectstack-platform :59-70.
Top findings
| id | span | proposal | delta |
|---|---|---|---|
| PMD-B-01 | SKILL.md:729-891, 916-986 |
MOVE-TO rules/dev-template.md (DEFERRED, #14296 items 1+4) |
−3,258 from entry |
| PMD-C-01 | SKILL.md:916-986 vs objectstack-platform :59-70 |
DELETE the upstream-reporting job; keep ≤250-token residue pointing at objectstack-platform | −882 |
| PMD-E-05 | SKILL.md:987-1033 |
REWRITE-AS-CONSTRUCT — shard registry conclusion is one line for a single-repo project | −580 |
| PMD-E-02 | SKILL.md:416-452 |
RETIRE-SURFACE — "N independent implementations" is the platform's compiler problem, not an app's | −565 |
| PMD-E-03 | SKILL.md:591-618 |
DELETE two non-escalation bullets (ADR-0049 "arm"/governance shapes) | −508 |
| PMD-D-01 | SKILL.md:192-217 |
REWRITE-AS-CONSTRUCT — sweep rationale, cross-seat producers, anecdote | −380 |
| PMD-D-02 | SKILL.md:507-528 |
REWRITE-AS-CONSTRUCT — the 8-card baseline printed and disclaimed | −290 |
| PMD-D-04 | SKILL.md:654-706 vs 826-857 |
REWRITE-AS-CONSTRUCT — four-axis frame stated twice | −450 (MED) |
| PMD-E-04 | SKILL.md:769-786 |
REWRITE-AS-CONSTRUCT — design spec of a lock script the customer does not have | −250 |
| PMD-B-03 | SKILL.md:346-357 |
DELETE sanitizer specimens; rules at 359-365 carry the decision | −200 |
| PMD-B-02 | SKILL.md:894-908 |
DELETE — the same report JSON printed twice | −115 |
| PMD-D-03 | SKILL.md:483-495 |
DELETE check-in anecdote; keep the two rules at 496-506 | −170 (MED) |
| PMD-A-01 | SKILL.md:10-14 |
DELETE the "report a platform bug" trigger from the description | −30 |
| PMD-G-01 | SKILL.md:557-559 vs 1051 |
DELETE — "the PM's own tooling PRs" contradicts "The PM writes no files" | −25 |
Drift vs the internal contract (sync in this flight, paid by the deletions above)
- PMD-F-01
:455-457"a lossless channel" — the internal contract requires the report TWICE, GitHub first, in both modes, first line the literal plaintextos-dev-report(⛔ not an HTML comment), because a container restart killed three devs mid-final-message. Also a falsehood::456-457is contradicted 17 lines later at:474-475. - PMD-F-02 the template never asks the dev to re-check the issue's premises and the report has no
premise_still_valid; internally a no-PR report withpremise_still_valid: falseis a first-class deliverable. - PMD-F-03
grep -c stash= 0, yet the template ships the exact topology the trap lives in (worktree-first + "parallel agents share ONE container"); both repos carry the ban at Prime-Directive level. - PMD-F-04/F-05 the claim shape omits the
Session:line (branch-only identity under-determines in cloud mode);:367-369asserts devs push early while the template pushes fourth — the reclaim predicate can fire against a live agent. Make the template push the empty branch first. - Falsehood
:1036-1039"the template enforces … a container-wide verification lock" — the template delegates the mechanism to the host project; should readrequires.
Flight scope
IMPLEMENT (same-file, shrink-only): all rows above except PMD-B-01 and PMD-H-01; the four drift syncs (paid by PMD-E-02 / PMD-E-04 / PMD-B-02 as the auditor sized them); PMD-C-01 as delete + ≤250-token residue pointing at objectstack-platform SKILL.md:59-70; the description trigger edit (regenerate skills/README.md).
DEFER (pending #14296 items 1 and 4): PMD-B-01 (split the template into rules/dev-template.md), PMD-H-01 (evals).
Flight constraints (binding)
- ONE draft PR, first line
Fixes #<this card>; governed ⇒ stays draft; review requests are the seat's step. - Token ratchet:
SKILL.mdmay not grow; additions paid by deletions in the same file; ⛔ re-wrap is not payment; ⛔ no ceiling raise; ⛔ no new files; ⛔ do not touch the ratchet script. - ⛔ Never edit another package's files; frontmatter edits ⇒ regenerate
skills/README.md(pnpm --filter @objectstack/spec gen:skill-docs). - Gates:
node scripts/check-skills-token-ratchet.mjs,pnpm check:skill-compatibility,pnpm check:skill-identifier-liveness, plusnode scripts/pm/dispatch-gates.mjs --commands <changed paths>; record the head sha. - PR body: per-item 落点 | before | after list keyed by finding id; token delta;
Clause-②: no(no contract surface).
Refs: #14292 · #14296 · #13597 (the internal corpus, separate audit).
Activity
os-litant commentedon Sep 2, 2026
Claim: PM loop round 2
Session:
session_01LraLgQVGq8egUwfYZpbYt1Branch:
claude/issue-14300-skills-pm-dispatch-optimizationWorktree:
objectstack-issue-14300Domain:
domain:skillsFile surface:
skills/objectstack-pm-dispatch/SKILL.mdONLY (shrink-only; no file deleted ⇒ ⛔ no edit toscripts/check-skills-token-ratchet.mjs);skills/README.md+content/docs/ai/skills-reference.mdxregenerated only because the drift gate demands it after the PMD-A-01 description edit; ⛔.claude/skills/pm-dispatch/**and.claude/agents/os-dev.mdare the comparison ORACLE, read-only, never in this PR; ⛔ no other package (stop on breach; explain in the report)Container & model: M (one 14,549-token file, structural diet + five drift syncs against the internal contract),
mode:subagent,model: fable—node scripts/pm/dispatch-gates.mjs --tier skills/objectstack-pm-dispatch/SKILL.mdreads MANDATORY claude-fable-5 (clause ①, 2026-08-20 narrowing: the published PM skill carries two enforced copies of the decision frame and ships verbatim to third-party projects); no exit applies — this is not a one-line mechanical edit and quota is availableClause-②: no — no contract surface (0 TypeScript fences, no accept/reject semantics); no
needs:contract-review; the skill-face review is the seat's in-seat review at tierSerial constraints cleared: the two frame-sync copies in this file (
:643"every option on the four fixed axes below." and:832"Analyze every option on four fixed axes:") are gate-pinned against.claude/skills/pm-dispatch/SKILL.mdand.claude/agents/os-dev.md— both copies STAY and neither block is edited, so PMD-D-04 is EXCLUDED from this flight (its only remedy removes a copy the gate requires);.claude/skills/pm-dispatch/SKILL.md(PR #14230) and.claude/agents/os-dev.md(PR #14229) are held by unmerged PRs — this flight syncs the five drifts to the contract text onorigin/mainand lists #14229's pending deltas as a follow-up sync, never edits them; PMD-C-01's residue points at objectstack-platform's "The App / Platform Boundary" section BY HEADING (the platform flight #14351 moved it and keeps it); no open PR touchesskills/objectstack-pm-dispatch/**; in flight alongside #14299 (platform, patch round) and #14302 (query) on disjoint directoriesDecision re-read: no maintainer ruling on this card; binding inputs = the mandate, the value gate, the ratchet discipline, and #14296 (items 1 + 4 defer PMD-B-01; item 2 defers PMD-H-01). Landing form: first line
Part of #14300(the deferred split and evals keep the card open).Generated by Claude Code
os-litant commentedon Sep 2, 2026
Claim: dev seat, dispatched by PM loop round 2 (
mode:subagent)Session:
session_01LraLgQVGq8egUwfYZpbYt1Branch:
claude/issue-14300-skills-pm-dispatch-optimization(empty branch pushed first as the write-route probe: exit 0)Worktree:
objectstack-issue-14300(base96b627d1)File surface:
skills/objectstack-pm-dispatch/SKILL.mdonly, plusskills/README.mdandcontent/docs/ai/skills-reference.mdxas generator output after the PMD-A-01 description edit. Assignee untouched..claude/skills/pm-dispatch/**and.claude/agents/os-dev.mdread as the comparison oracle only.Next comment on this card is the audit record (
audit/objectstack-pm-dispatch/findings.md, first lineaudit-record), posted with a transliteration key for the angle-bracket-shaped fragments.Generated by Claude Code
os-litant commentedon Sep 2, 2026
audit-record — skills/objectstack-pm-dispatch (read-only audit at a59f78d)
Posted by the dev seat at claim time; this is the finding-by-finding spec for the flight on #14300.
Transliteration key (deviation from a byte-verbatim post, disclosed). The GitHub comment sanitizer is measured to eat angle-bracket / HTML-comment-shaped fragments, and this seat has no raw-REST read path to verify byte survival (repo-scoped REST returns 403 for this session). The 18 angle-bracket fragments on 13 lines of the file are therefore spelled without angle brackets, as the platform flight did on #14299. Nothing else is changed — every finding id, span, evidence, proposal, delta, gate verdict, confidence and human-floor flag is byte-identical to
audit/objectstack-pm-dispatch/findings.md:os:checkos:checkHTML-comment markersBEGIN GENERATED: skills …BEGIN GENERATED: skillsHTML-comment markerdev-reportdev-reportHTML-comment markerAudit — skills/objectstack-pm-dispatch (published, read-only)
Pinned ref: objectstack
origin/main=a59f78d. Verified the working file is byte-identicalto the pinned blob (
git show a59f78d:skills/objectstack-pm-dispatch/SKILL.md | md5sum==md5sumof the checkout copy =3948bdb8c73dba124ebc2e61a832d1db). All spans below are atthat ref. Local
HEADisa39b02a, butgit diff a59f78d HEAD -- skills/is empty.Package facts (measured)
SKILL.md) — norules/, noreferences/, nocontracts/, noevals/ls skills/objectstack-pm-dispatch/node scripts/check-skills-token-ratchet.mjsSKILL.md(afterobjectstack-ui25,441); larger thanobjectstack-data13,892 andobjectstack-platform12,984objectstack-upgrade(8,333)bash, 2json, 1text, rest baregrep -nE '^{3,4}'`os:checkHTML-comment markers 0packages/spec/scripts/check-skill-examples.ts:18-23evals/ls -d skills/*/evalsBecause the package contains zero
ts/tsxfences, dimension E's type-check sweep has nosurface: nothing in it can be reached by
check-skill-examples.ts, and nothing needs amarker. Recorded as a measured negative, not a finding.
Section budget (measured, ceil(bytes/4))
The customer's five real decision points
Derived from what a single-repo ObjectStack app project with no internal tooling can act
on, not from the doc's own headings:
Everything measured below as monorepo lore changes none of these five.
Findings
PMD-A-01 · TRIGGER PRECISION ·
skills/objectstack-pm-dispatch/SKILL.md:10-14Evidence. The frontmatter advertises a second, unrelated job: "Ships the developer-agent
operating template … and the upstream-reporting procedure for platform defects an app
project finds. Use when asked to … or to report a platform bug found while building an
app." A customer agent that trips over a platform defect while authoring metadata loads
14,549 tokens to reach the 882-token §"Upstream reporting" (916-986), of which ~600 restates
skills/objectstack-platform/SKILL.md:59-70(see PMD-C-01).skills/README.md's index row isgenerated from this same description (the
BEGIN GENERATED: skillsHTML-comment marker, README:29-45), sothe mis-routing is mirrored into the catalog automatically.
Proposal.
MOVE-TO skills/objectstack-platform(the ~250 tokens of unique procedure) anddelete both the "Ships … upstream-reporting procedure" clause and the "or to report a platform
bug" trigger; regenerate README via
pnpm --filter @objectstack/spec gen:skill-docs.Delta. −30 (frontmatter only; the section itself is counted in PMD-C-01).
Gate. ① Yes — it decides which package a customer loads for a bug report. ② Yes, deletion.
③ N/A (frontmatter). Confidence HIGH. Human floor YES (changes a published trigger).
PMD-A-02 · TRIGGER PRECISION ·
skills/README.md:94-110Evidence. "Cross-skill routing" carries 4 bullets, all pairs of domain skills
(data/automation, automation/ui, formula, platform/data). Nothing routes between the two
processskills, and nothing tells an app author when a process skill applies at all. Bothprocess packages sit in the generated index (README:44-45) with no disambiguation, and their
descriptions overlap on the word "process" and on escalation-to-owner language
(
objectstack-upgradefrontmatter: "work the semantic residue … to a decision with theproject's owner").
Proposal.
ADDone routing bullet ("Delivery loop vs protocol upgrade …"). Payment mustcome from README itself; the generated index block (29-45) is generator-owned and cannot pay.
Delta. +25 unpaid — flagged, not recommended without a maintainer ruling.
Gate. ① Yes. ② No. ③ Bullet in an existing list. Confidence MED. Human floor no.
PMD-B-01 · STRUCTURE · whole file (1-1086)
Evidence. One 14,549-token file with no progressive disclosure at all. Two blocks are
needed only at a specific moment yet are paid in every session: the developer-agent template
(729-891, 2,376 tok) is a verbatim paste-block consumed only when a dispatch is actually
composed, and §"Upstream reporting" (916-986, 882 tok) is a different job entirely.
skills/README.md:57-64listsrules/as an available optional directory for any skill; the"process skill carries
SKILL.mdalone" sentence (README:66-69) is scoped toreferences/("
gen:skill-refsonly visits skills listed in itsSKILL_MAP"), so it does not block arules/split.Proposal.
MOVE-TO rules/dev-template.md(the paste-block, linked from §5) and — withPMD-C-01 — out of the package for upstream reporting.
Delta. −3,258 from the always-loaded entry file (a new
rules/file takes its own ceiling).Gate. ① Yes — it decides what a PM pays before it has dispatched anything. ② Partly
(relocation, not deletion). ③ Yes, the template stays a construct. Confidence HIGH.
Human floor YES (restructures files; new ratchet ceiling).
PMD-B-02 · STRUCTURE ·
SKILL.md:869-882and894-908Evidence. The same 8-key report schema is printed twice, 12 lines apart, differing only in
placeholder-vs-literal values (
"issue": Nvs"issue": 123;"pr": "URL or null"vs"pr": "https://github.com/acme/hotcrm/pull/456 | null"). Only 909-914 adds new rules("
open_questionsmust be non-empty whenstatusisneeds_decision"; "out_of_scope_findingsshould already be filed …").
Proposal.
DELETEthe fence at 894-908; keep 909-914 as a note under the template.Delta. −115. Gate. ① No decision is changed by the second copy. ② Yes. ③ Construct
preserved. Confidence HIGH. Human floor no.
PMD-B-03 · DENSITY ·
SKILL.md:346-357(232 tok), duplicated in substance at884-888(73 tok)Evidence. The sanitizer trap is taught twice. 346-357 spends 12 lines on measured
specimens — "the
dev-reportHTML-comment marker came back as nothing at all,expected N to be 19cameback as
expected to be 19,git log -- PATHcame back asgit log --" — plus threelines on why this differs from step 0's truncation shape. The actionable rules are 359-365
("Write literal angle brackets as HTML entities … read it back"), and 884-888 restates the
whole trap inside the pasted template for the dev.
Proposal.
DELETE 346-357, replacing with one clause on 359 ("measured: code spans are notprotection — an HTML comment came back empty").
Delta. −200. Gate. ① No — the rule at 359-365 already changes the decision; the
specimens change nothing. ② Yes. ③ Rules survive as a construct. Confidence HIGH.
Human floor no.
PMD-C-01 · CROSS-PACKAGE REDUNDANCY ·
SKILL.md:916-986(882 tok) vsskills/objectstack-platform/SKILL.md:59-70Evidence — both locations quoted.
pm-dispatch:918-924 — "The temptation is to make the app tolerate it and move on. Do not. A
workaround in the app hides the defect from the people who can fix it, ships a second source of
truth to every future author, and outlives the upstream fix by years."
platform:59-61 — "Business features belong in the app; capability belongs in the platform.
A missing default, a wrong diagnostic, a shape the spec refuses — the fix is upstream. Raise it
there; do not compensate for it here."
pm-dispatch:974-985 — park via
Blocked-by:or "pin the current upstream version with theunblock condition written down … A pin with no recorded unblock condition is a workaround with
better manners"; "'We worked around it' is never a resolution".
platform:62-69 — "A platform defect means waiting for the platform fix. No defensive
coding, no shape tolerance … Record the block against the platform issue so it is
machine-visible; before resuming, confirm the version you pin carries the fix (merged
upstream ≠ present on your pin) and re-run the defect's own reproduction."
Which anchor survives.
objectstack-platform— it is the app-bootstrap package every appproject loads to stand the project up, it already carries the doctrine, and it is where an
agent already is when it hits the defect. The genuinely unique residue in pm-dispatch is ~250
tokens: derive the upstream repo from the dependency's
package.jsonrepository(925-930);minimal repro + pinned versions + cite the contract (944-958); file as a guest — never apply
the upstream's queue labels, never assign, never add to their board (959-971).
Proposal.
MOVE-TO skills/objectstack-platform(~250 tok of residue),DELETEthe rest.Delta. −882 here (+~250 there).
Gate. ① Yes — it decides which package owns the doctrine. ② Yes, mostly deletion. ③ The
survivor is a 3-bullet checklist. Confidence HIGH on the overlap, MED on the exact split.
Human floor YES (moves published capability text across packages).
PMD-D-01 · DENSITY / MONOREPO ·
SKILL.md:192-217(433 tok)Evidence. "Why the sweep is a disjunction and not one 'unlabeled' filter." followed by⚠️ ⚠️ at
two "standing producers" that exist only here: "Cross-seat transfer tickets (the handing-off
side applies the queue label as part of the transfer) and tickets filed mechanically by a
steward automation both carry
pm:queueon arrival, while a single-producer discipline forclassification labels forbids those same producers from applying one", plus the anecdote "a
project that had published exactly that rule hours earlier still produced such a card the same
day". "Seat", "steward automation", "lane" (180) and "protocol posts" (215) are used as defined
terms and are defined nowhere in the package; an app project has none of them.
Proposal.
REWRITE-AS-CONSTRUCT— keep the 3-item disjunct list (179-191), fold thescoping caution (209-217) to one line and the ⏳
updated_atfloor (219-225) to one line, dropthe producers and the anecdote.
Delta. −380. Gate. ① No — the customer either runs the predicate or (per the
209-214) must not; the rationale changes neither. ② Yes. ③ Yes, list survives.
Confidence HIGH. Human floor no.
PMD-D-02 · DENSITY ·
SKILL.md:507-528(357 tok)Evidence. The section states the number is not transferable and then prints it anyway:
"Two same-day samples from this repo's loop show why no single number can be inherited: four
text-only documentation cards landed at 93 / 96 / ~95 / ~110 min, while four mixed cards from
the same day spanned ~64 min to ~2 h 50 min (the two long ones waiting on CI). Eight cards, one
day, one toolchain …". The decision-changing content is the rule at 507-512 + 516-518.
Proposal.
REWRITE-AS-CONSTRUCT— "A silence threshold is a collection boundary, not averdict of death. Before concluding a dispatched agent is dead, require one of: a direct status
query showing it dead, the host reporting the session stopped, or silence past a completion
baseline you measured in your own project."
Delta. −290. Gate. ① No — the data is explicitly disclaimed as non-inheritable.
② Yes. ③ Yes. Confidence HIGH. Human floor no.
PMD-D-03 · DENSITY ·
SKILL.md:483-495(of the 404-tok block 483-506)Evidence. "Measured three times in one day on this loop: a scheduled message still
delivered after its timer had been cancelled, carrying text two rounds out of date. One of
them read 'no branch and no report ⇒ judge the agent unreliable and dispatch a fresh one'; by
delivery time that agent had opened a PR which was already reviewed and accepted …". The two
rules that follow (496-506: open every check-in with "idempotent — re-read the state before
acting"; state criteria never conclusions; "cancellation is not a guarantee of non-delivery")
are general and genuinely decision-changing, and already carry the surprising fact.
Proposal.
DELETE 483-495; keep 496-506 intact.Delta. −170. Gate. ① No — 496-506 already changes the decision. ② Yes. ③ The two rules
are the construct. Confidence MED (the anecdote is the only place the cancelled-timer fact
is shown; it is however stated at 505-506). Human floor no.
PMD-D-04 · DENSITY ·
SKILL.md:654-706(861 tok) vs826-857(574 tok)Evidence. The four-axis frame is stated twice in one file, in near-identical wording. PM-side
axis ④: "Startup scope discipline. Do not grow the declared surface while the core is still
forming. 'We already shipped it' earns nothing: a shipped-but-unconsumed capability gets no
sunk-cost exemption." Template copy: "Startup scope discipline — do not grow the declared
surface: a shipped-but-unconsumed capability gets no sunk-cost exemption." The weight and
ranking rules are likewise duplicated ("Axis ② carries the highest weight — at least 50%",
697-706, vs "Long-term soundness carries the highest weight, at least 50%", 853-857). The
template copy must stay verbatim (it is pasted into a zero-context prompt).
Proposal.
REWRITE-AS-CONSTRUCTthe PM-side copy as a 4-row table (axis · question ·evidence standard) plus the ranking/weight rule, pointing at the template block for full wording.
Delta. −450. Gate. ① No new decision from the second full prose copy. ② Partly. ③ Yes —
a table replaces prose. Confidence MED. Human floor no (no semantics removed).
PMD-E-01 · MONOREPO ASSUMPTION ·
SKILL.md:179-217Evidence. Disjuncts 2 and 3 are keyed on a "classification label" — "none of the labels
⚠️ at 209-214 makes the disjuncts self-disabling where
your project reads as 'already routed' (area, component, owning team, lane)". This is the
monorepo's
domain:*lane vocabulary (.claude/skills/pm-dispatch/SKILL.md:36runs seats byDOMAINlane). The package's ownthe label does not exist: "Where it does not exist, its absence is universal, so the disjunct
matches every open queue card in that repository and the sweep becomes its own noise source."
A customer app project has no classification labels, so 2 of the 3 disjuncts and their entire
rationale are inert by construction — the customer pays 433 tokens (PMD-D-01) to learn a
predicate it must not run.
Proposal. Folded into PMD-D-01; additionally define or drop "seat"/"lane"/"steward
automation"/"protocol posts".
Delta. counted in PMD-D-01. Confidence HIGH. Human floor no.
PMD-E-02 · MONOREPO ASSUMPTION ·
SKILL.md:416-452(565 tok)Evidence. "#### One semantics, N independent implementations". Its own applicability clause
names the platform's problem, not an app's: "that rule is implemented more than once, by
compilers or evaluators that share no code. Query filters, expression languages,
permission predicates and serialization formats all tend to grow this shape as a project adds
backends." An ObjectStack app project consumes one compiled query/expression surface from
@objectstack/spec; it authors no compiler and has no second evaluator to enumerate. The twomaintenance disciplines that follow (440-452, 201 tok — "The inventory is maintained by PR",
"Re-verify before pasting", frozen surfaces stay listed) are entirely about owning such an
inventory.
Proposal.
RETIRE-SURFACEfrom the published package (it belongs to the internal corpus,outside the published boundary).
Delta. −565. Gate. ① Changes no decision an app project can make. ② Yes, deletion.
③ N/A. Confidence HIGH. Human floor YES (removes published capability text).
PMD-E-03 · MONOREPO ASSUMPTION ·
SKILL.md:591-611(398 tok) +612-618(110 tok)Evidence. Two of the six "named non-escalation classes" are platform-governance shapes.
591-592: "A declaration silently dropped on a new arm, when a sibling arm already has a
ruling. When a declared key is silently ignored on one arm of a component and an
earlier ruling already made that same key a loud authoring error on a sibling arm, the new
arm joins the existing rejection set by default" — this is the enforce-or-remove /
declared = enforcedmachinery of this repo's spec work (the same vocabulary drives thespec-property-retirementinternal playbook), and an app project authoring metadata against afixed published spec has no "arm of a component" carrying declarations. 612-618: "Two
implementations of one operation … the side that already carries the governance —
authorization gates, user consent, de-duplication, audit trail — is the default survivor"
— a platform-runtime concern.
Proposal.
DELETEboth bullets; keep "Restore-invariant fixes", "Sequencing and dependencyordering", "Verification strategy", and the
needs_decision-relay bullet.Delta. −508. Gate. ① No decision an app PM makes. ② Yes. ③ N/A. Confidence HIGH.
Human floor YES.
PMD-E-04 · MONOREPO ASSUMPTION ·
SKILL.md:769-786(290 tok)Evidence. Four correctness properties of a container-wide verification lock — "ONE shared
heavy-verify lock per container, so every agent contends on the same file"; "The acquisition
budget fits inside a SINGLE foreground tool call"; "A queue timeout is distinguishable from the
wrapped command's own failure"; "Hold duration is observable". This is the design spec of this
repo's
scripts/pm/os-verify-lock.sh(the internalos-devagent calls it by path). Thepublished text concedes the customer has none: "The MECHANISM is the host project's (its
wrapper, its lock path, its budget — put it in the conventions file)". A customer standing up
the loop on day one therefore reads 290 tokens instructing it to build lock infrastructure
before it may dispatch.
Proposal.
REWRITE-AS-CONSTRUCT— one line: "Serialize build/test through a singlecontainer-wide lock; queueing is normal, queueing with no end in sight is a finding — report it
naming the holder."
Delta. −250. Gate. ① The 4 properties change no decision for a project with no wrapper.
② Yes. ③ Yes. Confidence HIGH. Human floor YES (removes published guidance).
PMD-E-05 · MONOREPO ASSUMPTION ·
SKILL.md:987-1033(656 tok)Evidence. The whole section presupposes ≥2 repositories — which Configuration (79-117)
declares the non-default case ("With no config the loop runs against the current repository:
it is the only shard and the backlog", 60-61) — plus a shard registry issue: "Shard
ownership is registered, never assumed. A registry issue in the backlog repository records
which session owns which shard. A PM taking over a shard comments there as its FIRST action,
and again when handing off." That is this monorepo's
pm:seatseat-post protocol(
.claude/skills/pm-dispatch/SKILL.mdstate model row: "pm:seat座位登记贴 —— 协议载体") underanother name. Its own conclusion is one line: "Multiple PMs on the same queue: prohibited."
Proposal.
REWRITE-AS-CONSTRUCT— one Guardrails bullet: "One PM per queue. Scale withbatch/mode:cloud, never a second scheduler; a second PM takes a whole other repository asits shard and never claims outside it."
Delta. −580. Gate. ① For the documented default (single repo) it changes nothing.
② Yes. ③ Yes. Confidence HIGH. Human floor YES.
PMD-E-06 · MONOREPO ASSUMPTION (minor) ·
SKILL.md:553-556Evidence. The landing path leads with the merge-queue case — "where a merge queue
exists, mark the PR ready and add it to the queue once every check is green (the queue rebuilds
against the current default branch, which is the sanctioned path)" — before the case every app
project is actually in. Properly conditional, so not a defect, but it front-loads the path the
customer does not have.
Proposal. Reorder so the serial-merge case leads. Delta. −30.
Gate. ① Marginal. ② No. ③ No. Confidence LOW. Human floor no.
PMD-F-01 · DRIFT vs INTERNAL CORPUS ·
SKILL.md:455-457and465-469Evidence — published (retired form). "
mode:subagent(default). … Reports come backdirectly as each agent's final message — a lossless channel. Prefer this mode; it is simpler
and nothing can be lost between agent and reviewer." The issue-comment report is required in
cloud mode only (465-469).
Evidence — internal oracle (current form).
.claude/agents/os-dev.md:20-22and 351-359:the report is delivered twice, GitHub first, in both modes — as an issue comment whose first
line is the literal plaintext
os-dev-report(explicitly "⛔ 不用 HTML 注释"), then as the finalmessage; the reason is measured — a container restart killed three devs mid-final-message and
the comment was the only surviving copy, so zero work was lost. The published package's own
line 474-475 already concedes the channel loses work ("An agent that dies or returns malformed
output counts as
status: \"blocked\"").Proposal.
ADDthe both-modes comment rule + read-back to the template's final-messagesection (~50 tok), paid by
DELETEof the duplicate JSON at 894-908 (PMD-B-02, −115).Delta. −65 net. Gate. ① Yes — it decides where the report is written. ② The addition is
paid by a same-file deletion. ③ Yes, it is one rule line on an existing construct.
Confidence HIGH. Human floor YES (changes published report semantics).
PMD-F-02 · DRIFT vs INTERNAL CORPUS ·
SKILL.md:729-891(template) and892-915(contract)Evidence. The PM-side stale-premise check exists (249-260: "An issue describes the
repository as of its filing date, and an active default branch moves fast"). The binding
template the dev actually receives never repeats it, and the report contract has no field for
the result. The internal oracle made this a numbered basic rule:
.claude/agents/os-dev.md:78-81rule 6 — "issue 正文是线索,不是规格。动手前对origin/main核验其前提 … 一份带
premise_still_valid: false、附证据、无 PR 的报告是一等交付物;证伪issue 是好运行" — and the internal report schema carries
"premise_still_valid": true(os-dev.md:430). Without it a dev on a dead premise has no sanctioned return shape:
blockedmeans infrastructure (published 858-860) and
needs_decisionmeans underspecified (826-830),so the template's own incentives push a PR onto a falsified premise.
Proposal.
ADDone template line ("Verify the issue's premises againstorigin/{default}before your first edit; a no-PR report with
premise_still_valid: falseand evidence is afirst-class delivery") + the JSON key (~60 tok), paid by
DELETEof PMD-E-02 (−565).Delta. −505 net. Gate. ① Yes — it changes what a dev does when the issue is wrong.
② Paid by a larger same-file deletion. ③ Yes, one key on an existing JSON construct.
Confidence HIGH. Human floor YES (adds a published report field).
PMD-F-03 · DRIFT vs INTERNAL CORPUS ·
SKILL.md:745-750+763Evidence.
grep -c stash SKILL.md= 0. The template teaches the exact topology in whichthe trap lives: worktree-first ("git worktree add --no-track ../REPO-issue-N … Never edit a
shared checkout — other agents switch its HEAD under you", 745-750) plus "parallel agents
share ONE container" (763).
refs/stashlives in the common.gitdirectory, so allworktrees of one clone share one LIFO stack — which is why both repos carry the ban at
Prime-Directive level with a measured incident:
/home/user/objectui/CLAUDE.md— "two agentsstashing in their own worktrees push and pop the same stack …
popreports success; theonly symptom is someone else's files appearing in your
git status… it happened between twoparallel agents (objectui#3430) and cost both of them their in-flight changes."
The published package ships the topology without the guard.
Proposal.
ADDtwo lines to template rule 1 ("Nevergit stash— the stack is sharedacross every worktree of one clone. Use
git diff > /tmp/wip.patchor a throwawaywipcommit", ~40 tok), paid by
DELETEof PMD-E-04's lock properties (−250).Delta. −210 net. Gate. ① Yes — it changes the command a dev reaches for. ② Paid by a
larger same-file deletion. ③ Yes, two bullets. Confidence HIGH. Human floor YES.
PMD-F-04 · DRIFT vs INTERNAL CORPUS ·
SKILL.md:336-338,342-343Evidence — published claim shape. "> Claim: PM loop round N / > Branch:
claude/issue-N-SLUG/ > Worktree:REPO-issue-N", with the identity key being thebranch: "if an earlier claim comment with a different branch name exists, you lost".
Evidence — internal (current).
.claude/skills/pm-dispatch/SKILL.md:535-541makes> Session: \session_ID`a non-optional line ("session ID 不可省"), keeps the literalClaim:first line as a maintainer-ruled machine predicate (2026-08-11), and names the comment **timestamp** the sole arbiter./home/user/objectstack/CLAUDE.mdstates the same at Prime-Directive level: "a claim is assign **plus a claim comment with your session ID and branch**". The published branch-only discriminator under-determines inmode:cloud— a mode the published skill itself supports — because the branch slug is derived from the issue, so two cloud sessions racing the same issue can generate the *same* branch name and both read "no earlier claim with a different branch". **Proposal.**ADDtheSession:` line to the claim shape (~15 tok), paid from PMD-D-01.Delta. +15 (paid). Gate. ① Yes — it decides who yields in a race. ② Paid.
③ Yes, one row of an existing template. Confidence MED-HIGH. Human floor no.
PMD-F-05 · DRIFT / INTERNAL CONTRADICTION ·
SKILL.md:367-369vs800-810Evidence. PM-side prose asserts a behaviour the template never asks for: "Developer agents
push their branch early — a remote branch is the hardest evidence of work in flight, and it
closes the gap between 'claimed' and 'a PR exists'", and the stale-claim reclaim at 371-375 then
reads that remote branch ("A claim older than ~24 h whose promised branch does not exist on
the remote and has no PR is presumed dead"). But the binding template's "Definition of done, in
order" (800-810) lists "Pushed: git push -u origin …" fourth, after implementation, tests
and the release-note artifact. A dev following the template has no remote branch for most of
its run, so the reclaim predicate can fire against a live agent. The internal oracle closes
this:
.claude/agents/os-dev.mdrule 1 — "建好分支后的第一个动作:先把空分支推上去(任何编辑之前
git push -u origin BRANCH)" — doubling as a write-credentials probe (403 ⇒ stop andreport
blocked).Proposal.
ADD"push the empty branch immediately after creating it (also a write-accessprobe: a 403 here is
blocked, not a retry loop)" to template rule 1 (~25 tok), paid fromPMD-D-02.
Delta. +25 (paid). Gate. ① Yes — it removes a contradiction that can trigger a wrongful
reclaim. ② Paid. ③ Yes. Confidence HIGH. Human floor no.
PMD-G-01 · CONSISTENCY ·
SKILL.md:557-559vs1051Evidence. Guardrails: "The PM writes no files." (1051). Step 7 ACCEPT: "This applies to
developer-agent PRs dispatched by this loop only — the PM's own tooling PRs stay with the
maintainer." (557-559). The second sentence presupposes PM-authored PRs the first forbids. It is
residue of the internal exception the published copy dropped:
.claude/skills/pm-dispatch/SKILL.md— "PM 不写文件、不写代码。 唯一例外:维护者逐 PR明示授权的
.claude/内部工具 PR".Proposal.
DELETEthe "the PM's own tooling PRs" clause.Delta. −25. Gate. ① Yes — it removes an apparent licence to author PRs. ② Yes. ③ N/A.
Confidence HIGH. Human floor no.
PMD-G-02 · CONSISTENCY (measured negative) · whole file
Evidence. Retired-spelling sweep run per the rubric (
silently|ignored|dropped|legacy| deprecat|\bM9\b|v5\.0|\bOLD\b|\bNEW\b|17\.[0-9]|project): no residue. All 14 "silently"/"ignored"/"dropped" hits are ordinary prose about behaviour (105, 450, 479, 592, 974, 1008 …);
line 754's "NEW, UNASSIGNED issues" is English emphasis, not the retired CEL
NEWtoken; theonly version reference is current-major and internally consistent — 979: "pinned at 17.2.0;
unpin when
UPSTREAM#Nships in >= 17.3". Noproject-as-workspace usage.Proposal. none. Delta. 0. Confidence HIGH. Human floor no.
PMD-H-01 · EVALS · package has no
evals/Evidence.
ls -d skills/*/evalsreturns 8 directories (ai, api, automation, data, i18n,platform, query, ui). Both
processskills — this one andobjectstack-upgrade— have none.This is the second-largest published package (14,549 tok, 7.7 % of the bundle) with zero
graded rubric, while
objectstack-data(13,892) ships one andobjectstack-query(5,443) shipsa 558-token one. Its decisions are unusually gradeable: escalate vs decide under the veto window
(565-595); batch independence (307-319); ACCEPT vs REWORK against GitHub rather than against the
report (529-548); and — the one this audit shows matters most — whether a given rule applies to
a project with no seats, lanes or lock wrapper.
Proposal.
ADD evals/README.md(~300 tok). It is a new file, so it takes a new ceilingrather than being paid by deletion inside
SKILL.md; that needs a maintainer ruling quoted inthe PR.
Delta. +300 (new file). Gate. ① Yes — evals are how the package's own drift gets caught.
② No. ③ Yes, a rubric is a construct. Confidence HIGH. Human floor YES (new ceiling).
PMD-I-01 · SIZE PROPORTIONALITY · whole package
Evidence. 14,549 tokens for a package that teaches no ObjectStack surface at all: 0
TypeScript fences, 0
os:checkmarkers, noreferences/_index.md, no Zod pointer. It costsmore than
objectstack-data(13,892) andobjectstack-platform(12,984), which teach theproduct, and 1.75× the other process skill (8,333). Against the five customer decision
points enumerated above that is ~2,900 tokens per decision. Measured customer-inert or
duplicated text totals ≈ 4,445 tokens (30.6 %) before the structural move; with the template
and upstream sections relocated (PMD-B-01, PMD-C-01) ≈ 7,350 tokens (50 %) leaves the
always-loaded entry file. The package sits at headroom 0 on its ceiling, so it currently
cannot absorb any of the three additions in PMD-F-01/02/03 without the deletions that pay them.
Proposal. Apply the deletions above; then re-ratchet.
Delta. −4,255 net across all findings (14,549 → ~10,294).
Gate. ① Yes. ② Yes. ③ Yes. Confidence HIGH. Human floor YES.
Incidental falsehoods (by-product, not the job)
IF-1 ·
SKILL.md:456-457— "Reports come back directly as each agent's final message — alossless channel … nothing can be lost between agent and reviewer." Contradicted inside
the same package 17 lines later at 474-475: "An agent that dies or returns malformed output
counts as
status: \"blocked\"with its raw output attached" — i.e. the channel is known to losewhole reports. Independently disproved by the internal oracle
(
.claude/agents/os-dev.md:355-357), which records a container restart killing three devsmid-final-message with the GitHub comment as the only surviving copy.
IF-2 ·
SKILL.md:1036-1039— "serialized heavy phases — which the developer-agenttemplate enforces with a container-wide verification lock, a heap cap, scoped builds and
worktree cleanup." The template does not enforce it; it explicitly delegates: "The MECHANISM
is the host project's (its wrapper, its lock path, its budget — put it in the conventions
file)" (771-772). For any project without a wrapper — every customer on day one — nothing is
enforced.
enforcesshould readrequires.Verdict
RESTRUCTURE. Pure-deletion reducible text measures 4,445 tokens = 30.6 %, at the
DIET/RESTRUCTURE boundary on its own; the structural half decides it. The package is one
monolithic 14,549-token file with zero progressive disclosure, zero evals, two blocks duplicated
inside itself (the report JSON, the sanitizer trap), a 2,376-token verbatim paste-block paid in
every session whether or not a dispatch happens, and an entire second job (upstream reporting)
that duplicates
objectstack-platformand mis-routes customers into a 14.5k-token load.The three highest-value additions, each with its payment
premise_still_valid(PMD-F-02, +60) ← paid by deleting"One semantics, N independent implementations" (PMD-E-02, −565). Net −505.
git stashban in the template (PMD-F-03, +40) ← paid by deleting the container-lockdesign properties (PMD-E-04, −250). Net −210.
← paid by deleting the duplicated report JSON (PMD-B-02, −115). Net −65.
Generated by Claude Code
os-litant commentedon Sep 2, 2026
os-dev-report
{ "issue": 14300, "status": "done", "branch": "claude/issue-14300-skills-pm-dispatch-optimization", "pr": "https://github.com/objectstack-ai/objectstack/pull/14444", "premise_still_valid": true, "summary": "skills/objectstack-pm-dispatch/SKILL.md shrunk from 14,549 to 11,567 tokens (net -2,982, lines 1,086 -> 879) in five commits keyed by finding id: PMD-C-01 (upstream reporting cut to a 245-token residue pointing at objectstack-platform's 'The App / Platform Boundary' by heading), E-05, E-02, E-03, D-01(+E-01), D-02, D-03, E-04, B-03, B-02, G-01, A-01 (description trigger dropped; skills/README.md and content/docs/ai/skills-reference.mdx regenerated by gen:skill-docs), the five drift syncs F-01..F-05 quoted from .claude/agents/os-dev.md and CLAUDE.md on origin/main 96b627d1, and the IF-2 'enforces' -> 'requires' correction. PMD-D-04 excluded by check:skill-frame-sync (both frame copies pinned; anchors now at :540 and :729), premise_false none, PMD-B-01 / H-01 deferred to #14296, the ~620-token gap against the card's ~-3,600 target itemised in the PR body, #14229's two pending deltas listed as a follow-up sync. Draft PR #14444 opened with first line 'Part of #14300', skip-changeset applied and read back twice (+4s and +2min: documentation, size/m, skip-changeset). REST channel was gated (403 on a repo-scoped read); card, comments and read-backs went through the zero-quota page payload, writes through MCP.", "tests": "head ea50dfb5 (== remote ref). Baseline on the untouched worktree, then after every commit: pnpm check:skill-frame-sync -> '4 copies of the decision frame are structurally isomorphic across 3 files; 4 axes: business-need -> long-term-soundness -> ai-authoring-safety -> startup-scope-discipline' (exit 0); pnpm check:skill-frame-freshness -> 'the decision frame in this tree is current with origin/main' (exit 0); node scripts/check-skills-token-ratchet.mjs -> 'skills/objectstack-pm-dispatch/SKILL.md is 11567 tokens (ceiling 14549; headroom 2982)' (exit 0); pnpm check:skill-identifier-liveness -> 'OK - Leg 1: 500 citation(s) ... (5 ledgered exemption(s)); Leg 2: 9 registered exhaustive section(s)' (exit 0, no Leg 2 heading bound to this file); pnpm check:skill-compatibility -> '11 SKILL.md file(s) reconciled against 78 workspace packages' (exit 0); pnpm --filter @objectstack/spec check:skill-docs -> 'Skill docs in sync' (exit 0); pnpm check:nul-bytes -> 'OK (scanned 7875 text file(s) ... no raw ASCII control bytes)' (exit 0). Re-derived union: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands from the tree at ea50dfb5 = 36 commands, every exit captured by redirect before any pipe: 33 green first pass; check:doc-formula-expressions and check:doc-security-posture green after building @objectstack/formula and @objectstack/lint (first pass exit 3 = PREREQUISITE NOT MET); check:skill-examples green after building types/client/client-react under the lock -> '259 prose examples type-check across 3 surface(s)' (first pass exit 1 = client-react dist unbuilt); node scripts/check-test-completeness.mjs NOT MEASURED locally by design (exit 3, needs a saved turbo test log; CI supplies it). node scripts/check-empty-changeset.mjs --base origin/main -> 'No empty-frontmatter changeset introduced by this diff'. Heavy steps under scripts/pm/os-verify-lock.sh (OS_VERIFY_LOCK_SLOT=issue-14300): spec build VERDICT command-exit 0 (waited 308s, held 206s); one earlier client-react closure build hit the 10-minute foreground cap (exit 143, lock held by issue-14304) and was re-run as a minimal types/client/client-react build (held 16s). Every edit asserted count-of-one on the exact source span and re-grepped after write (deleted anchors 0, inserted anchors 1). PR body read back from the rendered page: 44/44 sentinel fragments present, draft. Audit-record comment read back byte-identical to the local transliterated copy except one collapsed blank line before the footer. CI on #14444: in_progress at report time (not polled).", "mcp_calls": "5 - claim comment, audit-record comment, create_pull_request, issue_write (skip-changeset), this report comment; all reads went through git and the zero-quota issue/PR page payload", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
os-litant commentedon Sep 2, 2026
ACCEPT — skills-lane seat (session
session_01LraLgQVGq8egUwfYZpbYt1), reviewer of record, verified against GitHub not the report.main, first linePart of #14300(PMD-B-01 split and PMD-H-01 evals deferred to [Decision] Skills optimization program — batch 1 (4 items): new-file ceilings for splits · planned-eval stubs · react-blocks double rendering · published pm-dispatch scope #14296 items 1 + 4 / 2, so the card stays open;pm:dispatched→pm:blockedby hand at merge, deferred half re-dispatched on this card after the ruling). Whole-body closing-keyword scan clean; the "Part-of PR must not also close its card" check is green.skills/objectstack-pm-dispatch/SKILL.md14,549 → 11,567 tokens (−2,982, −20.5%; ceiling 14,549 untouched — re-lock is the program's single post-flight step);skills/README.md+content/docs/ai/skills-reference.mdxregenerated (frontmatter-derived). No new file, no deletion, no ratchet-script edit, no.claude/**edit, nocontent/docs/releases/.:540and:729;check:skill-frame-syncgreen ("4 copies … structurally isomorphic across 3 files") andcheck:skill-frame-freshnessgreen on every commit; PMD-D-04 recorded asexcluded_by_gate.skip-changeseton the PR — correct (nothing released by any package).ea50dfb5: all 38 check runs completed success or skipped by path filter — Lint & Repo Gates green at 07:25Z, Type Check ×4, Test Core 1–6, Build Docs, all PR guards. Local union 35/36 exit 0 withcheck-test-completenessNOT MEASURED — consistent with CI.claude-fable-5-1) — PASS. The five drift syncs match the oracle onorigin/main: F-01 report delivered twice, GitHub comment first with a literal plaintext first-line marker, never an HTML comment (.claude/agents/os-dev.md:17, :354); F-02premise_still_validand the no-PR report as a first-class delivery (:76, :432, :444); F-03 the stash ban with the shared-.gitmechanism and the wip-commit / patch-file spellings (:226-228, CLAUDE.md); F-04 theSession:line in the claim shape (CLAUDE.md's claim rule); F-05 the empty branch pushed before any edit, 403 = blocked. IF-2enforces→requirescorrect. PMD-C-01's 245-token residue points at objectstack-platform's "The App / Platform Boundary" by heading (present on PR skills(platform): optimization flight — orphan and pointer files removed, hooks reference linked directly, requires/engines/onEnable taught (net −3,608 tokens) #14351's head). The D-02 dead-agent rule (status query, host stop signal, or silence past a self-measured baseline) matches the internal collect rules. Disclosed deviation accepted: the published skill's owndev-reportmarker is a fixed literal (the internalos-dev-reportis this repo's instance).skills/**, and clause-① fable-mandatory) ⇒ terminal = human merge. Review requested from the two authorized approvers with the draft bit held; ⛔ not flipped ready, not enqueued.Generated by Claude Code
os-litant commentedon Sep 2, 2026
Round 1 MERGED — PR #14444 landed on
mainat 08:57Z (approved by os-zhuang). The card stays open for its second round.Session:
session_01LraLgQVGq8egUwfYZpbYt1Ruling landed. #14296 was ruled
1A 2A 3A 4Aat 09:27Z (comment 5507419465): item 1 authorizes the entry +rules/split under three conditions (the same PR nets ≥ 10% off the whole package; every new file's ceiling pinned at its landed count; a split is never a channel for added prose; the PR body quotes the ruling), and item 4 sets this package's target — stay in the catalog, ≈ 30% off to ≤ 10k tokens, the developer template externalized torules/dev-template.md, the four internal-contract drifts corrected (round 1 already synced the drifts it could reach inside one file).State:
pm:dispatched→pm:queue(notpm:blocked— the blocker is gone). Round 2 scope, for the next dispatch: the split PR per items 1 + 4 on a fresh branch frommain,skills/objectstack-pm-dispatch/**only,Part of #14300, governed ⇒ draft,needs:contract-reviewon both carriers (therules/extraction moves contract text), the two decision-frame copies gate-pinned to the internal file and never edited. Dispatched when a heavy slot frees (≤ 3 heavy in flight; #14315 / #14316 are in flight now).Generated by Claude Code
os-litant commentedon Sep 2, 2026
Round 2 gated —
pm:queue→pm:blocked,Blocked-by: #14568.Session:
session_01LraLgQVGq8egUwfYZpbYt1The ui split (#14298 round 2) measured that a byte-conserving split cannot net ≥ 10% off its package in the same PR once round 1 has taken the priced deletions; this package's split (template →
rules/dev-template.mdafter PR #14444 landed the diet) is the same shape. Decision batch 2 (#14568, one item) asks the maintainer whether #14296 item 1's condition (a) binds the PR arithmetically or is the anti-growth guard; the reading given there governs this round too. Re-queued the moment #14568 is ruled.Generated by Claude Code
os-litant commentedon Sep 2, 2026
Unblocked — #14568 ruled A (director seat, comment 5511939006, 15:22Z): condition (a) of the #14296 item-1 ruling is the programme-level anti-growth guard, and the ruling states it applies identically to this package's split. A split PR lands token-neutral or negative; the package arithmetic is the programme's (round 1, PR #14444, plus the split).
State
pm:blocked→pm:dispatchedin the same stroke (claim for round 2; assignee unchanged). Round 2 = the #14296 item-4 split ofskills/objectstack-pm-dispatch/SKILL.mdinto entry +rules/with the template inrules/, entry ≤ 10k tokens, plus this card's deferred items as recorded in the seat's ACCEPT on #14444. Dispatch brief follows on the dev's claim comment; branchclaude/issue-14300-pm-dispatch-split. Governedskills/**⇒ draft-only; atCONTRACT_REVIEW_TIER(the published PM skill is a fable-mandated surface); ⛔ never in one PR with.claude/skills/pm-dispatch/**.Session:
session_01LraLgQVGq8egUwfYZpbYt1Generated by Claude Code
os-litant commentedon Sep 2, 2026
Claim: dev seat, round 2 (
mode:subagent), dispatched on this card by the skills-lane seatSession:
session_01LraLgQVGq8egUwfYZpbYt1Branch:
claude/issue-14300-pm-dispatch-split(fromorigin/mainca48cf37; the empty branch was pushed first as the write-route probe: exit 0, new branch)Worktree:
objectstack-issue-14300-r2(baseca48cf37)File surface:
skills/objectstack-pm-dispatch/SKILL.md(entry, shrinks),skills/objectstack-pm-dispatch/rules/dev-template.md(new — the developer-agent template moved out of the entry),scripts/check-skills-token-ratchet.mjs(exactly two rows: the new file's row pinned at its landed count, the entry's row re-locked at its landed count). Assignee and card labels untouched. Read-only oracles:.claude/agents/os-dev.md,CLAUDE.md,.claude/skills/pm-dispatch/**;scripts/pm/check-skill-line-ratchet.mjsuntouched; no other package.Scope: the #14296 item 1 + item 4 split under the #14568 = A reading (PR lands token-neutral or negative on the package; programme arithmetic = round 1 −2,982 + this PR), both gate-pinned copies of the decision frame stay in the entry (
check:skill-frame-syncreads its copies by file path), the PMD-H-01 disposition with evidence, and the follow-up sync of #14229's two deltas quoted from the oracle onorigin/main. Governedskills/**⇒ draft PR only, never flipped ready; review requests are the seat's step.Generated by Claude Code
os-litant commentedon Sep 2, 2026
os-dev-report
{ "issue": 14300, "status": "done", "branch": "claude/issue-14300-pm-dispatch-split", "pr": "https://github.com/objectstack-ai/objectstack/pull/14660", "premise_still_valid": true, "summary": "Draft PR #14660 (first line 'Fixes #14300', head fef3b449, base ca48cf37, 2 commits, 3 files) lands the #14296 item-1/item-4 split under the #14568 = A reading: skills/objectstack-pm-dispatch/SKILL.md 11,567 -> 9,708 tokens (entry <= 10k met), the developer-agent template moved verbatim to skills/objectstack-pm-dispatch/rules/dev-template.md (1,838 tokens; one H1 and one {decision_frame} placeholder line added), both gate-pinned copies of the decision frame kept in the entry (anchors at :534 and :633; a moved published-dev copy would make check:skill-frame-sync FAIL on a 0-match start anchor, not pass vacuously), package 11,567 -> 11,546 (-21; split commit -11, sync commit -10), programme account round 1 -2,982 + this PR -21 = -3,003 / 14,549 = -20.6%. Ratchet rows: rules/dev-template.md added at 1,838, SKILL.md re-locked 14,549 -> 9,708, no other row touched, self-test 64/64. PMD-H-01 disposition: premise false, the package has never had an evals/ directory (git ls-tree on origin/main lists SKILL.md only; git grep for objectstack-pm-dispatch/evals empty; no evals ceiling row), so nothing to delete and no row to drop; the audit's +300 evals README proposal is foreclosed by #14296 item 2 = A. #14229's two deltas synced into the template from .claude/agents/os-dev.md on origin/main (rule 1 non-guarantee clause :85-88; ratchet funding discipline :323-327), +108 tokens funded by five verbatim in-package restatements plus one published-only rationale sentence, all itemised in the PR body. Labels on the PR read back as ['documentation','skip-changeset'] (whole-set write after a read showing none; nothing stripped). Assignee and card labels untouched; the 11:50Z comment's 'needs:contract-review on both carriers' was superseded by the dispatch brief (Clause-2: no, clause 1 in-seat), so none applied. Worktree removed without --force after the push (git status clean, HEAD == remote). CI on #14660: in_progress at report time, not polled. Deviation disclosed: the two commits carry the platform-mandated attribution trailer (Co-Authored-By + Claude-Session), which names a model; the dispatch's no-model-identifier clause was applied to the PR body and to this report.", "tests": "Baseline at ca48cf37 before any edit: check-skills-token-ratchet 'skills/objectstack-pm-dispatch/SKILL.md 11567 / 14549 (-2982)'; check:skill-frame-sync '35 markdown files scanned'; check:skill-identifier-liveness '41 published file(s)'. After each commit and at head fef3b449 (union re-derived from the tree at fef3b449 with no paths, 25 commands, every exit captured by redirect before any pipe): 23 exit 0 on the first pass — node scripts/check-skills-token-ratchet.mjs '✓ check-skills-token-ratchet: 32 authored bundle file(s) within their ceilings; 11 generator-owned file(s) measured, not ratcheted.' with rows 'SKILL.md 9708 / 9708 (+0)' and 'rules/dev-template.md 1838 / 1838 (+0)', --self-test '64 cases pass'; pnpm check:skill-frame-sync '✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files … 36 markdown files scanned for undeclared copies'; pnpm check:skill-frame-freshness '✓ … the decision frame in this tree is current with origin/main (fetched just now)'; pnpm check:skill-identifier-liveness 'OK — Leg 1: 465 citation(s) over 42 published file(s) … (3 ledgered exemption(s)); Leg 2: 8 registered exhaustive section(s), 0 ledgered gap(s)' (no Leg 2 binding on this file); pnpm check:skill-compatibility '✓ … 11 SKILL.md file(s) reconciled against 79 workspace packages'; pnpm --filter @objectstack/spec run check:skill-docs '✅ Skill docs in sync' (frontmatter untouched, no regeneration); pnpm check:role-word 'OK, no new occurrences' (0 in both files); pnpm check:corpus-claim-drift 'OK, no new claim sites'; pnpm check:doc-authoring, check:pm-governed-merges, check:pm-dispatch-gates ('1240 cases pass'), check:ratchet-remedy-authority, check:watch-hint-literal, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:cli-command-ids, check:bash32-floor, check:agent-test-spelling, check:cross-package-test-inputs (both spellings), check-ci-filter-parity, check-shard-attestation, bare-root-worklist --self-test: exit 0 each; pnpm check:nul-bytes 'OK (scanned 7996 text file(s) … no raw ASCII control bytes)'; node scripts/check-empty-changeset.mjs --base origin/main '✓ No empty-frontmatter changeset introduced by this diff'. pnpm --filter @objectstack/lint run check:doc-formula-expressions: first pass exit 3 'PREREQUISITE NOT MET — @objectstack/formula is not built', green after building the lint and formula closures under scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-14300-r2 ('VERDICT command-exit 0 · held the lock 130s · waited 406s'; the first lock attempt timed out 'VERDICT queue-timeout (exit 99) · never acquired · waited 540s', slot kept, resumed after lock-free gate work) — '✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 422 files / 1364 TS blocks judged clean'. NOT MEASURED: node scripts/check-test-completeness.mjs exit 3 'PREREQUISITE NOT MET — this gate grades a saved turbo run test log, and no log was named' (CI supplies it). Every edit asserted count-of-one on its exact source span before writing and re-grepped after (moved anchors 1 in the destination, 0 in the source; the one aborted sync run threw on its own assertion before any write, git status clean). The cross-file link ./rules/dev-template.md was verified by hand: no doc-link gate walks skills/**.", "mcp_calls": "11 — issue_read get_comments on #14300 (the page payload carried only the first 15 timeline items) and on #14296 (the ruling comment), pull_request_read on #14444 (the two-delta list) and twice on #14660 (body and labels read-back), issue_read get_labels on #14660 (failed: PR numbers do not resolve as issues), add_issue_comment ×2 (claim, this report), create_pull_request, issue_write (skip-changeset); card, audit record, round-1 report, #14568 and the oracle went through git and the zero-quota page payload", "open_questions": [ { "question": "The dispatch brief says no model identifiers in commits, while the platform's attribution requirement mandates the 'Co-Authored-By: Claude Fable 5.1' + Claude-Session trailer on every commit (round 1's commits carry the same trailer). Which governs the commit trailer?", "options": ["A keep the platform trailer on commits and keep model identifiers out of PR bodies and reports (what this PR does)", "B rewrite the two commits without the trailer — needs a force-push, which is forbidden, so it can only happen as new commits on a fresh branch"], "recommendation": "A, because the trailer is the platform's attribution contract and the PR body and report already carry no model identifier; B costs a branch rebuild for a trailer the repo's own history uses on every AI commit." } ], "out_of_scope_findings": [] }Generated by Claude Code
os-litant commentedon Sep 2, 2026
ACCEPT — round 2, PR #14660 @
fef3b449(Fixes #14300), with the in-seat skill-face review (clause ①) — PASSSession:
session_01LraLgQVGq8egUwfYZpbYt1(skills lane seat)Verified against GitHub and on the branch itself (fetched
claude/issue-14300-pm-dispatch-splitatfef3b449, diff against merge-baseca48cf37):main, 2 commits (the split, then the agents(os-dev): verify-lock non-guarantee clause + ratchet funding discipline in the dev contract #14229 sync — each droppable), 3 files, +148 / −133:skills/objectstack-pm-dispatch/SKILL.md, the newrules/dev-template.md,scripts/check-skills-token-ratchet.mjs. Labelsdocumentation,skip-changeset. CI onfef3b449: all 37 check runs completed — Lint & Repo Gates (17:56Z), Type Check ×4, Test Core 1–6, Governed Surface Queue Guard, both PR guards, Check Changeset, Check Documentation Links all success; the rest skipped by design.rules/dev-template.mdat 1,838 — no other row. Line multiset of the entry before vs entry + rules after: 732 → 734 non-blank, 25 lines new to the tree — the pointer paragraph, the fence lines, the H1, the{decision_frame}placeholder, the two agents(os-dev): verify-lock non-guarantee clause + ratchet funding discipline in the dev contract #14229 deltas and the re-flowed lines around them; 23 lines removed — the three restatements the split exposed and the six duplicate sentences that fund the sync, each named in the PR body.check-skill-frame-sync.mjsbinds bothpublished-pmandpublished-devcopies toskills/objectstack-pm-dispatch/SKILL.mdby file path (:131,:139); both copies stay in the entry (the frame heading at:539, the "When to STOP" block re-fenced under the template heading),rules/dev-template.mdcarries a{decision_frame}placeholder and no fingerprint; the gate reports "36 markdown files scanned for undeclared copies", green.CONTRACT_REVIEW_TIER; served modelclaude-fable-5-1= the constant onmain) — PASS. The two agents(os-dev): verify-lock non-guarantee clause + ratchet funding discipline in the dev contract #14229 deltas match the oracle verbatim in substance: the verify-lock non-guarantee ("it excludes only work routed through it — gate runs, installs and dev servers are not — so wall-clock readings taken under a hold are shared-box readings") =.claude/agents/os-dev.md:85-88; the ratchet funding discipline ("paid only by deleting content: a re-wrap is not payment … a ceiling is raised only by the maintainer — nothing left to delete ⇒ report blocked") =os-dev.md:323-327, rendered without this repo's dates and quoted rulings per the route-B convention. The six funding deletions are restatements whose rule survives elsewhere in the template (the binding-file paragraph, the STOP rule in the frame block, rule 4, the report block). The three internal-only hunks of agents(os-dev): verify-lock non-guarantee clause + ratchet funding discipline in the dev contract #14229 have no published counterpart — correctly not synced.Clause-②: no— nothing to strip.git ls-treeonorigin/mainlists onlySKILL.mdfor this package, noevals/row exists in the ratchet, and item 2 = A forecloses adding one. Nothing to delete, nothing to drop.All three deferrals the seat's ACCEPT on #14444 recorded (the split, PMD-H-01, the #14229 sync) are closed by this PR ⇒
Fixes #14300is the right landing form; this card closes on merge and the seat stripspm:dispatchedthen. TheCo-Authored-Bytrailer question is answered on #13680 (harness attribution, accepted). Follow-up already on the ledger: the role-word baseline class (#14659) — this package carries zero occurrences, so it was not hit here.Governed surface (
skills/**, fable-mandated): the PR stays draft; review requested from os-zhuang and hotlong; landing is the maintainer's. #12911 (pm-dispatch construct-removal) dispatches on the split tree after this merges.Generated by Claude Code