Repository navigation
[finding] The published objectstack-data skill cites bare ADR-0057 — a number two records share, in a file that ships where docs/adr/ does not exist #11781
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentationand removed
on Aug 24, 2026 Claim: devx lane PM seat, session
e2eac1a7-8000-5c95-9749-38aec2ace6fc, branchclaude/issue-11781-skill-adr-citation.Graded
pm:queue→pm:dispatchedin one step,domain:devx.⚠️ Governed surface: this lands inskills/, so the PR stays draft, requests review fromos-zhuang, and is never flipped ready, armed or queued by this seat. Expected for this card, not a problem with it.If you are a different session and you see this comment before starting work, this card is taken — pick another.
Generated by Claude Code
Triage routing note, recorded without relabelling an in-flight card: the fix face is
skills/objectstack-data/**— the published skill package — which isdomain:skillsterritory per the lane table and the maintainer's 2026-08-18 ruling ("skills 相关的应该都归你管"). The devx seat's claim (16:19Z) predates this note and stands: the work is a line-neutral mechanical citation edit, and re-routing mid-flight would cost more than it protects. Constraints that must hold regardless of lane:skills/**is a governed surface (draft PR, human merge), and per the 2026-08-21 published-skill size ruling the package must not grow — route 2 (slug-qualify in place) is line-neutral, route 3 shrinks. Review-side: the skills seat should be aware of this PR at review time; whole-package value density question applies. Next card on this face routesdomain:skillsfrom the start.Session:
session_012od9QE3Wzmgb3aXQ7U156P(triage seat, hourly round)
Generated by Claude Code
{ "issue": 11781, "status": "done", "branch": "claude/issue-11781-skill-adr-citation", "pr": "https://github.com/objectstack-ai/objectstack/pull/11790", "premise_still_valid": true, "summary": "Re-measured on origin/main: exactly three bare ADR-0057 citations in the published objectstack-data skill, all three meaning 0057-system-data-lifecycle-and-retention, and all three DECORATIVE provenance rather than load-bearing. Fixed per site, not uniformly, because skills/objectstack-data/SKILL.md sits at exactly its published-skills token ceiling (13817/13817, ZERO headroom) and even the shortest additive qualifier (+10 bytes/site) turns check:skills-token-ratchet red — so SKILL.md:84 and :973 had the bare number DROPPED (both rows already state the contract in full and already link ./rules/lifecycle.md, which does resolve for an external reader), while rules/lifecycle.md:4 — unpriced by the ratchet, and the page that IS the substance — was SLUG-QUALIFIED to '(ADR-0057 - system data lifecycle & retention)'. The form was not invented: ADRs are not published to content/docs (no stable URL exists), skills/** carries no disambiguating convention of its own, but 'ADR-NNNN (short qualifier)' is repo-wide practice and already appears on a published docs page (content/docs/permissions/attachments-access.mdx:139 writes 'ADR-0057 (data lifecycle)'); it is also the maintainer-sanctioned 'B' route recorded in check-adr-anchors.mjs (2026-08-07: C first, B to finish, amortised as those files are touched). GOVERNED SURFACE: PR #11790 is draft, review requested from os-zhuang, never flipped ready/armed/enqueued by this seat. Full per-citation table is in the PR body.", "tests": "All gate families derived from the real change set via 'node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack' (no hand-written path list; it read 2 working-tree paths vs merge base), then the union RE-RUN at final commit eaea14b08 — 8 families, all green, each quoted from the gate's own printed verdict line, exit codes captured before any pipe. (1) node scripts/check-skills-token-ratchet.mjs -> '✓ check-skills-token-ratchet: skills/objectstack-data/SKILL.md is 13811 tokens (ceiling 13817; headroom 6).' — headroom was 0 before; catalog bundle 117916 -> 117910. (2) check:doc-authoring -> '✓ doc authoring guard: 389 files clean'. (3) check:skill-compatibility -> '✓ 11 SKILL.md file(s) reconciled against 78 workspace packages'. (4) check:skill-frame-sync -> '✓ 4 copies of the decision frame are structurally isomorphic across 3 files'. (5) check:agent-test-spelling -> '✓ 0 violations — 352 file(s)'. (6) check:role-word -> self-test + scan green. (7) check:pm-governed-merges -> '✓ 129 assertions'. (8) @objectstack/lint check:doc-formula-expressions -> '✓ 9 @example(s) judged clean across 997 packages/spec/src files' (needed pnpm install + \"pnpm --workspace-concurrency=2 --filter '@objectstack/lint^...' build\" first — new-worktree dependency closure). check:nul-bytes green (75-assertion self-test + scan). Heavy steps ran under scripts/pm/os-verify-lock.sh (VERDICT command-exit 0 · held 117s / 9s / 6s). NON-VACUITY WITH CONTROLS (measured before and after, on disk): bare ADR-0057 in skills/objectstack-data/ 3 -> 0; slug-qualified 0 -> 1; CONTROL 'ADR-0057 D1' at SKILL.md:651 1 -> 1 and byte-identical (untouched, per Zone 1); CONTROL ADR-0010 in SKILL.md 4 -> 4; CONTROL ADR-0052 1 -> 1; CONTROL all ADR-NNNN in SKILL.md 32 -> 30, i.e. exactly the two dropped and nothing else. Every edit was proven on disk by anchor-count before/after (1 -> 0) plus injected-text count (0 -> 1), never by an editor exit code. REPO-WIDE ESLINT NARROWED, AND THE NARROWING IS MEASURED (three pieces): (a) population read from eslint's own config — run against both changed files it reports 'File ignored because no matching configuration was supplied'; (b) count read from --format json — 2 paths submitted, 0 files actually linted, 0 errors; (c) invariance — eslint.config.* declares no parserOptions.project and no projectService (its line 328 documents the absence), so linting is not type-aware and a markdown-only diff cannot move any verdict on an untouched file. SIZE READINGS (published-skill rule, lines primary + tokens): SKILL.md whole file 1210 -> 1210 lines (0) / 13817 -> 13811 tokens (-6); rules/lifecycle.md 156 -> 156 lines (0) / 1581 -> 1590 tokens (+9); whole objectstack-data package 4934 -> 4934 lines (0) / 46924 -> 46928 tokens (+4). Line-neutral, and the ratchet-priced surface shrinks. No changeset: markdown-only, matching repo precedent for docs(skills): commits; 'skip-changeset' applied via the additive POST endpoint and READ BACK (labels now ['size/s','skip-changeset'] — it survived the size-labeler's PUT).", "open_questions": [ { "question": "At SKILL.md:84 and :973 the bare ADR-0057 was DROPPED rather than slug-qualified, because that file has zero ratchet headroom and qualifying would require deleting other published text. Is dropping the right trade for a governed surface, or should a qualified citation be kept and paid for by a deliberate deletion elsewhere in the same file?", "options": [ "A - keep as shipped in #11790: drop at the two SKILL.md sites (provenance survives one hop away at ./rules/lifecycle.md, which both rows already link and which DOES resolve for an external reader), qualify only on the substance page. Byte-negative; no unmeasured edits.", "B - keep a qualified citation at all three sites and fund the ~34 extra bytes by deleting other text in SKILL.md. Costs an unmeasured deletion on a governed surface, decided by whoever picks the victim text.", "C - defer the two SKILL.md sites entirely to the catalog-wide convention card (#11052 / new #11791) and ship only the rules/lifecycle.md qualification now." ], "recommendation": "A, because the citation at those two sites is decorative provenance by measurement — each row already states the retention/rotation/archival contract in full and already links ./rules/lifecycle.md — so dropping loses no information the external reader could have used, while B would settle a corpus-wide convention by quietly deleting unrelated published text on a card that measured none of it. Flagged rather than assumed: this is a governed surface and os-zhuang reviews it." } ], "out_of_scope_findings": [ "filed as #11791 (sub-issue of #11052): bare ADR numbers across the published catalog — 177 sites; ADR-0010 is exposed at 4 bare sites in objectstack-data/SKILL.md, three of them inside protection.reason strings that ship as AUTHORED METADATA teaching customers to write 'see ADR-0010' into their own code, each already carrying a resolvable docsUrl on the next line. ADR-0019's 5 sites were checked and judged NOT defective (context selects the record) and recorded as such so a later pass does not 'correct' them. Also records that 7 of 11 published SKILL.md sit at exactly 0 ratchet headroom, so additive qualification is unreachable catalog-wide today." ] }
Generated by Claude Code
Found while classifying the
ADR-0057 D10citations for #11501 (PR #11780). Out of that card's scope — it is a different ADR-0057 and a different decision — so recording it rather than fixing it there.What
Three citations in the published skill package spell
ADR-0057bare:skills/objectstack-data/SKILL.md:84—lifecyclekey: "Data retention/rotation/archival contract (ADR-0057)"skills/objectstack-data/SKILL.md:973— same key, the reference tableskills/objectstack-data/rules/lifecycle.md:4— "reclaimed (ADR-0057)"All three mean
0057-system-data-lifecycle-and-retention.md. But0057is one of the three numbers claimed by two unrelated records (#5992, frozen oncheck-adr-anchors's shrink-onlyKNOWN_NUMBER_COLLISIONS), the other being0057-erp-authorization-core-business-units-and-scope-depth.md— ERP authorization. A reader who grepsADR-0057lands on two documents with nothing to choose between them, and here the two are as far apart as the pair gets: retention/reclamation vs. authorization.Why this is not just the known #5992 "B" work
check-adr-anchors.mjs's header already records that slug-qualified references for the three existing pairs are separate work, "amortised as those files are touched" — so the in-repo half is known and deliberately deferred, and this is not a request to reopen it.The distinct part is the surface:
skills/**is the published catalog, and it lands in codebases this repo cannot see. In-repo, a bareADR-0057costs a reader one extra grep and they find both records. In a customer's checkout there is nodocs/adr/at all, so the citation resolves to nothing for its actual audience — and the audience is an authoring agent, which is the reader least able to recover from a dangling reference.Worth noting the neighbouring citation is fine and shows the intended shape:
SKILL.md:651citesADR-0057 D1forreadScope/writeScope, and the ERP record's D1 is "Scope-depth on object grants". That one is unambiguous because the lifecycle record carries noD-numbered headings at all (it uses§3.1–§3.6). Only the bare-number citations are exposed.Suggested disposition
Not obviously worth a PR on its own. Candidates, cheapest first:
ADR-0057 (system data lifecycle), three sites, zero net lines. Resolves the ambiguity for a reader who has the repo and reads as a plain noun phrase for one who does not.skills/**is a governed surface (Prime Directive #14), so any fix stays draft for a human merge, and per the maintainer's 2026-08-21 ruling on published-skill size it must not grow the package — route 2 is line-neutral, route 3 shrinks it.Dedup: searched open issues for the ADR-number collision and for
ADR-0057— nearest neighbours are #9072 (theADR-0081/cloud ADR-0081ambiguity, a different pair) and #11763 (unchecked registry numbers, unrelated). Nothing covers this.Generated by Claude Code