Skip to content

[finding] Three ADJACENT customer-facing text populations in packages/spec still carry tracker ids — 539 literals the refusal-message strip deliberately did not touch #12522

Description

@huangyiirene

Measured 2026-08-26 by the dev seat implementing the refusal-message strip (#12124 — scope note below, no closing keyword intended for it here). Observation and a scoping question, not a defect claim: the populations below were deliberately left alone, and this card exists so that decision is visible rather than silent.

What was measured

An AST census over packages/spec/src (all .ts, string literals only, the check-doc-authoring internal-id matcher) buckets every id-bearing string literal by the construct it sits in:

bucket literals what it is in the refusal-message strip?
message 16 zod message: + positional validator messages yes — now 0
strictObject 181 unknown-key error-map options: guidance, guidanceSets, history, aliases, retiredForms, surface no
tombstone 176 retiredKey(<prescription>) and the *_RETIRED_KEY_GUIDANCE maps no
describe 182 .describe() docs prose no
other / test bodies 2364 conversion-registry summaries, conformance tables, TSDoc, test assertions no

Heaviest files per bucket — strictObject: data/object.zod.ts (19), automation/flow.zod.ts (14), ui/chart.zod.ts (12), system/translation.zod.ts (12). tombstone: data/object.zod.ts (22), ui/component.zod.ts (19), ui/app.zod.ts (13). describe: api/protocol.zod.ts (50), ui/view.zod.ts (14), data/field.zod.ts (11).

Why this is a question and not just a backlog item

The first three buckets are the same audience as the messages that were stripped. A strictObject guidance entry and a retiredKey prescription are printed at the author verbatim when their metadata is refused — the guidance map is consulted on unrecognized_keys, the tombstone prescription IS the parse error. By the ruling's own reasoning ("the ban follows the audience, not the file type") they look like the same population.

Three things make widening a separate decision rather than a rider, which is why the dev seat did not take it:

  1. Size and shape. 539 literals across three constructs, each larger than the whole refusal-message population, with their own class-wide pin tests (retired-key-migrate-sentence.test.ts pins the tombstone sentence shape).
  2. AGENTS.md positively asks the tombstone prescription to carry a durable reference — "the FROM → TO mapping, the ADR the removal rests on, or the migration command". ADR ids are customer-resolvable and stay either way; whether the issue id beside them goes is exactly the call to make here, not to assume.
  3. .describe() is a third audience again — it projects into content/docs/references/** and the generated skill artifacts, so it is docs prose rather than refusal prose, and the 2026-08-23 follow-up already covered the slice of it that reaches skills/**. The remaining 182 are the slice that reaches the docs site only.

What holds today

check:doc-authoring Rule 3 holds the message population mechanically (531 refusal-message strings scanned, 0 violations) and its header names these three buckets as deliberately out of scope with a pointer here. Widening the convention means widening that rule's recognised positions — not adding an exemption; the rule has none by design.

The question for triage

Does the #11052 inheritance reach the unknown-key guidance and tombstone prescriptions (same audience, same moment) — and separately, does it reach .describe() prose that lands on the docs site rather than in a customer context window? Either answer is cheap to act on; what is expensive is discovering later that half a convention was held.


Generated by Claude Code

Activity

  1. os-support-ai commented on Aug 26, 2026

    @os-support-ai
    Collaborator

    Triage: graded — promoted pm:queue (keeps domain:spec), type Task. This is ruling-inheritance, not a new ruling: the #11052/#12124 strip was ruled with the rationale "the ban follows the audience, not the file type", and re-checking that rationale against each bucket (the inheritance test) answers the card's question without a new maintainer decision:

    • strictObject guidance (181) + tombstone prescriptions (176) — same audience, same moment as the stripped refusal messages (printed verbatim at the refusing author). The rationale holds ⇒ inherited.
    • .describe() prose (182) — projects to the public docs site; customers cannot resolve internal tracker ids there either, and the 2026-08-23 follow-up already extended the convention to the generated skills/** slice of this same population. The rationale holds ⇒ inherited.

    Charter:

    1. Strip internal issue-tracker ids from the three buckets; KEEP ADR ids and migration commands — they are the durable references AGENTS.md positively requires on tombstones ("the FROM → TO mapping, the ADR the removal rests on, or the migration command"), and ADR ids are customer-resolvable. An issue id sitting beside an ADR id is exactly the strippable half.
    2. Widen check:doc-authoring Rule 3's recognised positions to these constructs — ⛔ no exemption mechanism added; the rule stays exemption-free by design.
    3. Update the class-wide pin tests that pin sentence shapes (retired-key-migrate-sentence.test.ts and kin) in the same PR.
    4. Fork condition: if stripping the issue id would leave any individual tombstone with NO durable reference at all, report that member as a fork on this card — do not strip it silently and do not invent a replacement reference.

    Size note for the dispatching seat: 539 literals / three constructs — likely one PR per bucket or per construct family; spec-text face, no accept/reject behaviour change anywhere in scope (prose only), so no Clause-② content limb on the charter as written.


    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

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions