Skip to content

check-ratchet-remedy-authority: widen the walk to scripts/pm/** — measure the roster first, then bring every hit under the #8435 convention and flip the self-test that pins the non-recursive walk (#14978 item 3, ruled A) #15179

Closed

Description

@claude

Filed by the domain:skills seat (session session_019RfFHiRCSs3JXLK4cwcfox, os-steve) to carry item 3 of decision card #14978, ruled A, measurement first by the maintainer on 2026-09-04 (decision batch #27, verbatim 「同意」; director record #14978 (comment)). Pure code, this lane's; not a governed surface.

What the ruling says

check-ratchet-remedy-authority (the #8435 detector) walks scripts/ NON-RECURSIVELY (corpusFiles(), a readdirSync admitted by extension — check-ratchet-remedy-authority.mjs:43 and :242), so the 14 gates under scripts/pm/*.mjs — including the per-file line ratchet the 2026-09-03 cross-file-move exception amends — have never been in its sweep; a self-test assertion (PR #14860) pins the non-recursive walk so that a wider walk reds there and makes the widening a decision someone takes.

  • Step 1 — measure: in a throwaway worktree, widen the walk to scripts/pm/** and produce the roster of hits (every scripts/pm/*.mjs whose author-facing text offers a registry-growing remedy without the ⛔ MAINTAINER-ONLY token or an outright refusal), with the verdict class each lands in.
  • Step 2 — one PR: add scripts/pm/ to the scan and bring every hit under the convention (mark the expanding remedy ⛔ MAINTAINER-ONLY, or refuse it outright — never push a refusing gate onto the marking shape); update the self-test that reds on a widened scan in the same PR so the widening is the explicit decision it was built to force; the roster and each hit's disposition in the PR body. If the roster is empty, the PR is the one-line scan widening plus the self-test flip.
  • ⛔ Not C (recursive scripts/**, an unmeasured area). Surface: scripts/check-ratchet-remedy-authority.mjs plus the hit scripts/pm/*.mjs files only.

Refs

#14978 (item 3, ruled A) · #8435 (the convention) · PR #14860 (the self-test pin) · #14685 item 5 / PR #14860 (the cross-file-move exception the gate documents).


Generated by Claude Code

Activity

  1. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    Claim: PM loop round 5 — ruled work (#14978 item 3 → A, measurement first)
    Session: session_019RfFHiRCSs3JXLK4cwcfox
    Branch: claude/issue-15179-remedy-authority-scripts-pm
    Worktree: objectstack-issue-15179
    Domain: domain:skills
    File surface: scripts/check-ratchet-remedy-authority.mjs (the corpus walk widened to scripts/pm/, the self-test pin flipped) plus the scripts/pm/*.mjs files the widened walk reports as hits, each brought under the #8435 convention (stop on breach; explain in the report). ⛔ Not recursive scripts/**; ⛔ no verdict class added; ⛔ a refusing gate is never pushed onto the marking shape.
    Container & model: S, mode:subagent, model: opus (tier: scripts/check-*.mjs — no path-derived mandate, default opus; the hits' remedies are judgment calls the convention prices by name)
    Clause-②: no
    Serial constraints cleared: scripts/check-ratchet-remedy-authority.mjs free (PR #14860 landed); scripts/pm/dispatch-gates.mjs and bare-root-worklist.mjs have PRs #15165 / #15164 in the queue at claim time — the dev works from the tree after they land (git fetch origin main before the worktree add; if either is still queued, the hit files are read from their PR heads and the flight merges main before pushing); #14899 (scheduled-only families, dispatch-gates.mjs) is dispatched after PR #15165 lands and may touch that file in parallel — this flight's edit to it, if any, is the remedy text only; the second to land merges main first. Not governed (scripts/**, no .md) ⇒ draft PR, in-seat contract-tier review, ready + auto-merge by the seat.

    Decision re-read (05:02Z): maintainer ruling 3A on #14978 (director record 5535783628): Step 1 measure the roster in a throwaway worktree; Step 2 one PR — add scripts/pm/ to the scan, bring every hit under the convention (mark ⛔ MAINTAINER-ONLY or refuse), update PR #14860's self-test that reds on a widened scan in the same PR; if the roster is empty the PR is the one-line widening plus the self-test flip.


    Generated by Claude Code

  2. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 15179,
      "status": "done",
      "branch": "claude/issue-15179-remedy-authority-scripts-pm",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/15199",
      "premise_still_valid": true,
      "summary": "Step 1 measured the roster in a throwaway detached worktree at origin/main efb35131 with corpusFiles() widened to scripts/pm/*.mjs and nothing else changed: scripts/pm has NO subdirectories (so one level and the ruling's scripts/pm/** name the same 14 .mjs files), 13 of the 14 classify `excluded`, and exactly one — dispatch-gates.mjs — classified `unmarked`. Both in-flight PRs were also measured at their heads (#15165 dispatch-gates, #15164 bare-root-worklist): identical verdicts; both have since landed and origin/main is merged into the branch. Step 2 landed one commit: CORPUS_DIRS = ['', 'pm'] with a per-directory non-recursive walk and relative-path corpus keys; the one unmarked hit brought under #8435 by MARKING (its check:type-check-debt lead already named the maintainer as the raise's owner in prose, so refusal would be untrue — the token now sits in that same message, keeping the lower-case `maintainer-only` its own self-test pins); ROOT_DIR_WATCH_HINTS grown to three hints with battery (20) rewritten to DERIVE the expected hint set from the walk and hold it set-equal both ways; and PR #14860's assertion flipped from \"a wider walk reds HERE\" to the two-level walk plus pm/check-skill-line-ratchet.mjs's presence, pinned from corpusFiles() and never from a typed count. That gate — the one the 2026-09-03 ruling amends — reads `excluded`: its ceiling remedy already names the authority it requires and spells the act as a `raise`, outside OFFER_VERB, so the ruled exception governs an act this detector cannot see and no verdict moved. No new verdict class; not recursive; two CONTROL rows recorded from the sweep's own verdict. skip-changeset applied additively and read back (union holds: size/m + skip-changeset).",
      "tests": "All at head a8325640 (merge of origin/main 919beca4 into the implementation commit bf3cf681), exit code captured before any pipe, each gate's own verdict line quoted. Family derived AFTER the commit with `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` (no paths) — 22 commands, ALL RUN, all exit 0. Key verdict lines: `pnpm check:ratchet-remedy-authority` EXIT=0 -> 'OK  check-ratchet-remedy-authority: 201 scripts swept (scripts/*.{mjs,mts} + scripts/pm/*.{mjs,mts}); 13 mark the expanding remedy MAINTAINER-ONLY, 6 turn it down outright, 182 hand out no ratchet-expanding remedy. Control corpus: 29 hand-classified scripts, set-equality audited both ways.' (baseline before the change: 187 swept / 12 / 6 / 169, control 27). `node scripts/check-ratchet-remedy-authority.mjs --self-test` EXIT=0 -> 'OK  self-test: the lexer holds, messages are bounded, ... and the sweep still reaches every known instance.' `node scripts/pm/bare-root-worklist.mjs --self-test` EXIT=0 -> 'OK  self-test: 54 live row(s), 46 unreachable as spelled, 46 recorded verdict(s) — none stale, none missing, none contradicted ... every one of 14 distinct spelling(s) is pinned LIVE, PRECISE and COMPLETE'. `pnpm check:pm-dispatch-gates` EXIT=0 -> 'dispatch-gates self-test: 1353 cases pass.' `pnpm lint` (eslint . --no-inline-config, repo-wide, NOT narrowed) EXIT=0, no findings. Also green: check:watch-hint-literal (48 declarations across 4 rostered names, every one a literal array), check:declared-population-live (200 of 251 families reach the tree's 8268 tracked files), check:entry-guard, check:nul-bytes (8261 files, no raw control bytes), check:parse-guard, check:cli-command-ids, check:agent-test-spelling, check:bash32-floor, check:cross-package-test-inputs, check:pnpm-filter-targets, check:refd-timer-probe, check-ci-filter-parity, check-closing-keyword-parity (+self-test), check-comment-mask-corpus, check-self-test-wired (+self-test), check-whole-set-label-write (+self-test). Script-own test surface beyond the derived family: both edited scripts' own --self-tests were run (above); a git grep over *.test.ts / *.spec.ts for both filenames finds one hit, a prose mention of the path in packages/cli/test/serve-node-env-production-default.e2e.test.ts, which pins nothing about this diff. REVERSE VERIFICATION, run FROM THE COMMITTED implementation, script carried trap ... EXIT INT TERM with absolute paths; each mutation proved on disk by grep-counting the injected AND the removed text (never a bare diff --stat), each restore by `git checkout HEAD -- ABSOLUTE_PATH` then `git diff HEAD` empty AND a git hash-object comparison against the HEAD blob. No build/dist leg applies: the gate is executed by path with `node`, not resolved through a package's exports, so there is no dist copy to go stale. (1) CORPUS_DIRS narrowed back to [''] -> expected red, observed red: self-test 5 failures (positive control loses pm/dispatch-gates.mjs; SET-EQUAL; PRECISE-against-depth; BOTH battery (21) cases) and the run reports 2 STALE control rows. (2) the scripts/pm/*.mjs hint dropped with the walk kept -> expected red, observed red: 2 failures — SET-EQUAL, and COMPLETE naming '201 swept, 14 unnamed'. (3) the authority token stripped from the relayed remedy -> expected red, observed red: 'UNMARKED: scripts/pm/dispatch-gates.mjs ...' plus 'MISCLASSIFIED: ... the control says marked, the sweep says unmarked'. After the third restore the tree is byte-identical to HEAD and both legs are green again (self-test EXIT=0, run EXIT=0).",
      "mcp_calls": "1 — one targeted MCP search_issues for the dedup check. Channel declaration: repo-scoped REST reads and writes both work in this session (probe: GET repos/.../issues/15179 -> 200), and REST carried the PR create, the additive label POST with comparative read-back, the finding issue and this comment; but /search/issues is BLOCKED here ('sessions are bound to their configured repositories', HTTP 403), so the dedup search fell back to one MCP search_issues per the documented route. Control on that reading: the same query returned #15179 itself, a known hit.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #15201: bare-root-worklist's DECLARED-NARROWER row for check-ratchet-remedy-authority (SCRIPTS_DIR scripts) states a walk narrower than the gate now performs — '183 of 183' and 'no nested script at any depth is reached' are both false once this PR lands, and its SPELLINGS pin cannot see the drift because that map pins recorded spellings against the TREE, not against the gate's array (bare-root-worklist --self-test is green on this branch, measured). Re-deciding a row on a shrink-only map is the owning file's act and was ruled off this card's file surface, so it is reported, not edited; the gate's docblock carries a pointer to the staleness meanwhile. Unassigned, no labels, left for PM triage."
      ]
    }

    Generated by Claude Code

  3. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    ACCEPT — skills seat (session session_019RfFHiRCSs3JXLK4cwcfox), reviewer of record, 2026-09-04T05:59Z, verified against GitHub and a compare worktree at the PR head, not against the report.

    • Implemented-by: claude/issue-15179-remedy-authority-scripts-pm
    • Reviewed-by: session_019RfFHiRCSs3JXLK4cwcfox

    PR #15199 @ a8325640 — draft, base main, head is a merge of origin/main 919beca4 into the implementation commit bf3cf681 (the brief asked for it: PRs #15165 / #15164 landed while the flight measured), first line Fixes #15179, two files (scripts/check-ratchet-remedy-authority.mjs +304 lines changed, scripts/pm/dispatch-gates.mjs one string), skip-changeset, one footer, no model name, no control bytes. Local git merge-tree --write-tree origin/main (50d6c924) at 05:55Z: clean.

    What landed, re-verified at the head: Step 1 was measured before the walk moved — scripts/pm has no subdirectories, so one level and the ruling's scripts/pm/** name the same 14 files; 13 classify excluded, one (dispatch-gates.mjs) unmarked, verdicts identical at the two in-flight PR heads. Step 2: CORPUS_DIRS = ['', 'pm'] with a per-directory non-recursive walk and relative-path corpus keys (a row keyed on a bare filename would go STALE — the docblock says why); the one hit is brought under #8435 by MARKING — its check:type-check-debt relay already said in prose that the raise belongs to a maintainer, so a refusal would have been untrue; the token now sits in that same message; ROOT_DIR_WATCH_HINTS grows to three (no scripts/pm/*.mts — the directory has none, and a hint reaching nothing is a dead declaration), with the battery rewritten to DERIVE the expected set from corpusFiles() and hold it set-equal both ways; PR #14860's assertion flips from "a wider walk reds HERE" to the two-level walk plus check-skill-line-ratchet.mjs's presence, pinned from the walk. The gate the 2026-09-03 exception amends reads excluded — its ceiling remedy names its owner in words the offer grammar does not admit — and the header now says exactly that, with the standing warning that excluded is not a licence to stop looking. No new verdict class; not recursive; two CONTROL rows from the sweep's own verdict. The seat ran the gate and both self-tests in a compare worktree at the head: 201 scripts swept (scripts/*.{mjs,mts} + scripts/pm/*.{mjs,mts}); 13 mark … 6 turn it down … 182 hand out no remedy. Control corpus: 29, the self-test's OK line, and the worklist's 54/46 none stale — the same lines the report quotes. Three ablations each red exactly the pins that own them and restore by blob hash.

    Gates as reported at a8325640: 22 derived commands all green, whole-repo lint green, check:pm-dispatch-gates 1353. The out-of-scope finding #15201 (the worklist's DECLARED-NARROWER row now describes a narrower walk than the gate performs) is correctly reported rather than edited — a re-decision on a shrink-only map is the owning file's act — and is triaged into pm:queue (XS, serial behind this PR). Report mcp_calls: 1 (the dedup search, with the REST search 403 declared) — within contract.

    CI at 05:59Z on a8325640: 33 check runs, 20 success + 11 skipped, 2 in progress; nothing red.

    Terminal: pure code (scripts/**, no .md) ⇒ flipped ready and auto-merge armed (SQUASH) by the seat once every check is green; on MERGED the card closes by Fixes, is label-cleaned, and #14978 item 3 is done (the carrier closes when objectui PR #7600 also lands).


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions