Agentic Project Foundation
Status: Reference — P0 → P7 substrate shipped (with caveats — see phase table). Active for ratchet shrink + remaining DOC-planned ESLint rules. Last updated: 2026-06-27 Owner: TwoMore mobile team
This is the canonical master plan for TwoMore's foundational infrastructure. It is built on the explicit acknowledgment that the project will continue to grow under an agentic workflow — most code changes will be authored by AI agents (Claude, Cursor, Aider, etc.), reviewed and approved by humans.
That constraint changes how we build infrastructure. Patterns optimized for human-only contributors are insufficient. Agents:
- Read documentation differently than humans (literal-minded, prone to hallucinated compliance)
- Have no native organizational structure to act as a Conway-Law constraint
- Can fabricate success claims (we've experienced this multiple times)
- Scale prompt-driven complexity faster than review can catch (5.9× LoC growth observed in research)
- Trust accumulates → supervision atrophies → drift accumulates invisibly (paradox of supervision)
The infrastructure must be mechanical, not merely documentary. It must make the right thing easier than the wrong thing. It must surface drift as a measurable signal, not wait for review to catch it.
The 9 infrastructure layers
┌──────────────────────────────────────────────────────────────┐
│ L9 Knowledge management — ADRs, generated graphs, blueprints│
├──────────────────────────────────────────────────────────────┤
│ L8 Process governance — phase gates, bake times, checklists │
├──────────────────────────────────────────────────────────────┤
│ L7 Observability — sensors, trends, health scores │
├──────────────────────────────────────────────────────────────┤
│ L6 CI required checks (drift action, fitness, types, lint) │
├──────────────────────────────────────────────────────────────┤
│ L5 Pre-commit/push hooks (verify-no-stale-claims, hooks) │
├──────────────────────────────────────────────────────────────┤
│ L4 Architecture fitness tests (ArchUnitTS) │
├──────────────────────────────────────────────────────────────┤
│ L3 ESLint custom rules (eslint-plugin-twomore) │
├──────────────────────────────────────────────────────────────┤
│ L2 Type system (branded types, discriminated unions) │
├──────────────────────────────────────────────────────────────┤
│ L1 Code generation (Hygen templates) — wrong path is harder │
├──────────────────────────────────────────────────────────────┤
│ L0 Agent ergonomics — AGENTS.md, prompt templates, verify │
└──────────────────────────────────────────────────────────────┘L0 is the agentic-specific addition. Without it, every layer above is operating without explicit awareness of who its primary consumer is.
Current state vs. target
| Layer | Current state | Target |
|---|---|---|
| L0 Agent ergonomics | AGENTS.md with 43 hard-constraint IDs + 8 AOR, CLAUDE.md rationale, prompt templates, review checklist, verify hooks | Keep AGENTS.md parseable and shrink remaining DOC-planned entries |
| L1 Code gen | Hygen templates for hook / mutation / screen / store (P5 shipped) | Add generators for adapter / port / domain entity as those layers grow |
| L2 Type system | TypeScript strict + branded types for MutationKey, QueryFreshness, StoragePartition (P5) | Add branded types for entity IDs (UserId, ClubId, etc.) as part of the Zod-schema migration |
| L3 ESLint | 52 active @twomore/* rules + recommended ruleset + 4-rule/87-waiver ratchet baseline | Drop ratchet entries by migrating waivered files to compliance |
| L4 Fitness tests | ArchUnitTS as the canonical layer (16 tests) + fs arch-test for TYPE-3 Zod schema coverage | Expand ArchUnitTS as new architectural truths solidify |
| L5 Pre-commit/push | Prettier (lint-staged) + pre-push: docs:check + typecheck + tests + lint:strict + lint:agents-md + verify:no-stale-claims | Keep hooks aligned with CI and avoid local-only bypasses |
| L6 CI required checks | GitHub Actions (P0.6) mirrors pre-push gates, including docs:check, plus drift action (P6, non-blocking) and supabase type-drift gate (P6, opt-in via secret) | Tighten drift fail-on from none to high after 1-week bake; activate supabase gate when secret lands |
| L7 Observability | yarn metrics snapshot + CI artifact upload (P7) — single point-in-time JSON; no trend yet | Weekly cron job that commits snapshot to a metrics branch + dependency graph artifact (P7-followup) |
| L8 Process governance | Phase gates in this doc | Formalized with bake times tracked, ADR directory |
| L9 Knowledge mgmt | rebuild-log + screen-blueprint + 2 strategy docs | + ADR directory, generated dependency graphs, sub-plan cross-links |
The original L3 ESLint gap is closed. The current work is ratchet shrink and turning the three remaining DOC-planned AGENTS entries into mechanical guards when their shapes are stable enough.
Sub-plans in scope
This master plan delegates phase-specific detail to two existing canonical sub-plans:
docs/architecture/networking-foundation-plan.md— Phase 14 (networking architecture: MMKV → persisted cache → AppState realtime → mutation queue → sync UI → freshness contracts). 6 layers, sequential bake gates, ~12 working days + ~6 weeks of bake time.docs/architecture/drift-prevention.md— 7-layer mechanical enforcement strategy with v2 refinements grounded in industry/academic research (Ford's Building Evolutionary Architectures, Shopify Packwerk, ICPC 2021, ArchUnitTS,driftGitHub Action, AGENTS.md Linux Foundation spec).
This master plan adds:
- L0 Agent ergonomics layer — the agentic-specific infrastructure that makes the other 8 layers usable by AI contributors without drift.
Phased rollout
Strict sequential. Each phase has a gate that must pass before the next begins. Phases are designed so that each one leaves the project in a strictly better state than before, even if the next phase is delayed.
| Phase | Layer focus | Scope | Effort | Bake gate |
|---|---|---|---|---|
| P0 | L0 + L9 | AGENTS.md atomic constraints, agent prompt templates, CLAUDE.md cleanup (remove fictional claims), ADR directory | 4h | exit criteria below |
| P0.5 | L0 + L5 | verify-no-stale-claims + pre-push hook + AGENTS.md schema lint + AGENTS.md consolidation (68 rules → 42) | 4h | 1 day, hook fires on at least one real commit |
| P0.6 | L6 | GitHub Actions CI mirroring pre-push gates, including docs drift checks; required-status-check on main closes the local-bypass channel | 1h | 1 successful CI run on main |
| P1 | L3 baseline | ESLint 9 + flat config + recommended rules (typescript-eslint, react, react-hooks, jsx-a11y, prettier-compat); root yarn lint; pre-push + CI wired | 4h | shipped — 0 errors / 40 advisory warnings on existing codebase |
| P2 | L3 plugin | @twomore/eslint-plugin scaffold + first rule (no-asyncstorage-outside-migration) + 9 RuleTester cases | 3h | shipped — rule blocks AsyncStorage outside allowlisted paths |
| P3 | L3 + L8 | Project ESLint plugin + ratchet baseline; later expanded into the current 52 active @twomore/* rules | 6h | shipped — baseline evolved; current snapshot is 52 active rules and 4 ratchet rules with 87 waivers |
| P4 | L4 | ArchUnitTS as the single fitness layer — 16 tests covering ARCH-1/2/3/4 + hex direction + UI purity + cycles + feature-package.json deps. Legacy file retired in P4d. | 4h | shipped — ARCH-1/2/3/4 all enforced via ArchUnitTS (ARCH-4 via custom adhereTo for the navigation allowlist) |
| P5 | L1 + L2 | Hygen templates (hook / mutation / screen / store) + branded types (MutationKey, QueryFreshness, StoragePartition) | 8h | shipped — every generator produces lint:strict + typecheck-clean output out of the box |
| P6 | L5 + L6 | drift GitHub Action (mick-gsk/drift@v2, non-blocking) + Supabase type-drift gate (yarn check:supabase-types, gated on SUPABASE_PROJECT_ID secret) | 4h | wired — drift activates on next CI run (post-billing); supabase gate activates when project-id secret lands |
| P7 | L7 | yarn metrics health snapshot (lint, ratchet, ArchUnitTS, LoC, AGENTS.md mechanical coverage) + CI artifact upload (90-day retention). Weekly trend job + dep graph deferred to P7-followup | 4h | shipped — current snapshot: 40 of 43 hard constraints mechanically enforced, 0/0 lint, 87 ratchet waivers |
Total: ~39 hours of foundational enforcement work (~5 working days) across 9 sequential phases (P0, P0.5, P1–P7). Then Phase 14 networking foundation begins on top.
P0 exit criteria (measurable)
P0 is "baked" only when ALL of the following are observably true:
AGENTS.mdexists at repo root and parses as valid Markdown — every constraint table has the columnsID | Rule | enforcement, every row matches its header column count, every ID follows the<PREFIX>-<NUMBER>format, IDs are unique within their prefix (validated byyarn lint:agents-mdshipped in P0.5), and every rule has a non-DOC-bare enforcement label (either an active mechanical layer,DOC (planned: <named layer>), orRuntime (<external system>)). NoREVIEWentries.docs/agent-prompts/contains at least 5 templates (add-screen,add-mutation,add-query,refactor-shared,perf-investigation) and aREADME.mdindex.docs/adr/containsREADME.md,TEMPLATE.md, and0001-agentic-project-foundation.md. ADR-0001's arXiv citations are verified to resolve (not fabricated).CLAUDE.mdno longer claims ESLint enforcement that does not exist; the "Enforcement Stack" section reflects honest current state with a planned-vs-current split.- The pointer banner at the top of CLAUDE.md tells agents to read AGENTS.md first.
- At least one real commit on the project after P0 lands has actually been authored against an
agent-prompts/template (proof of usability, not just publication).
If any of items 1–5 are false, P0 is not done and must be fixed before P0.5 begins. Item 6 is a soft signal — track it; if no template-driven commit lands within 7 days, the templates aren't usable as written and need revision.
The phases are conservatively scoped so each is independently shippable and rollbackable. If Phase 3's ratchet file is buggy, Phase 4 doesn't start until it's stabilized.
L0 Agent ergonomics — the agentic-specific layer
This is the layer that doesn't exist in human-only project foundations. It accommodates the agentic workflow explicitly.
AGENTS.md (machine-readable atomic constraints)
Following the AGENTS.md spec donated to the Linux Foundation by OpenAI in late 2025, this file holds atomic, parseable directives distinct from human narrative.
The live file is at the repo root: /AGENTS.md. Current shape after the consolidation pass:
- 43 hard constraints in 8 sections (Architecture, Type, Tamagui/styling, Components, Data, Persist stores, Korean market, Code style)
- 8 agent operating rules (consolidated from an earlier 14)
- Every rule has a non-bare
enforcementvalue: an active mechanical layer (e.g.arch-test,TypeScript strict),DOC (planned: <named ESLint or ArchUnitTS rule>), orRuntime (<external system>) - No
REVIEWentries — semantic guidance lives indocs/best-practices/review-checklist.md
The yarn lint:agents-md script (P0.5) enforces this schema mechanically and rejects any rule that introduces REVIEW or bare DOC.
docs/agent-prompts/ templates
Curated prompt templates for common task types so agents don't reinvent context every session:
agent-prompts/add-screen.md— full prompt scaffold for adding a new feature screenagent-prompts/add-mutation.md— for adding a new mutation hookagent-prompts/add-query.md— for query hooksagent-prompts/refactor-shared.md— for shared-package edits (with explicit blast-radius checks)agent-prompts/perf-investigation.md— for performance profiling work
Each template:
- States the task
- Names exact files in/out of scope
- Lists verification steps
- References AGENTS.md hard constraints
- Provides the verification commands
docs/best-practices/review-checklist.md (semantic gates)
Some rules are inherently judgment-based — "render skeletons during loading, not EmptyState"; "use useMemo not useQuery for pure CPU"; "lift state up to avoid double observers." No AST can prove these. Listing them next to mechanically-enforced rules turned AGENTS.md into a wishlist. They now live in this dedicated checklist that reviewers apply at PR time. When eslint-plugin-twomore ships rules that do mechanically detect a CHK-* item, the item moves back into AGENTS.md and is removed from the checklist.
CLAUDE.md cleanup
CLAUDE.md becomes the rationale and narrative companion to AGENTS.md. Its job is to explain why rules exist. The hard constraints live in AGENTS.md. The fictional ESLint claims got removed in P0.
Verify-no-stale-claims hook
A pre-push script that compares the most recent commit message against git diff HEAD~1 to detect false-success claims. If a commit claims "added X to file Y" but the diff doesn't show Y modified, fail the push.
# scripts/verify-no-stale-claims.sh — wired into .husky/pre-push
node scripts/verify-claims.js HEAD || { echo "Commit message claims don't match the diff. Refusing to push."; exit 1; }The script parses commit messages for file-path mentions and verifies each one appears in git diff --name-only HEAD~1 HEAD. It's an honesty check.
Cross-cutting principles
Every rule must have at least one mechanical enforcement layer
Rules that exist only in CLAUDE.md / AGENTS.md without a corresponding ESLint rule, ArchUnitTS test, or type-system constraint are tracked as enforcement debt. The ratio of "rules declared" to "rules mechanically enforced" is a measurable architectural-health metric.
Every architectural change ships with its enforcement
If Phase 14a (MMKV migration) lands without its no-asyncstorage-outside-migration ESLint rule, the next PR can undo the migration silently. Architectural work and its enforcement are inseparable; they ship in the same PR or both wait.
Bake gates are non-negotiable
A phase's bake gate exists because changes touching every screen / every mutation / every store have non-obvious failure modes that surface over days, not minutes. Skipping bakes is how data-loss bugs reach production. We've already seen drift incidents in this conversation; bake gates are the slow-down mechanism that prevents the next class.
Sensors before scale
L7 observability ships before P5/L1 templates because templates without observability mean we can't measure adoption. We need to know whether the templates are being used (by counting generator-provenance markers in new files) before we declare the L1 layer working.
Approval gates
Before P0 begins
(Right now.)
- ✅ This master plan reviewed and approved
- ✅ Sub-plans (networking-foundation, drift-prevention) cross-referenced
- ✅ Estimated effort + bake time accepted
Before any networking foundation work (Phase 14a) begins
All P0–P7 gates passed:
- ✅ AGENTS.md atomic constraints published
- ✅ Agent prompt templates in
docs/agent-prompts/ - ✅ CLAUDE.md fictional claims removed
- ✅ ADR directory established
- ✅ ESLint baseline running on entire codebase without false positives
- ✅
eslint-plugin-twomorewith 4 highest-leverage rules active - ✅ Ratchet baseline file in place; CI enforces it
- ✅ ArchUnitTS migrated with 16 fitness tests passing
- ✅ Hygen templates for hook / mutation / screen / store
- ✅ Branded types: MutationKey, QueryFreshness, StoragePartition
- ✅ verify-no-stale-claims pre-push hook active
- ✅ drift GitHub Action wired with structural health baseline
- ✅ Supabase type drift CI gate active
- ⏳ Weekly trend observability job remains a P7-followup;
yarn metricsis the current point-in-time snapshot
Without these, MMKV migration in Phase 14a degrades on the next PR. With them, that PR doesn't merge.
What this plan is NOT
- Not complete. L8 process governance and L9 knowledge management have implementation details left to expand as we go.
- Not static. Each phase produces lessons; we revise the master plan after every phase.
- Not the only valid path. Industry has multiple valid agentic-foundation patterns; this is the one that fits TwoMore's stack and history.
- Not a substitute for code review. Mechanical layers catch ~90%; review catches the rest. Both required.
How to read this plan
If you're an agent reading this for the first time:
- Read AGENTS.md (hard constraints) — that's the law
- Read CLAUDE.md (rationale) — that's the why
- Read
docs/agent-prompts/<task-type>.mdfor your task - Use the appropriate Hygen template if generating new code
- Run
yarn checkbefore reporting done - Verify
git statusshows your changes after editing
If you're a human reading this for the first time:
- Read this master plan
- Read the sub-plans (networking-foundation, drift-prevention)
- Look at the phase table — your contribution context is whichever phase is currently active
- PR descriptions reference the phase + ADR they relate to