From 97850d5d0e00521dbb60c6d6716fbf55f3f6521c Mon Sep 17 00:00:00 2001 From: "Walden, Laurance" Date: Fri, 27 Mar 2026 21:56:18 -0700 Subject: [PATCH] chore: update AIAgentMinder to v3.2.0 - Status line context monitoring (replaces compact-reorient.js hook) - Context cycling scripts for autonomous sprint execution - Updated rules: git-workflow, scope-guardian, approach-first, debug-checkpoint, tool-first - Updated sprint-workflow with context cycle state machine - Removed obsolete hooks (compact-reorient.js, pr-pipeline-trigger.js) - All optional features enabled (correction-capture, code-quality, sprint-workflow, architecture-fitness) - CLAUDE.md structural sections updated (Behavioral Rules, Context Budget) - Cleaned obsolete .pr-pipeline.json keys Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/aiagentminder-version | 2 +- .claude/commands/aam-brief.md | 71 +-- .claude/commands/aam-grill.md | 4 +- .claude/commands/aam-pr-pipeline.md | 577 +++++++++++++++++++++++ .claude/commands/aam-quality-gate.md | 38 +- .claude/commands/aam-retrospective.md | 16 +- .claude/commands/aam-self-review.md | 11 +- .claude/commands/aam-sync-issues.md | 116 +++++ .claude/commands/aam-tdd.md | 9 +- .claude/hooks/compact-reorient.js | 28 -- .claude/rules/README.md | 2 +- .claude/rules/code-quality.md | 2 +- .claude/rules/sprint-workflow.md | 228 ++++++--- .claude/scripts/context-cycle.sh | 111 +++++ .claude/scripts/context-monitor.sh | 60 +++ .claude/scripts/install-profile-hook.ps1 | 121 +++++ .claude/scripts/install-profile-hook.sh | 116 +++++ .claude/scripts/sprint-runner.ps1 | 90 ++++ .claude/scripts/sprint-runner.sh | 67 +++ .claude/settings.json | 43 +- .pr-pipeline.json | 35 ++ CLAUDE.md | 23 +- 22 files changed, 1529 insertions(+), 241 deletions(-) create mode 100644 .claude/commands/aam-pr-pipeline.md create mode 100644 .claude/commands/aam-sync-issues.md delete mode 100644 .claude/hooks/compact-reorient.js create mode 100644 .claude/scripts/context-cycle.sh create mode 100644 .claude/scripts/context-monitor.sh create mode 100644 .claude/scripts/install-profile-hook.ps1 create mode 100644 .claude/scripts/install-profile-hook.sh create mode 100644 .claude/scripts/sprint-runner.ps1 create mode 100644 .claude/scripts/sprint-runner.sh create mode 100644 .pr-pipeline.json diff --git a/.claude/aiagentminder-version b/.claude/aiagentminder-version index 7ec1d6d..a4f52a5 100644 --- a/.claude/aiagentminder-version +++ b/.claude/aiagentminder-version @@ -1 +1 @@ -2.1.0 +3.2.0 \ No newline at end of file diff --git a/.claude/commands/aam-brief.md b/.claude/commands/aam-brief.md index 87f6a77..2e6400f 100644 --- a/.claude/commands/aam-brief.md +++ b/.claude/commands/aam-brief.md @@ -57,8 +57,7 @@ Ask in a single grouped message: - What are the immediate next priorities? - What significant decisions have already been made? (stack choices, auth approach, DB, APIs, key libraries) -- these become DECISIONS.md entries - Any known blockers or open questions? -- Do you want **code quality guidance** enabled? (TDD, review-before-commit, build-before-commit — adds ~18 lines of context per session) -- Do you want **sprint-driven development**? (structured issue decomposition with per-issue PRs — recommended for multi-phase projects) +- Any governance features you want to disable? (TDD, sprint planning, architecture fitness rules are all enabled by default) ### Step E3: Generate State Files @@ -74,9 +73,10 @@ Do NOT generate `docs/strategy-roadmap.md` unless the user asks. Instead: 3. **Populate `CLAUDE.md` Project Identity** with actual values from the audit. -4. **Handle optional features** based on Step E2 answers: - - If code quality guidance enabled: copy `code-quality.md` from the AIAgentMinder template to `[target]/.claude/rules/code-quality.md` (create the directory if needed). Also copy `project/.claude/rules/README.md`. - - If sprint planning enabled: copy `sprint-workflow.md` from template to `[target]/.claude/rules/sprint-workflow.md`. Create `SPRINT.md` from template. Add `@SPRINT.md` to CLAUDE.md (after the Context Budget table — this is Claude Code's native import syntax, loads SPRINT.md every session). Add SPRINT.md row to CLAUDE.md Context Budget table: `| SPRINT.md | ~35 lines active | Archived when sprint completes |`. Add reminder to Human Actions: "Review and approve sprint issues before Claude begins coding — every sprint starts with your approval." +4. **Install all governance features** (all enabled by default — same as new projects): + - Copy `code-quality.md` from the AIAgentMinder template to `[target]/.claude/rules/code-quality.md` (create the directory if needed). Also copy `project/.claude/rules/README.md`. + - Copy `sprint-workflow.md` from template to `[target]/.claude/rules/sprint-workflow.md`. Create `SPRINT.md` from template. Add `@SPRINT.md` to CLAUDE.md (after the Context Budget table — this is Claude Code's native import syntax, loads SPRINT.md every session). Add SPRINT.md row to CLAUDE.md Context Budget table: `| SPRINT.md | ~35 lines active | Archived when sprint completes |`. Add reminder to Human Actions: "Review and approve sprint specs before Claude begins coding — every sprint starts with your approval." + - Copy `architecture-fitness.md` from template to `[target]/.claude/rules/architecture-fitness.md`. Tell the user to customize it. 5. **Ask:** "Do you want a `docs/strategy-roadmap.md` too? It's optional for existing projects -- useful if you want a north-star doc for future phases." @@ -108,51 +108,27 @@ Ask questions in grouped rounds, not one at a time. Adapt based on project type. - MCP servers? (database tools, browser automation, etc. -- or "none") - Target launch date? -### Round 3: Quality & Testing +### Round 3: Governance Setup -**For personal tools or simple CLI/library projects:** Skip this round. Default to Lightweight tier. Tell the user: "Based on the project scope, I'm defaulting to Lightweight testing (smoke tests for critical paths). Let me know if you want more thorough testing." +**All governance features are enabled by default.** Do not ask the user to choose a tier or opt into individual features. Install everything: -**For all other projects**, ask: -- How important is reliability? -- Users beyond yourself? -- Testing preference? (or should I recommend?) +- **Code quality guidance:** TDD, review-before-commit, build-before-commit +- **Sprint planning:** structured issue decomposition with spec phase, per-issue PRs, autonomous execution +- **Architecture fitness rules:** structural constraints — user customizes after setup -Then determine quality tier: +Tell the user in one line: +> "All governance features enabled — TDD, sprint planning, self-review, and architecture fitness rules. Edit `.claude/rules/` to disable any you don't want." -| Signal | Tier | Testing | -|--------|------|---------| -| Personal, simple, solo | **Lightweight** | Smoke tests only | -| Small team, moderate complexity | **Standard** | Unit + integration tests, CI | -| Public-facing, user data, payments | **Rigorous** | Unit + integration + E2E + security scanning | -| Safety-critical, compliance | **Comprehensive** | All above + load testing + audit logging | +**Install all governance files:** -After determining the quality tier, ask about optional features: - -**Code quality guidance:** -- For **Standard, Rigorous, Comprehensive** tiers: "I recommend enabling code quality guidance (TDD, review-before-commit, build-before-commit). This adds ~18 lines of context per session. Enable? (y/n)" — default yes -- For **Lightweight** tier: "Code quality guidance is available (TDD, review-before-commit). It's optional for Lightweight projects. Enable? (y/n)" — default no - -**Sprint planning:** -- For **Standard, Rigorous, Comprehensive** tiers: "I recommend enabling sprint planning. When you start a phase, I'll decompose work into reviewable issues and work them one-by-one with per-issue PRs. Enable? (y/n)" — default yes -- For **Lightweight** tier: "Sprint planning is available — structured issue decomposition with per-issue PRs. It's optional for simple projects. Enable? (y/n)" — default no - -**Architecture fitness rules:** -- For **Rigorous, Comprehensive** tiers: "I recommend enabling architecture fitness rules. These are structural constraints (layer boundaries, external API rules, etc.) that you customize for your project. Claude enforces them during code review and PR creation. Enable? (y/n)" — default yes -- For **Standard** tier: "Architecture fitness rules are available — structural constraints for your project architecture. They're most valuable when you have a clear layered architecture. Enable? (y/n)" — default no -- For **Lightweight** tier: skip entirely - -If code quality guidance enabled: copy `code-quality.md` from the AIAgentMinder template (`project/.claude/rules/code-quality.md`) to `[target]/.claude/rules/code-quality.md` (create the directory if needed). Also copy `project/.claude/rules/README.md`. - -If sprint planning enabled: -- Copy `sprint-workflow.md` from template (`project/.claude/rules/sprint-workflow.md`) to `[target]/.claude/rules/sprint-workflow.md` -- Create `SPRINT.md` from template (`project/SPRINT.md`) if it doesn't exist -- Add `@SPRINT.md` to CLAUDE.md after the Context Budget table (Claude Code's native import syntax — loads SPRINT.md every session when the file exists) -- Add to CLAUDE.md Context Budget table: `| SPRINT.md | ~35 lines active | Archived when sprint completes |` -- Add to `docs/strategy-roadmap.md` Human Actions Needed: "Review and approve sprint issues before Claude begins coding — every sprint starts with your approval" - -If architecture fitness rules enabled: -- Copy `architecture-fitness.md` from template (`project/.claude/rules/architecture-fitness.md`) to `[target]/.claude/rules/architecture-fitness.md` -- Tell the user: "Architecture fitness rules copied. Open `.claude/rules/architecture-fitness.md` and replace the placeholder constraints with rules for your project's architecture." +1. Copy `code-quality.md` from the AIAgentMinder template (`project/.claude/rules/code-quality.md`) to `[target]/.claude/rules/code-quality.md` (create the directory if needed). Also copy `project/.claude/rules/README.md`. +2. Copy `sprint-workflow.md` from template to `[target]/.claude/rules/sprint-workflow.md`. +3. Create `SPRINT.md` from template (`project/SPRINT.md`) if it doesn't exist. +4. Add `@SPRINT.md` to CLAUDE.md after the Context Budget table (Claude Code's native import syntax — loads SPRINT.md every session when the file exists). +5. Add to CLAUDE.md Context Budget table: `| SPRINT.md | ~35 lines active | Archived when sprint completes |`. +6. Add to `docs/strategy-roadmap.md` Human Actions Needed: "Review and approve sprint specs before Claude begins coding — every sprint starts with your approval." +7. Copy `architecture-fitness.md` from template to `[target]/.claude/rules/architecture-fitness.md`. +8. Tell the user: "Architecture fitness rules copied. Open `.claude/rules/architecture-fitness.md` and replace the placeholder constraints with rules for your project's architecture." ### Decision Forcing: Surface Hard-to-Reverse Choices @@ -223,6 +199,5 @@ not vague disclaimers. "Won't support offline mode" is good. "Won't do everythin - For deferred decisions: add a `` marker in the roadmap's Open Questions section. 4. Populate `## MVP Goals` in `CLAUDE.md` with Phase 1 deliverables (3-5 testable bullet points) 5. If MCP servers were mentioned, add `**MCP Servers:**` line to Project Identity in `CLAUDE.md` -6. Summarize what was enabled: mention code quality guidance and/or sprint planning if enabled. If code quality guidance enabled, note it lives in `.claude/rules/` and is loaded natively by Claude Code each session. If sprint planning enabled, note SPRINT.md is loaded via `@import` in CLAUDE.md. -7. If sprint planning was enabled: "Sprint planning enabled. When you're ready, say 'start a sprint' or 'begin Phase 1' and I'll propose issues for your review." -8. Tell the user: "Your roadmap is ready. Tell me to start Phase 1 when you're ready." +6. Summarize what was installed: "All governance features enabled — TDD, sprint planning, self-review, and architecture fitness rules. Governance rules live in `.claude/rules/` and are loaded automatically each session. SPRINT.md is loaded via `@import` in CLAUDE.md." +7. Tell the user: "Your roadmap is ready. When you're ready, say 'start a sprint' or 'begin Phase 1' and I'll propose issues with detailed specs for your review." diff --git a/.claude/commands/aam-grill.md b/.claude/commands/aam-grill.md index d0b791a..5e8ec96 100644 --- a/.claude/commands/aam-grill.md +++ b/.claude/commands/aam-grill.md @@ -16,7 +16,7 @@ Read the plan or design being questioned. Sources may include: Also read: - `DECISIONS.md` — for prior decisions that constrain the design space -- `docs/strategy-roadmap.md` — for quality tier and scope context +- `docs/strategy-roadmap.md` — for scope context --- @@ -78,7 +78,7 @@ If yes, append each decision to DECISIONS.md in the project's existing format, i - **Use `/aam-grill`** when a design is non-obvious, high-stakes, or has multiple interdependent decisions. - **Use `approach-first.md`** for routine check-ins — state intent, confirm, proceed. -- For Rigorous+ quality tiers, consider running `/aam-grill` before architecture changes touching more than 5 files. +- Consider running `/aam-grill` before architecture changes touching more than 5 files. --- diff --git a/.claude/commands/aam-pr-pipeline.md b/.claude/commands/aam-pr-pipeline.md new file mode 100644 index 0000000..fd6a376 --- /dev/null +++ b/.claude/commands/aam-pr-pipeline.md @@ -0,0 +1,577 @@ +# /aam-pr-pipeline - Autonomous PR Review Pipeline + +Review, fix, test, and merge a pull request autonomously. Handles the full +review→fix→test→merge loop with human escalation for high-risk or genuinely +blocked cases. + +Invoked in-session by the sprint workflow after PR creation, or manually: +`/aam-pr-pipeline` (uses current branch PR) or `/aam-pr-pipeline `. + +--- + +## Step 0: Parse Input and Load Config + +**Determine the PR:** + +If invoked with a PR URL argument: parse owner, repo, and PR number. + +If invoked without arguments, get current PR: +```bash +git rev-parse --abbrev-ref HEAD +gh pr view --json number,url,headRefName,baseRefName,title,body,author +``` + +If no open PR for the current branch, tell the user and stop. + +**Load config** from `.pr-pipeline.json` at the repo root (if it exists): + +```json +{ + "highRiskPatterns": ["**/auth/**", "**/security/**", "**/payment/**", + "**/billing/**", "**/migration/**", ".github/workflows/**", + "Dockerfile*", "docker-compose*", "*.tf", "*.tfvars"], + "cycleLimit": 5, + "autoMerge": true, + "mergeMethod": "squash", + "skipPatterns": ["package-lock.json", "yarn.lock", "*.lock", + "dist/**", "build/**", ".next/**"], + "notification": { "email": "", "from": "pipeline@resend.dev" }, + "testCommand": null, + "mergeWait": { "pollIntervalSeconds": 30, "timeoutMinutes": 15 } +} +``` + +If the file is absent, use these defaults. + +**Get PR metadata:** +```bash +gh pr view {number} --json number,title,body,headRefName,baseRefName,files,labels,headRefOid,author +``` + +**Initialize cycle counter:** Check PR labels for a label matching `ai-cycle-N`. +Set `cycleNumber` to N, or 1 if no such label exists. + +**Detect worktree:** Check if the current working directory path contains +`.pr-pipeline-worktrees/`. If yes, `isWorktree = true`. + +--- + +## Step 1: High-Risk File Gate + +Get the list of changed files from the PR metadata (Step 0, `files` field). + +Check each file path against `highRiskPatterns`. Use glob-style matching: +`**` matches any path segment, `*` matches within a single segment. + +If ANY file matches a high-risk pattern: + +1. Comment on the PR: + ``` + ## PR Pipeline — Human Review Required + + This PR modifies files in a high-risk area that requires human review before + automated processing: + + {list each matching file and which pattern it matched} + + The pipeline has stopped. Please review and merge manually, or remove the + relevant files from the PR if the change is unintentional. + ``` + ```bash + gh pr comment {number} --body "..." + ``` + +2. Add label and set status: + ```bash + gh pr edit {number} --add-label "needs-human-review" + gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=failure \ + -f context="ai-review/claude" \ + -f description="High-risk files detected — human review required" + ``` + +3. Send notification email if `notification.email` is configured (see + Notification Helper at the bottom of this file). + +4. **STOP. Proceed to Step 9 (Cleanup) then exit.** + +--- + +## Step 2: Cycle Limit Check + +If `cycleNumber` exceeds `cycleLimit`: + +1. Comment on the PR: + ``` + ## PR Pipeline — Cycle Limit Reached + + The automated review-fix loop has run {cycleNumber} times without converging. + Manual review is required to resolve the remaining feedback. + ``` + ```bash + gh pr comment {number} --body "..." + ``` + +2. Add label and set status: + ```bash + gh pr edit {number} --add-label "needs-human-review" + gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=failure \ + -f context="ai-review/claude" \ + -f description="Review cycle limit reached ({cycleNumber}) — manual review required" + ``` + +3. Send notification email if configured. + +4. **STOP. Proceed to Step 9 (Cleanup) then exit.** + +**Update cycle label:** +```bash +# Remove old label if present +gh pr edit {number} --remove-label "ai-cycle-{cycleNumber-1}" +# Add new label (create it first if it doesn't exist) +gh api repos/{owner}/{repo}/labels -f name="ai-cycle-{cycleNumber}" \ + -f color="0075ca" 2>/dev/null || true +gh pr edit {number} --add-label "ai-cycle-{cycleNumber}" +``` + +--- + +## Step 3: Review the Code + +Set status to pending: +```bash +gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=pending \ + -f context="ai-review/claude" \ + -f description="Review in progress" +``` + +**Get the diff:** +```bash +git diff {baseRefName}...HEAD +``` + +If the diff is empty (no changes vs base), post a comment noting this and stop. + +**Read context beyond the diff:** + +For each file changed in the PR, you CAN and SHOULD read the full source file +to understand context that isn't visible in the diff. Focus especially on: +- The surrounding functions of changed lines +- Interfaces or types that changed code depends on +- Existing error handling patterns in the file + +Also read: +- `.claude/rules/architecture-fitness.md` if it exists +- `.claude/rules/code-quality.md` if it exists + +**Read prior review comments** to avoid re-flagging addressed issues: +```bash +gh pr view {number} --json comments \ + --jq '[.comments[] | select(.body | startswith("## Claude Code Review"))] | last' +``` + +**Read prior developer evaluation comments** (this is a re-review after fixes): +```bash +gh pr view {number} --json comments \ + --jq '[.comments[] | select(.body | startswith("## Developer Evaluation"))] | last' +``` + +**Review focus:** +- Bugs and logic errors (highest priority) +- Security vulnerabilities: injection, auth bypass, data exposure, hardcoded secrets +- Missing error handling on external calls, file I/O, and network requests +- Performance: N+1 queries, unbounded loops, blocking calls in async contexts +- Breaking API changes (removed fields, changed types, renamed endpoints) + +**Do NOT flag:** +- Minor style preferences not backed by existing project conventions +- Issues already addressed in prior reviews +- Issues where the developer's rebuttal in a prior `## Developer Evaluation` + comment gave a valid context-based justification + +**Produce a structured verdict** (hold in memory — do not output as raw JSON): + +``` +verdict: "clean" | "issues_found" +issues: [ + { + file: string, + line: number | null, + severity: "critical" | "major" | "minor", + description: string, + suggested_fix: string | null, + fix_confidence: "confident" | "uncertain" | "no_fix", + context_sufficient: boolean // false = reviewer unsure due to limited diff context + } +] +summary: string +``` + +--- + +## Step 4: Route on Verdict + +**If verdict is `clean`** (or all issues have `context_sufficient: false`): + +Post review comment: +```bash +gh pr comment {number} --body "## Claude Code Review + +{summary} + +No actionable issues found. +{list any context_sufficient:false items as informational only, prefixed with ℹ️}" +``` + +Set status success: +```bash +gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=success \ + -f context="ai-review/claude" \ + -f description="Review passed" +``` + +**Proceed to Step 6 (Run Tests).** + +**If verdict is `issues_found`** (at least one issue with `context_sufficient: true`): + +Post review comment listing all issues: +```bash +gh pr comment {number} --body "## Claude Code Review + +{summary} + +{for each issue: + ### {SEVERITY}: {file}:{line} + {description} + **Suggested fix** ({fix_confidence}): {suggested_fix} + [ℹ️ Informational only — may not be an issue with full context] (if context_sufficient:false) +}" +``` + +Set status failure: +```bash +gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=failure \ + -f context="ai-review/claude" \ + -f description="Review found {count} issue(s)" +``` + +**Proceed to Step 5 (Evaluate and Fix).** + +--- + +## Step 5: Evaluate and Fix Issues + +Switch roles: you are now the **developer** working on this PR. + +For each issue from Step 3 where `context_sufficient: true`: + +Read the full source file for each issue. Evaluate with full repo context: + +**A) VALID** — The issue is real and worth fixing. Fix it. + +**B) CONTEXT_INSUFFICIENT** — The reviewer flagged this based on a partial diff, +but with full repo access the code is correct. Explain specifically what context +the reviewer was missing and why the code is correct. + +**C) NOT_WORTH_IMPLEMENTING** — The suggestion is technically valid but the +implementation cost outweighs the benefit for this PR. +IMPORTANT: Never use this for critical/major bugs or security issues. +Only valid for minor stylistic suggestions, premature optimizations, or +architectural preferences that don't affect correctness. + +**For VALID issues:** Fix the code, then: +```bash +git add {changed files} +git commit -m "[ai-fix] Address review feedback: {brief one-line summary}" +``` + +**For CONTEXT_INSUFFICIENT or NOT_WORTH_IMPLEMENTING:** Document the reasoning. +Do NOT change the code. + +**Safety escalation check:** + +After evaluating all issues, check: +- Is `cycleNumber >= cycleLimit`? +- AND did you dismiss any issue as `NOT_WORTH_IMPLEMENTING` (not `CONTEXT_INSUFFICIENT`) + where the original `severity` was `critical` OR the description mentions security? + +If both conditions are true: the pipeline is stuck at the cycle limit with a developer +dismissing a critical/security finding. Human judgment is needed. + +1. Post a comment showing both the reviewer's finding and the developer's dismissal. +2. Add label `needs-human-review`. +3. Send notification email. +4. **STOP. Proceed to Step 9 (Cleanup) then exit.** + +**Routing after evaluation:** + +If any fixes were committed (`[ai-fix]` commits exist): +```bash +git push origin HEAD +``` +Set review status back to pending (re-review will begin). +**Loop back to Step 2** with `cycleNumber += 1`. + +If all issues were dismissed (no commits): +Post a developer evaluation comment: +```bash +gh pr comment {number} --body "## Developer Evaluation + +{summary of evaluation} + +{for each issue: + ### {icon} Issue: {file} + **Disposition:** {fixed | context_insufficient | not_worth_implementing} + **Reasoning:** {specific explanation with file/line references} +}" +``` + +Set review status to success: +```bash +gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=success \ + -f context="ai-review/claude" \ + -f description="Review issues addressed" +``` + +**Proceed to Step 6 (Run Tests).** + +--- + +## Step 6: Run Tests + +Set test status to pending: +```bash +gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=pending \ + -f context="tests/claude" \ + -f description="Test execution in progress" +``` + +**Detect the test runner:** + +If `testCommand` is set in config, use that. Otherwise check in this order: +- `package.json` with a `test` script → `npm test` +- `*.csproj` or `*.sln` in repo root → `dotnet test` +- `pytest.ini`, `pyproject.toml`, or `setup.py` → `pytest` +- `go.mod` → `go test ./...` +- If none found: note "No test suite detected" and proceed to Step 7. + +**Run tests.** You MUST execute the test suite yourself — do not describe tests +for a human to run. + +If the PR changes functionality not covered by existing tests, write and run +additional targeted verification: +- HTTP endpoints: use `curl` or `Invoke-WebRequest` +- CLI tools: invoke directly +- File generators: run the generator and verify output exists and is parseable + +**If all tests pass:** + +Post comment: +```bash +gh pr comment {number} --body "## Test Execution Results + +{summary} + +{for each test: ✅/❌ **{name}**: {details}}" +``` + +Set status: +```bash +gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=success \ + -f context="tests/claude" \ + -f description="All tests passed" +``` + +**Proceed to Step 7 (Pre-Merge Readiness).** + +**If tests fail with a code bug you can fix:** + +Fix the code, re-run the failing test to confirm it passes, then: +```bash +git add {changed files} +git commit -m "[ai-fix] Fix test failure: {brief description}" +git push origin HEAD +``` + +**Loop back to Step 2** with `cycleNumber += 1` (the push triggers re-review). + +**If tests are blocked** (cannot execute due to genuinely external requirements): + +The ONLY acceptable reasons for escalation: +- A test requires a running external service you cannot start +- A test requires credentials or secrets you don't have access to +- A test requires physical hardware interaction +- A test requires visual inspection only a human can perform + +If you CAN approximate the verification (mock the dependency, check output +format, validate logic without the live service), DO THAT instead of escalating. + +For genuine blocks: +```bash +gh pr comment {number} --body "## Test Execution Results — Blocked + +{for each blocked item: + - **{description}**: {why Claude cannot execute this test} +}" +``` + +Add label and set status: +```bash +gh pr edit {number} --add-label "needs-human-review" +gh api repos/{owner}/{repo}/statuses/{sha} \ + -f state=failure \ + -f context="tests/claude" \ + -f description="Test execution blocked — human verification required" +``` + +Send notification email (see Notification Helper). Include the blocked items +and the PR URL so the human can decide: merge manually or fix the environment. + +**STOP. Proceed to Step 9 (Cleanup) then exit.** + +--- + +## Step 7: Pre-Merge Readiness + +Both pipeline checks (`ai-review/claude` and `tests/claude`) are green. +Before merging, confirm all OTHER required checks have also passed. + +Poll with backoff: +```bash +gh pr checks {number} --json name,state,status,conclusion +``` + +Repeat every `mergeWait.pollIntervalSeconds` seconds (default 30) until: +- All checks have a `conclusion` of `success` or `skipped` → proceed to Step 8 +- Any check has `conclusion` of `failure` or `cancelled` → escalate (see below) +- Total wait exceeds `mergeWait.timeoutMinutes` (default 15 min) → escalate + +**If an external check fails or times out:** + +Send notification email listing which check(s) failed/timed out. +Set a label: `gh pr edit {number} --add-label "ci-failure"` +**STOP. Proceed to Step 9 (Cleanup) then exit.** + +Note: do NOT post a PR comment about the failure — the CI system typically +already posts its own failure details. + +--- + +## Step 8: Auto-Merge + +All checks are green. If `autoMerge` is false in config, post a comment +notifying the user that the PR is ready to merge manually, then stop. + +**Attempt merge:** +```bash +gh pr merge {number} --{mergeMethod} --delete-branch +``` +(Default `mergeMethod` is `squash`.) + +**If merge succeeds:** + +Post a final summary comment: +```bash +gh pr comment {number} --body "## PR Pipeline Complete + +Reviewed, tested, and merged automatically. + +- Review cycles: {cycleNumber} +- Fixes applied: {count of [ai-fix] commits} +- Tests executed: {count} ({passed} passed)" +``` + +**If merge fails — attempt self-resolution first:** + +Check the failure reason: +- **Merge conflict:** Pull base branch, resolve conflicts, commit, push, then + loop back to Step 7 (wait for checks on the resolution commit): + ```bash + git fetch origin {baseRefName} + git merge origin/{baseRefName} + # Resolve conflicts by reading both versions and choosing the correct merge + git add {conflicted files} + git commit -m "[ai-fix] Resolve merge conflict with {baseRefName}" + git push origin HEAD + ``` +- **Branch out of date (not a conflict):** Rebase or merge base and retry. +- **PR already merged:** No action needed, skip to cleanup. +- **PR closed or draft:** Post a comment noting the unexpected state, stop. + +**If merge fails with a reason the pipeline cannot resolve** (branch protection +rule the pipeline can't satisfy, admin approval required, etc.): + +```bash +gh pr edit {number} --add-label "needs-human-review" +``` + +Send notification email with the failure reason and PR URL. +**STOP. Proceed to Step 9 (Cleanup) then exit.** + +--- + +## Step 9: Cleanup + +Remove the `ai-pipeline-active` label (n8n sets it before spawning; the pipeline owns removal): +```bash +gh pr edit {number} --remove-label "ai-pipeline-active" 2>/dev/null || true +``` + +If `isWorktree` is true (running in a pipeline worktree): +```bash +# Get the repo root (parent of the worktree's parent .pr-pipeline-worktrees dir) +REPO_ROOT=$(git worktree list | head -1 | awk '{print $1}') +WORKTREE_PATH=$(pwd) +cd "$REPO_ROOT" +git worktree remove "$WORKTREE_PATH" --force +``` + +If `isWorktree` is false (manual invocation in the user's working copy): skip worktree cleanup. + +--- + +## Notification Helper + +When a notification email is needed, read `notification.email` and +`notification.from` from config. If `notification.email` is empty, skip email +and post a PR comment instead. + +If email is configured, read the Resend API key: +```bash +# Try environment first, fall back to Bitwarden +RESEND_KEY="${RESEND_API_KEY:-$(bw get item 'Resend API Key' --session $BW_SESSION 2>/dev/null | \ + node -e 'let d=""; process.stdin.on("data",c=>d+=c).on("end",()=>console.log(JSON.parse(d).notes))' 2>/dev/null)}" +``` + +Send via Resend: +```bash +curl -s -X POST https://api.resend.com/emails \ + -H "Authorization: Bearer $RESEND_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "from": "{notification.from}", + "to": ["{notification.email}"], + "subject": "PR Pipeline: {reason} — {repo}#{prNumber}", + "html": "{formatted HTML with PR URL, reason, and relevant details}" + }' +``` + +--- + +## Integration with Sprint Workflow + +The sprint workflow invokes `/aam-pr-pipeline` in-session after creating a PR. +When the pipeline completes successfully (PR merged), control returns to the +sprint workflow which continues to the next issue. + +When the pipeline escalates, the PR label (`needs-human-review`, `ci-failure`, +`ai-cycle-{N}`) indicates the current state. The sprint workflow stops and +notifies the user. Resolve the issue, then re-invoke `/aam-pr-pipeline` to +resume. diff --git a/.claude/commands/aam-quality-gate.md b/.claude/commands/aam-quality-gate.md index 73b8300..1846034 100644 --- a/.claude/commands/aam-quality-gate.md +++ b/.claude/commands/aam-quality-gate.md @@ -1,62 +1,48 @@ # /aam-quality-gate - Pre-PR Quality Checks -Run this before creating any pull request. It enforces the quality tier declared in `docs/strategy-roadmap.md`. +Run this before creating any pull request. Runs the full quality checklist — all checks, every time. --- -## Step 1: Read the Quality Tier +## Step 1: Run All Checks -Read `docs/strategy-roadmap.md` and find the **Quality Tier** section. +Execute every check in order. Fix failures before proceeding to the next check. -If the file is missing or the tier is placeholder: default to **Standard** and note this to the user. - ---- - -## Step 2: Run Checks by Tier - -### Lightweight +### Build - [ ] **Build passes** — Run the project's build command. If it fails, fix before proceeding. -If all checks pass → proceed to PR creation. - -### Standard (run Lightweight checks first, then:) +### Tests - [ ] **Tests exist for new functionality** — For each new or changed function/module, confirm at least one test covers it. - [ ] **Test suite passes** — Run the full test suite. Zero failing tests. - [ ] **No debug statements** — Search for `console.log`, `debugger`, `print(`, `puts`, `binding.pry` in changed files. Remove any found. -If all checks pass → proceed to PR creation. - -### Rigorous (run Standard checks first, then:) +### Coverage & Lint - [ ] **Test coverage delta** — Run coverage and confirm new code is covered. Flag any untested branches in critical paths. - [ ] **No `any` types** (TypeScript projects) — Search changed `.ts`/`.tsx` files for `: any` and `as any`. Each occurrence needs justification or fixing. - [ ] **Linter clean** — Run the project's linter (`eslint`, `ruff`, `golangci-lint`, etc.). Zero new warnings. -If all checks pass → proceed to PR creation. - -### Comprehensive (run Rigorous checks first, then:) +### Security - [ ] **No hardcoded secrets** — Search changed files for patterns: API keys, connection strings, passwords, tokens. None should be literal strings. - [ ] **Error handling on external calls** — For each new call to an external service, API, or database: confirm there's explicit error handling (try/catch, `.catch()`, `if err != nil`). - [ ] **Security scan** — Run the project's security scanner if configured (`npm audit`, `pip-audit`, `govulncheck`, `trivy`, etc.). Address any high/critical findings. -If all checks pass → proceed to PR creation. - --- -## Step 3: Report and Decide +## Step 2: Report and Decide After running checks: -- **All pass:** "Quality gate passed ([Tier] tier). Creating PR." -- **Failures found:** List each failure with the specific file and line. Do not create the PR until failures are resolved unless the user explicitly overrides: "Proceed despite quality gate failure? (y/n)" +- **All pass:** "Quality gate passed. Creating PR." +- **Failures found:** List each failure with the specific file and line. Fix all failures before creating the PR. During autonomous sprint execution, fix failures without asking — do not prompt for override. -If the user overrides: create the PR and add a note to the PR description: "⚠ Quality gate override: [reason for override]." +If invoked manually outside a sprint and the user explicitly requests an override: create the PR and add a note to the PR description: "Quality gate override: [reason for override]." --- ## Integration with Sprint Workflow -This command is called automatically by the sprint workflow before each PR creation. You can also invoke it manually at any time with `/aam-quality-gate`. +This command is called automatically by the sprint workflow before each PR creation. During sprint execution, quality gate failures must be fixed — not overridden. You can also invoke it manually at any time with `/aam-quality-gate`. diff --git a/.claude/commands/aam-retrospective.md b/.claude/commands/aam-retrospective.md index 51e904c..5130096 100644 --- a/.claude/commands/aam-retrospective.md +++ b/.claude/commands/aam-retrospective.md @@ -8,7 +8,7 @@ Generate a brief retrospective for the completed sprint. Called automatically at Read the following: -1. `SPRINT.md` — sprint goal, issue list, final statuses (including any risk-tagged issues) +1. `SPRINT.md` — sprint goal, issue list, final statuses (including Post-Merge column) 2. Use TaskList to get final task states and any notes 3. `DECISIONS.md` — identify entries added during this sprint (by date or sprint reference) 4. Recent git log for this sprint's branches: @@ -27,8 +27,10 @@ From the data gathered, calculate: | --- | --- | | **Planned issues** | How many issues were in the approved sprint | | **Completed issues** | How many reached `done` | +| **Rework items** | How many items required rework (post-merge validation failures or test failures after initial "done") | | **Blocked issues** | How many are still `blocked` at sprint end | -| **Risk-tagged issues** | How many had `[risk]` tag; how many triggered `/aam-self-review` | +| **Post-merge validations** | How many items had post-merge validation tasks; how many passed vs. failed | +| **Risk-tagged issues** | How many had `[risk]` tag | | **Scope additions** | Issues added after sprint approval | | **Scope removals** | Issues removed after sprint approval | | **Decisions logged** | DECISIONS.md entries added this sprint | @@ -45,8 +47,12 @@ Date: {today} Delivery: Planned: {n} issues Completed: {n} issues ({%} completion rate) + Rework: {n} items [list IDs and failure description if any] Blocked: {n} issues [list IDs and blocker reason if any] - Risk-tagged: {n} issues [list which ones, note if self-review found issues] + +Quality: + Post-merge validations: {n} defined, {n} passed, {n} failed + {If rework items exist: "Rework was needed for: [list items and root cause]"} Scope: {No scope changes} OR {Added: [issue titles] / Removed: [issue titles]} @@ -57,7 +63,7 @@ Decisions: Patterns: [One honest observation about what went well] - [One honest observation about what was harder than expected] + [One honest observation about what was harder than expected — e.g., "S2-003 required rework due to staging env mismatch"] ``` --- @@ -69,6 +75,7 @@ Read prior archived sprint lines from `SPRINT.md` (lines starting with `S{n} arc From each archived line and from the current sprint's metrics (Step 2), identify **stress indicators**: - **Scope churn**: any scope additions or removals occurred during the sprint - **Blocked issues**: any issues ended the sprint in `blocked` status +- **Rework items**: any items required rework (post-merge validation failures). Each rework item counts as a stress indicator. - **Context pressure**: the sprint had 7+ planned issues **Recommendation logic:** @@ -79,6 +86,7 @@ From each archived line and from the current sprint's metrics (Step 2), identify - 1 stress indicator in the most recent sprint: reduce max by 1. - 2+ stress indicators in the most recent sprint: reduce both min and max by 1. - Stress indicators present in 2+ of the last 3 sprints: reduce both min and max by 1 (cumulative with above). + - Rework items in the most recent sprint: each rework item counts as a stress indicator. **Hard boundaries:** The recommendation must fall within 3–7 issues. Clamp to this range after all adjustments. Never recommend more than 7 regardless of history. diff --git a/.claude/commands/aam-self-review.md b/.claude/commands/aam-self-review.md index 4286751..de96d5e 100644 --- a/.claude/commands/aam-self-review.md +++ b/.claude/commands/aam-self-review.md @@ -17,13 +17,14 @@ If the diff is empty: tell the user "No changes vs main — nothing to review." Also read: - `.claude/rules/architecture-fitness.md` if it exists (structural constraints to enforce) - `.claude/rules/code-quality.md` if it exists (quality standards for this project) -- `docs/strategy-roadmap.md` Quality Tier section (to calibrate review depth) --- ## Step 2: Choose Review Lens -Ask the user which lens to apply (or accept all three for a full review): +During autonomous sprint execution: always run all three lenses — do not ask. + +When invoked manually, ask the user which lens to apply (or accept all three for a full review): **A) Security** — injection, auth bypass, data exposure, hardcoded secrets **B) Performance** — N+1 queries, unbounded loops, missing indexes, blocking I/O @@ -111,9 +112,7 @@ After all subagents complete: 2. **If High severity issues found:** Do not proceed to PR. Fix the issues and re-run `/aam-self-review` or `/aam-quality-gate`. -3. **If Medium/Low issues only:** Ask the user: "Medium/Low issues found. Fix before PR, or proceed with issues noted in PR description? (fix / proceed)" - - If fix: address issues, then proceed to PR creation. - - If proceed: add a "Review Notes" section to the PR description listing the known issues. +3. **If Medium/Low issues only:** During autonomous sprint execution, fix them — do not ask whether to proceed. When invoked manually, ask the user: "Medium/Low issues found. Fix before PR, or proceed with issues noted in PR description? (fix / proceed)" 4. **If no issues:** Proceed directly to PR creation. @@ -121,6 +120,6 @@ After all subagents complete: ## Integration with Sprint Workflow -`/aam-self-review` is called by the sprint workflow before PR creation for **Rigorous** and **Comprehensive** quality tiers. For **Standard** tier it's optional. For **Lightweight** tier it's skipped. +`/aam-self-review` is called by the sprint workflow before PR creation for every item. During autonomous sprint execution, address all findings by fixing them — do not prompt. Fix Medium/Low findings as well. You can also invoke it manually at any time with `/aam-self-review`. diff --git a/.claude/commands/aam-sync-issues.md b/.claude/commands/aam-sync-issues.md new file mode 100644 index 0000000..3e99bac --- /dev/null +++ b/.claude/commands/aam-sync-issues.md @@ -0,0 +1,116 @@ +# /aam-sync-issues - Sync Sprint Issues to GitHub + +Push the current sprint's issues to GitHub Issues for visibility outside Claude Code. + +Run this after sprint planning is approved, or at any point to bring GitHub Issues in sync with the current sprint state. + +--- + +## Prerequisites + +- A GitHub remote must be configured (`git remote -v` shows an `origin` pointing to a GitHub repo) +- `gh` CLI must be installed and authenticated (`gh auth status`) +- An active sprint must exist in `SPRINT.md` (`**Status:** in-progress` or `proposed`) + +--- + +## Step 1: Validate Prerequisites + +```bash +git remote -v +gh auth status +``` + +- If no GitHub remote: stop. "No GitHub remote found. Add one with `git remote add origin ` first." +- If `gh` not authenticated: stop. "GitHub CLI not authenticated. Run `gh auth login` first." +- If no SPRINT.md or no active sprint: stop. "No active sprint found. Run a sprint first, then sync." + +--- + +## Step 2: Read Current Sprint + +Read `SPRINT.md`. Extract: +- Sprint number (e.g., `S1`) +- Sprint goal +- Each issue: ID, title, type, risk flag, status + +--- + +## Step 3: Check Existing GitHub Issues + +```bash +gh issue list --label "aiagentminder" --json number,title,state,labels --limit 100 +``` + +Build a map of existing issues by their sprint ID label (e.g., label `S1-001`). + +--- + +## Step 4: Create or Update Issues + +For each sprint issue: + +**If no matching GitHub issue exists** (no issue with label matching the sprint issue ID): + +```bash +gh issue create \ + --title "[S{n}-{seq}] {title}" \ + --body "{body}" \ + --label "aiagentminder,sprint-S{n},{type}" \ + [--label "risk" if risk-tagged] +``` + +Body format: +``` +**Sprint:** S{n} — {sprint goal} +**Type:** {feature | fix | chore | spike} +**Status:** {todo | in-progress | done | blocked} + +{acceptance criteria if available from sprint planning} +``` + +**If a matching GitHub issue exists:** +- If sprint status is `done` and GitHub issue is open: close it. + ```bash + gh issue close {number} --comment "Completed in sprint S{n}." + ``` +- If sprint status is `blocked` and GitHub issue is open: add a comment. + ```bash + gh issue comment {number} --body "⚠ Blocked: {blocked reason if known}" + ``` +- If sprint status changed but issue is already in the right state: skip. + +**Labels used:** +- `aiagentminder` — marks all AIAgentMinder-managed issues +- `sprint-S{n}` — identifies the sprint (e.g., `sprint-S1`) +- `{type}` — `feature`, `fix`, `chore`, or `spike` +- `risk` — for risk-tagged issues + +Create labels that don't exist yet: +```bash +gh label create "aiagentminder" --color "0075ca" --description "AIAgentMinder sprint issue" 2>/dev/null || true +gh label create "sprint-S{n}" --color "e4e669" --description "Sprint S{n}" 2>/dev/null || true +``` + +--- + +## Step 5: Print Summary + +``` +GitHub Issues synced — Sprint S{n} + +Created: +- #{number}: [S{n}-{seq}] {title} +- [repeat] + +Updated: +- #{number}: [S{n}-{seq}] {title} — closed (done) +- #{number}: [S{n}-{seq}] {title} — commented (blocked) + +Skipped (no change): +- {count} issue(s) already in sync + +View sprint issues: gh issue list --label "sprint-S{n}" +``` + +If nothing changed: "All {count} sprint issues are already in sync with GitHub." diff --git a/.claude/commands/aam-tdd.md b/.claude/commands/aam-tdd.md index bd08e07..8fe4c8d 100644 --- a/.claude/commands/aam-tdd.md +++ b/.claude/commands/aam-tdd.md @@ -8,12 +8,9 @@ Guided TDD workflow for implementing features through red-green-refactor cycles. ## Step 0: Read Context -Read `docs/strategy-roadmap.md` and find the **Quality Tier** section. +Read `.claude/rules/code-quality.md` if it exists — this skill complements that rule with the full structured methodology. -- **Standard tier and above:** TDD is the expected workflow. Proceed. -- **Lightweight tier:** TDD is optional. Ask: "Quality tier is Lightweight — TDD is optional. Proceed with TDD anyway? (y/n)" - -Also read `.claude/rules/code-quality.md` if it exists — the skill complements that rule, not replaces it. +Also read `docs/strategy-roadmap.md` for scope context and any testing strategy notes. --- @@ -92,7 +89,7 @@ Run tests after each refactor step. Never refactor while RED — get to GREEN fi ## When to Use This - **Use `/aam-tdd`** when starting a new feature or when the test plan is non-obvious. -- **Use `code-quality.md`** (loaded automatically at Standard+ tiers) for day-to-day TDD discipline without the full structured workflow. +- **Use `code-quality.md`** (loaded automatically) for day-to-day TDD discipline without the full structured workflow. - Pairs well with `/aam-triage` — triage produces a fix plan as RED-GREEN cycles that this skill can execute. --- diff --git a/.claude/hooks/compact-reorient.js b/.claude/hooks/compact-reorient.js deleted file mode 100644 index 9403eb7..0000000 --- a/.claude/hooks/compact-reorient.js +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env node -// Hook: SessionStart (compact matcher only) — Re-orient Claude after context compaction. -// Outputs active sprint summary (first 15 lines of SPRINT.md) if a sprint is in progress; -// otherwise outputs a brief status line. -// -// Fires ONLY post-compaction (via "matcher": "compact" in settings.json), not on every -// session start. Native .claude/rules/ loading, @import syntax, and Session Memory handle -// everything else automatically. -// -// Cross-platform (Node.js). No dependencies. - -const fs = require("fs"); -const path = require("path"); - -const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd(); -const sprintFile = path.join(projectDir, "SPRINT.md"); - -if (fs.existsSync(sprintFile)) { - const content = fs.readFileSync(sprintFile, "utf8"); - if (content.includes("**Status:** in-progress")) { - const lines = content.split("\n").slice(0, 15); - console.log("--- Sprint context (post-compaction reorientation) ---"); - console.log(lines.join("\n")); - process.exit(0); - } -} - -console.log("No active sprint."); diff --git a/.claude/rules/README.md b/.claude/rules/README.md index 2aa205a..fc865c6 100644 --- a/.claude/rules/README.md +++ b/.claude/rules/README.md @@ -13,7 +13,7 @@ All `.md` files in this directory are auto-discovered and loaded automatically. | `tool-first.md` | Tool-first autonomy — use CLI/API tools instead of asking the user to do it (always active) | | `correction-capture.md` | Correction capture — flags repeated wrong-first-approach patterns and proposes permanent instructions (always active) | | `code-quality.md` | TDD cycle, build-before-commit, review-before-commit, error handling (optional) | -| `sprint-workflow.md` | Sprint governance over native Tasks — planning, approval gates, review/archive (optional) | +| `sprint-workflow.md` | Sprint governance over native Tasks — planning, approval gates, context cycling, review/archive (optional) | | `architecture-fitness.md` | Structural constraints — layer boundaries, external API rules, etc. (optional, customize for your project) | Add your own `.md` files here for project-specific rules. Files support YAML frontmatter with `globs:` patterns to scope rules to specific file paths. diff --git a/.claude/rules/code-quality.md b/.claude/rules/code-quality.md index 1b15d5b..f9fcf66 100644 --- a/.claude/rules/code-quality.md +++ b/.claude/rules/code-quality.md @@ -7,7 +7,7 @@ description: Code quality and development discipline rules ## Development Discipline -**TDD cycle (Standard tier and above):** Write a failing test first. Implement the minimal solution to make it pass. Refactor only after tests are green. +**TDD cycle:** Write a failing test first. Implement the minimal solution to make it pass. Refactor only after tests are green. **Build and test before every commit:** Run the project's build command and full test suite before staging anything. Never commit code that doesn't compile or has failing tests. diff --git a/.claude/rules/sprint-workflow.md b/.claude/rules/sprint-workflow.md index 2efd578..fbdeced 100644 --- a/.claude/rules/sprint-workflow.md +++ b/.claude/rules/sprint-workflow.md @@ -1,99 +1,195 @@ --- -description: Sprint planning and execution workflow +description: Sprint planning and execution workflow — state machine with mandatory quality steps --- -# Sprint Workflow Guidance +# Sprint Workflow # AIAgentMinder-managed. Delete this file to opt out of sprint-driven development. -## Overview +Sprint governance (bounded scope, approval gates, review/archive) tracks in `SPRINT.md`. Issue execution uses native Tasks (TaskCreate/TaskUpdate/TaskList — persistent, cross-session). `SPRINT.md` is the sprint header; individual issues are native Tasks. -Sprint workflow has two layers: +## State Machine -- **Sprint governance** (AIAgentMinder): bounded scope, approval gates, review/archive cycle — tracked in `SPRINT.md` -- **Issue execution** (native Tasks): per-issue tracking, persistence, cross-session state — managed with Claude Code's native TaskCreate/TaskUpdate/TaskList tools +``` +PLAN → SPEC → APPROVE → [per item: EXECUTE → TEST → REVIEW → MERGE → VALIDATE] → COMPLETE + ↑ + CONTEXT_CYCLE (at NEXT transition) +``` -`SPRINT.md` is the sprint header: goal, approved scope, sprint number, and status. Individual issues live as native Tasks. +**Human checkpoints** (pause for input): PLAN (approve issues), APPROVE (approve specs), BLOCKED, REWORK. +**Autonomous** (proceed without asking): all other transitions after spec approval. -## Sprint Planning +## Quality Checklist (non-negotiable — never skip, even if told "go faster") -When the user asks to start a sprint or begin a phase: +Per item, in order. Fix failures before advancing — no skipping to "come back later." -1. Read `docs/strategy-roadmap.md` for the phase's features and acceptance criteria. -2. Read `DECISIONS.md` for architectural context that affects implementation choices. -3. Check `SPRINT.md` for archived sprint lines. If present, read the `` comment from the most recent archive — use that range as the recommended issue count. If no archive exists, default to 4–5 issues. Never plan more than 7 issues regardless of sizing comment. -4. Determine sprint scope. A sprint covers a coherent subset of the phase's work — typically 4–7 issues. Prefer fitting whole features over hitting an exact count: if a feature needs 6 issues and the sizing range says 4–5, plan 6 but confirm with the user. More than 7 issues signals context overload; fewer than 3 signals insufficient granularity. -5. Decompose into discrete issues. Each issue must be completable in a single focused effort. One PR per issue. Each issue must have: a title, a type (feature/fix/chore/spike), acceptance criteria, and references to relevant roadmap items. -6. **Risk tagging:** For each issue, check if it touches a high-risk area: - - Auth or session handling - - Payments or billing - - Data migration or schema changes - - Public API changes (breaking or additive) - - Security-sensitive config or secrets handling +1. Read spec + gather context → 2. Feature branch → 3. Failing tests (TDD RED) → 4. Implement to pass (TDD GREEN) → 5. Refactor (tests green) → 6. Full test suite (zero failures) → 7. `/aam-quality-gate` → 8. `/aam-self-review` → 9. Create PR → 10. `/aam-pr-pipeline` (review→fix→test→merge) → 11. Post-merge validation (if any) - If yes, add `[risk]` to the issue title. Risk-tagged issues trigger automatic `/aam-self-review` before PR creation regardless of quality tier. +## Autonomy Rules -7. Write the sprint header to `SPRINT.md`: +After spec approval, execute all items sequentially without permission. The approved spec IS the permission. +**Ask human ONLY when:** blocked (dependency/credentials/ambiguous AC), debug checkpoint (3 failed same-error attempts), test needs human action (physical/hardware/unresolvable visual), post-merge fails, insufficient info for spec. + +**Never ask** "Shall I proceed/create PR/run QG/run tests/merge?" — always yes. + +**Never skip** (even if user says "go faster"): TDD, full test suite, quality gate, self-review, PR pipeline, post-merge validation. "Reduce interruptions" = stop asking permission, NOT skip quality. When uncertain if permission prompt or quality step → quality step. + +## PLAN + +1. Read `docs/strategy-roadmap.md` for phase features/AC. +2. Read `DECISIONS.md` for architectural context. +3. Check `SPRINT.md` archives for `` → use as recommended count. Default 4-5. Max 7 regardless. +4. Scope: 4-7 issues covering a coherent phase subset. Prefer whole features over exact count. >7 = context overload; <3 = insufficient granularity. +5. Decompose: title, type (feature/fix/chore/spike), AC, roadmap refs. One PR per issue. Completable in single focused effort. +6. **Risk tag `[risk]`** if touching: auth/session, payments/billing, data migration/schema, public API changes, security/secrets. +7. Write sprint header to `SPRINT.md`: ```markdown - **Sprint:** S{n} — {sprint goal} + **Sprint:** S{n} — {goal} **Status:** proposed - **Phase:** {phase name from roadmap} - **Issues:** {count} issues proposed + **Phase:** {phase} + **Issues:** {count} proposed - | ID | Title | Type | Risk | Status | - |---|---|---|---|---| - | S{n}-001 | {title} | feature | | todo | - | S{n}-002 | {title} [risk] | fix | ⚠ | todo | + | ID | Title | Type | Risk | Status | Post-Merge | + |---|---|---|---|---|---| + | S{n}-001 | {title} | feature | | todo | n/a | + | S{n}-002 | {title} [risk] | fix | ⚠ | todo | n/a | ``` +8. Present numbered list with AC per issue. Note risk tags and deferred work. **Wait for approval.** + +Issue ID format: `S{sprint}-{seq}` (S1-001, S2-003). → User approves → SPEC. + +## SPEC + +Write detailed spec per item before coding. + +```markdown +### S{n}-{seq}: {title} +**Approach:** {files to create/modify, patterns, key decisions} +**Test Plan (TDD RED):** 1. {behavior-focused failing test} 2. ... +**Integration/E2E:** {Playwright/API tests, or "None"} +**Post-Merge Validation:** {deploy-dependent tests, or "None"} +**Files:** Create: {list} | Modify: {list} +**Dependencies:** {other items, or "None"} +**Custom Instructions:** {human-provided, or "None"} +``` + +Present all specs together. User may: approve all, revise items, add custom instructions, reorder. If info missing (unclear AC, unknown API), ask for that specific info — don't guess. → User approves → APPROVE. + +## APPROVE + +1. Update `SPRINT.md` status to `in-progress`. +2. Create native Task per issue (title with risk tag, description: AC + spec summary + issue ID, dependencies from spec). +3. Confirm: "Sprint S{n} started. {count} tasks. Beginning execution." + +→ Immediately begin EXECUTE for first item. + +## EXECUTE + +1. Update Task to `in_progress`, SPRINT.md row to `in-progress`. +2. Read spec + relevant source files. +3. Branch: `{type}/S{n}-{seq}-{short-desc}`. +4. TDD RED → TDD GREEN → Refactor → Integration/E2E if spec defines → Full test suite (zero failures; investigate unrelated failures as regressions). + +→ All pass → TEST. + +## TEST + +1. Full suite (clean run). 2. `/aam-quality-gate` — fix failures. 3. `/aam-self-review` — fix High; fix Medium/Low without asking. 4. Playwright/browser tests if spec requires (screenshots for visual; escalate to human only if unresolvable). + +→ All pass → REVIEW. + +## REVIEW -8. Present the sprint to the user as a numbered list with acceptance criteria for each issue. Note any risk-tagged issues. If phase work was deferred, briefly note what was left out and why. **Wait for the user to review, edit, discuss, and approve before proceeding.** +1. Create PR (title refs item ID; body: what built, how tested, decisions). +2. `/aam-pr-pipeline` in session. Handles review→fix→retest→merge. If escalated (needs-human-review, ci-failure, cycle limit) → BLOCKED. -Issue ID format: `S{sprint_number}-{sequence}` (e.g., S1-001, S1-002, S2-001). +→ Pipeline merges → MERGE. -## After User Approval +## MERGE -Once the user approves: +1. `git checkout main && git pull`. 2. Update Task to `completed`, SPRINT.md row to `done`. 3. Check spec for post-merge validation. -1. Update `SPRINT.md` status from `proposed` to `in-progress`. -2. Create a native Task for each approved issue using the TaskCreate tool: - - Title: the issue title (including `[risk]` tag if applicable) - - Description: acceptance criteria + issue ID (e.g., `[S1-001]`) - - Use task dependencies where one issue must complete before another starts -3. Confirm to the user: "Sprint S{n} started. {count} tasks created. Working issues in order." +→ Post-merge exists → VALIDATE. None → NEXT. -## Sprint Execution +## VALIDATE -- Work issues in the proposed order unless the user directs otherwise. -- For each issue: create a feature branch (`{type}/S{n}-{seq}-{short-desc}`), implement, commit referencing the issue ID (`feat(auth): implement login endpoint [S1-003]`). -- Before creating a PR: run `/aam-quality-gate` to confirm the issue meets the project's quality tier. Fix any failures before proceeding. -- For **Rigorous** and **Comprehensive** quality tiers: also run `/aam-self-review` after the quality gate passes. Address any High severity findings before proceeding. -- For **risk-tagged issues** (`[risk]`): run `/aam-self-review` regardless of quality tier (even Lightweight/Standard). Address any High severity findings before creating the PR. -- After all checks pass, create the PR. If `.claude/commands/aam-pr-pipeline.md` exists, run `/aam-pr-pipeline` in the current session to review, test, and merge the PR. If the pipeline succeeds (PR merged), update the issue's Task to `completed` and SPRINT.md row to `done`, then switch back to the base branch and pull (`git checkout main && git pull`) before starting the next sprint issue. If the pipeline escalates (`needs-human-review` or `ci-failure` label), stop and notify the user before continuing. If the pipeline command is not installed, wait for the user to confirm the PR is handled before beginning the next issue. -- Update the native Task status as you work: pending → in_progress → completed (or leave pending if blocked). -- Update SPRINT.md issue status to match: `todo` → `in-progress` → `done` or `blocked`. -- If an issue cannot be completed: mark both the Task and SPRINT.md entry as `blocked` and notify the user with a clear description of what's needed. +1. If deployed env needed, poll availability (max 15 min; if exceeded, notify human, continue to NEXT — Post-Merge stays `pending`, **sprint cannot close until validated**). +2. Run post-merge tests. Update SPRINT.md Post-Merge: `pass`, `fail`, or `pending`. A `pending` validation is a blocking obligation, not informational. -## Sprint Completion +→ Pass → NEXT. Fail → REWORK. Deferred → NEXT (pending remains). -A sprint ends when all issues are `done` or `blocked`. +## REWORK -- If blocked issues exist: notify the user and wait for resolution. Once blocks are resolved, complete remaining issues, then proceed to review. -- Present a sprint review: completed issues with PR links, decisions logged to DECISIONS.md, any risk-tagged issues and their self-review outcomes, summary of what was accomplished, and what remains for the next sprint. -- Run `/aam-retrospective` to generate metrics for the sprint. Present it alongside the review. -- If the user accepts the review: archive the sprint — replace SPRINT.md contents with: +1. Notify human: what failed, expected vs actual, diagnosis. +2. Add row: `| S{n}-{seq}r | Rework: {title} — {failure} | fix | ⚠ | todo | n/a |` +3. Create native Task. **Wait for human acknowledgment.** - ``` - S{n} archived ({date}): {planned} planned, {completed} completed. {scope_changes} scope changes, {blocked} blocked. {brief summary}. - - ``` +→ Human acknowledges → EXECUTE rework item (full cycle). Sprint can't close with outstanding rework. - The `sizing` comment is the recommended issue range for the next sprint, derived from `/aam-retrospective` Step 4. Scope changes and blocked counts are recorded as stress indicators for future sizing adjustments. Full sprint detail is preserved in git history and in native task history. +## NEXT + +1. Find next `todo` in SPRINT.md. 2. Complete any deferred VALIDATE steps now ready. 3. Context pressure check (see CONTEXT_CYCLE). + +→ Cycle needed → CONTEXT_CYCLE. Next exists → EXECUTE. All `done` + all Post-Merge `pass`/`n/a` → COMPLETE. All `done` but any `pending` → execute those validations — **do not present sprint review**. + +## COMPLETE + +**Precondition:** Every SPRINT.md row Post-Merge must be `pass` or `n/a`. Any `pending` → STOP, return to VALIDATE. Do not present review/retrospective/archive. + +1. Sprint review: completed issues + PR links, decisions, risk items + self-review outcomes, rework + resolution, summary. +2. `/aam-retrospective` for metrics. +3. Optional docs-only PR through pipeline. +4. **Wait for human acceptance.** Archive: + ``` + S{n} archived ({date}): {planned} planned, {completed} completed, {rework} rework. {scope_changes} scope, {blocked} blocked. {summary}. + + ``` +5. "Sprint S{n} complete. Ready for next sprint when you are." + +→ Next sprint requested → increment number → PLAN. + +## BLOCKED + +Any state → BLOCKED when: external dependency unavailable, missing credentials, ambiguous AC, debug checkpoint (3 failed attempts), test needs human action, pipeline escalation. + +Update SPRINT.md to `blocked`. Notify human: what, why, what unblocks. Wait. → Human resolves → return to prior state. + +## CONTEXT_CYCLE + +Autonomous context management at NEXT transitions. Persists state, self-terminates, fresh session resumes (requires profile hook or sprint-runner). + +**Primary signal:** Read `.context-usage` in the project root. If the file exists and `should_cycle` is `true`, cycle. Thresholds: 250k tokens Sonnet, 350k Opus, 35% unknown models. + +**Fallback** (`.context-usage` absent — status line not configured): Cycle when ANY true: 3+ items completed this session | debug checkpoint triggered | rework executed. When in doubt, cycle. + +**Steps (all required, in order):** + +1. **Commit all work** — nothing uncommitted. +2. **Write `.sprint-continuation.md`:** + ```markdown + # Sprint Continuation State + **Generated:** {ISO timestamp} + **Reason:** {why} + **Session items completed:** {count} + ## Resume Point + **Sprint:** S{n} **Next:** S{n}-{seq} **State:** EXECUTE **Branch:** main + ## Completed This Session + {items with one-line status} + ## Critical Context + {2-5 bullets NOT in SPRINT.md/DECISIONS.md/spec — only what would be lost} + ## Next Session + 1. Read SPRINT.md 2. TaskList 3. EXECUTE S{n}-{seq} 4. Continue autonomous + ``` +3. **Write `.sprint-continue-signal`** (empty file; existence = signal). +4. **Run `bash .claude/scripts/context-cycle.sh`** (finds CLI process, kills it; profile hook/sprint-runner catches signal and restarts). +5. **Fallback** if termination fails: tell user to `/exit` then run `claude "CONTEXT CYCLE: Read .sprint-continuation.md and resume sprint execution."` -- The user can then ask to begin a new sprint. Increment the sprint number. +**After cycle (new session receives `CONTEXT CYCLE:` prompt):** Read `.sprint-continuation.md` → `SPRINT.md` → `TaskList` → next spec → delete `.sprint-continuation.md` → resume EXECUTE. -## Cross-Session Behavior +## Cross-Session -- `SPRINT.md` persists across sessions via git — it's the sprint header and authoritative scope record. -- Native Tasks persist across sessions automatically (stored at `~/.claude/tasks/`). -- When resuming a session with an active sprint: read `SPRINT.md` to get context, then use TaskList to see current task states. Resume from where you left off. -- `/aam-handoff` works independently — it checkpoints decisions and key context. Do not modify SPRINT.md or tasks during handoff; sprint state is updated during sprint execution. +- `SPRINT.md` persists via git. Tasks persist in `~/.claude/tasks/`. Resuming: read both, identify current state, continue. +- Specs preserved in git history (committed at APPROVE) — re-read if context lost. +- `/aam-handoff` is independent; don't modify SPRINT.md or tasks during handoff. +- `.sprint-continuation.md` and `.sprint-continue-signal` are ephemeral, gitignored. +- Restart requires profile hook (`install-profile-hook.ps1`) or sprint-runner. Without either, Claude tells user the command. diff --git a/.claude/scripts/context-cycle.sh b/.claude/scripts/context-cycle.sh new file mode 100644 index 0000000..d35c8f7 --- /dev/null +++ b/.claude/scripts/context-cycle.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +# context-cycle.sh — Self-termination script for Claude Code context cycling. +# Called by Claude when context pressure warrants a fresh session. +# +# How it works: +# 1. Traces from the current bash shell up the process tree +# 2. Finds the parent claude/claude.exe (CLI) process +# 3. Kills it +# 4. The parent shell gets its prompt back +# 5. The shell prompt hook or sprint-runner catches the signal file +# and starts a new Claude instance with the continuation prompt. +# +# Prerequisites: +# - .sprint-continuation.md and .sprint-continue-signal already written +# - Either the profile hook or sprint-runner set up to catch the restart +# +# Cross-platform: Windows (Git Bash), macOS, Linux. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)" + +# Verify state files exist before killing anything +if [ ! -f "$PROJECT_DIR/.sprint-continuation.md" ]; then + echo "ERROR: .sprint-continuation.md not found in $PROJECT_DIR" >&2 + echo "Write the continuation file before calling context-cycle.sh" >&2 + exit 1 +fi + +if [ ! -f "$PROJECT_DIR/.sprint-continue-signal" ]; then + echo "ERROR: .sprint-continue-signal not found in $PROJECT_DIR" >&2 + echo "Write the signal file before calling context-cycle.sh" >&2 + exit 1 +fi + +# --- Platform-specific PID tracing --- + +find_claude_pid_windows() { + # Git Bash on Windows: use /proc/$$/winpid + WMI + local BASH_WINPID + BASH_WINPID=$(cat /proc/$$/winpid 2>/dev/null) || return 1 + + powershell.exe -NoProfile -ExecutionPolicy Bypass -Command " + \$current = $BASH_WINPID + for (\$i = 0; \$i -lt 15; \$i++) { + \$proc = Get-CimInstance Win32_Process -Filter \"ProcessId=\$current\" -ErrorAction SilentlyContinue + if (-not \$proc) { break } + if (\$proc.Name -eq 'claude.exe' -and \$proc.ExecutablePath -like '*\.local*') { + Write-Output \$current + exit 0 + } + \$current = \$proc.ParentProcessId + } + exit 1 + " 2>/dev/null | tr -d '\r\n' +} + +find_claude_pid_unix() { + # macOS / Linux: trace ppid chain using ps + local current=$$ + for _ in $(seq 1 15); do + local ppid + ppid=$(ps -o ppid= -p "$current" 2>/dev/null | tr -d ' ') || return 1 + [ -z "$ppid" ] && return 1 + [ "$ppid" = "0" ] && return 1 + + # Check if the parent process is claude + local pname + pname=$(ps -o comm= -p "$ppid" 2>/dev/null | tr -d ' ') || return 1 + + if [[ "$pname" == "claude" || "$pname" == "claude.exe" ]]; then + echo "$ppid" + return 0 + fi + current="$ppid" + done + return 1 +} + +# Detect platform and find Claude PID +CLAUDE_PID="" +if [ -f /proc/$$/winpid ] 2>/dev/null; then + # Windows (Git Bash) + CLAUDE_PID=$(find_claude_pid_windows) || true +else + # macOS / Linux + CLAUDE_PID=$(find_claude_pid_unix) || true +fi + +if [ -z "$CLAUDE_PID" ]; then + echo "ERROR: Could not find claude in process ancestry" >&2 + echo "Context cycle aborted — state files are preserved. Restart manually:" >&2 + echo " claude \"CONTEXT CYCLE: Read .sprint-continuation.md and resume sprint execution.\"" >&2 + exit 1 +fi + +echo "Context cycle: terminating Claude CLI (PID $CLAUDE_PID)..." +echo "Fresh session will start automatically via profile hook or sprint-runner." + +# Kill the Claude process. This terminates our parent — we become orphaned. +# The signal file tells the restart mechanism to pick up. +if [ -f /proc/$$/winpid ] 2>/dev/null; then + taskkill //PID "$CLAUDE_PID" //F > /dev/null 2>&1 +else + kill -9 "$CLAUDE_PID" 2>/dev/null || true +fi + +# If we get here, the kill may not have taken effect yet. +sleep 2 +exit 0 diff --git a/.claude/scripts/context-monitor.sh b/.claude/scripts/context-monitor.sh new file mode 100644 index 0000000..236705c --- /dev/null +++ b/.claude/scripts/context-monitor.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# context-monitor.sh — Status line data bridge for context cycling. +# Receives status line JSON on stdin, writes .context-usage to project root. +# No stdout output (data bridge only). +# Requires: jq +# +# Configured in .claude/settings.json: +# "statusLine": { "type": "command", "command": "bash .claude/scripts/context-monitor.sh" } + +input=$(cat) + +# Bail if jq not available +command -v jq >/dev/null 2>&1 || exit 0 + +model_id=$(echo "$input" | jq -r '.model.id // "unknown"') +total_input=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0') +total_output=$(echo "$input" | jq -r '.context_window.total_output_tokens // 0') +window_size=$(echo "$input" | jq -r '.context_window.context_window_size // 0') +used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // 0') +cwd=$(echo "$input" | jq -r '.cwd // "."') + +# Skip if no context data yet (early in session) +if [ "$window_size" = "0" ] || [ "$window_size" = "null" ]; then + exit 0 +fi + +# Model-specific absolute token thresholds +case "$model_id" in + *opus*) threshold=350000 ;; + *sonnet*) threshold=250000 ;; + *) threshold=0 ;; # unknown model — fall back to percentage +esac + +# Calculate tokens currently in context window +used_tokens=$(echo "$used_pct $window_size" | awk '{printf "%d", ($1 / 100) * $2}') + +# Determine if cycling is warranted +should_cycle=false +if [ "$threshold" -gt 0 ]; then + if [ "$used_tokens" -ge "$threshold" ]; then + should_cycle=true + fi +else + # Fallback: 35% for unrecognized models + used_int=$(echo "$used_pct" | cut -d. -f1) + if [ "$used_int" -ge 35 ]; then + should_cycle=true + fi +fi + +# Write to project root (atomic via temp file) +tmpfile="$cwd/.context-usage.tmp" +outfile="$cwd/.context-usage" + +cat > "$tmpfile" << EOF +{"should_cycle":$should_cycle,"model":"$model_id","used_tokens":$used_tokens,"threshold":$threshold,"used_pct":$used_pct,"window_size":$window_size,"total_input":$total_input,"total_output":$total_output} +EOF + +mv "$tmpfile" "$outfile" 2>/dev/null || cp "$tmpfile" "$outfile" 2>/dev/null +rm -f "$tmpfile" 2>/dev/null diff --git a/.claude/scripts/install-profile-hook.ps1 b/.claude/scripts/install-profile-hook.ps1 new file mode 100644 index 0000000..cbd2ecd --- /dev/null +++ b/.claude/scripts/install-profile-hook.ps1 @@ -0,0 +1,121 @@ +<# +.SYNOPSIS + Installs the Claude context-cycle prompt hook into your PowerShell profile. + +.DESCRIPTION + Adds a function to your $PROFILE that automatically catches Claude context + cycle signals. When Claude self-terminates for a context cycle, your shell + prompt renders, the hook sees the signal file, and starts a fresh Claude + instance with the continuation prompt — fully automatic, zero intervention. + + This is the recommended setup for context cycling. It works regardless of + whether you started Claude via sprint-runner.ps1 or plain `claude`. + + Safe to run multiple times — checks for existing installation first. + +.PARAMETER Uninstall + Remove the hook from your profile. + +.EXAMPLE + .\install-profile-hook.ps1 + .\install-profile-hook.ps1 -Uninstall +#> + +param( + [switch]$Uninstall +) + +$profilePath = $PROFILE.CurrentUserCurrentHost + +# Marker comments to identify our hook +$markerStart = "# === AIAgentMinder Context Cycle Hook START ===" +$markerEnd = "# === AIAgentMinder Context Cycle Hook END ===" + +$hookCode = @" + +$markerStart +# Auto-restarts Claude after a context cycle (self-termination for fresh context). +# Installed by AIAgentMinder. Remove this block or run install-profile-hook.ps1 -Uninstall. +`$_aamOriginalPrompt = if (Test-Path Function:\prompt) { `${function:prompt}.ToString() } else { `$null } + +function prompt { + # Check for context cycle signal in current directory + `$signal = Join-Path `$PWD ".sprint-continue-signal" + if (Test-Path `$signal) { + Remove-Item `$signal -Force + `$cont = Join-Path `$PWD ".sprint-continuation.md" + if (Test-Path `$cont) { + Write-Host "" + Write-Host "=== Context cycle — resuming sprint with fresh context ===" -ForegroundColor Cyan + & claude "CONTEXT CYCLE: Read `$cont and resume sprint execution. CLAUDE.md and rules load automatically. Focus on sprint state recovery from the continuation file." + # After the resumed session exits, fall through to normal prompt + } + else { + Write-Host "Context cycle signal found but no continuation file. Starting fresh Claude." -ForegroundColor Yellow + & claude + } + } + + # Call original prompt or default + if (`$_aamOriginalPrompt) { + [scriptblock]::Create(`$_aamOriginalPrompt).Invoke() + } + else { + "PS `$(`$executionContext.SessionState.Path.CurrentLocation)`$('>' * (`$nestedPromptLevel + 1)) " + } +} +$markerEnd +"@ + +# --- Uninstall --- +if ($Uninstall) { + if (-not (Test-Path $profilePath)) { + Write-Host "No profile found at $profilePath — nothing to uninstall." -ForegroundColor Yellow + exit 0 + } + + $content = Get-Content $profilePath -Raw + if ($content -match [regex]::Escape($markerStart)) { + $pattern = "(?s)\r?\n?" + [regex]::Escape($markerStart) + ".*?" + [regex]::Escape($markerEnd) + $content = [regex]::Replace($content, $pattern, "") + Set-Content $profilePath -Value $content.TrimEnd() -NoNewline + Write-Host "Context cycle hook removed from $profilePath" -ForegroundColor Green + } + else { + Write-Host "Hook not found in profile — nothing to uninstall." -ForegroundColor Yellow + } + exit 0 +} + +# --- Install --- + +# Create profile if it doesn't exist +if (-not (Test-Path $profilePath)) { + $profileDir = Split-Path $profilePath -Parent + if (-not (Test-Path $profileDir)) { + New-Item -ItemType Directory -Path $profileDir -Force | Out-Null + } + New-Item -ItemType File -Path $profilePath -Force | Out-Null + Write-Host "Created new profile at $profilePath" -ForegroundColor DarkGray +} + +# Check for existing installation +$existingContent = Get-Content $profilePath -Raw -ErrorAction SilentlyContinue +if ($existingContent -and $existingContent.Contains($markerStart)) { + Write-Host "Context cycle hook is already installed in $profilePath" -ForegroundColor Yellow + Write-Host "To reinstall, run with -Uninstall first, then install again." -ForegroundColor DarkGray + exit 0 +} + +# Append hook to profile +Add-Content $profilePath -Value $hookCode + +Write-Host "Context cycle hook installed in $profilePath" -ForegroundColor Green +Write-Host "" +Write-Host "How it works:" -ForegroundColor Cyan +Write-Host " When Claude self-terminates for a context cycle, your shell prompt" +Write-Host " automatically catches the signal and starts a fresh Claude instance." +Write-Host " Same terminal, same environment variables, zero intervention." +Write-Host "" +Write-Host "To activate now, run: . `$PROFILE" -ForegroundColor Yellow +Write-Host "To uninstall later: .\install-profile-hook.ps1 -Uninstall" -ForegroundColor DarkGray diff --git a/.claude/scripts/install-profile-hook.sh b/.claude/scripts/install-profile-hook.sh new file mode 100644 index 0000000..baa80e9 --- /dev/null +++ b/.claude/scripts/install-profile-hook.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# install-profile-hook.sh — Installs the Claude context-cycle prompt hook +# into your shell profile (~/.bashrc, ~/.zshrc, or both). +# +# When Claude self-terminates for a context cycle, your shell prompt +# renders, the hook sees the signal file, and starts a fresh Claude +# instance with the continuation prompt — fully automatic. +# +# Usage: +# ./install-profile-hook.sh # Install +# ./install-profile-hook.sh --uninstall # Remove + +set -euo pipefail + +MARKER_START="# === AIAgentMinder Context Cycle Hook START ===" +MARKER_END="# === AIAgentMinder Context Cycle Hook END ===" + +HOOK_CODE=' +'"$MARKER_START"' +# Auto-restarts Claude after a context cycle (self-termination for fresh context). +# Installed by AIAgentMinder. Remove this block or run install-profile-hook.sh --uninstall. + +_aam_context_cycle_check() { + if [ -f ".sprint-continue-signal" ]; then + rm -f ".sprint-continue-signal" + if [ -f ".sprint-continuation.md" ]; then + echo "" + echo "=== Context cycle — resuming sprint with fresh context ===" + claude "CONTEXT CYCLE: Read .sprint-continuation.md and resume sprint execution. CLAUDE.md and rules load automatically. Focus on sprint state recovery from the continuation file." + else + echo "Context cycle signal found but no continuation file. Starting fresh Claude." + claude + fi + fi +} + +# Install into the appropriate shell hook +if [ -n "${ZSH_VERSION:-}" ]; then + # Zsh: use precmd hook + autoload -Uz add-zsh-hook 2>/dev/null || true + if type add-zsh-hook &>/dev/null; then + add-zsh-hook precmd _aam_context_cycle_check + else + precmd_functions+=(_aam_context_cycle_check) + fi +elif [ -n "${BASH_VERSION:-}" ]; then + # Bash: append to PROMPT_COMMAND + if [[ "${PROMPT_COMMAND:-}" != *"_aam_context_cycle_check"* ]]; then + PROMPT_COMMAND="${PROMPT_COMMAND:+${PROMPT_COMMAND};}_aam_context_cycle_check" + fi +fi +'"$MARKER_END"'' + +# --- Detect which profile files to modify --- +detect_profiles() { + local profiles=() + # Always check for zshrc if zsh exists + if command -v zsh &>/dev/null && [ -f "$HOME/.zshrc" ]; then + profiles+=("$HOME/.zshrc") + elif command -v zsh &>/dev/null; then + profiles+=("$HOME/.zshrc") + fi + # Always check for bashrc if bash exists + if [ -f "$HOME/.bashrc" ]; then + profiles+=("$HOME/.bashrc") + fi + # Fallback: if nothing found, use .bashrc + if [ ${#profiles[@]} -eq 0 ]; then + profiles+=("$HOME/.bashrc") + fi + echo "${profiles[@]}" +} + +# --- Uninstall --- +if [ "${1:-}" = "--uninstall" ]; then + for profile in $(detect_profiles); do + if [ -f "$profile" ] && grep -qF "$MARKER_START" "$profile"; then + # Remove the hook block + sed -i.bak "/$MARKER_START/,/$MARKER_END/d" "$profile" + rm -f "${profile}.bak" + echo "Context cycle hook removed from $profile" + else + echo "Hook not found in $profile — nothing to uninstall." + fi + done + exit 0 +fi + +# --- Install --- +for profile in $(detect_profiles); do + # Create profile if it doesn't exist + if [ ! -f "$profile" ]; then + touch "$profile" + echo "Created $profile" + fi + + # Check for existing installation + if grep -qF "$MARKER_START" "$profile"; then + echo "Context cycle hook is already installed in $profile" + echo "To reinstall, run with --uninstall first, then install again." + continue + fi + + # Append hook + echo "$HOOK_CODE" >> "$profile" + echo "Context cycle hook installed in $profile" +done + +echo "" +echo "How it works:" +echo " When Claude self-terminates for a context cycle, your shell prompt" +echo " automatically catches the signal and starts a fresh Claude instance." +echo " Same terminal, same environment variables, zero intervention." +echo "" +echo "To activate now, run: source ~/.bashrc (or ~/.zshrc)" +echo "To uninstall later: ./install-profile-hook.sh --uninstall" diff --git a/.claude/scripts/sprint-runner.ps1 b/.claude/scripts/sprint-runner.ps1 new file mode 100644 index 0000000..13543e0 --- /dev/null +++ b/.claude/scripts/sprint-runner.ps1 @@ -0,0 +1,90 @@ +<# +.SYNOPSIS + Sprint session wrapper — runs Claude in a loop with automatic context cycling. + +.DESCRIPTION + Starts Claude and monitors for context cycle signals. When Claude detects + context pressure mid-sprint, it writes state files and self-terminates. + This wrapper catches the exit, waits briefly, and starts a fresh Claude + instance with a continuation prompt — same terminal, same env vars. + + For sessions started without this wrapper, the PowerShell profile hook + (installed via install-profile-hook.ps1) provides the same functionality. + +.PARAMETER Prompt + Optional initial prompt to pass to Claude on the first run. + +.PARAMETER PermissionMode + Optional permission mode to pass to Claude (e.g., "auto", "acceptEdits"). + +.EXAMPLE + .\sprint-runner.ps1 + .\sprint-runner.ps1 -Prompt "plan and start a sprint for phase 2" + .\sprint-runner.ps1 -Prompt "resume sprint" -PermissionMode "acceptEdits" +#> + +param( + [string]$Prompt = "", + [string]$PermissionMode = "" +) + +$contFile = Join-Path $PWD ".sprint-continuation.md" +$signalFile = Join-Path $PWD ".sprint-continue-signal" + +# Clean stale signals from a previous crashed cycle +if (Test-Path $signalFile) { + Write-Host "Cleaning stale cycle signal from previous session..." -ForegroundColor DarkYellow + Remove-Item $signalFile -Force +} + +$cycle = 0 + +while ($true) { + $cycle++ + + # Build the Claude argument list + $claudeArgs = @() + if ($PermissionMode) { + $claudeArgs += "--permission-mode" + $claudeArgs += $PermissionMode + } + + if (Test-Path $contFile) { + # Continuation from a previous cycle — pass resume prompt + $resumePrompt = "CONTEXT CYCLE: Read $contFile and resume sprint execution. CLAUDE.md and rules load automatically. Focus on sprint state recovery from the continuation file." + Write-Host "`n=== Context Cycle $cycle — Resuming sprint with fresh context ===" -ForegroundColor Cyan + & claude @claudeArgs $resumePrompt + } + elseif ($Prompt -and $cycle -eq 1) { + # First run with user-provided prompt + Write-Host "=== Starting sprint session ===" -ForegroundColor Cyan + & claude @claudeArgs $Prompt + } + else { + # Normal interactive session + if ($cycle -eq 1) { + Write-Host "=== Sprint session ready (context cycling enabled) ===" -ForegroundColor Cyan + } + else { + Write-Host "`n=== Context Cycle $cycle — Fresh session ===" -ForegroundColor Cyan + } + & claude @claudeArgs + } + + # After Claude exits, check for continuation signal + if (Test-Path $signalFile) { + Remove-Item $signalFile -Force + Write-Host "`n=== Context pressure detected — cycling session ===" -ForegroundColor Yellow + Write-Host "Environment preserved. Fresh instance starting in 3 seconds..." -ForegroundColor Yellow + Start-Sleep -Seconds 3 + continue + } + + # Normal exit — clean up and stop + if (Test-Path $contFile) { + # Stale continuation file without signal — clean it up + Remove-Item $contFile -Force + } + Write-Host "`n=== Sprint session ended ===" -ForegroundColor Cyan + break +} diff --git a/.claude/scripts/sprint-runner.sh b/.claude/scripts/sprint-runner.sh new file mode 100644 index 0000000..0e00a4e --- /dev/null +++ b/.claude/scripts/sprint-runner.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# sprint-runner.sh — Runs Claude in a loop with automatic context cycling. +# +# When Claude detects context pressure mid-sprint, it writes state files and +# self-terminates. This wrapper catches the exit, waits briefly, and starts +# a fresh Claude instance with a continuation prompt. +# +# Usage: +# ./sprint-runner.sh +# ./sprint-runner.sh "plan and start a sprint for phase 2" +# ./sprint-runner.sh "resume sprint" --permission-mode acceptEdits + +set -euo pipefail + +CONT_FILE=".sprint-continuation.md" +SIGNAL_FILE=".sprint-continue-signal" +INITIAL_PROMPT="${1:-}" +shift 2>/dev/null || true +EXTRA_ARGS=("$@") + +# Clean stale signals from a previous crashed cycle +if [ -f "$SIGNAL_FILE" ]; then + echo "Cleaning stale cycle signal from previous session..." + rm -f "$SIGNAL_FILE" +fi + +CYCLE=0 + +while true; do + CYCLE=$((CYCLE + 1)) + + if [ -f "$CONT_FILE" ]; then + RESUME_PROMPT="CONTEXT CYCLE: Read $CONT_FILE and resume sprint execution. CLAUDE.md and rules load automatically. Focus on sprint state recovery from the continuation file." + echo "" + echo "=== Context Cycle $CYCLE — Resuming sprint with fresh context ===" + claude "${EXTRA_ARGS[@]}" "$RESUME_PROMPT" || true + elif [ -n "$INITIAL_PROMPT" ] && [ "$CYCLE" -eq 1 ]; then + echo "=== Starting sprint session ===" + claude "${EXTRA_ARGS[@]}" "$INITIAL_PROMPT" || true + else + if [ "$CYCLE" -eq 1 ]; then + echo "=== Sprint session ready (context cycling enabled) ===" + else + echo "" + echo "=== Context Cycle $CYCLE — Fresh session ===" + fi + claude "${EXTRA_ARGS[@]}" || true + fi + + # After Claude exits, check for continuation signal + if [ -f "$SIGNAL_FILE" ]; then + rm -f "$SIGNAL_FILE" + echo "" + echo "=== Context pressure detected — cycling session ===" + echo "Environment preserved. Fresh instance starting in 3 seconds..." + sleep 3 + continue + fi + + # Normal exit — clean up and stop + if [ -f "$CONT_FILE" ]; then + rm -f "$CONT_FILE" + fi + echo "" + echo "=== Sprint session ended ===" + break +done diff --git a/.claude/settings.json b/.claude/settings.json index 85e7e31..a9d4e42 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,25 +1,12 @@ { - "hooks": { - "SessionStart": [ - { - "matcher": "compact", - "hooks": [ - { - "type": "command", - "command": "node .claude/hooks/compact-reorient.js", - "timeout": 10 - } - ] - } - ] + "statusLine": { + "type": "command", + "command": "bash .claude/scripts/context-monitor.sh" }, "permissions": { "allow": [ - // Version control "Bash(git:*)", "Bash(gh:*)", - - // Shell utilities (safe operations) "Bash(ls:*)", "Bash(dir:*)", "Bash(pwd:*)", @@ -68,21 +55,11 @@ "Bash(sha256sum:*)", "Bash(shasum:*)", "Bash(openssl:*)", - - // Containers & orchestration "Bash(docker:*)", "Bash(docker-compose:*)", - - // .NET build tools "Bash(dotnet:*)", - - // Build & test "Bash(make:*)", - - // Cloud CLIs "Bash(az:*)", - - // Environment & platform tools "Bash(winget:*)", "Bash(choco:*)", "Bash(scoop:*)", @@ -98,19 +75,5 @@ "Bash(git push --force:*)", "Bash(git push -f:*)" ] - }, - "hooks": { - "SessionStart": [ - { - "matcher": "compact", - "hooks": [ - { - "type": "command", - "command": "node .claude/hooks/compact-reorient.js", - "timeout": 10 - } - ] - } - ] } } diff --git a/.pr-pipeline.json b/.pr-pipeline.json new file mode 100644 index 0000000..d6e72ed --- /dev/null +++ b/.pr-pipeline.json @@ -0,0 +1,35 @@ +{ + "highRiskPatterns": [ + "**/auth/**", + "**/security/**", + "**/payment/**", + "**/billing/**", + "**/migration/**", + ".github/workflows/**", + "Dockerfile*", + "docker-compose*", + "*.tf", + "*.tfvars" + ], + "cycleLimit": 5, + "autoMerge": true, + "mergeMethod": "squash", + "skipPatterns": [ + "package-lock.json", + "yarn.lock", + "pnpm-lock.yaml", + "*.lock", + "dist/**", + "build/**", + ".next/**" + ], + "notification": { + "email": "", + "from": "pipeline@resend.dev" + }, + "testCommand": null, + "mergeWait": { + "pollIntervalSeconds": 30, + "timeoutMinutes": 15 + } +} diff --git a/CLAUDE.md b/CLAUDE.md index 033b4e6..9beeb76 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,10 +24,8 @@ ## Behavioral Rules ### Git Workflow -- **Never commit directly to main** -- always use feature branches -- Branch naming: `feature/short-description`, `fix/short-description`, `chore/short-description` -- All changes via PR. Claude creates PRs; human reviews and merges -- After human merges: `git checkout main && git pull`, then start next branch + +See `.claude/rules/git-workflow.md` — loaded natively by Claude Code each session. ### PR Format - Clear title (under 70 chars), summary of what/why, test plan with verification steps @@ -40,11 +38,12 @@ - When you need a credential, ask: "Please provide your [SERVICE] API key. I'll store it in .env." ### Autonomy Boundaries -**You CAN autonomously:** Create files, install NuGet packages, run builds/tests, create branches and PRs, scaffold code, manage dependencies, install and use CLI tools, query cloud services and APIs + +**You CAN autonomously:** Create files, install packages, run builds/tests, create branches and PRs, scaffold code, install and use CLI tools, query cloud services and APIs **Only when explicitly asked:** Merge PRs -**Ask the human first:** Create GitHub repos, sign up for services, provide API keys, approve major architectural changes, make billing decisions, switch from sandbox to live trading, change risk parameters or sleeve allocations +**Ask the human first:** Create GitHub repos, sign up for services, provide API keys, approve major architectural changes **Tool-first rule:** See `.claude/rules/tool-first.md` — never ask the user to do something you can do with a tool @@ -54,10 +53,9 @@ - Flag risks early rather than discovering them mid-implementation ### Verification-First Development -- Before implementing a feature, confirm requirements by restating what you'll build -- Write tests appropriate to the project's quality tier (see strategy-roadmap.md) -- When the quality tier is Standard or above: write failing tests first, then implement -- Every PR should reference the acceptance criteria from strategy-roadmap.md + +- Write failing tests first, then implement +- Run the full test suite before every commit ### Trading-Specific Rules - **NEVER** switch from SANDBOX to LIVE trading mode without explicit human approval @@ -66,6 +64,7 @@ - All trading logic must be deterministic (rule-based); AI is for analysis only ### Decision Recording + - Record significant architectural decisions in DECISIONS.md (library choices, API contracts, auth approach, data model changes, deploy decisions) - Record known shortcuts and workarounds in the Known Debt section of DECISIONS.md - Include alternatives considered — a decision without alternatives is an assertion, not a record @@ -77,6 +76,6 @@ > Use `/context` for real-time context usage and optimization tips. -**Always loaded:** CLAUDE.md — keep under ~100 lines; don't add without removing something +**Always loaded:** CLAUDE.md — keep under ~50 lines; don't add without removing something -**On-demand:** DECISIONS.md — add `@DECISIONS.md` here to auto-load; move superseded ADRs to `docs/archive/` +**On-demand:** DECISIONS.md — add `@DECISIONS.md` here to auto-load; delete superseded entries