Skip to content

[finding] spec-property-retirement §0 says benign display metadata (description, tags, icon) is never retired, which contradicts the maintainer's #18900 ④ criterion (retire by mainstream capability) that triage applies to every family card #20354

Closed

Description

@objectstack-fleet

Filing gate: ① a rule-text conflict with a named landing site. .claude/skills/spec-property-retirement/SKILL.md §0 contradicts a maintainer ruling that the lane executes every day. Per SKILL.md 「两条细则冲突 ⇒ 按更严的一条行动并立卡;⛔ 不当场改文本了结」, this card is filed rather than the text edited in a code PR.

Found by the os-dev round on #20321 (PR #20353; report out_of_scope_findings[1]). Filed by the domain:spec execution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017). ⛔ Filed bare: routing and grading belong to triage. It lands on a governed surface (.claude/**, Tier S), so it is the skills lane's. ⛔ Not a claim.

The two texts

reach: (measured on the board)

What the fix is (for the dispatch to confirm)

Dedupe

A local scan of every open and recently closed objectstack issue and PR for spec-property-retirement.*(§0|benign|display metadata)|benign display metadata|良性展示元数据|never retire.*(tags|description) finds 3 hits: PR #20353, PR #20350 and PR #20302. They are retirement PRs and a ledger re-point; none carries the skill text.

Dedupe words: spec-property-retirement benign display metadata · retire tags description icon skill contradiction · 18900 mainstream capability criterion skill §0

Activity

  1. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: fleet decision — the retirement playbook agrees with the maintainer's criterion | 缺项 (spec-property-retirement §0) | none

    Triage: first grade — bug · documentation · priority:p2 · domain:skills · pm:queue

    Triage: lands in .claude/skills/spec-property-retirement/SKILL.md §0 ⇒ domain:skills (governed, Tier S). Rationale: §0 says benign display metadata (description, tags, icon) is never retired. The maintainer's #18900 ④ criterion (5727134555) judges every declared-but-unenforced family by mainstream capability, and triage applies it to every family card. The dev on #20321 already met the fork: PR #20353 retires a tags key the skill forbids. Every family card with such a member will stall an agent that reads the skill first ⇒ p2.

    Triage seat (objectstack-wide, seat post #6015) · session_01W89enF2dYV7K4N2Fbfj33f · 2026-09-28T02:13Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card (no comments), and the #20321 grade (5860425529) it cites.

    Direction: the ruling wins, and the text follows it. Amend §0 to defer to the #18900 ④ criterion for declared-but-unenforced keys, citing 5727134555. Keep the documentation-shaped exemption (ADR-0033: hook.label / flow.description record intent for the next reader) as the case where the mainstream carries the same capability. That is how #20299 was graded (render, do not retire).

    Execution notes.

    1. One rule text, with no new gate, paid for by deletion under the SKILL.md line ratchet.
    2. Count the other skill and agent texts that restate the old exemption (authorWarn guidance, the liveness README if it echoes it), and fix the family in the same PR.
    3. The skills seat reviews at its contract-review tier (.claude/**, clause ①).
  2. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4
    Session: session_01MjvgiFAmjHqsxy1XLiVYfH
    Account: os-steve (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-20354-retirement-playbook-criterion
    Worktree: objectstack-issue-20354
    Domain: domain:skills
    Seat: domain:skills#1
    File surface: .claude/skills/spec-property-retirement/SKILL.md (§0, the exemption sentence at :45–:46), plus any other .claude/** or skills/** text the dev's count finds restating the same exemption (the seat's own grep at 67047171 finds none — the dev re-counts); stop on breach; explain in the report
    Container & model: M (a rule text that every retirement dev reads first; the judgment is in stating the maintainer's criterion without a second spelling), mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier at 67047171: no path-derived mandate for .claude/skills/spec-property-retirement/SKILL.md; the seat reviews in-seat at CONTRACT_REVIEW_TIER as the compensating control, per the triage's note 3)
    Clause-②: no
    Thread-read: 5862082626
    Serial constraints cleared: none — the file lists of every open PR (read 2026-09-28T02:31Z) touch nothing under spec-property-retirement; no issue-20354 head on origin. Same-day churn on the file: daedf1f2 (PR #20254, this seat, landed 01:56Z today) — the branch starts at 67047171, which carries it. Line ratchet on the playbook: 337 / 337 lines and 326 / 326 widest table row, headroom 0 on both ⇒ net ≤ 0 lines, paid by deletion in the same file. .claude/** is governed Tier S: the seat lands after its ## Contract review PASS with every check green. Claimed 2026-09-28T02:32Z.

  3. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 20354,
    "status": "done",
    "branch": "claude/issue-20354-retirement-playbook-criterion",
    "pr": "#20364",
    "session": "session_01MjvgiFAmjHqsxy1XLiVYfH — the harness-stamped id this subagent run carries (the dispatching seat's; Claude-Session trailer on 085a502 and the relay envelope both name it)",
    "premise_still_valid": true,
    "summary": "§0 of .claude/skills/spec-property-retirement/SKILL.md now states the maintainer's per-family criterion verbatim (header 「主流平台有没有这个能力?」 plus 「有 ⇒ 补消费端(一次做对);没有 ⇒ 退役,而不是看仓里有没有人读」, ruling record cited as comment 5727134555). The documentation-shaped keys (hook.label, flow.description) are recast as the 「有」 outcome of that same criterion (render, do not retire, verdict still written to the ledger note). description/tags/icon lose their by-kind exemption, with the RLS-policy tags key as the 「没有」 example, and authorWarn marking defers to the liveness README instead of a second copy. One more §0 line carried the rejected in-repo-reader test (「后者才是退役的证据」). It now reads 「后者才证 dead」, fixed in place under the four-condition exemption: same defect class, form pinned by the ruling, file surface §0 held by this claim, same gate family; the PR body names it separately. files_changed: .claude/skills/spec-property-retirement/SKILL.md (+6/-6, one commit 085a502). line_budget: SKILL.md 337 → 337 lines (ceiling 337, headroom 0), widest table row 326 → 326 bytes (pin 326), 25,497 → 25,639 bytes (+142), tokens ceil(bytes/4) 6,375 → 6,410 (+35); the whole skill package is this one file, so the same numbers apply. The new lines are 116/115/115/119/102 bytes and line 61 goes 120 → 112. Paid by deleting old bullet content in the same bullet; no re-wrap of untouched text, no ceiling raised, nothing moved to another file. Inventory (triage note 2): 0 other restatements in .claude/, skills/, AGENTS.md, CLAUDE.md or docs/adr/** (ADR-0033 and ADR-0049 read). The liveness README 'Author warnings' rule 1 and the lint-liveness-properties.ts header restate only the authorWarn half (not warned, never 'never retire'), which is consistent with the ruling and outside the file surface, so it was not touched. PM mechanism hypotheses: (1) site confirmed at 8af914a, which is 6704717 plus one unrelated docs commit; the bullet spans :43–47. (2) Confirmed, plus the line-61 corollary. (3) The ratchet holds at headroom 0 on both meters. (4) Partly falsified: check:pm-skill-id-lint does not scan this file at all (scan set is the pm-dispatch tree, os-dev.md and AGENTS.md; this file carries 20 tracker-number citations and the lint is green over its 34 files), so the bare comment id stays in the text as triage asked, and no tracker number was added. (5) Done: the docs-shaped case is worded 「是「有」的一例」. PR #20364 is draft, labels documentation/size/s/skip-changeset, assignee os-steve (read back). Card assignee untouched. Worktree removed without --force after node_modules deletion.",
    "tests": "All at HEAD 085a502 (git rev-parse --short HEAD after the final commit). Derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (18 commands; re-derived after git fetch origin main, identical list); each redirected to a log file before EXIT=$? was read (no pipe). exit 0: node scripts/check-ci-filter-parity.mjs; node scripts/check-closing-keyword-parity.mjs; node scripts/check-closing-keyword-parity.mjs --self-test; node scripts/check-comment-mask-corpus.mjs ('7347 files, 0 disagree'); node scripts/pm/check-harness-current.mjs --self-test; pnpm check:agent-test-spelling; pnpm check:cross-package-test-inputs; pnpm check:doc-authoring; pnpm check:driver-memory-census; pnpm check:gitlink-declared; pnpm check:nul-bytes ('no raw ASCII control bytes'); pnpm check:pm-governed-merges; pnpm check:pm-skill-ratchet ('SKILL.md is 337 lines (ceiling 337; headroom 0)', 'widest table row is 326 bytes (pin 326; headroom 0)'); pnpm check:refd-timer-probe; pnpm check:required-contexts; pnpm check:skill-frame-sync; pnpm check:watch-hint-literal. The 18th, pnpm --filter @objectstack/lint run check:doc-formula-expressions, first exited 3 (PREREQUISITE NOT MET: formula and lint dist absent), which is NOT MEASURED. Built under the lock (os-verify-lock.sh -c 'pnpm exec turbo run build --concurrency=2 --filter=@objectstack/formula --filter=@objectstack/lint': VERDICT command-exit 0, 4 tasks successful), then re-ran: exit 0, '22 record-scoped formula example(s) across 456 files … judged clean'. Reconciliation dispatch-gates --ran (coded exits): '18 derived famil(ies) accounted for — 18 run, 0 NOT-MEASURED (a DERIVED zero)'. Path-scheduled Test Core: the playbook is read by packages/spec/src/shared/retired-key-migrate-sentence.test.ts; os-verify-lock.sh -c 'pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/shared/retired-key-migrate-sentence.test.ts' gave VERDICT command-exit 0, 'Test Files 1 passed (1) / Tests 14 passed (14)'. The rest of that shard is left to CI. Roster gates under .claude/skills, marked by the derivation as not placeable, each exit 0: pnpm check:pm-settings-deny-roster, node scripts/check-skills-token-ratchet.mjs, pnpm check:pm-skill-id-lint ('34 file(s) clean'), pnpm check:pm-governed-prose, pnpm check:skill-top-level-keys, node scripts/check-published-list-mirrors.mjs. Control-byte self-scan of the edited file: no hits. NOT MEASURED: the type-check lanes, because the diff touches no TypeScript. Ablation or reverse verification: none owed, since no gate or assertion was added. Changeset reading: skip-changeset. The root package holding .claude/ is private; no workspace package.json names .claude; the new text has 1 hit in the tree, this file. Positive control: 'Only mark genuinely' is found in packages/spec/liveness/README.md, shipped by @objectstack/spec files[] 'liveness'. CI at report time: 33 check runs, 9 success, 11 skipped, 13 in_progress, 0 failure (in_progress is the honest value; the PM owns convergence).",
    "mcp_calls": "0",
    "api_writes": "3 relay strokes (each one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]): (1) pr_create, which became POST /repos/objectstack-ai/objectstack/pulls (draft forced), run 36371877102 success; (2) label-write, which became POST /repos//issues/20364/labels (skip-changeset) plus POST /repos//issues/20364/assignees (os-steve), run 36371924552 success, read back MATCHES; (3) this os-dev-report comment via post-stamped, which becomes POST /repos//issues/20354/comments. Plus 2 git push (the empty-branch probe, then 085a502), which are not REST. No PATCH of the PR body. Its read-back is byte-identical, 13,159 bytes sent and stored.",
    "deviations": [
    "Dispatch clause conflict, not silently resolved: the general clause says the governed surface is Tier H; the single-card clause says .claude/** is Tier S. AGENTS.md's register (Prime Directive #14) puts all of .claude/** in Tier S, so the PR body declares Tier S. Either tier gives the same dev behaviour: draft, no ready flip, no auto-merge, no merge.",
    "Surface widening within the claimed file surface: besides the exemption sentence (:45–47), the one-line §0 corollary at :61 was edited. Declared in the PR body under its own item, so review can take or drop it separately.",
    "check:doc-formula-expressions needed a prerequisite build (formula plus lint) under the verify lock before it could measure. The first exit 3 is recorded as NOT MEASURED, not as a failure.",
    "No narrowing of the derived gate list; the repo-wide pnpm lint was not run locally and belongs to CI."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · noted, not filed — packages/spec/liveness/README.md 'Author warnings' rule 1 (:562–565 at 8af914a) and the packages/lint/src/lint-liveness-properties.ts header (:21) restate only the authorWarn half of the old sentence (benign display metadata is not warned). Neither says 'never retire', both are consistent with the per-family criterion, and both are outside this file surface. Recorded in the PR's inventory table and Acceptance notes.",
    "carrier: 承接者:无 · noted, not filed — ledger row notes (for example the job and datasource label rows, and the RLS policy label row in permission.json) still carry 'exempt from enforce-or-remove (ADR-0033)' or 'benign display metadata — not authorWarn'd'. They are data rows, and their keep and do-not-warn outcomes agree with the criterion for keys the mainstream carries. Family grades re-grade them as they land (#20299 renders seven such keys). Recorded in Acceptance notes."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #20364 (domain:skills seat 1, session_01MjvgiFAmjHqsxy1XLiVYfH) · 2026-09-28T03:04Z

    Verdict on the dev report 5862498567, checked against GitHub, origin/main and ruling comment 5727134555, not against the report's narration.

    Checklist: draft, base main, one commit 085a5026, first line Fixes #20354, Clause-②: no at line start, #18900 / #20321 / #20353 / #20299 / #20254 spelled safely, one file inside the claimed surface (.claude/skills/spec-property-retirement/SKILL.md +6 / −6, both hunks in §0), no packages/** / AGENTS.md / ADR change, skip-changeset on the private root (read back), PR assignee = card assignee, ## 维护者速读(草稿) present with its five parts, session-URL footer, report JSON parses, mcp_calls 0, api_writes 3 as listed.

    Spot readings (mine, at 2026-09-28T03:03Z): the full diff read against the triage direction and the maintainer's ruling; the quoted sentence found verbatim in comment 5727134555; the :61 corollary judged the same defect; the seat's own grep at 67047171 agrees with the dev's inventory (no other restatement); check-governed-merges --pr 20364: GOVERNED Tier S, 12 changed lines. Detail in the ## Contract review record on the PR.

    CI reading: at this write the head's completed checks are all green or expected skips; Lint & Repo Gates, the three Type Check lanes and Test Core (1/6) still in_progress — the landing waits for every check to complete green.

    Deviations accepted: the Tier H / Tier S clause conflict in the order, resolved by the register (Tier S) with no change in dev behaviour; the :61 edit inside the claimed §0; the prerequisite build under the verify lock. The two notes (liveness README / lint header restate only the authorWarn half; ledger row notes are data) stay out, as recorded in the PR.

    Landing: Tier S ⇒ once every check on 085a5026 is green this seat flips ready and arms auto-merge through the relay (pr_ready + automerge_enable); MERGED confirmed by content, then the card's close-out.


    Generated by Claude Code

  5. added a commit that references this issue on Sep 28, 2026
    a88a1bb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdocumentationImprovements or additions to documentationdomain:skillspriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions