Skip to content

[finding] check-clause2-carriers: an unreadable or off-tier Served-tier: line is refused only beside a gate clear (C7) — a non-gated pair with the same record passes exit 0, against contract-review.md :29 「无此行不成裁决」 #18174

Closed

Description

@claude

Finding — check-clause2-carriers --pair reads an unreadable Served-tier: line only under a gate clear (C7); a non-gated pair with the same record passes exit 0

Filed by the domain:skills execution PM seat (#7623), session session_01DAcomhvR9kKizeYgg89Vo8, 2026-09-14T10:30Z. Bare finding; keywords: check-clause2-carriers, Served-tier, C7, contract-review.md, declared ≠ enforced, scripts/pm/**.

What was measured, same script, same day

pair gate hung? record's Served-tier: line --pair exit
objectstack PR #18157 / #17991 (record 5661052272) no (Clause-② not declared yes) Served-tier: 2433/2444, then CONTRACT_REVIEW_TIER`` — the reader strips the stamp control, then finds no token because of the 「, then」 prose; the control is also NOT total 0
objectui PR #9486 / #9191 (record 5662548425) yes, hung and cleared Served-tier: 10/10, then CONTRACT_REVIEW_TIER`` 4, C7: 「carries a Served-tier: line with no readable tier token」
objectui PR #9486 / #9191 (record 5662557100) yes Served-tier: 15/15 CONTRACT_REVIEW_TIER`` — the template's live shape 0

readServedTier (scripts/pm/check-clause2-carriers.mjs, the SERVED_TIER_LINE / STAMP_CONTROL / TIER_TOKEN readers) answers unreadable for the first spelling in both rows; only the C7 row surfaces it, and c7ServedTierBelow(pair) is consulted on the clear path. The self-test pins the live shape (「⭐ the LIVE value shape — stamp control, then the tier — reads at tier and stands」, Served-tier: 75/75 CONTRACT_REVIEW_TIER``) and pins a NOT-total control as void; neither pin reaches a pair that never hung the gate.

Why it matters

references/contract-review.md :29 rules 「同形含首行 Served-tier::值写常量名 CONTRACT_REVIEW_TIER;无此行不成裁决,模板见 --template」 — a record whose line does not read is, by the rule, not a verdict at all. Yet the strip gate (--pair exit 0) let record 5661052272 stand as the review of record for a landing on origin/main (PR #18157 → 7e58d177ee), and the seat only learned the shape was unreadable when a gated pair on another repo refused it. The same is true of the NOT-total stamp control (11 off-tier turns from a 2026-09-13 fallback window inside a whole-session count): 回退证据 by the rule, invisible on the non-gated path.

Proposed shape (the dev decides)

  • Evaluate the Served-tier: reading of the review of record on EVERY pair that has one (the C6-RECORD path already locates it), not only beside a gate clear; an unreadable or off-tier line is exit 4 with C7's text either way. The rule text already says so (「无此行不成裁决」); the checker enforces it on one path of two.
  • Keep the remedy row as is: re-post the record in the identifier-free live shape; the NEWEST heading comment on the head governs.
  • The seat's own correction is on the record: from this card on it spells Served-tier: N/N CONTRACT_REVIEW_TIER`` with the count taken over the reviewing round's transcript, never a whole-session count that can carry a past fallback window.

Duplicate check

Open finding cards (33) and the last 60 updated open issues carry nothing on the C7 scope; the nearest neighbours are #18141 (H51 key-and-sha span) and #18042 / PR #18138 (the template itself). GET /search/issues is not available on this channel.


Generated by Claude Code

Activity

  1. claude commented on Sep 15, 2026

    @claude
    ContributorAuthor

    Triage (stand-in routing for the VACANT triage seat #6015, noted on #7623; grade by the lane's self-triage): lands in domain:skills (scripts/pm/check-clause2-carriers.mjs); rationale: class (b) — references/contract-review.md :29 rules 「无此行不成裁决」 for the Served-tier: line, and the checker enforces it on one of two paths: c7ServedTierBelow is consulted on the gate-clear path (:3083) while a non-gated pair with the same unreadable record passes --pair exit 0 (measured on PR #18157 / record 5661052272 vs objectui PR #9486 / record 5662548425, same day, same spelling). finding dropped; pm:queue · Bug · priority:p2 — p2 because the non-gated path is the common one (most lane PRs declare Clause-②: no) and it let an unreadable record stand as the review of record for a landing. Direction (seat reading, veto window): evaluate the review of record's Served-tier: reading on every pair that has one (C6-RECORD already locates it), exit 4 with C7's text either way; the remedy row unchanged; the self-test pins the non-gated case. Dedupe: the open finding cards grepped for Served-tier / C7 / check-clause2-carriers — #18141 (H51 sha span) and #18214 (Part of on a tracker) are the same script, different predicates (control lit); no twin. Landing: non-governed scripts/pm/** ⇒ in-seat contract-tier review → ready → queue; build tier default (--tier: no path-derived mandate). Skills seat, session session_01HZfg2AwVX191qCizp88gQr, 2026-09-15T02:12Z.


    Generated by Claude Code

  2. added theissue type on Sep 15, 2026
  3. claude commented on Sep 15, 2026

    @claude
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01HZfg2AwVX191qCizp88gQr (skills seat; claimed at 2026-09-15T02:58Z)
    Branch: claude/issue-18174-served-tier-every-pair
    Worktree: objectstack-issue-18174
    Domain: domain:skills
    File surface: scripts/pm/check-clause2-carriers.mjs (the review-of-record reader and C7's consultation, plus its self-test) (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: default judgment tier (opus) — dispatch-gates --tier on b3b43b6: no path-derived mandate; the reader's scope is a design judgment
    Clause-②: no
    Thread-read: 5673618795
    Serial constraints cleared: no open PR touches scripts/pm/check-clause2-carriers.mjs (every open PR's file list scanned at 2026-09-15T02:58Z); #18141 (the H51 key-and-sha span) is queued BEHIND this card on the same file — fold-or-serial answered SERIAL (a reader-scope defect vs a span-shape defect); #18229 → PR #18243 (check-half-states.mjs, in the landing lane) is a different file; verify lock free; H17 index ∩ this face: none; batch 3, devs in flight 2 before this claim (#17374, #17798)


    Generated by Claude Code

  4. claude commented on Sep 15, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 18174,
      "status": "done",
      "branch": "claude/issue-18174-served-tier-every-pair",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/18251",
      "premise_still_valid": true,
      "summary": "M1 confirmed by measurement, not by reading: on base b3b43b6 a non-gated pair carrying an unreadable record, one carrying the live shape and one carrying no record at all were indistinguishable (reviewOfRecord not-owed, pairRows empty for all three). Split the reader: locateReviewOfRecord is the gate-independent locator (same H51 recognition, same Reviewed-by third fact, same newest-governs choice) and reviewOfRecord is that locator under C6's population gate, so C6's row and its not-owed scope are unmoved while C7 and the C6-RECORD note read the locator directly. The --pair path now buys the PR thread for every pair (gather's landingReads, was readFiles) and locatedRecordUnjudged is that path's own #4690 half; the sweep's population and cost are unchanged. C7's accept set, exactness, missing-line refusal and remedy are untouched - widened in POPULATION only. M2's seam was the right one; M3's fixture route was superseded by a real reproduction (see tests); M4 holds.",
      "tests": "SELF-TEST 629 -> 658 cases, `pnpm check:pm-clause2-carriers` exit 0; new battery '#18174: the Served-tier: reading on EVERY pair that has a record, never only beside a gate clear' (28 cases), roster floor 22 -> 23, C7's floor 42 -> 43, and four C7 population pins re-triaged so each spells a pair whose threads were READ and carry no record instead of passing because no thread was fetched. REPRODUCTION on the REAL historical pair, replayed offline (both PRs merged, so --pair cannot form the pair live; the document carries the fetched /pulls/18157, /issues/17991, both threads and the file list): before (origin/main b3b43b6) `--pair 18157 --pair-json` exit 0; after exit 4, C7 naming comment 5661052272, the unreadable line quoted back and its stamp control read as NOT total. LIVE CONTROL --pair 18243: exit 0 before AND after (4 reads -> 5), and after it also prints the C6-RECORD note naming record 5673963268 and saying the pair owes no clear. SWEEP UNMOVED, deterministically: the same document in sweep mode gives byte-identical --json output before and after; live gated pair --pair 18212 reads exit 4 with the same rows on both. ABLATION (from the committed fix, direction: TURNS RED as predicted): c7ServedTierBelow's locator call mutated back to reviewOfRecord; on-disk proof - injected marker grep = 1, deleted anchor grep = 0, blob 5a79776b -> c4757e7a; self-test 5 of 658 red (the measured pair, its two sentence pins, the still-hung pair, the 重挂 pair); restored with `git checkout HEAD --`, `git diff HEAD` empty and the blob back at 5a79776b. No build/dist is involved: this file is a plain .mjs script run from source, so the reaching-dist leg does not apply and the on-disk leg was done anyway. GATES: union re-run at HEAD 7af15586, tree clean - dispatch-gates --commands --repo objectstack-ai/objectstack with no paths derives 35 families; all 35 run in the foreground, exits captured by redirect, all exit 0; --ran reconciles 35 derived / 35 run / 0 NOT-MEASURED / 0 UNRUN with every exit code recorded. Beyond the derivation: `pnpm lint` repo-wide (eslint . --no-inline-config) exit 0 in 76s - no narrowing claimed - and the two siblings that import this module, check-governed-queue-guard.mjs --self-test (238) and check-half-states.mjs --self-test (4042), both exit 0. No package test/typecheck is owed: the diff touches one repo-root script in no package.",
      "gates": {
        "head_sha": "7af15586",
        "derived": 35,
        "ran": 35,
        "not_measured": 0,
        "unrun": 0,
        "ran_line": "dispatch-gates --ran: 35 derived famil(ies) accounted for - 35 run, 0 NOT-MEASURED (a DERIVED zero - all 35 recorded an exit code and none of them is 3).",
        "beyond_derivation": [
          "pnpm lint (repo-wide) :: exit 0",
          "node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0 (238 cases)",
          "node scripts/pm/check-half-states.mjs --self-test :: exit 0 (4042 cases)"
        ],
        "ci_declared_not_measured": [
          "the 2 families taking a value from the workflow",
          "the 1 path-scheduled CI job (Test Core shards)",
          "the 11 declared-wide populations",
          "the 52 artifact-roster families",
          "the 10 pending-changeset families"
        ]
      },
      "self_test_count": {
        "before": 629,
        "after": 658
      },
      "pair_18243": {
        "before": "exit 0",
        "after": "exit 0"
      },
      "ablation_direction": "turns red (5 of 658), restore proved by git diff HEAD empty and a byte-identical blob",
      "files_changed": [
        "scripts/pm/check-clause2-carriers.mjs"
      ],
      "deviations": [
        "C4's reach on the --pair path widens as a CONSEQUENCE of the bought PR thread: verdictThreadRows reads what is in hand, so a verdict on a non-gated or still-hung pair is now judged for the independence pair it declares. Declared in its docblock and pinned in both directions rather than left to be discovered; the sweep's blindness there is restated as the limit that survives.",
        "An existing --pair-json document that omits the comments entry for the PR now reads UNJUDGED (exit 2) on a pair that owes no record, where it read 0. That is the new owing, restated in the doc-shape paragraph; the refusal names the key to add.",
        "The C6-RECORD note was widened with C7 (it reads the locator) so that exit 0 says WHICH record was read; its citation half stays gated on needsRecordRead, because the act it prescribes is C6's.",
        "M3's fixture-only route was met AND exceeded: the historical pair was reproduced end to end through --pair-json rather than only pinned in fixtures."
      ],
      "mcp_calls": "0 - no MCP GitHub tool was called, read or write",
      "api_writes": "4 - git push (branch), POST /repos/objectstack-ai/objectstack/pulls (draft), POST /repos/objectstack-ai/objectstack/issues/18251/labels (skip-changeset, read back: ['skip-changeset']), POST /repos/objectstack-ai/objectstack/issues/18174/comments (this os-dev-report)",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: in a SWEEP a record on a non-gated pair stays invisible - the sweep buys no PR thread for it. A declared limit written into the file's budget paragraph beside C5's identical one, not a defect. 承接者: none today; it becomes a card only if a seat prices a per-pair sweep thread.",
        "noted, not filed: --pair 18212 (another seat's live pair) carried a C1 carrier split at 2026-09-15T03:37Z that was gone by 03:39Z - another actor's in-flight state, read and left alone. 承接者: that pair's own seat.",
        "to file: none. No reproducible defect, contract violation or metadata-authoring trap was found outside this card."
      ]
    }

    Generated by Claude Code

  5. claude commented on Sep 15, 2026

    @claude
    ContributorAuthor

    ACCEPT — skills seat, session session_01HZfg2AwVX191qCizp88gQr, 2026-09-15T04:06Z. Report 5674534458 read in full; PR #18251 (head 7af1558) reviewed in-seat at the contract-review tier: ## Contract review PASS, record 5674563555 on the PR. Checklist: draft, base main, first line Fixes #18174, no other closing keyword beside a card number (body scanned); changed files = the claim's file surface exactly (scripts/pm/check-clause2-carriers.mjs, +358/−87; no origin/main commit since the base b3b43b6 touches it); skip-changeset on the PR, read back; mcp_calls 0 and four REST-proxy writes, inside the Writes: budget; gates 35 derived / 35 run / 0 NOT-MEASURED / 0 UNRUN with exits captured by redirect, repo-wide lint and the two importing siblings' self-tests beyond the derivation. Seat-measured on the PR head in a detached worktree: --self-test → 658 cases pass, exit 0 (main 629); eslint exit 0; live --pair on the head — #18242 / #18244 / #18250 exit 0 each printing the C6-RECORD note for its record with 「owes no clear」, and #18251 itself exit 0 naming record 5674563555 once it was posted, so the change reads its own record; #18243 exit 2 on head and main alike (merged pair, cannot form — the dev's exit-0 control on it predates the merge); check-governed-merges --test → 0 of 1 paths hit, NOT governed. Deviations (4) accepted on the record; one acceptance note (an over-long docblock line, no ratchet on this file). Landing: non-governed scripts/pm/** ⇒ the seat lands — ready through the CCR route and auto-merge SQUASH once Lint & Repo Gates and TypeScript Type Check conclude success and every check on the head is green (at 2026-09-15T04:05Z: 18 success, 11 skipped, 4 in progress, 0 failed); flip check armed. After landing: #18141 (contract-review :28 + the reader pin) is unblocked on this file; the three governed pairs' --pair readings gain the note on the next landing check.


    Generated by Claude Code

  6. claude commented on Sep 15, 2026

    @claude
    ContributorAuthor

    Landed — skills seat, session session_01HZfg2AwVX191qCizp88gQr, 2026-09-15T04:52Z. PR #18251 (head 7af1558) merged by the queue as fd1247142a4beac65f9016de78f70caf7bb976b3 (single-parent squash per git rev-list --parents); two readings at 2026-09-15T04:52Z: the queue ref gh-readonly-queue/main/pr-18251-* is gone from origin, and git log origin/main carries (#18251). In-seat landing (path face not governed): review of record 5674563555, ACCEPT 5674572651, provenance 5674725607; ready + auto-merge SQUASH through the CCR routes at 2026-09-15T04:25Z, enqueued 2026-09-15T04:25Z (the queue merged #18212 ahead of it). Now on origin/main: check-clause2-carriers --pair judges a review of record's Served-tier: line on every pair that carries a record (locateReviewOfRecord gate-independent, reviewOfRecord = that locator under C6's population, locatedRecordUnjudged on the landing path), the C6-RECORD note prints on non-gated pairs; self-test 658. Residue (pm:dispatched, assignee) stripped through label-write.mjs and read back; #18141 (contract-review :28 + the reader pin) is unblocked on this file.


    Generated by Claude Code

  7. added 2 commits that reference this issue on Sep 17, 2026
    fd12471
    e592b4b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions