diff --git a/.ai/workflow-contract.json b/.ai/workflow-contract.json index 3d7d251..af6bceb 100644 --- a/.ai/workflow-contract.json +++ b/.ai/workflow-contract.json @@ -40,46 +40,79 @@ "When moving status, remove the previous status/* label first." ] }, + "sub_issues": { + "when": "Multi-file features (3+ files) or features that benefit from smaller AI context windows.", + "parent_issue": "The original feature issue. Tracks overall status. Only the parent gets status label transitions.", + "sub_issue_title_format": "{type}: {summary} (#{parent_index})", + "sub_issue_body": "First line must be 'Relates to #{parent_index}'. Each sub-issue is a self-contained unit of work.", + "sub_issue_labels": "status/backlog + same type/* as parent. Sub-issues stay in backlog; parent issue tracks status.", + "sub_issue_milestone": "Same sprint milestone as parent.", + "rules": [ + "ONE branch for the parent issue. Never create branches per sub-issue.", + "ONE PR for the parent issue. The PR closes the parent and all sub-issues.", + "Commits reference the specific sub-issue index they implement.", + "Sub-issues should be small enough to fit in a single AI context window.", + "Plan milestones map 1:1 to sub-issues." + ], + "examples": { + "parent": "#105 'feat: Add Grafana dashboards and alerting'", + "sub_issues": [ + "#106 'feat: Grafana dashboard provisioning infrastructure (#105)'", + "#107 'feat: Application Overview Grafana dashboard (#105)'" + ] + } + }, "branching": { - "branch_format": "issue-{index}-{slug}", + "branch_format": "issue-{parent_index}-{slug}", "target_branch": "main", - "example": "issue-42-add-fuel-efficiency-report" + "note": "Always use the parent issue index. When sub-issues exist, the branch is for the parent.", + "examples": [ + "issue-42-add-fuel-efficiency-report (standalone issue)", + "issue-105-add-grafana-dashboards (parent issue with sub-issues #106-#111)" + ] }, "commit_conventions": { "message_format": "{type}: {short summary} (refs #{index})", "allowed_types": ["feat", "fix", "chore", "docs", "refactor", "test"], + "note": "When working on a sub-issue, {index} is the sub-issue number. For standalone issues, {index} is the issue number.", "examples": [ "feat: add fuel efficiency calculation (refs #42)", - "fix: correct VIN validation for pre-1981 vehicles (refs #1)" + "fix: correct VIN validation for pre-1981 vehicles (refs #1)", + "feat: add dashboard provisioning infrastructure (refs #106)", + "feat: add API performance dashboard (refs #108)" ] }, "pull_requests": { - "title_format": "{type}: {summary} (#{index})", + "title_format": "{type}: {summary} (#{parent_index})", + "note": "PR title always uses the parent issue index.", "body_requirements": [ - "Link issue(s) using 'Fixes #123' or 'Relates to #123'.", + "Link parent issue using 'Fixes #{parent_index}'.", + "Link all sub-issues using 'Fixes #{sub_index}' on separate lines.", "Include test plan and results.", "Confirm acceptance criteria completion." ], + "body_example": "Fixes #105\nFixes #106\nFixes #107\nFixes #108\nFixes #109\nFixes #110\nFixes #111", "merge_policy": "squash_or_rebase_ok", "template_location": ".gitea/PULL_REQUEST_TEMPLATE.md" }, "execution_loop": [ "List repo issues in current sprint milestone with status/ready; if none, pull from status/backlog and promote the best candidate to status/ready.", "Select one issue (prefer smallest size and highest priority).", - "Move issue to status/in-progress.", + "Move parent issue to status/in-progress.", "[SKILL] Codebase Analysis if unfamiliar area.", "[SKILL] Problem Analysis if complex problem.", "[SKILL] Decision Critic if uncertain approach.", - "[SKILL] Planner writes plan as issue comment.", + "If multi-file feature (3+ files): decompose into sub-issues per sub_issues rules. Each sub-issue = one plan milestone.", + "[SKILL] Planner writes plan as parent issue comment. Plan milestones map 1:1 to sub-issues.", "[SKILL] Plan review cycle: QR plan-completeness -> TW plan-scrub -> QR plan-code -> QR plan-docs.", - "Create branch issue-{index}-{slug}.", - "[SKILL] Planner executes plan, delegates to Developer per milestone.", - "[SKILL] QR post-implementation per milestone (results in issue comment).", - "Open PR targeting main and linking issue(s).", - "Move issue to status/review.", - "[SKILL] Quality Agent validates with RULE 0/1/2 (result in issue comment).", + "Create ONE branch issue-{parent_index}-{slug} from main.", + "[SKILL] Planner executes plan, delegates to Developer per milestone/sub-issue.", + "[SKILL] QR post-implementation per milestone (results in parent issue comment).", + "Open ONE PR targeting main. Title uses parent index. Body lists 'Fixes #N' for parent and all sub-issues.", + "Move parent issue to status/review.", + "[SKILL] Quality Agent validates with RULE 0/1/2 (result in parent issue comment).", "If CI/tests fail, iterate until pass.", - "When PR is merged, move issue to status/done and close issue if not auto-closed.", + "When PR is merged, parent and all sub-issues move to status/done. Close any not auto-closed.", "[SKILL] Doc-Sync on affected directories." ], "skill_integration": { diff --git a/CLAUDE.md b/CLAUDE.md index 4f4d0a6..2a9383f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -174,9 +174,19 @@ Issues are the source of truth. See `.ai/workflow-contract.json` for complete wo - Every PR must link to at least one issue - Use Gitea MCP tools for issue/label/branch/PR operations - Labels: `status/backlog` -> `status/ready` -> `status/in-progress` -> `status/review` -> `status/done` -- Branches: `issue-{index}-{slug}` (e.g., `issue-42-add-fuel-report`) +- Branches: `issue-{parent_index}-{slug}` (e.g., `issue-42-add-fuel-report`) - Commits: `{type}: {summary} (refs #{index})` (e.g., `feat: add fuel report (refs #42)`) +### Sub-Issue Decomposition +Multi-file features (3+ files) must be broken into sub-issues for smaller AI context windows: +- **Sub-issue title**: `{type}: {summary} (#{parent_index})` -- parent index in title +- **Sub-issue body**: First line `Relates to #{parent_index}` +- **ONE branch** per parent issue only. Never branch per sub-issue. +- **ONE PR** per parent issue. Body lists `Fixes #N` for parent and every sub-issue. +- **Commits** reference the specific sub-issue: `feat: add dashboard (refs #107)` +- **Status labels** tracked on parent only. Sub-issues stay `status/backlog`. +- **Plan milestones** map 1:1 to sub-issues. + ## Architecture Context for AI ### 9-Container Architecture diff --git a/README.md b/README.md index f138378..ec04e98 100644 --- a/README.md +++ b/README.md @@ -240,10 +240,19 @@ make migrate # run DB migrations Skills: codebase-analysis, problem-analysis, decision-critic, planner, doc-sync Role-Agents: Developer, Technical Writer (TW), Quality Reviewer (QR), Debugger Domain Agents: Feature Agent, Frontend Agent, Platform Agent, Quality Agent - + Labels: status/backlog -> status/ready -> status/in-progress -> status/review -> status/done Commits: {type}: {summary} (refs #{N}) | Types: feat, fix, chore, docs, refactor, test Branches: issue-{N}-{slug} | Example: issue-42-add-fuel-report + + SUB-ISSUE PATTERN (multi-file features) + ---------------------------------------- + Parent: #105 "feat: Add Grafana dashboards" + Sub: #106 "feat: Dashboard provisioning (#105)" <-- parent index in title + Branch: issue-105-add-grafana-dashboards <-- ONE branch, parent index + Commit: feat: add provisioning (refs #106) <-- refs specific sub-issue + PR: feat: Add Grafana dashboards (#105) <-- ONE PR, parent index + Body: Fixes #105, Fixes #106, Fixes #107... <-- closes all QUALITY RULES -------------