Re-run notice (2026-06-13)
This ticket and its phase children (#41 / #42 / #43) were reopened and repurposed for a fresh regeneration of primer-react through the corrected, registry-scoped meta-skill. All comments above the reopen belong to the superseded run #2 — ignore them; this run writes its own handoffs and posts its own comments. The earlier run-#2 artifact is already on main; this run validates a meta-skill fix and lands as a dry-run, not on main.
Why this run
A diagnosis on the working thread found the produced references/anti-patterns.md had leaked meta-skill governance (a "Layer C — Meta-skill craft" section) into the consumer skill, carried a redundant component-trap table, and the meta-spec contradicted itself on where token-discipline rows live. The meta-skill (extract-ds-skill) was corrected (commit edbdaf7 on fix/meta-produced-antipatterns-schema):
references/anti-patterns.md,references/skill-template.md,references/persist.mdnow define the producedanti-patterns.mdas a thin slug-resolution / audit registry: theshell/*Bad/Good/Why table + theasset/*registry, and nothing else.- Layer C governance is never emitted into the produced skill; token-discipline rows live in
references/tokens.md; the routing table must not advertiseanti-patterns.mdas a generation-time load target.
This run regenerates primer-react through that corrected meta-skill and confirms the produced anti-patterns.md comes out clean.
Where it runs
- Working directory: the standalone copy at
.claude/worktrees/dryrun-20-improved-metaskill/(Ralph's$PWD). It already contains the corrected meta-skill and the currentprimer-react(19 components) to overwrite. Do NOT usefeature/regenerate-primer-react(prior run, merged). - The copy is on
fix/meta-produced-antipatterns-schema; optionallygit switch -c dryrun/20-improved-metaskillin the copy so commits land on a throwaway dryrun branch. Output stays in the copy — no PR tomain(dry-run). - Model: as in run #2 (e.g. Fable-5-low), one extraction phase per Ralph iteration.
Invocation inputs (public sources, unchanged)
github.com/primer/react(slate-scoped.docs.json+.stories.tsx— raw-fetch per file, never clone)github.com/primer/primitiveshttps://primer.style/(live site; backing repo archived July 2025 — do NOT crawl it; Storybook is JS-rendered, NOT an input)github.com/vercel-labs/primer-nextjs-template(reference project)
Slate (19, pinned)
Button, IconButton, TextInput, Textarea, Select, Checkbox, FormControl, Heading, Text, Stack, Label, CounterLabel, Flash, StateLabel, BranchName, ProgressBar, Spinner, Timeline, RelativeTime.
(Run #2 pinned 15; the harvest-convergence loop #33 added ProgressBar / Spinner / Timeline / RelativeTime. This run pins the full 19 to match the skill being overwritten.)
- Phase-1 gate pre-answer: apply the 19-slate verbatim as "go" — see #41.
- Phase-2 close pre-answer: "approved — write the handoff" — see #42.
- Phase-3 slug-collision pre-answer: "overwrite" the existing
primer-reactin the copy — see #43.
Acceptance criteria
Carried from run #2:
-
references/design-craft.mdpresent, byte-identical to hash1d09044e35ad17d60ce9c9998f082690c502a2d3; the routing row fires. - DS-specific taste rules extracted from
primer.styleprose appear in the produced skill with citations. - Zero positive prop/enum claims outside the claims file; the claims probe typechecks; zero cited local paths failing
test -e; zerolib-esmreferences. -
[VERIFY]: 0 unresolved, or each remaining marker explicitly accepted and listed. -
check-skill-docs.shproduced-mode exit 0 (incl.TOKEN_COVERAGE,SLATE_COVERAGEfor 19,DESIGN_CRAFT=PASS). - Adversarial spot-check by a fresh agent (no extraction context): 10 random prop claims vs
dist/*.d.ts— 10/10 hold. - Every slate component (19) has its own contract section; StateLabel lifecycle-vs-metadata present; BranchName
as="span"rule present.
New for this run — the registry-scoped anti-patterns.md (the point of the fix):
- Produced
references/anti-patterns.mdis a thin slug registry: it contains theshell/*Bad/Good/Why table and theasset/*registry — and nothing else. - No "Layer C — Meta-skill craft" section, and no
craft//wiring//cite//state// Layer-Ccomponent/*governance in the producedanti-patterns.md. - No component-trap consolidation table in
anti-patterns.md(component traps live only inreferences/components/<name>.md). - Token-discipline rows live in
references/tokens.md, not in the producedanti-patterns.md. - The
SKILL.mdrouting table does not route an agent toanti-patterns.md"during generation" (omitted, or a maintenance/registry-labeled row). -
SLUG_RESOLUTION=PASSwithasset/*slugs resolving against the (thin)anti-patterns.md;SHELL_INVARIANTS=PASS.
Execution model
Phased Ralph loop, one extraction phase per AFK iteration, chained by the skill's handoff documents. The loop must never close this issue — the operator does the final tick-off after reviewing the dry-run output.
References
- Working-thread diagnosis + meta-skill fix:
fix/meta-produced-antipatterns-schema, commitedbdaf7. - Prior runs: #31 (run #1), #40 / #41 / #42 / #43 (run #2 — this set, now repurposed), #33 (harvest convergence, 15 → 19).
Activity
3Run #2 Phase 3 complete — per-row acceptance report (from #43, commit 2302380)
.claude/skills/primer-react/ is live on feature/regenerate-primer-react (clean add — run #1 artifact was already removed in 2de5b27, so this commit ships 33 new files and replaces nothing). Produced-mode audit: CHECK_RESULT=PASS exit 0, all 12 checks green including the new DESIGN_CRAFT=PASS. Phase 3 handoff: .extract-ds-skill-scratch/handoffs/phase-3.md.
| # | Acceptance row | Verdict | Evidence |
|---|---|---|---|
| 1 | references/design-craft.md byte-identical to WS1 hash + routing row fires | PASS | git hash-object .claude/skills/primer-react/references/design-craft.md = 1d09044e35ad17d60ce9c9998f082690c502a2d3. Routing row present in SKILL.md: user composes a screen, page, or section layout → references/design-craft.md → DS-agnostic design-craft defaults, shipped verbatim by the meta-skill — the DS wins on conflict. WS1 dependency now merged (a4135b9); the row that was BLOCKED on run #1 is GREEN on run #2. |
| 2 | DS-specific taste rules from primer.style prose with citations | PASS (same scope caveat as run #1) | 7 rules extracted with per-URL citations across 5 files (foundations/{home,product,primitives,octicons,accessibility}.md + foundations/index.md): 5 token/* in foundations/primitives.md (css-variable-consumption, color-mode-auto, theme-file-attribute-pairing, accessibility-theme-variants, base-vs-functional) + 2 asset/* in foundations/octicons.md (octicon-size-buckets, octicon-name-size-suffix). Caveat: density/empty-state taste pages sit outside the accepted depth-1 crawl set — logged in foundations/product.md as future-pass candidates. |
| 3 | Zero positive prop/enum claims outside claims file; probe typechecks; zero cited local paths failing test -e; zero lib-esm references | PASS | 93 prop claims verified against @primer/react@38.26.0 in Phase 2 (Button: 8, IconButton: 4, TextInput: 10, Textarea: 6, Select: 7, Checkbox: 5, FormControl: 5, Heading: 7, Text: 5, Stack: 9, Label: 9, CounterLabel: 4, Flash: 6, StateLabel: 7, BranchName: 1) — 68 positive + 25 negative claims, 0 typecheck errors. Every enum in the contract files cites its dist/**/*.d.ts:<line>. Re-checked at persist: every cited node_modules/@primer/react/dist/... path exists; grep -ri lib-esm .claude/skills/primer-react/ → zero hits. |
| 4 | [VERIFY]: 0 unresolved, or each remaining accepted + listed | PASS (1, pre-accepted) | 1 marker preserved verbatim: references/foundations/octicons.md:23 (asset/octicon-name-size-suffix — no naming-convention anchor on the catalog page; 12/12 exemplar-consumed octicon exports grep-resolve in node_modules/@primer/octicons-react/dist/icons.d.ts@19.28.0). Operator-accepted on #41. Uses the [VERIFY: <reason>] form, so the audit's strict \[VERIFY\] grep counts 0; substantive open item recorded in the closing message + phase-3 handoff. |
| 5 | check-skill-docs.sh produced-mode exit 0 (incl. TOKEN_COVERAGE, SLATE_COVERAGE, DESIGN_CRAFT=PASS) | PASS | Exit 0, CHECK_RESULT=PASS. All rows green: ROUTING_TABLE=PASS, COMPONENT_FILES=PASS, BEST_PRACTICES_COVERAGE=PASS, SLUG_RESOLUTION=PASS, SCOPE_GUARDRAIL=PASS, WIRING_NOT_SYNTHESIZED=PASS, EXAMPLES_INDEX=PASS, FOUNDATIONS_INDEX=PASS, TOKEN_COVERAGE=PASS (12 consumed / 12 covered), SHELL_INVARIANTS=PASS, SLATE_COVERAGE=PASS, DESIGN_CRAFT=PASS (the row that was BLOCKED on run #1 lands GREEN on run #2). |
| 6 | Adversarial spot-check by a fresh agent: 10 random prop claims vs dist/*.d.ts | NOT ATTEMPTED (operator-side) | Per the #43 ticket body step 6, this row needs an agent with no extraction context — it stays operator-side on #40. (Run #1 reported 10/10 confirmed; the same instrument can be re-run against run #2.) |
| 7 | Every slate component has its own contract section; StateLabel lifecycle-vs-metadata present | PASS | 15/15 per-file contracts under references/components/ (button.md, icon-button.md, text-input.md, textarea.md, select.md, checkbox.md, form-control.md, heading.md, text.md, stack.md, label.md, counter-label.md, flash.md, state-label.md, branch-name.md) + ## Component slate declaration in SKILL.md (audit's SLATE_COVERAGE=PASS confirms). StateLabel-for-lifecycle / Label-for-metadata rule duplicated in BOTH state-label.md AND label.md, cited to dist/StateLabel/StateLabel.d.ts:2-21 + upstream packages/react/src/StateLabel/StateLabel.tsx:71; "Never build a lifecycle capsule out of Label" present verbatim. |
| 8 | BranchName as="span" rule present | PASS | references/components/branch-name.md: renders <a> by default (as: Component = 'a', cited to dist/BranchName/BranchName.d.ts:3 + upstream packages/react/src/BranchName/BranchName.tsx:16); as="span" rule for non-link chips appears in description, When-to-use, Accessibility, Best Practices, Composition example, AND Things-to-never-invent sections. |
Notes for the operator tick-off: snapshot to dry-runs/ skipped this iteration (Ralph scope was persist + commit); the operator can cp -R .claude/skills/primer-react/ dry-runs/2026-06-11-primer-react-run-2/extracted-skill/ manually if a frozen artifact is wanted. Phase 3 handoff (audit tally, follow-ups, sibling-agent pickup) is at .extract-ds-skill-scratch/handoffs/phase-3.md. Zero extractor files were touched during this iteration.
Registry-scoped regeneration — Phase 3 complete — per-row acceptance report (commit 92343ae)
.claude/skills/primer-react/ regenerated through the corrected, registry-scoped meta-skill (edbdaf7) in the dry-run copy at .claude/worktrees/dryrun-20-improved-metaskill/. Slug-collision recorded answer: overwrite. One commit on the throwaway branch dryrun/20-improved-metaskill (durable fix/meta-produced-antipatterns-schema left clean); no PR to main (dry-run). The meta-skill's only behavioral change vs the prior 19-component artifact is the produced anti-patterns.md schema, so the regeneration delta is concentrated there + the SKILL.md routing row (2 files, −39/+9 in anti-patterns.md, 1 line in SKILL.md); all 19 component contracts, examples, foundations, tokens.md, and design-craft.md carry forward byte-identical.
Produced-mode check-skill-docs.sh (--ds-package-root node_modules/@primer/primitives): CHECK_RESULT=PASS exit 0, every row green.
Rubric — #40's acceptance criteria
| # | Acceptance row (rubric from #40) | Verdict | Evidence |
|---|---|---|---|
| 1 | references/design-craft.md byte-identical to WS1 hash + routing row fires | PASS | git hash-object …/design-craft.md = 1d09044e35ad17d60ce9c9998f082690c502a2d3. Carried forward verbatim (cp by scaffold.sh, not regenerated). Audit DESIGN_CRAFT=PASS asserts both the byte-diff and the SKILL.md routing row. |
| 2 | DS-specific taste rules from primer.style prose with citations | PASS (same depth-1 scope caveat as runs #1–#5) | 10 foundation rules cited, 0 [VERIFY]: audit FOUNDATION_RULES=10 cited=10 verify=0. 5 token/* in foundations/primitives.md (+ duplicated as ### token/* subsections in tokens.md) + 3 asset/* in foundations/octicons.md, each per-URL cited to https://primer.style/…. Carried forward unchanged. |
| 3 | Zero positive prop/enum claims outside the claims file; probe typechecks; zero cited local paths failing test -e; zero lib-esm import references | PASS | Phase-2 proof point: 101 prop/enum claims verified against @primer/react@38.26.0 + @primer/octicons-react@19.28.0 (86 positive + 15 negative, 0 typecheck errors). Re-checked at persist: CITATION_VERIFICATION Layer-1 resolves 290/290 prose cites (0 unresolved, 0 out-of-range) — every cited node_modules/@primer/…dist/… path resolves. lib-esm appears in exactly 2 places, both prohibition rules (SKILL.md Import rules + AGENTS.md failure mode) — zero taught lib-esm imports (the 3rd prohibition, in the old Layer B trap table, was removed with that table). |
| 4 | [VERIFY]: 0 unresolved, or each remaining accepted + listed | PASS (1, pre-accepted) | 1 marker preserved verbatim at references/foundations/octicons.md:25 (asset/octicon-name-size-suffix — the Octicons catalog has no naming-convention anchor; 12/12 exemplar-consumed octicon exports grep-resolve in icons.d.ts@19.28.0). Pre-accepted across runs #1–#5. Uses the [VERIFY: <reason>] form, so the audit's strict grep counts VERIFY_MARKERS=0. |
| 5 | check-skill-docs.sh produced-mode exit 0 (incl. TOKEN_COVERAGE, SLATE_COVERAGE for 19, DESIGN_CRAFT=PASS) | PASS | Exit 0, CHECK_RESULT=PASS. All rows: ROUTING_TABLE, COMPONENT_FILES, BEST_PRACTICES_COVERAGE, SLUG_RESOLUTION, VERIFY_MARKERS=0, FOUNDATION_RULES=10 cited=10 verify=0, SCOPE_GUARDRAIL, WIRING_NOT_SYNTHESIZED, EXAMPLES_INDEX, FOUNDATIONS_INDEX, TOKEN_COVERAGE=PASS (12/12), SHELL_INVARIANTS=PASS, SLATE_COVERAGE=PASS (19/19), DESIGN_CRAFT=PASS, PROBE_DERIVED_TOKENS=NONE, CITATION_VERIFICATION=NONE (resolution-only PASS - no claims file). |
| 6 | Adversarial spot-check by a fresh agent: 10 random prop claims vs dist/*.d.ts | NOT ATTEMPTED (operator-side) | Per the #43 body step 7 + loop guard, this row needs an agent with no extraction context — it stays operator-side. The surgical run did not touch any prop/enum contract file, so run #5's 10/10 instrument re-runs unchanged against this artifact. |
| 7 | Every slate component (19) has its own contract section; StateLabel lifecycle-vs-metadata present | PASS | 19/19 per-file contracts under references/components/ + the ## Component slate declaration (audit SLATE_COVERAGE=PASS). StateLabel-for-lifecycle / Label-for-metadata present in BOTH state-label.md (13 lifecycle/octiconMap/pullMerged hits) AND label.md (7 lifecycle/StateLabel hits). Carried forward unchanged. |
| 8 | BranchName as="span" rule present | PASS | branch-name.md carries 8 as="span" mentions (description, When-to-use, Accessibility, Best Practices, Composition, Things-to-never-invent). Carried forward unchanged. |
Registry-scoped anti-patterns.md — the focus of this run
| New-for-this-run criterion | Verdict | Evidence |
|---|---|---|
Produced anti-patterns.md is a thin slug registry: shell/* Bad/Good/Why table + asset/* registry, and nothing else | PASS | The only ## headings in the file are ## Layer B — Shell invariants (Bad/Good/Why) (6 shell rows) and ## Asset rules — octicons (3 asset/* registry lines), under a one-paragraph "this is a registry, not a generation-time load target" preamble. Nothing else. |
No "Layer C — Meta-skill craft" section; no craft/ / wiring/ / cite/ / state/ / Layer-C component/* governance | PASS | grep -ciE 'Layer C|Meta-skill craft|craft/|wiring/|state/|cite/|regenerated-not-copied|css-prose-summary|slate-contract-missing' → 0. The leaked craft/regenerated-not-copied, wiring/css-prose-summary, and component/slate-contract-missing Layer C rows are removed (none were referenced anywhere else in the produced skill). |
| No component-trap consolidation table | PASS | The 22-row "Layer B — Component traps" table is removed. Verified before removal that every trap already lives in its per-component file (Button warning/loading, IconButton aria-label/tooltipDirection, TextInput leadingVisual, Textarea resize, Select multiple/placeholder, Stack direction/gap/justify/baseline, Label-vs-StateLabel, Text variant/weight, Heading as, BranchName as=span, StateLabel pullMerged, Flash variant, CounterLabel scheme, octicon closed-prop-surface) — every component file ships a ## Common mistakes / ## Things to never invent section. Removal is pure de-duplication; nothing lost. |
Token-discipline rows live in references/tokens.md, not in anti-patterns.md | PASS | anti-patterns.md: 0 token//hex-literal/ad-hoc rows. tokens.md: 8 token-discipline rows (## Token usage rules table + 5 ### token/* foundation subsections). |
SKILL.md routing table does not route to anti-patterns.md "during generation" | PASS | The old generation-time row (user reads a known anti-pattern → references/anti-patterns.md) is relabeled to the sanctioned maintenance form: | (maintenance) slug registry / audit | references/anti-patterns.md | shell + asset slug resolution; rules mirrored into ## Hard rules + per-component files; not required during generation | (per skill-template.md). |
SLUG_RESOLUTION=PASS with asset/* resolving against the thin anti-patterns.md; SHELL_INVARIANTS=PASS | PASS | Audit SLUG_RESOLUTION=PASS (3 asset/* slugs resolve against the asset registry; 5 token/* resolve in tokens.md; no orphaned component/*). SHELL_INVARIANTS=PASS (all 6 cited shell/* slugs resolve against the shell table). |
Notes for the operator tick-off
- CITATION_VERIFICATION posture: the produced skill ships no claims file, so the produced-mode gate operates in
resolution-only NONEmode (run-#5 posture) — Layer-1 resolution PASSES across all 290 prose cites; the Phase-2 scratchclaims.txt(6/10-row partial) was moved aside so its partial coverage does not register 280 falseuncoveredmisses. Building out the full CITE-coverage set remains the documented follow-up (PR #51 produced the equivalent for the run-#4 baseline). dry-runs/snapshot skipped this iteration (Ralph scope: persist + commit); freeze manually withcp -R .claude/skills/primer-react/ dry-runs/2026-06-13-primer-react-registry/extracted-skill/if a frozen artifact is wanted.- Pre-commit hook:
tsc --noEmitPASS. Zero extractor (extract-ds-skill) files touched. - Loop guard respected — #40 left OPEN for the operator's final tick-off; only #43 (this Phase-3 ticket) is closed by the loop.
Phase tickets for run #2:
The loop must never close this issue (#40). Operator does the final tick-off after reviewing the landing PR from
feature/regenerate-primer-react.