20 KiB
Meta-Repo Workflow
Workflow for meta-repositories — repos that aggregate multiple components via git submodules, npm/cargo/pnpm/go workspaces, or ad-hoc conventions. The meta-repo itself has little or no source code of its own; it orchestrates cross-cutting documentation, CI/CD, and component registration.
This flow differs fundamentally from greenfield and existing-code:
- No problem/research/plan phases — meta-repos don't build features, they coordinate existing ones
- No test spec / implement / run tests — the meta-repo has no code to test
- No
_docs/00_problem/artifacts — documentation target is_docs/*.mdunified docs, not per-feature_docs/NN_feature/folders - Primary artifact is
_docs/_repo-config.yaml— generated bymonorepo-discover, read by every other step
Step Reference Table
| Step | Name | Sub-Skill | Internal SubSteps |
|---|---|---|---|
| 1 | Discover | monorepo-discover/SKILL.md | Phase 1–10 |
| 2 | Config Review | (human checkpoint, no sub-skill) | — |
| 2.5 | Glossary & Architecture Vision | (inline, no sub-skill) | Steps 1–5 |
| 3 | Status | monorepo-status/SKILL.md | Sections 1–5 |
| 4 | Document Sync | monorepo-document/SKILL.md | Phase 1–7 (conditional on doc drift) |
| 4.5 | Integration Test Sync | monorepo-e2e/SKILL.md | Phase 1–6 (conditional on suite-e2e drift; skipped if suite_e2e: block absent in config) |
| 5 | CICD Sync | monorepo-cicd/SKILL.md | Phase 1–7 (conditional on CI drift) |
| 6 | Loop | (auto-return to Step 3 on next invocation) | — |
Onboarding is NOT in the auto-chain. Onboarding a new component is always user-initiated (monorepo-onboard directly, or answering "yes" to the optional onboard branch at end of Step 5). The autodev does NOT silently onboard components it discovers.
Detection Rules
Resolution: when a state file exists, state.step + state.status drive detection and the conditions below are not consulted. When no state file exists (cold start), walk the rules in order — first match wins. Meta-repo uses _docs/_repo-config.yaml (and its confirmed_by_user flag) as its primary folder-probe signal rather than per-step artifact folders.
Step 1 — Discover
Condition: _docs/_repo-config.yaml does NOT exist
Action: Read and execute .cursor/skills/monorepo-discover/SKILL.md. After completion, auto-chain to Step 2 (Config Review).
Step 2 — Config Review (session boundary)
Condition: _docs/_repo-config.yaml exists AND top-level confirmed_by_user: false
Action: This is a hard session boundary. The skill cannot proceed until a human reviews the generated config and sets confirmed_by_user: true. Present using Choose format:
══════════════════════════════════════
DECISION REQUIRED: Config review pending
══════════════════════════════════════
_docs/_repo-config.yaml was generated by monorepo-discover
but has confirmed_by_user: false.
A) I've reviewed — proceed to Status
B) Pause — I'll review the config and come back later
══════════════════════════════════════
Recommendation: B — review the inferred mappings (tagged
`confirmed: false`), unresolved questions, and assumptions
before flipping confirmed_by_user: true.
══════════════════════════════════════
- If user picks A → verify
confirmed_by_user: trueis now set in the config. If stillfalse, re-ask. If true, auto-chain to Step 2.5 (Glossary & Architecture Vision). - If user picks B → mark Step 2 as
in_progress, update state file, end the session. Tell the user to invoke/autodevagain after reviewing.
Do NOT auto-flip confirmed_by_user. Only the human does that.
Step 2.5 — Glossary & Architecture Vision (one-shot)
Condition (folder fallback): _docs/_repo-config.yaml exists AND confirmed_by_user: true AND (_docs/glossary.md does NOT exist OR the cross-cutting architecture doc identified in docs.cross_cutting does NOT contain a ## Architecture Vision section).
State-driven: reached by auto-chain from Step 2 (user picked A).
Goal: Capture meta-repo-wide terminology and the user's architecture vision once, after the config is confirmed but before any sync skill runs. Without this, monorepo-document will faithfully propagate per-component changes but never surface a unified mental model of the meta-repo to the user, and the AI will keep re-inferring the same project terminology on every invocation.
Why inline (no sub-skill): monorepo-discover is hard-guarded to write only _repo-config.yaml; monorepo-document only edits existing docs. Glossary and architecture-vision creation is a first-time, user-confirmed write that crosses both guarantees, so it lives directly in the flow.
Inputs:
_docs/_repo-config.yaml(component list, doc map, conventions, assumptions log)- Cross-cutting docs listed under
docs.cross_cutting(existing architecture doc, if any) - Each component's
primary_doc(read-only, for terminology + responsibility extraction) - Root
README.mdifrepo.root_readmeis referenced
Outputs:
_docs/glossary.md(or<docs.root>/glossary.mdifdocs.root≠_docs/) — NEW- The cross-cutting architecture doc updated in place: a
## Architecture Visionsection is prepended (or merged into an existing "Vision" / "Overview" heading) - One new entry appended to
_docs/_repo-config.yamlunderassumptions_log:recording the run - A new top-level config entry:
glossary_doc: <path>so futuremonorepo-statusandmonorepo-documentruns treat the glossary as a known cross-cutting doc
Procedure:
-
Draft glossary from
_repo-config.yaml+ each component's primary doc. Include:- Component codenames as they appear in the config (
namefield) and any rename pairs the user noted inunresolved:resolutions - Domain terms that recur across ≥2 component docs
- Acronyms / abbreviations
- Convention names from
conventions:(e.g., commit prefix, deployment tier names) - Stakeholder personas if cross-cutting docs reference them
Each entry: one-line definition + source (
source: components.<name>.primary_docorsource: _repo-config.yaml conventions). Skip generic terms.
- Component codenames as they appear in the config (
-
Draft architecture vision from the meta-repo perspective:
- One paragraph: what the system as a whole is, what each component contributes, the runtime topology (one binary / N services / N clients + 1 server / hybrid), how components communicate (REST / gRPC / queue / DB-shared / file-shared)
- Components & responsibilities (one-line each), pulled directly from
_repo-config.yamlcomponents:list - Cross-cutting concerns ownership: which doc owns which concern (auth, schema, deployment, etc.) — pulled from
docs.cross_cutting[].owns - Architectural principles / non-negotiables the user has implied across components (e.g., "all components share a single Postgres", "submodules own their own CI", "deployment is per-tier, not per-component")
- Open questions / structural drift signals: components missing from
docs.cross_cutting, components in registry but not in config (registry mismatch), or contradictions between component primary docs
-
Present condensed view to the user (NOT the full draft files):
══════════════════════════════════════ REVIEW: Meta-Repo Glossary + Architecture Vision ══════════════════════════════════════ Glossary (N terms drafted from config + component docs): - <Term>: <one-line definition> - ... Architecture Vision — meta-repo level: <one-paragraph synopsis> Components / responsibilities: - <component>: <one-line> - ... Cross-cutting ownership: - <concern> → <doc> - ... Principles / non-negotiables: - <principle> - ... Open questions / drift signals: - <q1> - <q2> ══════════════════════════════════════ A) Looks correct — write the files B) Add / correct entries (provide diffs) C) Resolve open questions / drift signals first ══════════════════════════════════════ Recommendation: pick C if drift signals exist; otherwise B if components or principles don't match your intent; A only when the inferred vision is exactly right. ══════════════════════════════════════ -
Iterate:
- On B → integrate the user's diffs/additions, re-present, loop until A.
- On C → ask the listed open questions in one batch, integrate answers, re-present.
- Do NOT proceed to step 5 until the user picks A.
-
Save:
- Write
_docs/glossary.md(alphabetical) with**Status**: confirmed-by-user+ date. - Update the cross-cutting architecture doc identified in
docs.cross_cutting(or create one at_docs/00_architecture.mdif none exists and the user's option-B input named one): prepend## Architecture Visionwith the confirmed paragraph + components + ownership + principles. Preserve every existing H2 below verbatim. - Append to
_docs/_repo-config.yaml:- Top-level
glossary_doc: <path-relative-to-repo-root>(sibling ofdocs.root) - New
assumptions_log:entry:{ date: <today>, skill: autodev-meta-repo Step 2.5, run_notes: "Captured glossary + architecture vision", assumptions: [...] }
- Top-level
- Do NOT flip any
confirmed: false→confirmed: truein the config; this step writes its own confirmed artifact, it does not retroactively confirm config inferences.
- Write
Self-verification:
- Every glossary entry traces to either the config or a component primary doc
- Every component listed in the vision matches a
components:entry in the config - All open questions are answered or explicitly deferred (with the user's acknowledgement)
- The cross-cutting architecture doc still contains every H2 it had before this step
- User picked option A on the latest condensed view
Idempotency: if both _docs/glossary.md exists AND the architecture doc already has a ## Architecture Vision section, this step is skipped on re-invocation. To refresh, the user invokes /autodev after deleting glossary.md (or running monorepo-discover with structural changes that justify a re-confirmation).
After completion, auto-chain to Step 3 (Status).
Step 3 — Status
Condition (folder fallback): _docs/_repo-config.yaml exists AND confirmed_by_user: true AND (_docs/glossary.md exists OR glossary_doc: is recorded in the config).
State-driven: reached by auto-chain from Step 2.5, or entered on any re-invocation after a completed cycle.
Action: Read and execute .cursor/skills/monorepo-status/SKILL.md.
The status report identifies:
- Components with doc drift (commits newer than their mapped docs)
- Components with CI coverage gaps
- Registry/config mismatches
- Unresolved questions
Based on the report, auto-chain branches:
- If doc drift found → auto-chain to Step 4 (Document Sync)
- Else if CI drift (only) found → auto-chain to Step 5 (CICD Sync)
- Else if registry mismatch found (new components not in config) → present Choose format:
══════════════════════════════════════
DECISION REQUIRED: Registry drift detected
══════════════════════════════════════
Components in registry but not in config: <list>
Components in config but not in registry: <list>
A) Run monorepo-discover to refresh config
B) Run monorepo-onboard for each new component (interactive)
C) Ignore for now — continue
══════════════════════════════════════
Recommendation: A — safest; re-detect everything, human reviews
══════════════════════════════════════
- Else → workflow done for this cycle. Report "No drift. Meta-repo is in sync." Loop waits for next invocation.
Step 4 — Document Sync
State-driven: reached by auto-chain from Step 3 when the status report flagged doc drift.
Action: Read and execute .cursor/skills/monorepo-document/SKILL.md with scope = components flagged by status.
The skill:
- Runs its own drift check (M7)
- Asks user to confirm scope (components it will touch)
- Applies doc edits
- Skips any component with unconfirmed mapping (M5), reports
After completion:
- If the status report ALSO flagged suite-e2e drift → auto-chain to Step 4.5 (Integration Test Sync)
- Else if the status report ALSO flagged CI drift → auto-chain to Step 5 (CICD Sync)
- Else → end cycle, report done
Step 4.5 — Integration Test Sync
State-driven: reached by auto-chain from Step 3 (when status report flagged suite-e2e drift and no doc drift) or from Step 4 (when both doc and suite-e2e drift were flagged).
Skip condition: if _docs/_repo-config.yaml has no suite_e2e: block, this step is skipped entirely — there's no harness to sync. The status report should not flag suite-e2e drift in that case; if it does, that's a status-skill bug.
Action: Read and execute .cursor/skills/monorepo-e2e/SKILL.md with scope = components flagged by status.
The skill:
- Verifies every path under
suite_e2e.*exists (binary fixtures excepted — see the skill's Phase 1) - Classifies each flagged change against the suite-e2e impact table
- Applies edits to
e2e/docker-compose.suite-e2e.yml,e2e/fixtures/init.sql,e2e/fixtures/expected_detections.jsonmetadata, ande2e/runner/tests/*.spec.tsselectors as needed - Bumps baseline
fixture_versionwith a-stalesuffix and appends a_docs/_process_leftovers/entry whenever the detection model revision changes (binary fixture cannot be regenerated automatically) - Reports synced files; does not run the suite e2e itself
After completion:
- If the status report ALSO flagged CI drift → auto-chain to Step 5 (CICD Sync)
- Else → end cycle, report done
Step 5 — CICD Sync
State-driven: reached by auto-chain from Step 3 (when status report flagged CI drift and no doc/suite-e2e drift), Step 4, or Step 4.5.
Action: Read and execute .cursor/skills/monorepo-cicd/SKILL.md with scope = components flagged by status.
After completion, end cycle. Report files updated across doc, suite-e2e, and CI sync.
Step 6 — Loop (re-entry on next invocation)
State-driven: all triggered steps completed; the meta-repo cycle has finished.
Action: Update state file to step: 3, status: not_started so that next /autodev invocation starts from Status. The meta-repo flow is cyclical — there's no terminal "done" state, because drift can appear at any time as submodules evolve.
On re-invocation:
- If config was updated externally and
confirmed_by_userflipped back tofalse→ go back to Step 2 - Otherwise → Step 3 (Status)
Explicit Onboarding Branch (user-initiated)
Onboarding is not auto-chained. Two ways to invoke:
1. During Step 3 registry-mismatch handling — if user picks option B in the registry-mismatch Choose format, launch monorepo-onboard interactively for each new component.
2. Direct user request — if the user says "onboard " during any step, pause the current step, save state, run monorepo-onboard, then resume.
After onboarding completes, the config is updated. Auto-chain back to Step 3 (Status) to catch any remaining drift the new component introduced.
Auto-Chain Rules
| Completed Step | Next Action |
|---|---|
| Discover (1) | Auto-chain → Config Review (2) |
| Config Review (2, user picked A, confirmed_by_user: true) | Auto-chain → Glossary & Architecture Vision (2.5) |
| Config Review (2, user picked B) | Session boundary — end session, await re-invocation |
| Glossary & Architecture Vision (2.5) | Auto-chain → Status (3) |
| Status (3, doc drift) | Auto-chain → Document Sync (4) |
| Status (3, suite-e2e drift only) | Auto-chain → Integration Test Sync (4.5) |
| Status (3, CI drift only) | Auto-chain → CICD Sync (5) |
| Status (3, no drift) | Cycle complete — end session, await re-invocation |
| Status (3, registry mismatch) | Ask user (A: discover, B: onboard, C: continue) |
| Document Sync (4) + suite-e2e drift pending | Auto-chain → Integration Test Sync (4.5) |
| Document Sync (4) + CI drift only pending | Auto-chain → CICD Sync (5) |
| Document Sync (4) + no further drift | Cycle complete |
| Integration Test Sync (4.5) + CI drift pending | Auto-chain → CICD Sync (5) |
| Integration Test Sync (4.5) + no CI drift | Cycle complete |
| CICD Sync (5) | Cycle complete |
Status Summary — Step List
Flow name: meta-repo. Render using the banner template in protocols.md → "Banner Template (authoritative)".
Flow-specific slot values:
<header-suffix>: empty.<current-suffix>: empty.<footer-extras>: add a single line:Config: _docs/_repo-config.yaml [confirmed_by_user: <true|false>, last_updated: <date>]
| # | Step Name | Extra state tokens (beyond the shared set) |
|---|---|---|
| 1 | Discover | — |
| 2 | Config Review | IN PROGRESS (awaiting human) |
| 2.5 | Glossary & Architecture Vision | SKIPPED (already captured) |
| 3 | Status | DONE (no drift), DONE (N drifts) |
| 4 | Document Sync | DONE (N docs), SKIPPED (no doc drift) |
| 4.5 | Integration Test Sync | DONE (N files), SKIPPED (no suite-e2e drift), SKIPPED (no suite_e2e config block) |
| 5 | CICD Sync | DONE (N files), SKIPPED (no CI drift) |
All rows accept the shared state tokens (DONE, IN PROGRESS, NOT STARTED, FAILED (retry N/3)); rows 2.5, 4, 4.5, and 5 additionally accept SKIPPED.
Row rendering format:
Step 1 Discover [<state token>]
Step 2 Config Review [<state token>]
Step 2.5 Glossary & Architecture Vision [<state token>]
Step 3 Status [<state token>]
Step 4 Document Sync [<state token>]
Step 4.5 Integration Test Sync [<state token>]
Step 5 CICD Sync [<state token>]
Notes for the meta-repo flow
- No session boundary except Step 2 and Step 2.5: unlike existing-code flow (which has boundaries around decompose), meta-repo flow only pauses at config review and the one-shot glossary/vision capture. Once both are confirmed, syncing is fast enough to complete in one session and Step 2.5 idempotently no-ops on every subsequent invocation.
- Cyclical, not terminal: no "done forever" state. Each invocation completes a drift cycle; next invocation starts fresh.
- No tracker integration: this flow does NOT create Jira/ADO tickets. Maintenance is not a feature — if a feature-level ticket spans the meta-repo's concerns, it lives in the per-component workspace.
- Onboarding is opt-in: never auto-onboarded. User must explicitly request.
- Failure handling: uses the same retry/escalation protocol as other flows (see
protocols.md).