Summary
The framework's promise is "generate enforcement rules from principles, not copy-pasted presets" (README "Methodology"), but it currently ships one preset — preset-next-15-canonical — and install.sh only accepts ts-server / react-next. This issue tracks making the one-button install configure the full enforcement perimeter (rules-as-tests + mutation + arch boundaries + hooks/CI + docs/skills/agents) for more stacks, in two stages:
- Stage 1 (curated bridge): add
react (SPA) and react-native (Expo/RN) presets by hand. Cheap relative to Stage 2, not zero — includes de-Next-ifying shared templates (eslint.config.react.mjs currently pulls @next/eslint-plugin-next).
- Stage 2 (general): realize the deferred L2 LLM-driven research path so an arbitrary detected stack is researched → synthesized → self-validated → installed, removing the per-stack hand-authoring bottleneck — without weakening "documents lie; tests don't".
Why it's Next-only today (grounded)
- The engine is already stack-agnostic:
synthesizer/synthesize.ts is a pure ResearchPlan → SynthesisPlan function, recipes filtered by an appliesTo: string[] framework key. The detector already generalizes (packages/core/detector/ emits stack + version + missing[] for any project; does not assume Next).
- The content is Next-only:
synthesizer/recipes/ has 5 files, all next-* / nextjs-*; only preset package is packages/preset-next-15-canonical/. Its 3 ESLint rules are Next-specific (RSC server/client boundary + server actions).
- The research layer (L2) was pivoted to deterministic-curated in Phase 5 — no live LLM/HTTP at runtime (
retros/phase-5.md:14-19). LLM-driven research is the documented future superset, deferred to a v2 trigger (retros/phase-5.md:81,151); the v2 contract (Anthropic web_search + allowed_domains) is already stubbed as a static allowlist (:19,73).
- Stack-agnostic core already applies to any TS project:
no-direct-time-randomness, no-unsafe-zod-parse, require-otel-span (packages/core/eslint-rules/).
So "more stacks" is blocked on rule content, not the pipeline.
Stage 1 — curated react and react-native presets
Presets
packages/preset-react-spa/ — React 19 SPA on Vite (no SSR / server actions).
packages/preset-react-native/ — Expo / React Native.
Mirror the preset-next-15-canonical layout: eslint-rules/, templates/ (eslint config, test-runner config, ARCHITECTURE.*.md, CI workflow), RULES.*.md, audit-self/.
Installer wiring
- Accept
react / react-native in the arg parser (install.sh:81) and stack guard (:189).
- Add menu options
3) react / 4) react-native (install.sh:177-190).
- Extend auto-detect: react-native/expo in deps →
react-native; react-dom present and next absent → react; else existing fallback.
Rules — REUSE first (per build-first-reuse-default.md)
- React SPA: ADOPT
eslint-plugin-react, eslint-plugin-react-hooks (exhaustive-deps), eslint-plugin-jsx-a11y (already in the dev-dep list). BUILD only gap rules, candidates: no-business-logic-in-component (via dependency-cruiser layer boundary), require-error-boundary.
- React Native: BUILD where no upstream analog fits —
no-web-only-globals (flag document/window/localStorage/DOM in RN), require-stylesheet-create, prefer-flashlist-over-flatlist. Each ships a paired valid/invalid test (principle 02).
- REFERENCE existing ecosystem skills instead of re-deriving RN best practices:
react-native-best-practices, building-native-ui, vercel-react-native-skills, treemap-rn.
- Prior-art SSOT is empty for these plugins — no
eslint-plugin-react/react-native entries in prior-art-evaluations.md today. The BUILD candidates above are hypotheses pending a per-preset R-phase (DeepWiki/WebSearch ≥3 phrasings + SSOT consult), not approved builds. Stage 1 adds the ADOPT/BUILD verdict entries as an explicit deliverable (each rule is a capability commit).
These two presets also serve as the proving cases for Stage 2's generate path.
Stage 2 — any detected stack (L2 LLM research path / v2)
L2 Research Agent — LLM path (Planner, read-only)
Implement the live path behind the existing L2 interface (packages/core/research/): given {stack, version, missing[]} from the detector, produce a versioned ResearchPlan (research-plan.schema.json) via Anthropic web_search constrained to allowed_domains. Planner is read-only — never writes files (keeps the L2/L3 prompt-injection firewall: untrusted fetched docs can't reach disk).
L3 Synthesizer — generalize beyond curated recipes
When no curated recipe matches a researched pattern, emit a candidate rule from the research plan as a structured, validated SynthesisPlan (never free-form LLM code). Curated recipes stay the deterministic fast-path/cache for known stacks (Next stays byte-stable).
L4 Self-validation gate — BUILD, then mandatory (tenet-preserving)
Every generated rule — curated or LLM-derived — must pass the principle gate before install: paired negative test (02), non-tautological (04), AST-over-grep where applicable (03), manifest-SSOT (05). A rule that can't fail against a synthetic violation fixture is dropped, not shipped. Determinism moves from "how the rule was authored" to "the rule provably fails when violated". Note: the L4 install-gate does not exist yet — retros/phase-5.md deferred the L4 Validator to "Phase 7+". Building it is an explicit Stage 2 deliverable, not a pre-existing mechanism this stage merely invokes.
Installer wiring — generic stack
- Detector result → curated preset if one exists, else the generate-and-validate flow.
- Generation is an explicit, consumer-side, opt-in step (
--generate / AIF_RESEARCH=llm) run install-time on the consumer's own Claude subscription — never in CI, so no-paid-llm-in-ci.md is intact. The framework itself never bills: any cost is the consumer's own, incurred only on explicit opt-in.
- Cache the generated
ResearchPlan + SynthesisPlan into .ai-factory/ so re-installs / --refresh are deterministic and reviewable (snapshot the artifact, not the generation).
Sequencing commitment (hybrid decision — added 2026-06-19)
Stage 1 is a bridge, not a terminus. To prevent it from stranding 3 hand-maintained presets (the "stale presets" failure README §Methodology warns of):
- On Stage 1 close (both presets merged) → the merging session writes
docs/meta-factory/research-patches/<date>-phase-5-v2-trigger-fired.md (fires the deferred Phase-5 v2 trigger this issue already names) AND opens the Stage 2 tracking umbrella. Stage 2 is the mandatory immediately-following umbrella, not "someday".
- Until that patch lands, every hand-authored preset beyond Next is tracked debt against README §Methodology, not silent drift.
Design rationale: docs/superpowers/specs/2026-06-19-multi-stack-hybrid-design.md (hybrid A-now + B-committed, with full A-vs-B trade-off analysis).
Acceptance criteria
Stage 1:
./install.sh react --dry-run and ./install.sh react-native --dry-run complete with ✅ Dry-run complete, no ❌ Unknown stack.
- Fresh Vite-React and Expo repos install cleanly; lint / test / arch:check / test:mutation all run; at least one custom rule per stack catches its target antipattern.
Stage 2:
./install.sh --generate on a stack with no curated preset (e.g. SvelteKit, Vue SPA, Fastify-only) installs a stack-appropriate set; every generated rule has a passing/failing paired test; rules failing the L4 gate are reported and excluded.
- Next.js path stays byte-identical; re-install from cache is deterministic.
Both: make self-audit stays green (recursive self-application unbroken); auto-detect picks the right stack from package.json.
Conventions to honor (repo discipline)
- Each new preset/rule is a capability commit → prior-art consult (
docs/meta-factory/prior-art-evaluations.md) + DeepWiki/WebSearch ≥3 phrasings + Prior-art: trailer (CLAUDE.md "Build-vs-reuse invariant"). Default per build-first-reuse-default.md: ADOPT upstream lint plugins; BUILD only genuine gaps + the research→synthesize→validate pipeline.
- New shipped docs (
RULES.*.md, ARCHITECTURE.*.md) carry Authoritative for: headers and join SHIPPED_DOCS in install.sh (principle 09). New rules ship paired negative tests (principle 02), AST-over-grep where applicable (principle 03).
- Stage 2 must preserve the L2 (read-only Planner) / L3 (validated-output-only) prompt-injection split; LLM fetch constrained to
allowed_domains. no-paid-llm-in-ci.md unchanged (research is install-time, not CI). Document Stage 2 as the firing of the deferred Phase-5 v2 trigger in a research-patch.
Risks / open questions
- LLM non-determinism → mitigated by L4 gate + caching the generated artifact; open: how to snapshot-test a path whose first run is variable (test the validator on fixtures, not raw generator output).
- Research quality for niche stacks → low-confidence stacks install only stack-agnostic core + flag "generated, review before trusting"; never claim full coverage.
Code claims in this issue verified against staging on 2026-06-19: install.sh:81 accepts only ts-server|react-next (guard :189-190, menu :179-184); synthesizer/recipes/ = 5 files, all next-*/nextjs-*; single packages/preset-next-15-canonical; 3 agnostic core rules in packages/core/eslint-rules/; L2 scaffolding present (packages/core/research/ incl. research-plan.schema.json, allowlist.ts, validate-plan.ts).
Summary
The framework's promise is "generate enforcement rules from principles, not copy-pasted presets" (README "Methodology"), but it currently ships one preset —
preset-next-15-canonical— andinstall.shonly acceptsts-server/react-next. This issue tracks making the one-button install configure the full enforcement perimeter (rules-as-tests + mutation + arch boundaries + hooks/CI + docs/skills/agents) for more stacks, in two stages:react(SPA) andreact-native(Expo/RN) presets by hand. Cheap relative to Stage 2, not zero — includes de-Next-ifying shared templates (eslint.config.react.mjscurrently pulls@next/eslint-plugin-next).Why it's Next-only today (grounded)
synthesizer/synthesize.tsis a pureResearchPlan → SynthesisPlanfunction, recipes filtered by anappliesTo: string[]framework key. The detector already generalizes (packages/core/detector/emits stack + version +missing[]for any project; does not assume Next).synthesizer/recipes/has 5 files, allnext-*/nextjs-*; only preset package ispackages/preset-next-15-canonical/. Its 3 ESLint rules are Next-specific (RSC server/client boundary + server actions).retros/phase-5.md:14-19). LLM-driven research is the documented future superset, deferred to a v2 trigger (retros/phase-5.md:81,151); the v2 contract (Anthropicweb_search+allowed_domains) is already stubbed as a static allowlist (:19,73).no-direct-time-randomness,no-unsafe-zod-parse,require-otel-span(packages/core/eslint-rules/).So "more stacks" is blocked on rule content, not the pipeline.
Stage 1 — curated
reactandreact-nativepresetsPresets
packages/preset-react-spa/— React 19 SPA on Vite (no SSR / server actions).packages/preset-react-native/— Expo / React Native.Mirror the
preset-next-15-canonicallayout:eslint-rules/,templates/(eslint config, test-runner config,ARCHITECTURE.*.md, CI workflow),RULES.*.md,audit-self/.Installer wiring
react/react-nativein the arg parser (install.sh:81) and stack guard (:189).3) react/4) react-native(install.sh:177-190).react-native;react-dompresent andnextabsent →react; else existing fallback.Rules — REUSE first (per
build-first-reuse-default.md)eslint-plugin-react,eslint-plugin-react-hooks(exhaustive-deps),eslint-plugin-jsx-a11y(already in the dev-dep list). BUILD only gap rules, candidates:no-business-logic-in-component(via dependency-cruiser layer boundary),require-error-boundary.no-web-only-globals(flagdocument/window/localStorage/DOM in RN),require-stylesheet-create,prefer-flashlist-over-flatlist. Each ships a paired valid/invalid test (principle 02).react-native-best-practices,building-native-ui,vercel-react-native-skills,treemap-rn.eslint-plugin-react/react-nativeentries inprior-art-evaluations.mdtoday. The BUILD candidates above are hypotheses pending a per-preset R-phase (DeepWiki/WebSearch ≥3 phrasings + SSOT consult), not approved builds. Stage 1 adds the ADOPT/BUILD verdict entries as an explicit deliverable (each rule is a capability commit).These two presets also serve as the proving cases for Stage 2's generate path.
Stage 2 — any detected stack (L2 LLM research path / v2)
L2 Research Agent — LLM path (Planner, read-only)
Implement the live path behind the existing L2 interface (
packages/core/research/): given{stack, version, missing[]}from the detector, produce a versionedResearchPlan(research-plan.schema.json) via Anthropicweb_searchconstrained toallowed_domains. Planner is read-only — never writes files (keeps the L2/L3 prompt-injection firewall: untrusted fetched docs can't reach disk).L3 Synthesizer — generalize beyond curated recipes
When no curated recipe matches a researched pattern, emit a candidate rule from the research plan as a structured, validated
SynthesisPlan(never free-form LLM code). Curated recipes stay the deterministic fast-path/cache for known stacks (Next stays byte-stable).L4 Self-validation gate — BUILD, then mandatory (tenet-preserving)
Every generated rule — curated or LLM-derived — must pass the principle gate before install: paired negative test (02), non-tautological (04), AST-over-grep where applicable (03), manifest-SSOT (05). A rule that can't fail against a synthetic violation fixture is dropped, not shipped. Determinism moves from "how the rule was authored" to "the rule provably fails when violated". Note: the L4 install-gate does not exist yet —
retros/phase-5.mddeferred the L4 Validator to "Phase 7+". Building it is an explicit Stage 2 deliverable, not a pre-existing mechanism this stage merely invokes.Installer wiring — generic stack
--generate/AIF_RESEARCH=llm) run install-time on the consumer's own Claude subscription — never in CI, sono-paid-llm-in-ci.mdis intact. The framework itself never bills: any cost is the consumer's own, incurred only on explicit opt-in.ResearchPlan+SynthesisPlaninto.ai-factory/so re-installs /--refreshare deterministic and reviewable (snapshot the artifact, not the generation).Sequencing commitment (hybrid decision — added 2026-06-19)
Stage 1 is a bridge, not a terminus. To prevent it from stranding 3 hand-maintained presets (the "stale presets" failure README §Methodology warns of):
docs/meta-factory/research-patches/<date>-phase-5-v2-trigger-fired.md(fires the deferred Phase-5 v2 trigger this issue already names) AND opens the Stage 2 tracking umbrella. Stage 2 is the mandatory immediately-following umbrella, not "someday".Design rationale:
docs/superpowers/specs/2026-06-19-multi-stack-hybrid-design.md(hybrid A-now + B-committed, with full A-vs-B trade-off analysis).Acceptance criteria
Stage 1:
./install.sh react --dry-runand./install.sh react-native --dry-runcomplete with✅ Dry-run complete, no❌ Unknown stack.Stage 2:
./install.sh --generateon a stack with no curated preset (e.g. SvelteKit, Vue SPA, Fastify-only) installs a stack-appropriate set; every generated rule has a passing/failing paired test; rules failing the L4 gate are reported and excluded.Both:
make self-auditstays green (recursive self-application unbroken); auto-detect picks the right stack frompackage.json.Conventions to honor (repo discipline)
docs/meta-factory/prior-art-evaluations.md) + DeepWiki/WebSearch ≥3 phrasings +Prior-art:trailer (CLAUDE.md "Build-vs-reuse invariant"). Default perbuild-first-reuse-default.md: ADOPT upstream lint plugins; BUILD only genuine gaps + the research→synthesize→validate pipeline.RULES.*.md,ARCHITECTURE.*.md) carryAuthoritative for:headers and joinSHIPPED_DOCSininstall.sh(principle 09). New rules ship paired negative tests (principle 02), AST-over-grep where applicable (principle 03).allowed_domains.no-paid-llm-in-ci.mdunchanged (research is install-time, not CI). Document Stage 2 as the firing of the deferred Phase-5 v2 trigger in a research-patch.Risks / open questions
Code claims in this issue verified against
stagingon 2026-06-19:install.sh:81accepts onlyts-server|react-next(guard:189-190, menu:179-184);synthesizer/recipes/= 5 files, allnext-*/nextjs-*; singlepackages/preset-next-15-canonical; 3 agnostic core rules inpackages/core/eslint-rules/; L2 scaffolding present (packages/core/research/incl.research-plan.schema.json,allowlist.ts,validate-plan.ts).