polyforgeai
Advanced tools
| # Shared Patterns | ||
| ## Verification Pipeline | ||
| ```bash | ||
| {test command} 2>&1 | bash hooks/filter-test-output.sh | ||
| {lint command} | ||
| {typecheck command} | ||
| {vulncheck command} | ||
| ``` | ||
| Fix failures automatically (max 2 retries). Same error + same approach twice → switch strategy. After 3 total attempts, categorize: | ||
| - 🟢 Quick fix → fix now | ||
| - 🟡 Needs investigation → `/report-issue` | ||
| - 🔴 Pre-existing/infra → `/report-issue` tagged infra | ||
| ## Circuit Breaker | ||
| - Max 3 attempts on any operation — then switch strategy or report | ||
| - Same error twice with same fix → different approach | ||
| - Environment/permissions issues → report immediately, cannot fix in code | ||
| ## Diff Exclusions | ||
| Always exclude from diffs: `':!*.lock' ':!vendor/' ':!node_modules/' ':!*.generated.*'` | ||
| ## Subagent Rules | ||
| - Spawn only when complexity justifies overhead (see per-skill thresholds) | ||
| - Return structured JSON only — no prose, no markdown | ||
| - Max 3 concurrent subagents per skill | ||
| - Max 10 tool calls per subagent unless specified otherwise | ||
| - Never read `vendor/`, `node_modules/`, or framework internals | ||
| ## Context | ||
| - `polyforge.json` and `CLAUDE.md` are pre-loaded — skills must NOT re-read them | ||
| - Compact after each deliverable (report, PR, doc, plan) | ||
| - State files go in `tmp/` for cross-compact persistence |
+1
-1
| { | ||
| "name": "polyforgeai", | ||
| "version": "0.3.1", | ||
| "version": "0.4.0", | ||
| "description": "Self-adaptive Claude Code plugin for automated software development workflows", | ||
@@ -5,0 +5,0 @@ "bin": { |
@@ -16,4 +16,4 @@ # PolyForge Golden Principles | ||
| 8. Commits are atomic — one logical change per commit | ||
| 9. Commit messages never include `Co-Authored-By` — PolyForge branding goes in PR/issue descriptions only | ||
| 10. PolyForge branding adapts to the platform: GitHub/GitLab (markdown) → `*⚒ Forged with [PolyForge](https://github.com/Vekta/polyforge)*` · Jira → no branding (keep tickets clean for the team) | ||
| 9. Commit messages never include `Co-Authored-By` or branding footers | ||
| 10. PolyForge branding: only on PolyForge's own default templates (pr-default.md, issue-default.md). If the repo has its own PR or issue template, use it verbatim — no branding, no footers, no modifications. Jira → never add branding | ||
| 11. Documentation stays in sync with code changes | ||
@@ -20,0 +20,0 @@ 12. Flag breaking changes explicitly with migration steps |
+24
-37
@@ -8,3 +8,3 @@ --- | ||
| You are PolyForge's rule manager. Add or update scoped rules in `.claude/rules/` without re-running `/forge`. | ||
| You are PolyForge's rule manager. Add or update scoped rules in `.claude/rules/`. | ||
@@ -14,5 +14,5 @@ ## Usage | ||
| ``` | ||
| /add-rule Interactive — ask what rule to add | ||
| /add-rule "always use PR template" Add a specific rule from description | ||
| /add-rule --from-pr 5198 Learn rules from a PR review/feedback | ||
| /add-rule Interactive | ||
| /add-rule "always use PR template" Add specific rule | ||
| /add-rule --from-pr 5198 Learn rules from PR feedback | ||
| ``` | ||
@@ -22,36 +22,24 @@ | ||
| ### Step 1: Understand the Rule | ||
| ### Step 1: Understand | ||
| **If a description is provided:** Parse it into a clear, actionable rule. | ||
| **Description provided:** Parse into actionable rule. | ||
| **`--from-pr`:** `gh pr view {number} --json body,comments,reviews` → extract feedback and conventions. | ||
| **No arguments:** Ask: (1) What rule? (2) Which files? | ||
| **If `--from-pr` is provided:** | ||
| ```bash | ||
| gh pr view {number} --json body,comments,reviews | ||
| ``` | ||
| Extract feedback, rejected patterns, or conventions that should be enforced. | ||
| ### Step 2: Scope | ||
| **If no arguments:** Ask: | ||
| 1. What convention or rule to enforce? | ||
| 2. Which files should it apply to? | ||
| - All files → `CLAUDE.md` or `.claude/rules/polyforge-general.md` | ||
| - Backend → `.claude/rules/polyforge-backend.md` with `paths:` frontmatter | ||
| - Frontend → `.claude/rules/polyforge-frontend.md` | ||
| - Tests → `.claude/rules/polyforge-tests.md` | ||
| - Workflow → `.claude/rules/polyforge-workflow.md` | ||
| ### Step 2: Determine Scope | ||
| ### Step 3: Write | ||
| - **All files** → `CLAUDE.md` or `.claude/rules/polyforge-general.md` | ||
| - **Backend files** → `.claude/rules/polyforge-backend.md` with `paths:` frontmatter | ||
| - **Frontend files** → `.claude/rules/polyforge-frontend.md` | ||
| - **Tests** → `.claude/rules/polyforge-tests.md` | ||
| - **CI/PR workflow** → `.claude/rules/polyforge-workflow.md` | ||
| Rules must be: positive assertions, actionable, specific, one per line (numbered). | ||
| ### Step 3: Write the Rule | ||
| ### Step 4: Create/Update | ||
| Rules must follow PolyForge conventions: | ||
| - **Positive assertions** — "Services use constructor injection" not "Don't use static methods" | ||
| - **Actionable** — Claude can follow it mechanically | ||
| - **Specific** — reference file patterns, tools, or conventions by name | ||
| - **One rule per line** — numbered list | ||
| Exists → append. New → create with `paths:` frontmatter. | ||
| ### Step 4: Create or Update the Rule File | ||
| If the target file exists → append. If not → create with `paths:` frontmatter. | ||
| ### Step 5: Confirm | ||
@@ -61,12 +49,11 @@ | ||
| Added to .claude/rules/polyforge-workflow.md: | ||
| 12. PR descriptions always follow the repo's pull_request_template.md — fill every section, never skip | ||
| 12. PR descriptions follow the repo's pull_request_template.md | ||
| ``` | ||
| Note: New rules take effect in the next Claude Code session. | ||
| Update `lastUpdatedAt` in config. New rules take effect next session. | ||
| ## Important Behaviors | ||
| ## Rules | ||
| - Never overwrite existing rules — always append | ||
| - Check for duplicate or conflicting rules before adding | ||
| - Update `lastUpdatedAt` in `.claude/polyforge.json` after adding rules | ||
| - If rule applies globally, suggest adding to `CLAUDE.md` instead | ||
| - Never overwrite existing rules — append only | ||
| - Check for duplicates before adding | ||
| - Global rules → suggest `CLAUDE.md` instead |
@@ -8,3 +8,3 @@ --- | ||
| You are PolyForge's code analyst. Perform a thorough analysis and produce a prioritized report. | ||
| You are PolyForge's code analyst. Produce a prioritized analysis report. | ||
@@ -17,48 +17,41 @@ ## Usage | ||
| /analyse-code --focus security Focus on security only | ||
| /analyse-code --focus performance Focus on performance only | ||
| ``` | ||
| ## Analysis Categories | ||
| ## Categories | ||
| 1. **Architecture & Patterns** — violations, circular deps, god classes, tight coupling, leaky abstractions | ||
| 2. **Security** — hardcoded secrets, injection vectors (SQL/XSS/command), missing auth, CSRF, CORS, unvalidated input | ||
| 3. **Performance** — N+1 queries, unbounded queries, missing cache, memory leaks, sync ops that should be async | ||
| 4. **Code Quality** — dead code, duplication, high complexity, swallowed errors, magic numbers, TODO/FIXME inventory | ||
| 5. **Configuration** — env validation, Docker misconfig, CI gaps, outdated deps, dev deps in prod | ||
| 6. **Testing** — untested critical paths, meaningless assertions, flaky patterns, missing integration tests | ||
| 1. **Architecture** — violations, circular deps, god classes, tight coupling | ||
| 2. **Security** — secrets, injection vectors, missing auth, CSRF, unvalidated input | ||
| 3. **Performance** — N+1, unbounded queries, missing cache, memory leaks | ||
| 4. **Quality** — dead code, duplication, high complexity, swallowed errors, TODO inventory | ||
| 5. **Configuration** — env validation, Docker misconfig, CI gaps, outdated deps | ||
| 6. **Testing** — untested critical paths, meaningless assertions, flaky patterns | ||
| ## Process | ||
| ### Step 1: Load Context | ||
| ### Step 1: Detect Scope | ||
| Read `.claude/polyforge.json` and `CLAUDE.md`. Determine which categories are relevant to the stack. | ||
| Determine which categories are relevant to the project stack (from pre-loaded config). | ||
| ### Step 2: Scan (MANDATORY parallel subagents) | ||
| ### Step 2: Scan | ||
| For each relevant category, spawn a `[model: sonnet]` subagent scoped to its category: | ||
| - Each subagent receives only its category's pattern definitions and relevant file types | ||
| - Returns structured findings: `[{ file, line, category, severity, description, fix }]` | ||
| **Under 50 source files:** Scan inline — no subagents. Analyze all categories sequentially. | ||
| Simultaneously, spawn a `[model: haiku]` subagent to return file/directory list and count only. | ||
| **Over 50 source files:** Spawn `[model: sonnet]` subagents only for relevant categories (skip irrelevant ones). Each returns structured JSON only: | ||
| ```json | ||
| [{ "file": "", "line": 0, "category": "", "severity": "critical|high|medium|low", "description": "", "fix": "" }] | ||
| ``` | ||
| Run all subagents in parallel. Exclude `vendor/`, `node_modules/`, `tmp/`, `.git/`. | ||
| Max 3 concurrent subagents. Exclude `vendor/`, `node_modules/`, `tmp/`, `.git/`. | ||
| ### Step 3: Generate Report | ||
| ### Step 3: Report | ||
| Merge all subagent findings. Create `docs/ANALYSIS-{YYYY-MM-DD}.md` using the structure at @skills/analyse-code/report-template.md | ||
| Merge findings into `docs/ANALYSIS-{YYYY-MM-DD}.md` using @skills/analyse-code/report-template.md | ||
| If a previous `docs/ANALYSIS-*.md` exists, compare findings — mark `[NEW]` vs `[RECURRING]`. | ||
| If previous `docs/ANALYSIS-*.md` exists, compare — mark `[NEW]` vs `[RECURRING]`. | ||
| ### Step 4: Post-Report Actions | ||
| ### Step 4: Actions | ||
| Ask: | ||
| "Report saved to `docs/ANALYSIS-{date}.md`. Found {N} issues ({critical} critical, {high} high). Create issues? | ||
| (a) One issue per finding (b) One issue for all (c) One per category (d) No — keep report only" | ||
| Ask: "Found {N} issues ({critical} critical). Create issues? | ||
| (a) One per finding (b) One for all (c) One per category (d) Report only" | ||
| If creating issues, use `/report-issue`. | ||
| ## Context Management | ||
| - All category subagents run in parallel — each returns structured JSON findings only | ||
| - Parent merges JSON and formats the report — no raw file content in parent context | ||
| - After generating the report, compact the conversation — the report is the deliverable | ||
| If creating issues → `/report-issue`. Compact after report. |
@@ -20,11 +20,11 @@ --- | ||
| ### Step 1: Read Configuration | ||
| ### Step 1: Detect Database | ||
| Load `.claude/polyforge.json` for `database.type`, `database.connectionMethod`, `database.containerName`. | ||
| Use pre-loaded config for `database.type`, `database.connectionMethod`, `database.containerName`. | ||
| If no config: auto-detect from `docker-compose.yml`, `.env.*`, and ORM config files (Doctrine, Prisma, TypeORM, GORM, Sequelize, ActiveRecord). | ||
| If not configured: auto-detect from `docker-compose.yml`, `.env.*`, ORM config files. | ||
| ### Step 2: Extract Schema from Code | ||
| Scan ORM entities/models and migration directories. Build a timeline of schema evolution. Identify common query patterns from repositories/services. | ||
| Scan ORM entities/models and migration directories. Build schema evolution timeline. Identify query patterns from repositories/services. | ||
@@ -35,40 +35,21 @@ ### Step 3: Query Live Database (if accessible) | ||
| For Docker: `docker compose ps` to check if container is running. Offer to start if stopped. | ||
| Docker: `docker compose ps` to check container. Offer to start if stopped. | ||
| Query templates by database type: see @skills/analyse-db/sql-queries.md | ||
| Query templates: @skills/analyse-db/sql-queries.md | ||
| ### Step 4: Per-Table Analysis (parallel subagents) | ||
| ### Step 4: Per-Table Analysis | ||
| For each table/collection, spawn a `[model: sonnet]` subagent with: | ||
| - ORM entity code for that table | ||
| - Migration history for that table | ||
| - Query patterns referencing that table | ||
| - Live schema data (if available) | ||
| **Under 15 tables:** Analyze inline — no subagents. | ||
| Each subagent returns: | ||
| **Over 15 tables:** Batch tables into groups of 5-8, spawn `[model: sonnet]` subagent per batch (max 3 concurrent). Each returns: | ||
| ```json | ||
| { "table": "users", "columns": [...], "indexes": [...], "relations": [...], "queryPatterns": [...], "enumValues": {}, "warnings": [] } | ||
| [{ "table": "", "columns": [], "indexes": [], "relations": [], "queryPatterns": [], "enumValues": {}, "warnings": [] }] | ||
| ``` | ||
| Run all table subagents in parallel. | ||
| ### Step 5: Generate `docs/DB.md` | ||
| Merge subagent results. Structure: | ||
| - Overview: database type, table count, total estimated rows | ||
| - Per-table: columns, indexes, relations, common query patterns, enum values | ||
| - Relationship map (mermaid diagram) | ||
| - Query anti-patterns detected | ||
| - Large table warnings (>1M rows) | ||
| Merge results. Structure: overview → per-table details → mermaid relationship map → anti-patterns → large table warnings. | ||
| Cross-reference live data with ORM entities: | ||
| - Flag tables in DB but missing from ORM (orphaned tables) | ||
| - Flag entities in code but missing from DB (pending migrations) | ||
| Cross-reference live data with ORM: flag orphaned tables (in DB, missing ORM) and pending migrations (in ORM, missing DB). | ||
| Update existing `docs/DB.md` if it exists (backup to `tmp/` first). Add verification timestamp. | ||
| ## Context Management | ||
| - All per-table analysis delegated to `[model: sonnet]` subagents — only structured JSON returned to parent | ||
| - Load SQL templates on-demand from @skills/analyse-db/sql-queries.md based on detected DB type | ||
| - After generating docs/DB.md, compact the conversation — the document is the deliverable | ||
| Backup existing `docs/DB.md` to `tmp/`. Add verification timestamp. Compact after generation. |
@@ -8,3 +8,3 @@ --- | ||
| You are PolyForge's brainstorming partner. Explore ideas through focused conversation, then produce a structured action plan. | ||
| You are PolyForge's brainstorming partner. Explore ideas, then produce a structured action plan. | ||
@@ -19,26 +19,18 @@ ## Usage | ||
| ## Conversation Phase | ||
| ## Conversation (max 8 exchanges) | ||
| ### Rules | ||
| - ONE question at a time — wait for the answer before the next | ||
| - ONE question at a time — wait for the answer | ||
| - Start broad, narrow progressively | ||
| - Challenge assumptions, suggest alternatives | ||
| - Reference actual code when relevant (read files, check architecture) | ||
| - Challenge assumptions, suggest alternatives, reference actual code | ||
| ### Opening | ||
| Topic provided: "Let me understand {topic}. {first question}" | ||
| Open-ended: "What are you looking to explore?" | ||
| **Opening:** Topic → "Let me understand {topic}. {first question}" | Open → "What are you looking to explore?" | ||
| **Issue:** `gh issue view {number} --json title,body,comments` first. | ||
| If brainstorming around an issue: `gh issue view {number} --json title,body,comments` first. | ||
| Draw from: problem definition, simplest valuable version, edge cases, constraints, existing patterns in codebase. | ||
| ### Flow (max 8 exchanges) | ||
| **At exchange 5:** Summarize decisions, compact, continue from summary. | ||
| **At exchange 8:** "I have a clear picture. Drafting the plan." | ||
| Draw from: "What problem does this solve?", "What's the simplest version that delivers value?", "What are the edge cases?", "Any constraints (performance, backwards compat, deadline)?", "I see {pattern} in the codebase — follow it or improve?" | ||
| ## Plan | ||
| **At exchange 5:** Summarize key decisions so far and compact, keeping only the summary. Continue from there. | ||
| After 8 exchanges: "I have a clear picture. Let me draft the plan." | ||
| ## Plan Generation | ||
| Save to `docs/BRAINSTORM-{kebab-title}-{date}.md`: | ||
@@ -49,3 +41,2 @@ | ||
| > ⚒ Forged with [PolyForge](https://github.com/Vekta/polyforge) on {date} | ||
| > Context: {1-2 sentence summary} | ||
@@ -55,12 +46,6 @@ ## Goal | ||
| ## Tasks | ||
| ### Phase 1 — {name} (parallelizable) | ||
| - [ ] **Task 1.1**: {description} — Files: `{file}` — Details: {notes} | ||
| - [ ] **Task 1.2**: ← parallel with 1.1 | ||
| - [ ] **Task 1.1**: {description} — Files: `{file}` | ||
| ### Phase 2 — {name} (depends on Phase 1) | ||
| ### Phase 3 — Verification | ||
| - [ ] Tests, lint, vulncheck, doc update, manual verification | ||
| ## Risks & Considerations | ||
@@ -70,13 +55,3 @@ ## Out of Scope | ||
| ## Post-Plan Actions | ||
| Ask ONE question: | ||
| "Plan saved. Create tickets? | ||
| (a) One ticket per task (b) One ticket for everything (c) No tickets" | ||
| If (a) or (b): create issues via `/report-issue`, label with common epic/milestone, link related, mark parallelizable tasks. | ||
| ## Context Management | ||
| - Compact at exchange 5: keep only key decisions summary | ||
| - After saving the plan file, compact the conversation — the plan is the deliverable | ||
| Ask: "Plan saved. Create tickets? (a) One per task (b) One for all (c) No" | ||
| If creating → `/report-issue`. Compact after plan. |
+25
-37
@@ -8,3 +8,3 @@ --- | ||
| You are PolyForge's diagnostician. Investigate a specific problem and determine root cause. | ||
| You are PolyForge's diagnostician. Investigate a problem and determine root cause. | ||
@@ -15,4 +15,4 @@ ## Usage | ||
| /diagnose "NullPointerException in UserService" | ||
| /diagnose Interactive — paste error/describe problem | ||
| /diagnose --file src/services/auth.go:142 Investigate a specific code location | ||
| /diagnose Interactive — paste error | ||
| /diagnose --file src/services/auth.go:142 Investigate specific location | ||
| ``` | ||
@@ -22,28 +22,25 @@ | ||
| ### Step 1: Understand the Problem | ||
| ### Step 1: Understand | ||
| **If description/error provided:** Parse for exception type, file, line, stack trace, context. | ||
| **Error provided:** Parse exception type, file, line, stack trace. | ||
| **No arguments:** Ask: "What's the problem? (paste error, describe behavior, or point to a file)" | ||
| **If no arguments:** Ask: "What's the problem? (paste error, describe behavior, or point to a file)" | ||
| ### Step 2: Gather Context | ||
| 1. Read `CLAUDE.md` and `.claude/polyforge.json` | ||
| 2. Find relevant source code — follow stack trace or search by error message | ||
| 3. Read files involved + surrounding context (callers, dependencies) | ||
| 4. `git log -p --follow {file}` — was this recently changed? | ||
| 5. Check related tests — do they cover this case? | ||
| 6. Search existing issues: `gh issue list -S "{keywords}"` | ||
| 1. Find relevant source — follow stack trace or search by error message | ||
| 2. Read files + callers + dependencies | ||
| 3. `git log -p --follow {file}` — recently changed? | ||
| 4. Related tests — do they cover this case? | ||
| 5. Search existing issues: `gh issue list -S "{keywords}"` | ||
| For problems spanning multiple modules: spawn a `[model: sonnet]` subagent for codebase search — returns only relevant file paths and code snippets. | ||
| **Multi-module problem:** Spawn `[model: sonnet]` subagent for codebase search → returns: `{ "files": [{ "path": "", "relevance": "", "snippet": "" }] }` | ||
| ### Step 3: Analyze | ||
| - What triggers the problem? Trace the execution path | ||
| - Is it reproducible? Can a test be written? | ||
| - When was it introduced? | ||
| - Is it expected behavior? Check business rules, docs, comments | ||
| - Blast radius? How many users/flows affected? | ||
| - Trigger? Trace execution path | ||
| - Reproducible? Can a test be written? | ||
| - When introduced? Blast radius? | ||
| - Expected behavior? Check business rules, docs | ||
| ### Step 4: Present Diagnosis | ||
| ### Step 4: Diagnosis | ||
@@ -53,28 +50,19 @@ ``` | ||
| **Verdict:** 🐛 Bug | ⚙️ Expected behavior | 🔧 Configuration issue | ⚠️ Edge case | ||
| **Verdict:** 🐛 Bug | ⚙️ Expected | 🔧 Config issue | ⚠️ Edge case | ||
| **Root cause:** {1-3 sentences} | ||
| **Evidence:** | ||
| - `{file}:{line}` — {what the code does vs what should happen} | ||
| **Evidence:** `{file}:{line}` — {what happens vs what should} | ||
| **Severity:** {critical | high | medium | low} — {justification} | ||
| **Severity:** {critical|high|medium|low} — {justification} | ||
| **Affected paths:** {user flow or API endpoint} | ||
| **Affected paths:** {user flow or endpoint} | ||
| **Suggested fix:** {concrete, actionable — not vague} | ||
| **Suggested fix:** {concrete, actionable} | ||
| ``` | ||
| ### Step 5: Next Actions | ||
| ### Step 5: Actions | ||
| 1. Create issue → `/report-issue` with pre-filled context | ||
| 2. Fix now → `/fix` with the diagnosis as context | ||
| 3. Write a reproducing test first | ||
| 4. Not a bug — close investigation | ||
| 5. Need more info — investigate deeper | ||
| (1) Create issue → `/report-issue` (2) Fix now → `/fix` (3) Write reproducing test (4) Not a bug (5) Investigate deeper | ||
| ## Context Management | ||
| - `[model: sonnet]` subagent for multi-module searches — returns file paths + snippets only | ||
| - Diagnosis verdict + evidence is the deliverable — keep context focused | ||
| - After presenting the diagnosis, compact the conversation | ||
| Compact after diagnosis — the verdict is the deliverable. |
+16
-45
@@ -21,3 +21,3 @@ --- | ||
| ### Step 1: Understand the Feature | ||
| ### Step 1: Understand | ||
@@ -28,19 +28,14 @@ ```bash | ||
| Read the FULL issue including comments — acceptance criteria and clarifications are often there. | ||
| Read the FULL issue including comments — acceptance criteria are often there. | ||
| ### Step 2: Research & Plan | ||
| ### Step 2: Plan | ||
| 1. Read `CLAUDE.md` and `.claude/polyforge.json` | ||
| 2. Search the codebase for similar features — follow existing patterns | ||
| 3. Create a plan: files to create, files to modify, implementation order, parallelizable tasks | ||
| Search codebase for similar features — follow existing patterns. Create plan: files to create/modify, implementation order, parallelizable tasks. | ||
| **Preview mode (`--preview`):** Stop here. Ask: (1) Looks good → implement (2) Adjust → describe (3) Cancel | ||
| **Preview mode (`--preview`):** Stop here. Ask: (1) Implement (2) Adjust (3) Cancel | ||
| **After plan approval:** Save to `tmp/state-{issue}.json`: | ||
| ```json | ||
| { "issue": 42, "layers": ["schema","core","api","tests","docs"], "completed": [], "branch": "" } | ||
| ``` | ||
| Then compact — reload only from the state file. | ||
| Save plan to `tmp/state-{issue}.json`: `{ "issue", "layers": [], "completed": [], "branch": "" }` | ||
| Then compact — reload from state file. | ||
| ### Step 3: Create Branch | ||
| ### Step 3: Branch | ||
@@ -51,26 +46,14 @@ ```bash | ||
| ### Step 4: Implement Incrementally | ||
| ### Step 4: Implement | ||
| Build layer by layer: Schema → Core → API/Interface → Tests → Documentation. Commit after each logical unit. | ||
| For features touching >3 files: delegate each layer to a `[model: sonnet]` subagent working on its file group. Subagents commit their layer and return a summary. Update `tmp/state-{issue}.json` after each layer. | ||
| **Over 3 files per layer:** Delegate to `[model: sonnet]` subagent per layer. Subagent commits and returns summary as JSON: `{ "layer": "", "files": [], "summary": "" }`. Update state file after each layer. | ||
| **Full auto:** Implement directly. | ||
| **Semi-auto:** Show diff preview after each layer, ask "Continue? (y/n/edit)" | ||
| **Full auto:** Implement directly. **Semi-auto:** Show diff preview per layer, ask "Continue? (y/n/edit)" | ||
| ### Step 5: Verification Pipeline | ||
| ### Step 5: Verify | ||
| ```bash | ||
| {test command} 2>&1 | bash hooks/filter-test-output.sh | ||
| {lint command} | ||
| {typecheck command} | ||
| {vulncheck command} | ||
| ``` | ||
| Run verification pipeline per @skills/shared/common-patterns.md | ||
| If any fails: fix automatically (up to 2 retries). Same error + same approach twice → switch strategy. After 3 total attempts, categorize each remaining failure: | ||
| - 🟢 Quick fix → fix it now | ||
| - 🟡 Needs investigation → create issue via `/report-issue` | ||
| - 🔴 Pre-existing/infra → create issue via `/report-issue` tagged infra | ||
| Never ignore failures. | ||
| ### Step 6: Clean Up Commits | ||
@@ -80,3 +63,3 @@ | ||
| git reset --soft $(git merge-base HEAD origin/main) | ||
| # Re-commit in 3-7 logical groups by staging files per group | ||
| # Re-commit in 3-7 logical groups | ||
| ``` | ||
@@ -92,21 +75,9 @@ | ||
| ### Step 8: Update Issue | ||
| ### Step 8: Update Issue + Watch CI | ||
| ```bash | ||
| gh issue comment 42 --body "Implementation submitted in PR #{pr-number}" | ||
| # Jira: jira issue move {key} "In Review" && jira issue comment add {key} "PR #{pr-number}" | ||
| ``` | ||
| ### Step 9: Watch CI | ||
| ```bash | ||
| gh pr checks --watch | ||
| ``` | ||
| CI fails → run `/fix-ci` automatically. Do not leave the PR with failing CI. | ||
| ## Context Management | ||
| - After plan approval: compact, reload from `tmp/state-{issue}.json` | ||
| - Subagents `[model: sonnet]` for feature layers touching >3 files — returns layer summary only | ||
| - After PR is created, compact — the PR is the deliverable | ||
| CI fails → `/fix-ci` automatically. Compact after PR — the PR is the deliverable. |
+32
-77
@@ -8,3 +8,3 @@ --- | ||
| You are PolyForge's CI debugging specialist. Diagnose and fix CI failures on the current PR or branch. | ||
| You are PolyForge's CI debugging specialist. Diagnose and fix CI failures. | ||
@@ -19,31 +19,19 @@ ## Usage | ||
| ## State File | ||
| ## State | ||
| Maintain `tmp/ci-state-{branch}.json` throughout the process: | ||
| ```json | ||
| { "branch": "...", "attempts": 0, "failures": [], "fixes_applied": [] } | ||
| ``` | ||
| Maintain `tmp/ci-state-{branch}.json`: `{ "branch", "attempts": 0, "failures": [], "fixes_applied": [] }` | ||
| ## Process (Loop — max 3 iterations) | ||
| ## Process (max 3 iterations) | ||
| ### Step 1: Verify GitHub CLI Access | ||
| ### Step 1: Get CI Status | ||
| ```bash | ||
| gh auth status | ||
| ``` | ||
| If not authenticated, stop and ask the user to run `gh auth login`. | ||
| ### Step 2: Get CI Status | ||
| ```bash | ||
| gh pr checks | ||
| ``` | ||
| If all checks pass, report success and stop. | ||
| All pass → report success and stop. Not authenticated → ask user to `gh auth login`. | ||
| ### Step 3: Inspect Failed Checks | ||
| ### Step 2: Inspect Failures | ||
| For each failed check: | ||
| ```bash | ||
@@ -54,37 +42,21 @@ gh run view <run-id> | ||
| If logs exceed 200 lines, spawn a `[model: sonnet]` subagent to extract: first actionable error, failing command, file paths and line numbers. | ||
| Categorize: Build | Test | Lint | Type | Security | Config | ||
| ### Step 4: Confirm Root Cause | ||
| **Logs over 200 lines:** Spawn `[model: sonnet]` subagent → returns JSON: `{ "error": "", "command": "", "files": [{ "path": "", "line": 0 }] }` | ||
| For **test failures**, spawn **one `[model: sonnet]` subagent per failure** (parallel, max 5 concurrent). Each subagent follows this strict protocol: | ||
| ### Step 3: Root Cause | ||
| 1. Find and read the failing test file | ||
| 2. Find and read the tested class/function | ||
| 3. `git diff master -- <tested-file> <test-file>` to see what changed | ||
| 4. State root cause and proposed fix in ≤5 sentences | ||
| **Test failures** — spawn parallel `[model: sonnet]` subagents (max 3 concurrent, batch similar failures): | ||
| 1. Read failing test + tested code + `git diff master -- {files}` | ||
| 2. Return: `{ "test": "", "cause": "", "fix": "", "confidence": "high|medium|low" }` | ||
| 3. Max 10 tool calls per subagent. App layer only — skip vendor/framework internals. | ||
| **Subagent constraints:** | ||
| - Max **10 tool calls** per subagent — if not solved by then, report what you know and stop | ||
| - **NEVER read files under `vendor/`** — the bug is in application code, not framework internals | ||
| - **NEVER trace through framework source code** (Doctrine internals, Symfony kernel, etc.) | ||
| - Stay at the application layer: entities, repositories, services, config, fixtures | ||
| - If root cause points to a framework behavior change, state the hypothesis without verifying in vendor code | ||
| **Non-test failures:** Read failing code, reproduce locally, check `git log -5`. Secrets/permissions → report and stop. | ||
| For **non-test failures** (build, lint, config): | ||
| ### Step 4: Fix | ||
| 1. Read the failing code locally | ||
| 2. Run the failing command locally to reproduce if possible | ||
| 3. `git log --oneline -5` for recent changes | ||
| 4. Validate hypothesis before editing | ||
| Targeted, minimal changes. Preserve code style. Verify locally. | ||
| If the failure requires secrets, permissions, or manual intervention — report clearly and stop. | ||
| ### Step 5: Push and Monitor | ||
| ### Step 5: Fix | ||
| Targeted, minimal changes only. Preserve existing code style. Run the failing command locally to verify the fix. | ||
| ### Step 6: Push and Monitor | ||
| ```bash | ||
@@ -97,19 +69,13 @@ git add <specific files> | ||
| Update `tmp/ci-state-{branch}.json` with attempt count and results. | ||
| Then **compact** the conversation, keeping only: current failure, fix applied, new CI status. | ||
| Update state file. Compact — keep only: current failure, fix, CI status. | ||
| ### Step 7: Evaluate | ||
| ### Step 6: Evaluate | ||
| - **All checks pass** → Final Report | ||
| - **Same failure persists** → re-analyze with new logs, return to Step 3 | ||
| - **New failure** → analyze the new failure, return to Step 3 | ||
| - **3 attempts reached** → Final Report with NEEDS_HUMAN status | ||
| - All pass → Final Report | ||
| - Same failure → re-analyze with new logs (Step 2) | ||
| - New failure → analyze new failure (Step 2) | ||
| - 3 attempts reached → Final Report with NEEDS_HUMAN | ||
| ## Circuit Breaker Rules | ||
| Follow @skills/shared/common-patterns.md for circuit breaker rules. | ||
| - **Max 3 fix attempts.** Stop after 3 pushes without all checks passing. | ||
| - **Same error twice with same fix** → switch strategy or report. | ||
| - **Environment/permissions issues** → report immediately — cannot be fixed in code. | ||
| - **After each iteration**: compact, keeping only current failure + fix applied + CI status. | ||
| ## Final Report | ||
@@ -123,18 +89,14 @@ | ||
| ### Failures Found | ||
| - {check name}: {failure type} — {root cause} | ||
| - {check}: {type} — {root cause} | ||
| ### Fixes Applied | ||
| - `{file}:{line}` — {what was changed and why} | ||
| - `{file}:{line}` — {change and why} | ||
| ### Verification | ||
| - Local: {command} → {pass/fail} | ||
| - CI: {status after push} | ||
| ### Remaining Failures | ||
| | Failure | Category | Proposed Action | | ||
| |---------|----------|-----------------| | ||
| | {check} | 🟢 Quick fix | {concrete fix — do it now} | | ||
| | {check} | 🟡 Needs investigation | {create issue with `/report-issue`} | | ||
| | {check} | 🔴 Infrastructure/config | {create issue assigned to ops} | | ||
| | Failure | Category | Action | | ||
| |---------|----------|--------| | ||
| | {check} | 🟢 Quick fix | {do it now} | | ||
| | {check} | 🟡 Investigate | {`/report-issue`} | | ||
| | {check} | 🔴 Infra/config | {issue to ops} | | ||
@@ -145,9 +107,2 @@ --- | ||
| After the report, offer to fix 🟢 quick fixes and create issues for 🟡🔴 failures. Never leave failures unaddressed. | ||
| ## Context Management | ||
| - `[model: sonnet]` subagent for CI logs exceeding 200 lines — returns only errors and context, no raw log | ||
| - **Test investigation subagents**: one per failure, parallel, max 10 tool calls each, no vendor/ reads | ||
| - **Compact after each push** before fetching new CI results — keep only current failure, fix, status | ||
| - After final report, compact the conversation | ||
| Offer to fix 🟢 and create issues for 🟡🔴. Compact after report. |
+14
-53
@@ -20,3 +20,3 @@ --- | ||
| ### Step 1: Fetch Issue Details | ||
| ### Step 1: Fetch Issue | ||
@@ -26,3 +26,2 @@ ```bash | ||
| gh issue view 123 --json title,body,labels,comments,assignees | ||
| # Jira | ||
@@ -32,20 +31,14 @@ curl "https://{domain}.atlassian.net/rest/api/3/issue/{key}" -H "Authorization: Basic {credentials}" | ||
| Read the full issue including comments — context is often in comments. | ||
| Read full issue including comments. | ||
| ### Step 2: Analyze & Plan | ||
| ### Step 2: Plan | ||
| 1. Read `CLAUDE.md` and `.claude/polyforge.json` | ||
| 2. Search the codebase for relevant files (use issue keywords) | ||
| 3. Understand current behavior before planning changes | ||
| 4. Create a plan: files to modify, changes to make, tests to add | ||
| Search codebase for relevant files (use issue keywords). Understand current behavior before planning. | ||
| **After plan approval:** Save to `tmp/state-{issue}.json`: | ||
| ```json | ||
| { "issue": 123, "files_to_modify": [], "tests_to_add": [], "branch": "" } | ||
| ``` | ||
| Then compact — reload only from the state file. | ||
| Save to `tmp/state-{issue}.json`: `{ "issue", "files_to_modify": [], "tests_to_add": [], "branch": "" }` | ||
| Then compact — reload from state file. | ||
| **Preview mode (`--preview`):** Stop here and display the plan. | ||
| ### Step 3: Create Branch | ||
| ### Step 3: Branch + Implement | ||
@@ -56,32 +49,17 @@ ```bash | ||
| ### Step 4: Implement Fix | ||
| **Full auto:** Implement directly + write tests. **Semi-auto:** Show diff, ask "Apply? (y/n/edit)". | ||
| **Full auto:** Implement directly, write/update tests, run pipeline, create PR. | ||
| **Semi-auto:** Show diff preview, ask "Apply? (y/n/edit)", then run pipeline. | ||
| **Independent file groups (>3 files):** Delegate each group to `[model: sonnet]` subagent. Returns: `{ "group": "", "files": [], "summary": "" }` | ||
| If the fix involves independent file groups: delegate each to a `[model: sonnet]` subagent. | ||
| ### Step 4: Verify | ||
| ### Step 5: Verification Pipeline | ||
| Run verification pipeline per @skills/shared/common-patterns.md | ||
| ```bash | ||
| {test command} 2>&1 | bash hooks/filter-test-output.sh | ||
| {lint command} | ||
| {typecheck command} | ||
| {vulncheck command} | ||
| ``` | ||
| ### Step 5: Clean Up + PR | ||
| If any fails: fix (up to 2 retries). Same error + same approach twice → switch strategy. After 3 total attempts: | ||
| - 🟢 Quick fix → fix it now | ||
| - 🟡 Needs investigation → create issue via `/report-issue` | ||
| - 🔴 Pre-existing/infra → create issue via `/report-issue` tagged infra | ||
| ### Step 6: Clean Up Commits | ||
| ```bash | ||
| git reset --soft $(git merge-base HEAD origin/main) | ||
| # Re-commit in 3-7 logical groups (cleanup commits absorbed into parent) | ||
| # Re-commit in 3-7 logical groups | ||
| ``` | ||
| ### Step 7: Create PR | ||
| Follow @skills/shared/pr-template-guide.md | ||
@@ -91,23 +69,6 @@ | ||
| gh pr create --title "fix: {description} (#{issue-number})" --body "..." | ||
| ``` | ||
| ### Step 8: Update Issue | ||
| ```bash | ||
| gh issue comment 123 --body "Fix submitted in PR #{pr-number}" | ||
| # Jira: jira issue move {key} "In Review" && jira issue comment add {key} "PR #{pr-number}" | ||
| ``` | ||
| ### Step 9: Watch CI | ||
| ```bash | ||
| gh pr checks --watch | ||
| ``` | ||
| CI fails → run `/fix-ci` automatically. | ||
| ## Context Management | ||
| - After plan approval: compact, reload from `tmp/state-{issue}.json` | ||
| - Subagents `[model: sonnet]` for independent file groups — returns summary only | ||
| - After PR is created, compact — the PR is the deliverable | ||
| CI fails → `/fix-ci` automatically. Compact after PR — the PR is the deliverable. |
@@ -8,3 +8,3 @@ --- | ||
| You are PolyForge's documentation generator. Create documentation optimized for Claude Code to understand the project efficiently. | ||
| You are PolyForge's documentation generator. Create documentation optimized for Claude Code. | ||
@@ -28,43 +28,27 @@ ## Usage | ||
| ### Step 1: Analyze Project (subagent) | ||
| ### Step 1: Analyze Project | ||
| Spawn a `[model: sonnet]` subagent to scan the full project and return a structured summary: | ||
| Spawn `[model: sonnet]` subagent to scan and return structured JSON only: | ||
| ```json | ||
| { | ||
| "stack": {}, "entryPoints": [], "architecture": "", | ||
| "patterns": [], "conventions": [], "envVars": [], | ||
| "knownQuirks": [], "keyFiles": [], "testFrameworks": [] | ||
| } | ||
| { "stack": {}, "entryPoints": [], "architecture": "", "patterns": [], "conventions": [], "envVars": [], "knownQuirks": [], "keyFiles": [], "testFrameworks": [] } | ||
| ``` | ||
| The subagent reads: entry points, config files, main modules, existing docs. Returns structured JSON only. | ||
| Subagent reads: entry points, config files, main modules, existing docs. **Discard raw scan data — use only the JSON.** | ||
| ### Step 2: Handle Existing Files | ||
| For each file to generate: | ||
| - Doesn't exist → create | ||
| - Exists with PolyForge marker (`Forged with PolyForge`) → update in-place | ||
| - Exists without marker → ask: "(a) Merge (b) Keep existing, create separate file (c) Replace (backup to tmp/)" | ||
| - Exists with PolyForge marker → update in-place | ||
| - Exists without marker → ask: "(a) Merge (b) Keep + create separate (c) Replace (backup to tmp/)" | ||
| ### Step 3: Generate and Confirm | ||
| ### Step 3: Generate | ||
| Show a preview with file names and line counts. Ask: "Generate? (y/n/preview {filename})" | ||
| Show preview with file names and line counts. Ask: "Generate? (y/n/preview {filename})" | ||
| Generate each file from the structured summary. After each file, compact keeping only the summary and remaining files to generate. | ||
| Generate each file from structured summary. Compact between files. | ||
| **CLAUDE.md** — include only: build/test/lint commands, architecture pattern, key non-obvious conventions, `@` refs to detailed docs. Include PolyForge commands list. | ||
| **CLAUDE.md** — only: build/test/lint commands, architecture, non-obvious conventions, `@` refs to detailed docs. Include PolyForge commands list. | ||
| **`.claude/rules/`** — scope with `paths:` frontmatter. Examples: | ||
| - `polyforge-backend.md`: `src/**/*.php`, `internal/**/*.go` | ||
| - `polyforge-frontend.md`: `src/**/*.tsx`, `src/**/*.ts` | ||
| - `polyforge-tests.md`: `tests/**/*`, `**/*.test.*`, `**/*.spec.*` | ||
| **`.claude/rules/`** — scope with `paths:` frontmatter. Positive assertions, one per line. | ||
| Rules must be positive assertions, actionable, and one per line. | ||
| ## Context Management | ||
| - Step 1 scan delegated entirely to `[model: sonnet]` subagent — structured JSON only returned | ||
| - Generate files one at a time, compact between each file | ||
| - CLAUDE.md MUST stay under 200 lines — non-negotiable | ||
| - Update `lastUpdatedAt` in `.claude/polyforge.json` after generating | ||
| Update `lastUpdatedAt` in `.claude/polyforge.json`. Compact after final file. |
+30
-51
@@ -8,68 +8,47 @@ --- | ||
| You are PolyForge's project initializer. Scan, detect, ask targeted questions, and generate configuration. | ||
| You are PolyForge's project initializer. Scan, detect, ask targeted questions, generate config. | ||
| ## Phase 0: Prerequisites Check | ||
| ## Phase 0: Prerequisites | ||
| Run silently — warn if missing, stop only if `git` is absent: | ||
| Run silently — warn if missing, stop only if `git` absent: | ||
| - `git --version` — required | ||
| - `gh auth status` — warn if absent: "⚠ GitHub features won't work. Install: https://cli.github.com/" | ||
| - `glab auth status` — only if remote points to gitlab.com | ||
| - Jira — only if `.jira` or `JIRA_URL` env detected | ||
| - `gh auth status` — warn if absent | ||
| - `glab auth status` — only if GitLab remote | ||
| - Jira — only if `.jira` or `JIRA_URL` detected | ||
| ## Phase 1: Automatic Detection | ||
| ## Phase 1: Detection | ||
| Spawn a `[model: haiku]` subagent to scan the project and return a detection JSON: | ||
| Spawn `[model: haiku]` subagent → returns detection JSON only: | ||
| ```json | ||
| { | ||
| "stack": ["node", "typescript"], | ||
| "framework": "express", | ||
| "packageManager": "npm", | ||
| "architecture": "clean", | ||
| "database": { "type": "postgres", "connectionMethod": "docker", "containerName": "db" }, | ||
| "testing": { "framework": "jest", "commands": { "test": "npm test", "lint": "npm run lint" } }, | ||
| "issueTracker": { "type": "github", "config": { "titlePrefix": "" } }, | ||
| "ciFile": ".github/workflows/ci.yml", | ||
| "existingClaude": false, | ||
| "existingPolyforge": false | ||
| } | ||
| { "stack": [], "framework": "", "packageManager": "", "architecture": "", "database": { "type": "", "connectionMethod": "", "containerName": "" }, "testing": { "framework": "", "commands": {} }, "issueTracker": { "type": "", "config": {} }, "ciFile": "", "existingClaude": false, "existingPolyforge": false } | ||
| ``` | ||
| The subagent scans: `package.json`, `composer.json`, `go.mod`, `docker-compose.yml`, `.env.*`, framework config files, git log/branches, issue list for title prefix conventions. | ||
| Subagent scans: package files, docker-compose, .env.*, framework configs, git log, issue list. | ||
| **Discard all raw scan output — use only the JSON.** | ||
| **Discard all raw scan output.** Use only the detection JSON. | ||
| If existing `.claude/` (not PolyForge): backup to `tmp/backup-{date}/.claude/`, inform user. | ||
| If existing `.claude/` (not from PolyForge): back up entirely to `tmp/backup-{date}/.claude/`, inform the user. | ||
| ## Phase 2: Questions (ONE AT A TIME) | ||
| ## Phase 2: Interactive Questions (ONE AT A TIME, numbered choices) | ||
| Show detection summary, then ask only what wasn't detected: | ||
| Show the detection summary, then ask only what wasn't detected: | ||
| 1. "Detected [stack]. Correct?" → (1) Yes (2) Yes + other repos (3) Correct | ||
| 2. "Architecture: [pattern]?" → (1) Yes (2) Not exactly | ||
| 3. "Issue tracker: [tracker]?" → (1) Yes (2) Different | ||
| 4. "Autonomy?" → (1) Full auto [Recommended] (2) Semi-auto | ||
| 5. (Full auto) "Grant full file access?" → (1) Yes → write `.claude/settings.json` NOW (2) No | ||
| 6. "Additional conventions?" | ||
| 7. "Generate docs now? (`/generate-doc`)" | ||
| 1. "I detected [stack]. Is this correct?" → (1) Yes (2) Yes + other internal repos (3) Needs correction | ||
| 2. "Architecture pattern: [pattern]. Does this match?" → (1) Yes (2) Not exactly (describe) | ||
| 3. "Issue tracker: [tracker]. Correct?" → (1) Yes (2) Different (specify) | ||
| 4. "Autonomy level?" → (1) Full auto — branch, fix, test, PR without asking [Recommended] (2) Semi-auto | ||
| 5. (If full auto) "Grant full file access? ⚠️ Read/write/execute anything in this directory." → (1) Yes — write `.claude/settings.json` NOW (2) No — manual approval | ||
| 6. "Additional conventions to enforce?" | ||
| 7. "Generate Claude-optimized docs now? (`/generate-doc`)" | ||
| ## Phase 3: Generate | ||
| If full access selected: **write `.claude/settings.json` immediately** with permissions: `Edit, Write, Bash, Read, Glob, Grep`. | ||
| Confirm file list before writing. Backup existing files to `tmp/backup-{date}/`. | ||
| ## Phase 3: Generate Configuration | ||
| Create: | ||
| - `.claude/polyforge.json` — master config | ||
| - `CLAUDE.md` — short (<200 lines), `@` refs to detailed docs, include PolyForge commands | ||
| - `.claude/rules/` — scoped rules with `paths:` frontmatter | ||
| - `docs/CONTEXT.md` — architecture details | ||
| - `tmp/` + `.gitignore` entry | ||
| Create these files (confirm the list before writing, back up any existing file to `tmp/backup-{date}/`): | ||
| - **`.claude/polyforge.json`** — master config from detection JSON + answers | ||
| - **`CLAUDE.md`** — short, high-signal (<200 lines), `@` refs to detailed docs. Include PolyForge commands: `/forge`, `/pr-review`, `/analyse-db`, `/analyse-code`, `/diagnose`, `/report-issue`, `/feature`, `/fix`, `/fix-ci`, `/brainstorm`, `/generate-doc`, `/squash`, `/add-rule` | ||
| - **`.claude/rules/`** — scoped rules by file type (paths: frontmatter) | ||
| - **`docs/CONTEXT.md`** — architecture details, patterns, dependencies | ||
| - **`tmp/`** directory + `.gitignore` entry | ||
| Log all actions to `tmp/forge-log-{date}.md`. | ||
| ## Context Management | ||
| - Phase 1 detection runs in a `[model: haiku]` subagent — only detection JSON returned to parent | ||
| - After Phase 1: discard all raw scan data, use only the JSON | ||
| - After generating files: present summary of created files and locations | ||
| - End with: "**Restart Claude Code** to load the new configuration." | ||
| Log to `tmp/forge-log-{date}.md`. End with: "**Restart Claude Code** to load new configuration." |
@@ -18,9 +18,9 @@ --- | ||
| ## Review Process | ||
| ## Process | ||
| ### Step 1: Gather PR Context (run all 4 in parallel) | ||
| ### Step 1: Gather PR Context (parallel) | ||
| ```bash | ||
| gh pr view {number} --json title,body,additions,deletions,files,commits,reviews,labels | ||
| gh pr diff {number} | ||
| gh pr diff {number} -- ':!*.lock' ':!vendor/' ':!*.generated.*' | ||
| gh pr checks {number} | ||
@@ -30,38 +30,29 @@ gh api repos/{owner}/{repo}/pulls/{number}/comments | ||
| ### Step 2: Check CI/CD Status | ||
| ### Step 2: Check CI | ||
| ```bash | ||
| gh run list --branch {branch} | ||
| gh run list --branch {branch} --limit 3 | ||
| gh run view {run-id} --log-failed 2>/dev/null | head -300 | ||
| ``` | ||
| If CI fails: report which jobs failed and why. Ask: "Fix CI failures automatically?" | ||
| CI fails → report which jobs failed and why. Ask: "Fix CI failures automatically?" | ||
| ### Step 3: Code Review (MANDATORY subagent — always, no size condition) | ||
| ### Step 3: Code Review | ||
| Spawn a `[model: sonnet]` subagent with isolated context to review the diff. The subagent checks: | ||
| **Under 300 lines diff:** Review inline — no subagent needed. | ||
| **Coherence & Completeness** | ||
| - All related files present (no missing migrations, tests, configs) | ||
| - No unresolved TODO/FIXME in the diff | ||
| - Feature works end-to-end based on code flow | ||
| **Over 300 lines diff:** Spawn `[model: sonnet]` subagent with the diff. Returns JSON only: | ||
| ```json | ||
| [{ "file": "", "line": 0, "category": "critical|warning|suggestion", "msg": "" }] | ||
| ``` | ||
| **Code Quality** | ||
| - Single responsibility, no duplication, consistent naming, complete error handling | ||
| Review checklist (inline or subagent): | ||
| - **Coherence**: all related files present, no unresolved TODO/FIXME, end-to-end flow works | ||
| - **Quality**: single responsibility, no duplication, consistent naming, error handling | ||
| - **Cross-file**: API contracts match, schema changes have migrations, test coverage matches | ||
| - **Security**: no secrets, input validation on boundaries, no injection vectors | ||
| - **Performance**: no N+1, no unbounded loops, indexes for new queries | ||
| **Cross-File Consistency** | ||
| - API contracts match between caller and callee | ||
| - Schema changes have ORM/migration updates | ||
| - Test coverage matches the changes | ||
| ### Step 4: Report | ||
| **Security** | ||
| - No hardcoded secrets, input validation on boundaries, no injection vectors | ||
| **Performance** | ||
| - No N+1 queries, no unbounded loops, indexes for new query patterns | ||
| If diff > 500 lines: subagent summarizes findings per-file and returns only the summary. | ||
| ### Step 4: Generate Report | ||
| ```markdown | ||
@@ -71,35 +62,22 @@ ## PR Review: #{number} — {title} | ||
| ### CI Status | ||
| - ✓ Build: passed | ||
| - ✗ Lint: failed (2 errors) | ||
| - ✓/✗ {check}: {status} | ||
| ### Critical (must fix) | ||
| - [ ] {finding with file:line reference} | ||
| - [ ] {finding} — `{file}:{line}` | ||
| ### Warnings (should fix) | ||
| - [ ] {finding with file:line reference} | ||
| - [ ] {finding} — `{file}:{line}` | ||
| ### Suggestions (nice to have) | ||
| - [ ] {finding with file:line reference} | ||
| - [ ] {finding} — `{file}:{line}` | ||
| ### What looks good | ||
| - {positive feedback on well-written parts} | ||
| - {positive feedback} | ||
| ``` | ||
| ### Step 5: Post-Review Actions | ||
| ### Step 5: Post-Review | ||
| Ask ONE question: | ||
| "Found {N} issues ({critical} critical, {warnings} warnings). What do you want to do? | ||
| (a) Fix critical issues automatically | ||
| (b) Fix all issues automatically | ||
| (c) Just show the report — I'll fix manually | ||
| (d) Post this review as a PR comment" | ||
| Ask: "Found {N} issues ({critical} critical). Action? | ||
| (a) Fix critical automatically (b) Fix all (c) Report only (d) Post as PR comment" | ||
| ## Configuration | ||
| Read `.claude/polyforge.json` for `autonomy`, `pipeline.prePR`, `project.linters`. | ||
| ## Context Management | ||
| - Run Step 1 commands in parallel — they are independent | ||
| - `[model: sonnet]` subagent for Step 3 — always mandatory, no size condition | ||
| - After generating the report, compact the conversation — the report is the deliverable | ||
| Compact after report — follow @skills/shared/common-patterns.md |
@@ -8,3 +8,3 @@ --- | ||
| You are PolyForge's issue reporter. Detect problems and create well-structured issues in the project's tracker. | ||
| You are PolyForge's issue reporter. Detect problems and create well-structured issues. | ||
@@ -21,59 +21,36 @@ ## Usage | ||
| ### Step 1: Determine Issue Tracker | ||
| ### Step 1: Detect Tracker | ||
| Read `.claude/polyforge.json` → `issueTracker.type`. | ||
| Use pre-loaded config for `issueTracker.type`. If not configured: check `gh api repos/{owner}/{repo} --jq '.has_issues'`, then Jira env vars, then GitLab remote. Jira auth: @skills/report-issue/jira-auth.md | ||
| If not configured: check `gh api repos/{owner}/{repo} --jq '.has_issues'`, then Jira env vars, then GitLab remote. | ||
| ### Step 2: Gather Details | ||
| For Jira authentication and template discovery: see @skills/report-issue/jira-auth.md | ||
| **Interactive** — ONE question at a time: (1) What's the problem? (2) Expected vs actual? (3) Affected code? (4) Severity? | ||
| ### Step 2: Gather Issue Details | ||
| **Scan mode** — spawn `[model: sonnet]` subagent → returns JSON: | ||
| ```json | ||
| [{ "file": "", "line": 0, "type": "", "severity": "", "description": "", "fix": "" }] | ||
| ``` | ||
| Present findings, let user pick which to create as issues. | ||
| **Interactive mode** — ONE question at a time: | ||
| 1. What's the problem? | ||
| 2. Expected vs actual behavior? | ||
| 3. Which part of the codebase is affected? | ||
| 4. Severity? (critical / high / medium / low) | ||
| ### Step 3: Enrich | ||
| **Scan mode** — spawn a `[model: sonnet]` subagent to analyze the directory and return findings: | ||
| - Uncaught exceptions / missing error handling | ||
| - TODO/FIXME comments with context | ||
| - Dead code / unreachable branches | ||
| - Performance anti-patterns (N+1, unbounded loops) | ||
| - Security issues (hardcoded secrets, missing validation) | ||
| Find file/line numbers, check `git blame`, search duplicates (`gh issue list -S "{keywords}"`), suggest severity. | ||
| Present all findings as a list, let user pick which to create as issues. | ||
| ### Step 4: Templates | ||
| ### Step 3: Enrich the Issue | ||
| Before creating: find relevant file/line numbers, check git blame, search for duplicates (`gh issue list -S "{keywords}"`), suggest severity label. | ||
| ### Step 4: Check for Issue Templates | ||
| ```bash | ||
| # GitHub | ||
| ls .github/ISSUE_TEMPLATE/ 2>/dev/null | ||
| cat .github/ISSUE_TEMPLATE/bug_report.md 2>/dev/null | ||
| # GitLab | ||
| ls .gitlab/issue_templates/ 2>/dev/null | ||
| ``` | ||
| **If a template exists — NON-NEGOTIABLE:** Use VERBATIM, fill in all applicable fields, never delete sections. Append PolyForge footer. | ||
| **Template exists:** Use VERBATIM — fill all fields, never delete sections. NEVER append branding or footers. | ||
| **No template:** Use @skills/shared/issue-default.md | ||
| **If no template:** Use default at @skills/shared/issue-default.md | ||
| ### Step 5: Create | ||
| ### Step 5: Create the Issue | ||
| ```bash | ||
| # Check for title prefix in polyforge.json → issueTracker.config.titlePrefix | ||
| # GitHub | ||
| gh issue create --title "{prefix} {title}" --body "{body}" --label "{severity},{type}" | ||
| # Jira (CLI preferred, REST fallback — see @skills/report-issue/jira-auth.md) | ||
| jira issue create --type "{type}" --summary "{title}" --body "{body}" --priority "{priority}" | ||
| # GitLab | ||
| glab issue create --title "{title}" --description "{body}" --label "{labels}" | ||
| # Check titlePrefix in config | ||
| # GitHub: gh issue create --title "{prefix} {title}" --body "{body}" --label "{severity},{type}" | ||
| # Jira: jira issue create --type "{type}" --summary "{title}" --body "{body}" --priority "{priority}" | ||
| # GitLab: glab issue create --title "{title}" --description "{body}" --label "{labels}" | ||
| ``` | ||
@@ -83,9 +60,2 @@ | ||
| Show full issue preview. Ask: "Create this issue? (y/n/edit)" | ||
| Log created issues to `tmp/issues-log-{date}.md`. | ||
| ## Context Management | ||
| - Scan mode: `[model: sonnet]` subagent for directory scanning — returns findings JSON only | ||
| - After creating issues, compact the conversation | ||
| Show preview. Ask: "Create this issue? (y/n/edit)". Log to `tmp/issues-log-{date}.md`. Compact after creation. |
@@ -12,3 +12,3 @@ # PR Template Usage | ||
| ## Step 2a: If a template exists — NON-NEGOTIABLE | ||
| ## Step 2a: If a template exists — RESPECT IT COMPLETELY | ||
@@ -18,3 +18,3 @@ 1. Use the template VERBATIM — keep every section, checkbox, and HTML comment | ||
| 3. Leave sections empty or unchecked if not applicable — NEVER delete them | ||
| 4. Append `*⚒ Forged with [PolyForge](https://github.com/Vekta/polyforge)*` at the very bottom | ||
| 4. NEVER append branding, signatures, or footers — the repo's template is the final format | ||
| 5. The PR must look like a human filled it in, not a bot replacement | ||
@@ -21,0 +21,0 @@ |
+15
-42
@@ -19,6 +19,4 @@ --- | ||
| ### Step 1: Analyze Commits | ||
| ### Step 1: Analyze | ||
| Spawn a `[model: haiku]` subagent to run: | ||
| ```bash | ||
@@ -30,22 +28,18 @@ git merge-base HEAD origin/main || git merge-base HEAD origin/master | ||
| Returns: commit list with messages, changed file list, total diff line count. | ||
| Under 3 commits → "Only {N} commits — nothing to clean up." Stop. | ||
| If fewer than 3 commits: "Only {N} commits — nothing to clean up." Stop. | ||
| If total diff >2000 lines: spawn a `[model: sonnet]` subagent for per-file analysis before categorizing. | ||
| **Over 2000 lines diff:** Spawn `[model: sonnet]` subagent for per-file categorization → returns JSON: `[{ "file": "", "category": "" }]` | ||
| ### Step 2: Categorize Commits | ||
| ### Step 2: Categorize | ||
| Group into: Schema/Infrastructure | Core Implementation | API/Interface | Tests | Documentation | Cleanup | ||
| Group: Schema/Infrastructure | Core Implementation | API/Interface | Tests | Documentation | Cleanup | ||
| Cleanup commits always absorbed into parent — never standalone. | ||
| **Cleanup commits always absorbed into parent — never standalone.** | ||
| ### Step 3: Propose | ||
| ### Step 3: Propose Plan | ||
| ``` | ||
| Current: 18 commits | ||
| Proposed: 4 commits | ||
| Current: 18 commits → Proposed: 4 commits | ||
| 1. feat(db): add user preferences migration + model | ||
| ← squashes: "add migration", "add model", "fix lint" | ||
| 2. feat(api): add preferences endpoints + service | ||
@@ -55,3 +49,3 @@ ← squashes: "add service", "add controller", "fix type error" | ||
| Ask: (1) Apply this plan (2) Show diffs per group first (3) Adjust grouping | ||
| Ask: (1) Apply (2) Show diffs per group (3) Adjust grouping | ||
@@ -62,10 +56,6 @@ ### Step 4: Execute | ||
| git reset --soft $(git merge-base HEAD origin/main) | ||
| # Stage and commit group by group | ||
| git add <schema files> && git commit -m "feat(db): ..." | ||
| git add <core files> && git commit -m "feat(api): ..." | ||
| git add <test files> && git commit -m "test: ..." | ||
| ``` | ||
| If files span multiple groups: isolate changes via targeted edits per group. | ||
| ### Step 5: Verify | ||
@@ -78,31 +68,14 @@ | ||
| Show: Before/After commit count, diff identical confirmation, test status. | ||
| Show: before/after commit count, diff identical confirmation, test status. | ||
| Ask: "Push with `--force-with-lease`?" (only if remote branch exists) | ||
| ### Step 6: Update PR Description | ||
| ### Step 6: Update PR | ||
| If PR exists: read existing body, preserve entire template structure, update only summary/changes sections. | ||
| If PR exists: preserve template structure, update only summary/changes. | ||
| ```bash | ||
| gh pr view --json number,body 2>/dev/null | ||
| gh pr edit --body "{updated body preserving template}" | ||
| ``` | ||
| ## Rules | ||
| ## Commit Message Format | ||
| ``` | ||
| type(scope): short description | ||
| - Key implementation detail | ||
| - Non-obvious decisions made | ||
| ``` | ||
| Types: `feat` | `fix` | `refactor` | `test` | `docs` | `chore` | ||
| ## Important Behaviors | ||
| - Target: 3-7 commits — never squash everything into 1 | ||
| - Never lose code — verify diff stat before and after is identical | ||
| - Never include `Co-Authored-By` in commit messages | ||
| - Never lose code — verify diff stat before and after | ||
| - Commit format: `type(scope): short description` + key details | ||
| - Use `--force-with-lease` not `--force` |
33
3.13%59026
-15.25%