Skip to content

check-half-states: read the landed release rule — H1/H24 prose says the definitional readings, and a new report-only row catches a Release: newer than the last Claim: with the assignee still set (and the exit that left no record) #15884

Closed

Description

@claude

Filed by the domain:skills seat (session session_019RfFHiRCSs3JXLK4cwcfox, os-steve) as the follow-up the seat named on PR #15848's verdict. Self-triaged priority:p3, pm:queue, pure code (scripts/pm/check-half-states.mjs).

What landed (PR #15848, merged 2026-09-05T11:52Z)

.claude/skills/pm-dispatch/SKILL.md now states, as rules: pm:queue 卡恒无 assignee,有即半态 (line 107); pm:dispatched 恒带 assignee (line 109); 释放是显式动作:让卡离手者同笔清 assignee + Release: 行(会话/因/去向);下一任重新认领 (line 465); the dead-claim reclamation routes through 释放回队 with the Release: line carrying the reason (line 493). references/state-machine.md carries the releaser line beside the applier and remover.

What is stale in the sweep

  • H1 (h1DispatchedNoAssignee) — the header inventory (line 88) still explains the row as "dispatch marks a claim; a claim is …" rather than as the definitional reading the rule now gives it (pm:dispatched always carries an assignee).
  • H24 (h24QueuedWithAssignee, sentence at ~4425–4440) still narrates the measured origin ("a state ROLLBACK that swapped the label and left the field … only dead-claim reclamation ever said 「同笔摘 assignee」") — the rule now says every exit from ownership clears the assignee in the same stroke and leaves a Release: line; the sentence should name that rule and its remedy (post the Release: line and clear the field, or re-claim), not the history.
  • No row reads the new record: a Release: line newer than the last Claim: on a card whose assignee is still set is a half-done release (the comment was written, the field was not cleared); the inverse — a pm:queue card with no assignee and no Release: after its last Claim: — is an exit that left no record. Both are report-only patrol input in the H1/H24 family.

What this card does

  1. H1 and H24 prose aligned to the landed rule (quote the SKILL.md lines, never paraphrase them into new Chinese); predicates unchanged.
  2. One new report-only row over the population H1/H24 already read (no new fetch class: Claim: and Release: lines come from the comment threads H2 already reads; the row is judged only where those comments are already fetched, and says UNJUDGED where they are not): a Release: newer than the last Claim: with the assignee still set → finding; a pm:queue card whose thread has a Claim: and no later Release: and no assignee → finding, stated as the lower bound it is. Declared in the registry as H plus digits, band state, with self-test cases in both directions and an ablation.
  3. Self-test count does not drop; SUMMARY_CLAUSE_ANCHORS gains the row's clause; SWEEP_COUNT_KEYS gains any new counter.

Serial

scripts/pm/check-half-states.mjs is in no flight and no open PR (PR #15795 and #15755 landed). Pure code ⇒ in-seat review, then ready + auto-merge by the seat.

Dedup

REST enumeration 2026-09-05T10:3xZ (1,200 items, 797 issues, positive controls hit) found no card on a release act or the assignee's exit; #15846 (closed by PR #15848) is the rule half, and its body names this sweep half as the follow-up.


Generated by Claude Code

Activity

  1. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    pm:queueReady for the PM dispatch loop
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 5, 2026
  2. claude commented on Sep 5, 2026

    @claude
    ContributorAuthor

    Claim: PM loop round 7 — filed and taken at first touch by the seat as the sweep half of the release rule PR #15848 landed (p3, pure code): H1/H24 prose aligned to the landed readings, one new report-only row over the population those rows already read
    Session: session_019RfFHiRCSs3JXLK4cwcfox
    Branch: claude/issue-15884-half-states-read-the-release-rule
    Worktree: objectstack-issue-15884
    Domain: domain:skills
    File surface: scripts/pm/check-half-states.mjs only — the H1 header-inventory sentence and the H24 finding sentence quote the landed SKILL.md lines (107, 109, 465, 493) instead of narrating the measured origin; one new registry row (id H plus digits, band state) over the comment threads H2 already fetches: a Release: line newer than the last Claim: while the assignee is still set, and a pm:queue card with a Claim:, no later Release: and no assignee — both report-only, UNJUDGED where the thread was not fetched; self-test cases both directions, ablation, SUMMARY_CLAUSE_ANCHORS and SWEEP_COUNT_KEYS updated; no new fetch class; predicates of H1/H24 unchanged.
    Container & model: S, mode:subagent, model: opus (dispatch-gates.mjs --tier on the path: no path-derived mandate; clause ② not engaged — a report-only patrol row, no accept/reject verdict moves)
    Clause-②: no
    Serial constraints cleared: the file is in no flight and no open PR (PR #15755 and #15795 landed; scan 12:2xZ); SKILL.md is untouched by this card. Pure code (check-governed-merges --test exit 0 for scripts/pm/**) ⇒ in-seat review, then ready + auto-merge by the seat; skip-changeset. The PR carries Fixes #15884.

    Decision re-read (12:2xZ): the rule this row reads is on main since 11:52Z (PR #15848, the maintainer's R3); the row adds no rule and reads only records the protocol already prescribes — no ruling owed.


    Generated by Claude Code

  3. claude commented on Sep 5, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 15884,
      "status": "done",
      "branch": "claude/issue-15884-half-states-read-the-release-rule",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/15901",
      "premise_still_valid": true,
      "summary": "One file, scripts/pm/check-half-states.mjs, at f845bc5d16. H1's header-inventory sentence now reads the state model's definition of the label (SKILL.md line 109) and the release act that is the only lawful way to empty the field (line 465), instead of narrating 'dispatch marks a claim'. H24's finding sentence opens on 「pm:queue 卡恒无 assignee,有即半态」, keeps both contradicting readers and the human/agent asymmetry, drops the state-ROLLBACK history and the 'only dead-claim reclamation ever said' clause, and states the remedy as the release act itself, quoting line 465 unbroken and naming both lawful exits (finish the release, or re-claim). New report-only row H47, band state, over the comment threads the sweep already holds: leg (a) a Release: line newer than the last Claim: while the assignee is still set; leg (b) an open pm:queue card with no assignee whose Claim: no later Release: answers, stated as the lower bound it is. RELEASE_COMMENT_MARKER mirrors CLAIM_COMMENT_MARKER's strictness and is no wider; CLAIM_COMMENT_MARKER is untouched and unmoved. The predicates of h1DispatchedNoAssignee and h24QueuedWithAssignee are unchanged, and the diff adds no REST path: the row calls commentCache.get only, so a card whose thread no other row bought is UNJUDGED rather than clean, and the releaseCandidates/releaseJudged pair plus the summary clause disclose the gap. The push sits at the foot of the per-card loop rather than at its head beside H1/H24, because at the head the cache is empty for that card on every iteration and the row would report UNJUDGED forever while looking healthy. Ordering is created_at with a thread-order fallback (governingClaim's and latestSeatMarker's existing resolution) rather than comment id, since ids are monotonic in practice but documented as an ordering nowhere, and equal stamps are exactly what a hurried release produces. PR body carries a duplicated attribution footer: the platform appended its own after mine, nothing was eaten, and it was left rather than PATCHed so the draft bit is never re-sent.",
      "tests": "SELF-TEST: 2341 cases pass (node scripts/pm/check-half-states.mjs --self-test, verdict line '✓ check-half-states self-test: 2341 cases pass.'), up from 2267 on main. No case dropped: comm over the two runs' case-name lists differs by exactly one entry, 'H24: …and names the paired write it is owed', whose assertion is preserved and re-pointed at the landed spelling 同笔清 assignee, with three companions added beside it. ABLATION (this script has no build step and no dist — it is a plain .mjs run directly, so there is no rebuild leg; the mutation was confirmed ON DISK instead): a throwaway copy placed in scripts/pm/ so every sibling resolves, proved byte-identical to HEAD:scripts/pm/check-half-states.mjs by blob hash before each leg, control green at 2341/2341. Leg A, h47ReleaseRecordDesync always declines (injected-text grep count 1, blob moved to 9e01cc2adf) -> 19 of 19 firing-direction H47 cases red, clean-direction cases stay green. Leg B, the findings.push removed (deleted-text grep count 0, injected 1) -> 2 red: the H47 registry-coverage case and the file's own standing invariant 'no band names a family the sweep never emits'. Leg C, the summary clause removed (deleted render line 0, injected 1, anchor row still 1) -> 9 red: 4 generic summaryClause invariants plus 5 H47 summary cases. Every restore proved by blob hash back to e98159bf32; the tree file's blob was e98159bf32 before and after, and git diff HEAD over it is empty. LIVE SWEEPS, read-only, before = origin/main's blob (extracted and hash-checked against origin/main:scripts/pm/check-half-states.mjs) and after = HEAD: objectstack 307 findings before / 305 after, objectui 163 / 167 — and H47 emitted ZERO rows on both boards, which is the expected reading: no card carries a Release: line yet (the rule landed 11:52Z), so leg (a) has no carrier by construction and leg (b) fires only where a thread was already fetched. Coverage disclosed as 85 of 272 candidate cards on objectstack and 28 of 235 on objectui. The before/after totals are eight minutes apart on live boards worked by parallel seats, so the deltas are drift, not this change: per-family counts show H24 identical in both pairs (1 objectstack, 4 objectui) and H47 contributing nothing to either side. GATES: derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on the final one-path file list; all 32 commands run and --ran reconciles, '✓ dispatch-gates --ran: 32 derived famil(ies) accounted for — 32 run, 0 NOT-MEASURED.' Seven of them first answered PREREQUISITE NOT MET exit 3 because the fresh worktree had no node_modules; after pnpm install all 32 are exit 0. The eight artifact-roster gates whose roster sits under scripts/ were run rather than read as silent: green except check:dts-closure and check:published-readme-exports, which answer PREREQUISITE NOT MET without a closure build and are NOT MEASURED here rather than passed. Whole-repo pnpm lint (eslint . --no-inline-config) exit 0 through bash scripts/pm/os-verify-lock.sh on slot issue-15884, VERDICT line 'command-exit 0 · held the lock 79s'. check-governed-merges --test on the final file list: 'NOT governed — ordinary queue landing applies'. Every exit code captured by redirecting first, never through a pipe. CI ON THE HEAD f845bc5d16: all 35 check runs completed — 24 success, 11 skipped, 0 failure — including Lint & Repo Gates, Live half-state sweep, Test Core 1..6, all four Type Check jobs, Check Changeset, Governed Surface Queue Guard.",
      "mcp_calls": "0 — no MCP GitHub call was made in this run: the card and its thread came from the public-repo single-issue payload channel, and every write (issue create, PR create, label add, read-backs, check-run polling) went through repo-scoped REST with curl after a 200 probe.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #15899: H8's remedy sentence (~line 1724), H19's release text (~3435) and the H24 header-inventory paragraph (~488) present 「同笔摘 assignee」 in quote brackets — the register this file uses for a verbatim SKILL.md quotation — but that phrasing is in no SKILL.md and never has been (git grep outside this script: zero hits; git log -S over SKILL.md on a non-shallow clone: empty). It prescribes only the first half of the landed release act, which is the exact shape the new H47 row exists to report, and four self-test cases pin it. Not addressed in this PR: the card's ruling scoped the diff to the H1 header sentence, the H24 finding sentence and the new row. No label and no assignee, left for triage."
      ]
    }

    Generated by Claude Code

  4. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:skillsDomain lane — seat card indexed by label:pm:seatpriority:p3toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions