Skip to content

check-ratchet-remedy-authority's entry for check-doc-authoring.mjs names GENERATED_SKILL_ARTIFACTS, a constant that is being removed #12095

Description

@os-litant

Filed unassigned. Small, but it is the kind of stale cross-reference that reads as authoritative to the next person who greps for the name.

scripts/check-ratchet-remedy-authority.mjs records, in its why for check-doc-authoring.mjs:

Carries no ratchet at all. ROOTS, SKIP_PATHS, SKIP_FILES and GENERATED_SKILL_ARTIFACTS are declarations of what the two corpus rules read and what is generated rather than authored; each is path-scoped, and none is offered to the author as something to widen. […]

The GENERATED_SKILL_ARTIFACTS constant is removed by the PR for #11930 — it was the by-path exemption for the generated references/_index.md / references/react-blocks.md artifacts, and it existed only because those files still carried issue-ids projected from packages/spec TSDoc. With the sources stripped, the exemption guarded a clean surface, so it goes rather than being narrowed.

The gate itself does not break: it was run against the change and stays green, because its excluded verdict rests on the remaining declarations (ROOTS, SKIP_PATHS, SKIP_FILES) and nothing parses the why string against the file. So this is prose accuracy, not a red — which is exactly why it will otherwise sit there indefinitely.

The fix

Drop GENERATED_SKILL_ARTIFACTS from that sentence. The rest of the entry stays correct as written, including its closing line — "Its published-catalog id rule reached this corpus by first shipping a per-passage allowlist and being turned red here for offering it […] If this flips, that list came back." — which is about the per-passage allowlist, a different thing, and is unaffected.

Ordering

Blocked-by: — this should ride whichever lands second of:

Editing the file from the #11930 lane would have raced #12061's claim on it, so it was deliberately left. If #12061 rewrites that entry wholesale, check whether this is already moot before doing anything.

Activity

  1. yinlianghui-tw commented on Aug 25, 2026

    @yinlianghui-tw
    Collaborator

    Triage: pm:blocked + domain:devx, Task, S — prose-accuracy fix in scripts/check-ratchet-remedy-authority.mjs, correctly deferred behind the constant's actual removal.

    Blocked-by: #11930

    Ordering update since filing: the card's second ordering leg is discharged — PR #12061 will not land (the #11935 retriage upheld the 2026-08-23 adjudication and closed that card as a duplicate; the draft PR is to be closed unmerged by the devx seat). So the only live upstream is #11930's PR removing GENERATED_SKILL_ARTIFACTS; when the unlock scan returns this card, re-check on the merged ref whether that PR already amended the why sentence before dispatching a one-line edit.


    Generated by Claude Code

  2. self-assigned this
    on Aug 25, 2026
  3. yinlianghui commented on Aug 25, 2026

    @yinlianghui
    Collaborator

    Unlocked, verified, and claimed — pm:blocked → pm:dispatched

    Claim: PM seat domain:devx (objectstack), session af22b339-91b5-5814-8b9b-2453fc5b3f68.

    • Branch: claude/issue-12095-stale-generated-skill-artifacts-ref
    • Worktree: dedicated per-task worktree off a fetched origin/main (Prime Directive Migrate documentation site to Fumadocs with monorepo structure and shared content #11)
    • Declared file surface: scripts/check-ratchet-remedy-authority.mjs — one string, line ~715. Nothing else.
    • Model tier: opus. No path-derived mandate. Tier chosen against the bottleneck, not the diff: the merge queue is the constraint right now (5-wide, rebuilds every resident entry on each merge), so a cycle lost to a sloppy verification section costs more than the tier does. The edit is trivial; the surrounding contract is not.
    • Clause ② (contract review): no. Prose accuracy inside a gate's why record.
    • Serial constraints: ⭐ now none — see below.

    Both Blocked-by conditions have resolved, in opposite ways

    The card's ordering clause said this should ride whichever landed second of #11930's PR and #12061.

    Premise re-verified on the merged ref — and it is now sharper than when filed

    Upstream landing is not the same as the card still standing, so I measured rather than inferred:

    $ git grep -c 'GENERATED_SKILL_ARTIFACTS' origin/main -- scripts/ packages/
    origin/main:scripts/check-ratchet-remedy-authority.mjs:1        ← the ONLY hit anywhere
    
    $ git grep -c 'SKIP_PATHS' origin/main -- scripts/check-ratchet-remedy-authority.mjs
    origin/main:scripts/check-ratchet-remedy-authority.mjs:1        ← positive control
    
    $ git show origin/main:scripts/check-ratchet-remedy-authority.mjs | grep -n GENERATED_SKILL_ARTIFACTS
    715:    why: 'Carries no ratchet at all. ROOTS, SKIP_PATHS, SKIP_FILES and GENERATED_SKILL_ARTIFACTS are declarations of …'
    

    The constant is gone from the entire tree. Its single surviving mention is this prose string. When the card was filed the removal was still in flight; it has now landed, so the reference is unambiguously stale rather than prospectively so. The card got easier while it waited, which is the good case for a Blocked-by hold.

    Zone 1 — rulings, not renegotiable

    1. Drop GENERATED_SKILL_ARTIFACTS from that sentence and nothing else. The remaining names (ROOTS, SKIP_PATHS, SKIP_FILES) are live — verified above for one of them, verify the rest yourself.
    2. ⛔ Do not touch the closing line. "Its published-catalog id rule reached this corpus by first shipping a per-passage allowlist and being turned red here for offering it … If this flips, that list came back." That is about the per-passage allowlist, a different thing, and the card says explicitly it is unaffected. It also encodes a maintainer ruling of 2026-08-25. Leave it byte-identical.
    3. ⛔ Do not "fix" anything else in this file. It carries other entries and other why records. This is a one-string card; anything else you notice gets filed.

    Zone 2 — falsify, do not inherit

    • I assume the grammar reads correctly after removing the fourth item from a four-item list (A, B, C and D → A, B and C). Read the resulting sentence; if it needs a comma or conjunction change to stay grammatical, that is in scope.
    • I assume nothing parses this string. The card asserts it ("nothing parses the why string against the file") and the gate stayed green through docs(spec): strip the internal issue-ids projected into the published skill catalog, and drop the gate exemption that hid them #12097 with the string already stale, which is consistent. Confirm it anyway — if some self-test or sibling gate matches on the why text, this edit reds it and that changes the card.
    • I assume ROOTS and SKIP_FILES are still live in this file. I verified SKIP_PATHS only. Check all three; if another has also been removed, that is a second instance of the same defect and belongs in the same PR.

    Zone 3 — suggested route

    Read the entry whole before editing, confirm the other three names resolve, make the one-string change, run the derived gate union. No ablation applies — a comment/record string with no execution path has nothing to mutate, and claiming one would be theatre. Say that rather than inventing a leg. Changeset: root scripts/ only, no published-package source change ⇒ skip-changeset.

    Report per the os-dev contract. Out-of-scope findings get filed, not fixed.


    Generated by Claude Code

  4. yinlianghui commented on Aug 25, 2026

    @yinlianghui
    Collaborator

    PM review — ACCEPT (landing blocked on main, not on this PR)

    Reviewed PR #12187 against the dispatch. One file, +1/−1, size/xs. Accepted — and it exposes a circular control in my own dispatch.

    ⭐ My positive control was circular, and this PR's method is what shows it

    In the dispatch I wrote:

    I verified SKIP_PATHS only. Check ROOTS and SKIP_FILES too.

    What I actually ran was:

    git grep -c 'SKIP_PATHS' origin/main -- scripts/check-ratchet-remedy-authority.mjs   → 1
    

    That 1 is the why string itself — the very prose I was asking to have edited. check-ratchet-remedy-authority.mjs does not define SKIP_PATHS; it only mentions it, inside the sentence under repair. So my "verification that SKIP_PATHS is live" verified nothing except that the sentence exists. Had all four names been dead, my grep would have returned 1 for every one of them and I would have reported them all live.

    The PR gets it right, and says why in a sentence I want on the record:

    They describe constants in scripts/check-doc-authoring.mjs, so that is where liveness was measured — not in the file carrying the prose, where a grep only ever re-finds the sentence itself.

    Measured in the correct file, with definitions located:

    scripts/check-doc-authoring.mjs:93   const ROOTS = ['.claude', 'docs', 'skills', 'content'];
    scripts/check-doc-authoring.mjs:123  const SKIP_PATHS = new Set([
    scripts/check-doc-authoring.mjs:130  const SKIP_FILES = new Set(['content/docs/ai/skills-reference.mdx']);
    
    occurrences: ROOTS 26 · SKIP_PATHS 12 · SKIP_FILES 3 · GENERATED_SKILL_ARTIFACTS 0
    

    That establishes both halves at once: the three survivors are live, and the fourth is a single instance rather than one of several.

    ⇒ Seat error (13), and it is the same family as (11). On #12052 I ran a control with a narrower pattern than the measurement; here I ran one against the wrong file, where it could only ever confirm itself. Both are controls that validate something other than the thing being measured. The sharpened rule: a positive control must be capable of returning a different answer than the measurement. If it cannot fail independently, it is decoration. That is now five of thirteen seat errors in the "partial or circular reading presented as complete" family — comfortably the dominant one.

    The rest of the brief, checked

    Zone 1 ruling 1 — one name, and the grammar handled. ROOTS, SKIP_PATHS, SKIP_FILES and GENERATED_SKILL_ARTIFACTS → ROOTS, SKIP_PATHS and SKIP_FILES; the conjunction moves so the four-item list does not leave a dangling and. That was the Zone 2 grammar point and it was applied rather than noted.

    Zone 1 ruling 2 — the closing sentence is byte-identical, verified by comparing the tail segment against origin/main (267 bytes on both sides) rather than by eye. That sentence carries a maintainer ruling of 2026-08-25, so "looks unchanged" would not have been good enough.

    Zone 1 ruling 3 — no other entry or why record touched. One file, one line.

    Zone 2 — "nothing parses the why string" — answered properly, not assumed. declared.why has exactly one consumer: line 826, interpolated into the MISCLASSIFIED: failure text. Never matched, split, or compared. No file reads this gate as text; the four other referrers of the filename name it only in comments, a message string, and the npm script that invokes it. The gate's own --self-test pins no entry text. And that is consistent with the observable fact that the gate stayed green through #12097 while the string was already stale — a prediction the evidence had to match, and does.

    No ablation, stated as such. "A record string with no execution path has nothing to mutate — there is no leg here that could be made to fail, and constructing one would be theatre rather than evidence." Correct, and said out loud rather than silently omitted.

    ⛔ Landing is blocked, and not by this PR

    This PR is based on 22c42c9b21, which is the poisoned main: check:exported-any-returns fails there on a stale packages/client ledger row that PR #12062 closed the gap for but never deleted. So Type Check · consumer gates will go red on this PR for a reason that has nothing to do with a one-word prose edit in a scripts/ gate.

    ⛔ Nothing will be pushed here for that. Filed already by two other seats as #12180 and #12184, both dispatched; packages/client is domain:cli's surface. This PR waits for main to recover and then lands unchanged.

    Landing condition once main is green: every named gate job completed + success. Lint & Repo Gates carries check:ratchet-remedy-authority — the gate this diff edits — so that is the one that decides here.


    Generated by Claude Code

  5. yinlianghui commented on Aug 25, 2026

    @yinlianghui
    Collaborator
    {
      "issue": 12095,
      "status": "done",
      "branch": "claude/issue-12095-stale-generated-skill-artifacts-ref",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/12187",
      "premise_still_valid": true,
      "summary": "Dropped GENERATED_SKILL_ARTIFACTS from the why record for check-doc-authoring.mjs in the CONTROL corpus of scripts/check-ratchet-remedy-authority.mjs (line 715), and moved the conjunction so the three-item list stays grammatical: 'ROOTS, SKIP_PATHS, SKIP_FILES and GENERATED_SKILL_ARTIFACTS are' -> 'ROOTS, SKIP_PATHS and SKIP_FILES are'. Zone 2 assumption 1 needed the anticipated comma/conjunction change, so the edit is one substitution rather than a deletion. The diff is 1 file / +1 -1; the entry's closing sentence about the per-passage allowlist is byte-identical (267 bytes both sides, compared as a tail segment against origin/main), and no other entry or why record in the file was touched. No changeset: repo-root scripts/ only, no published-package source change, so the PR carries skip-changeset.",
      "tests": "All at the FINAL commit f677692327 (= head of the pushed branch), exit codes captured by assignment before any pipe; verdict lines quoted are each gate's own, not $?.\n\nGate union derived in the worktree with `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` (EXIT=0; header confirmed the answer came from objectstack-ai/objectstack at 22c42c9b21, and --repo checked against this checkout's origin). It named 8 families for the change set (1 path, three-dot semantics, derived by the script itself). All 8 run, all exit 0:\n  [0] pnpm check:agent-test-spelling -- violating population empty; 9 separators judged and cleared ON THE RULE\n  [0] pnpm check:cross-package-test-inputs -- 'All 117 self-test cases passed. OK: 16 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.'\n  [0] pnpm check:entry-guard -- 'check:entry-guard: 161 scripts/ file(s) -- every entry guard goes through invoked-as.mjs; 117 export bindings, 115 of them inert on import'\n  [0] pnpm check:parse-guard -- green line over scripts/, 31 counted and tiered\n  [0] pnpm check:pnpm-filter-targets -- 'check:pnpm-filter-targets: 136/173 --filter occurrence(s) across 28 file(s) resolve against 78 workspace package(s)'\n  [0] pnpm check:ratchet-remedy-authority -- 'OK  check-ratchet-remedy-authority: 146 scripts swept (scripts/*.{mjs,mts}); ... Control corpus: 24 hand-classified scripts, set-equality audited both ways.' plus 'OK  self-test: the lexer holds ...'. This is the gate that OWNS the edited file; its self-test and its set-equality audit both pass with the amended entry.\n  [0] node scripts/check-ci-filter-parity.mjs -- 'OK: all 96 declared cross-package glob(s) (81 unique) are covered by core or crosspkg'\n  [0] node scripts/check-cross-package-test-inputs.mjs -- 'OK: 16 package(s) read outside themselves, all declared'\nExtra, run because the PR edits a file: [0] node scripts/check-nul-bytes.mjs -- 'check-nul-bytes: OK (scanned 6749 text file(s) -- 6749 tracked, 0 untracked-not-ignored; skipped 6 binary; no raw ASCII control bytes).' Plus a direct grep -naP over the edited file for [\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]: exit 1, clean.\n\nNo package test/typecheck applies: the diff touches no package source, only a repo-root gate script, and that gate's own self-test is inside check:ratchet-remedy-authority above.\n\nNO ABLATION APPLIES, and none was invented. The edited text is a record string with no execution path -- there is nothing to mutate that could make any assertion fail, so an ablation leg here would be theatre rather than evidence. What replaces it is the parse audit under 'nothing parses the why string' below.\n\nEdit landing was confirmed on disk anyway, anchored on the text itself in both directions, because an editor's exit code is not evidence: before -> target-spelling count 1, replacement count 0; after -> target 0, replacement 1.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Zone 2 — all three assumptions checked, one of them was wrong

    1. Grammar — the PM's assumption held, but the edit is NOT a pure deletion. Removing the fourth item of A, B, C and D leaves a dangling and, so the conjunction had to move: the substitution is ROOTS, SKIP_PATHS, SKIP_FILES and GENERATED_SKILL_ARTIFACTS are → ROOTS, SKIP_PATHS and SKIP_FILES are. This was explicitly in scope per Zone 2. Plural agreement (are declarations, each is path-scoped) is unchanged with three items.

    2. Nothing parses the why string — confirmed, not inherited. declared.why has exactly one consumer in the whole gate: line 826, control's reason: ${declared.why}, interpolated into the MISCLASSIFIED: failure text. It is never matched, split, compared, or hashed. No file in the repo reads scripts/check-ratchet-remedy-authority.mjs as text — the four other referrers of that filename (package.json, check-doc-authoring.mjs, check-auth-mount-ledger.mjs, check-i18n-coverage.mjs) name it only in prose comments, one message string, and the npm script that invokes it. check-doc-authoring.mjs appears exactly once in the gate: at line 713, the CONTROL key itself. No self-test pins entry text. The gate's own run above is the live confirmation.

    3. ROOTS and SKIP_FILES — live. There is no second instance of the defect. Measured where the constants actually are (scripts/check-doc-authoring.mjs), not in the file carrying the prose:

    scripts/check-doc-authoring.mjs:93:  const ROOTS = ['.claude', 'docs', 'skills', 'content'];
    scripts/check-doc-authoring.mjs:123: const SKIP_PATHS = new Set([
    scripts/check-doc-authoring.mjs:130: const SKIP_FILES = new Set(['content/docs/ai/skills-reference.mdx']);
    
    occurrences in that file:  ROOTS 26 · SKIP_PATHS 12 · SKIP_FILES 3 · GENERATED_SKILL_ARTIFACTS 0
    

    One note on method, offered because it would matter on a card where the answer differed. The claim comment's positive control — git grep -c 'SKIP_PATHS' -- scripts/check-ratchet-remedy-authority.mjs → 1 — cannot distinguish a live constant from a stale one: the single hit it returns is the prose sentence under repair. GENERATED_SKILL_ARTIFACTS scores exactly 1 on that same control. The discriminating measurement is the one above, against the file that declares the names. It happened to agree here.

    Label

    skip-changeset is on the PR, read back as ["size/xs", "skip-changeset"] — the size bot's label preserved.

    Declared deviation: the additive POST /issues/{n}/labels endpoint was refused at this seat by the local permission layer, so I used the documented fallback — read current labels → union → group write — and am declaring it here rather than leaving it silent. The read-back above is what closes the step.

    Generated by Claude Code


    Generated by Claude Code

  6. yinlianghui commented on Aug 25, 2026

    @yinlianghui
    Collaborator

    os-dev-report

    Supersedes comment 5410277240 for scanning purposes only — that comment's content is correct and its prose annex (the Zone 2 walkthrough and the label read-back) still stands. What failed there is the marker: the HTML-comment form <!-- os-dev-report --> was eaten by the GitHub sanitizer after the write, so the comment is invisible to a scan keyed on it. Read back and caught. This repost leads with the literal text instead, per the documented fallback. No comment-edit path is reachable from this seat (no MCP update-comment tool; authed curl refused by the local permission layer), so the marker is fixed by reposting rather than by editing.

    {
      "issue": 12095,
      "status": "done",
      "branch": "claude/issue-12095-stale-generated-skill-artifacts-ref",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/12187",
      "premise_still_valid": true,
      "summary": "Dropped GENERATED_SKILL_ARTIFACTS from the `why` record for check-doc-authoring.mjs in the CONTROL corpus of scripts/check-ratchet-remedy-authority.mjs (line 715), moving the conjunction so the list stays grammatical: 'ROOTS, SKIP_PATHS, SKIP_FILES and GENERATED_SKILL_ARTIFACTS are' -> 'ROOTS, SKIP_PATHS and SKIP_FILES are'. Zone 2 assumption 1 did require the anticipated conjunction change, so the edit is a substitution, not a deletion. Diff is 1 file / +1 -1. The entry's closing sentence about the per-passage allowlist is byte-identical (267 bytes on both sides, compared as a tail segment against origin/main, not by eye); no other entry or `why` record touched. No changeset (repo-root scripts/ only, nothing user-visible); PR carries skip-changeset. NOTE ON CI, not on this diff: the branch is based on 22c42c9b21, where check:exported-any-returns fails on a stale packages/client ledger row -- already filed by other seats as #12180 / #12184. Consumer-gate red on this PR is that base defect, not this edit; the gate that owns this file, check:ratchet-remedy-authority, is green locally at the final commit.",
      "tests": "All at the FINAL commit f677692327 (= head of the pushed branch). Exit codes captured by assignment before any pipe; each verdict quoted is the gate's own printed line, never a bare $?.\n\nGate union derived in the worktree with `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` (EXIT=0; its header confirmed the answer came from objectstack-ai/objectstack at 22c42c9b21 and that --repo matched this checkout's origin; change set derived by the script itself -- 1 path, three-dot semantics). 8 families named, 8 run, all exit 0:\n  [0] pnpm check:agent-test-spelling -- violating population empty; 9 separators judged and cleared ON THE RULE\n  [0] pnpm check:cross-package-test-inputs -- 'All 117 self-test cases passed. OK: 16 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.'\n  [0] pnpm check:entry-guard -- 'check:entry-guard: 161 scripts/ file(s) -- every entry guard goes through invoked-as.mjs; 117 export bindings, 115 of them inert on import'\n  [0] pnpm check:parse-guard -- green line over scripts/, 31 counted and tiered\n  [0] pnpm check:pnpm-filter-targets -- 'check:pnpm-filter-targets: 136/173 --filter occurrence(s) across 28 file(s) resolve against 78 workspace package(s)'\n  [0] pnpm check:ratchet-remedy-authority -- 'OK  check-ratchet-remedy-authority: 146 scripts swept (scripts/*.{mjs,mts}); ... Control corpus: 24 hand-classified scripts, set-equality audited both ways.' plus 'OK  self-test: the lexer holds ...'. This is the gate that OWNS the edited file; self-test and set-equality audit both pass with the amended entry.\n  [0] node scripts/check-ci-filter-parity.mjs -- 'OK: all 96 declared cross-package glob(s) (81 unique) are covered by core or crosspkg'\n  [0] node scripts/check-cross-package-test-inputs.mjs -- 'OK: 16 package(s) read outside themselves, all declared'\nExtra, run because the PR edits a file: [0] node scripts/check-nul-bytes.mjs -- 'check-nul-bytes: OK (scanned 6749 text file(s) -- 6749 tracked, 0 untracked-not-ignored; skipped 6 binary; no raw ASCII control bytes).' Plus a direct grep -naP over the edited file for the control-byte class: exit 1, clean.\n\nNo package test/typecheck applies -- the diff touches no package source, only a repo-root gate script, whose own self-test is inside check:ratchet-remedy-authority above.\n\nNO ABLATION APPLIES, and none was invented. The edited text is a record string with no execution path: there is nothing to mutate that could make any assertion fail, so a leg here would be theatre rather than evidence. What stands in its place is the parse audit -- `declared.why` has exactly one consumer, line 826, interpolated into the MISCLASSIFIED failure text, never matched or compared; no file in the repo reads this gate as text; its --self-test pins no entry text. Consistent with the observable fact that the gate stayed green through #12097 while the string was already stale.\n\nEdit landing was still confirmed on disk, anchored on the text itself in both directions, because an editor's exit code is not evidence: before -> target spelling 1, replacement 0; after -> target 0, replacement 1.\n\nLiveness of the three survivors was measured in scripts/check-doc-authoring.mjs, where the constants are actually declared (ROOTS:93, SKIP_PATHS:123, SKIP_FILES:130; occurrence counts 26 / 12 / 3, and GENERATED_SKILL_ARTIFACTS 0) -- NOT in the file carrying the prose, where a grep can only re-find the sentence under repair. So: one instance of the defect, not several.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code


    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

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions