#40

WS2 · Regenerate primer-react through the corrected registry-scoped meta-skill (HITL)

OpendieDeMiguelopened 5mo ago

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.md now define the produced anti-patterns.md as a thin slug-resolution / audit registry: the shell/* Bad/Good/Why table + the asset/* 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 advertise anti-patterns.md as 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 current primer-react (19 components) to overwrite. Do NOT use feature/regenerate-primer-react (prior run, merged).
  • The copy is on fix/meta-produced-antipatterns-schema; optionally git switch -c dryrun/20-improved-metaskill in the copy so commits land on a throwaway dryrun branch. Output stays in the copy — no PR to main (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/primitives
  • https://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-react in the copy — see #43.

Acceptance criteria

Carried from run #2:

  • references/design-craft.md present, byte-identical to hash 1d09044e35ad17d60ce9c9998f082690c502a2d3; the routing row fires.
  • DS-specific taste rules extracted from primer.style prose 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; zero lib-esm references.
  • [VERIFY]: 0 unresolved, or each remaining marker explicitly accepted and listed.
  • check-skill-docs.sh produced-mode exit 0 (incl. TOKEN_COVERAGE, SLATE_COVERAGE for 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.md is a thin slug registry: it contains the shell/* Bad/Good/Why table and the asset/* registry — and nothing else.
  • No "Layer C — Meta-skill craft" section, and no craft/ / wiring/ / cite/ / state/ / Layer-C component/* governance in the produced anti-patterns.md.
  • No component-trap consolidation table in anti-patterns.md (component traps live only in references/components/<name>.md).
  • Token-discipline rows live in references/tokens.md, not in the produced anti-patterns.md.
  • The SKILL.md routing table does not route an agent to anti-patterns.md "during generation" (omitted, or a maintenance/registry-labeled row).
  • SLUG_RESOLUTION=PASS with asset/* 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, commit edbdaf7.
  • Prior runs: #31 (run #1), #40 / #41 / #42 / #43 (run #2 — this set, now repurposed), #33 (harvest convergence, 15 → 19).

Activity

3
dieDeMiguel5mo ago

Phase tickets for run #2:

  • Phase 1: #41 (discovery — Ralph-runnable now; no blockers)
  • Phase 2: #42 (validate — blocked by #41)
  • Phase 3: #43 (persist + audit — blocked by #42)

The loop must never close this issue (#40). Operator does the final tick-off after reviewing the landing PR from feature/regenerate-primer-react.

dieDeMiguel5mo ago

Run #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 rowVerdictEvidence
1references/design-craft.md byte-identical to WS1 hash + routing row firesPASSgit 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.
2DS-specific taste rules from primer.style prose with citationsPASS (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.
3Zero positive prop/enum claims outside claims file; probe typechecks; zero cited local paths failing test -e; zero lib-esm referencesPASS93 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 + listedPASS (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.
5check-skill-docs.sh produced-mode exit 0 (incl. TOKEN_COVERAGE, SLATE_COVERAGE, DESIGN_CRAFT=PASS)PASSExit 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).
6Adversarial spot-check by a fresh agent: 10 random prop claims vs dist/*.d.tsNOT 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.)
7Every slate component has its own contract section; StateLabel lifecycle-vs-metadata presentPASS15/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.
8BranchName as="span" rule presentPASSreferences/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.

dieDeMiguel5mo ago

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)VerdictEvidence
1references/design-craft.md byte-identical to WS1 hash + routing row firesPASSgit 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.
2DS-specific taste rules from primer.style prose with citationsPASS (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.
3Zero positive prop/enum claims outside the claims file; probe typechecks; zero cited local paths failing test -e; zero lib-esm import referencesPASSPhase-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 + listedPASS (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.
5check-skill-docs.sh produced-mode exit 0 (incl. TOKEN_COVERAGE, SLATE_COVERAGE for 19, DESIGN_CRAFT=PASS)PASSExit 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).
6Adversarial spot-check by a fresh agent: 10 random prop claims vs dist/*.d.tsNOT 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.
7Every slate component (19) has its own contract section; StateLabel lifecycle-vs-metadata presentPASS19/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.
8BranchName as="span" rule presentPASSbranch-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 criterionVerdictEvidence
Produced anti-patterns.md is a thin slug registry: shell/* Bad/Good/Why table + asset/* registry, and nothing elsePASSThe 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/* governancePASSgrep -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 tablePASSThe 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.mdPASSanti-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"PASSThe 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=PASSPASSAudit 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 NONE mode (run-#5 posture) — Layer-1 resolution PASSES across all 290 prose cites; the Phase-2 scratch claims.txt (6/10-row partial) was moved aside so its partial coverage does not register 280 false uncovered misses. 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 with cp -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 --noEmit PASS. 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.