diff --git a/AGENTS.md b/AGENTS.md index 6bab7bc..01e2aba 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,7 +7,7 @@ Humans steer. Agents execute. When agents struggle, fix the harness. Run the session-start script to gather context before doing anything else: ```bash -SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh --task ) +SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh --task ) echo "$SESSION" ``` @@ -33,7 +33,7 @@ Full metadata (commands, remotes, language): `projects.json` | Playbooks | `docs/playbooks/` | | Agent roles | `agents/` | | Entropy management | `docs/conventions/entropy-management.md` | -| Repo learnings | `docs/learnings/` | +| Repo learnings | `docs/learnings/README.md` (external — see setup) | ## Task Dispatch diff --git a/README.md b/README.md index 481bd59..472367e 100644 --- a/README.md +++ b/README.md @@ -235,7 +235,7 @@ docs/ playbooks/ Step-by-step guides for recurring operations golden-principles.md Enforced invariants across all repos philosophy.md Design principles guiding case (incl. context engineering) - learnings/ Per-repo tactical knowledge from retrospective + learnings/README.md Setup for external learnings repo (per-repo knowledge) ideation/ Ideation artifacts (contracts, specs) tasks/ diff --git a/agents/closer.md b/agents/closer.md index 8bb61d8..03c81da 100644 --- a/agents/closer.md +++ b/agents/closer.md @@ -12,10 +12,12 @@ Create a pull request with a thorough description based on the task file, progre You receive from the orchestrator: -- **Task file path** — absolute path to the `.md` task file in `/Users/nicknisi/Developer/case/tasks/active/` +- **Case repo path** (`CASE_REPO`) — absolute path to the case harness repo +- **Task file path** — absolute path to the `.md` task file in `${CASE_REPO}/tasks/active/` - **Task JSON path** — the `.task.json` companion - **Target repo path** — absolute path to the repo - **Verifier AGENT_RESULT** — structured output from the verifier (screenshot URLs, evidence markers, pass/fail) +- **Reviewer AGENT_RESULT** — structured output from the reviewer (findings, severity counts) ## Workflow @@ -23,7 +25,7 @@ You receive from the orchestrator: Run the session-start script to orient yourself: ```bash -SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh --task ) +SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh --task ) echo "$SESSION" ``` @@ -38,7 +40,7 @@ Read the output to understand: current branch, last commits, task status, which - `.case-manual-tested` — should have `evidence` field (if src/ files changed) - `.case-reviewed` — should have `critical: 0` (review findings summary) 4. Extract video and screenshot tags from the verifier's progress log entry or AGENT_RESULT (look for ` agent closer status completed - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent closer completed now + bash ${CASE_REPO}/scripts/task-status.sh agent closer status completed + bash ${CASE_REPO}/scripts/task-status.sh agent closer completed now ``` The hook will handle: `status → pr-opened` and `prUrl`. diff --git a/agents/implementer.md b/agents/implementer.md index e7e5fae..e6ec314 100644 --- a/agents/implementer.md +++ b/agents/implementer.md @@ -12,11 +12,12 @@ Implement a fix or feature in the target repo. Write code, run automated tests, You receive from the orchestrator: -- **Task file path** — absolute path to the `.md` task file in `/Users/nicknisi/Developer/case/tasks/active/` +- **Case repo path** (`CASE_REPO`) — absolute path to the case harness repo +- **Task file path** — absolute path to the `.md` task file in `${CASE_REPO}/tasks/active/` - **Task JSON path** — the `.task.json` companion (same stem as the .md) - **Target repo path** — absolute path to the repo where you'll work - **Issue summary** — title, body, and key details from the GitHub/Linear issue -- **Playbook path** — reference to the relevant playbook in `/Users/nicknisi/Developer/case/docs/playbooks/` +- **Playbook path** — reference to the relevant playbook in `${CASE_REPO}/docs/playbooks/` ## Workflow @@ -24,7 +25,7 @@ You receive from the orchestrator: Run the session-start script to orient yourself: ```bash -SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh --task ) +SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh --task ) echo "$SESSION" ``` @@ -34,15 +35,19 @@ Read the output to understand: current branch, last commits, task status, which 1. Update task JSON: set status to `implementing` and agent phase to running ```bash - bash /Users/nicknisi/Developer/case/scripts/task-status.sh status implementing - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent implementer status running - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent implementer started now + bash ${CASE_REPO}/scripts/task-status.sh status implementing + bash ${CASE_REPO}/scripts/task-status.sh agent implementer status running + bash ${CASE_REPO}/scripts/task-status.sh agent implementer started now ``` 2. Read the task file (`.md`) — understand the objective, acceptance criteria, and checklist 3. Read the target repo's `CLAUDE.md` for project-specific instructions 4. Read the playbook referenced in the task file -5. Read `/Users/nicknisi/Developer/case/projects.json` to find the repo's available commands (test, typecheck, lint, build, format) -6. Read `/Users/nicknisi/Developer/case/docs/learnings/{repo}.md` for tactical knowledge from previous tasks in this repo +5. Read `${CASE_REPO}/projects.json` to find the repo's available commands (test, typecheck, lint, build, format) +6. Read tactical knowledge from previous tasks in this repo: + ```bash + bash ${CASE_REPO}/scripts/read-learning.sh {repo} || true + ``` + Review the output before starting. If the command fails (CASE_LEARNINGS_REPO not set), skip — learnings are supplementary. ### 2. Implement @@ -91,9 +96,9 @@ Then create the final commit as usual. Prefer the JSON reporter for structured evidence (pass/fail counts, duration, per-file breakdown): ```bash # Preferred — structured evidence via vitest JSON reporter - pnpm test --reporter=json 2>&1 | bash /Users/nicknisi/Developer/case/scripts/mark-tested.sh + pnpm test --reporter=json 2>&1 | bash ${CASE_REPO}/scripts/mark-tested.sh # Fallback — if JSON reporter is unavailable or the repo doesn't use vitest - pnpm test 2>&1 | bash /Users/nicknisi/Developer/case/scripts/mark-tested.sh + pnpm test 2>&1 | bash ${CASE_REPO}/scripts/mark-tested.sh ``` This creates `.case-tested` with a hash of test output AND updates the task JSON `tested` field. You do NOT set `tested` directly. @@ -115,8 +120,8 @@ Then create the final commit as usual. 4. **Update task JSON**: ```bash - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent implementer status completed - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent implementer completed now + bash ${CASE_REPO}/scripts/task-status.sh agent implementer status completed + bash ${CASE_REPO}/scripts/task-status.sh agent implementer completed now ``` ### 5. Output diff --git a/agents/retrospective.md b/agents/retrospective.md index c14e181..11f7307 100644 --- a/agents/retrospective.md +++ b/agents/retrospective.md @@ -12,6 +12,7 @@ You run after every `/case` pipeline completion (success or failure). Your job: You receive from the orchestrator: +- **Case repo path** (`CASE_REPO`) — absolute path to the case harness repo - **Task file path** — absolute path to the `.md` task file (with progress log from all agents) - **Task JSON path** — the `.task.json` companion (with status, agent phases, evidence flags) - **Pipeline outcome** — "completed" (PR created) or "failed" (stopped at some agent) @@ -23,7 +24,7 @@ You receive from the orchestrator: Run the session-start script to orient yourself: ```bash -SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh --task ) +SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh --task ) echo "$SESSION" ``` @@ -91,7 +92,7 @@ For each finding, apply the fix directly: 4. For script changes, verify syntax with `bash -n ` after editing 5. Log each applied change with file path and one-line summary -**What you can edit** (all within `/Users/nicknisi/Developer/case/`): +**What you can edit** (all within `${CASE_REPO}/`): - `docs/architecture/` — architecture docs - `docs/conventions/` — convention docs - `docs/playbooks/` — playbooks @@ -100,7 +101,7 @@ For each finding, apply the fix directly: - `scripts/` — harness scripts - `hooks/` — hook scripts - `skills/` — skill files -- `docs/learnings/` — per-repo tactical knowledge +- External learnings repo (via `${CASE_REPO}/scripts/write-learning.sh`) — per-repo tactical knowledge **What you must NEVER edit:** - Target repo source code (anything outside `case/`) @@ -124,21 +125,28 @@ After applying harness improvements, check if the run produced tactical knowledg **How to append:** 1. Identify the target repo from the task file's `## Target Repos` section -2. Read `docs/learnings/{repo}.md` +2. Read existing learnings to check for duplicates: + ```bash + bash ${CASE_REPO}/scripts/read-learning.sh {repo} + ``` 3. Check if a similar learning already exists (don't duplicate) 4. Append a new entry: - ``` - - **{YYYY-MM-DD}** — `{file or area}`: {1-2 line tactical note}. (from task {task-filename}) + ```bash + bash ${CASE_REPO}/scripts/write-learning.sh {repo} "- **{YYYY-MM-DD}** — \`{file or area}\`: {1-2 line tactical note}. (from task {task-filename})" ``` ### 4c. Escalate Repeated Violations -After updating learnings, scan the learnings file for patterns: +After updating learnings, scan the learnings for patterns: -1. Read `docs/learnings/{repo}.md` +1. Read the learnings: + ```bash + LEARNINGS=$(bash ${CASE_REPO}/scripts/read-learning.sh {repo}) + echo "$LEARNINGS" + ``` 2. Look for 3+ entries describing the same class of issue (e.g., multiple entries about mocking, multiple about import paths) 3. If found, escalate: - - If it's a repo-specific pattern -> note it for the repo's CLAUDE.md (add a comment to the learnings file: "ESCALATION CANDIDATE: consider adding to {repo} CLAUDE.md") + - If it's a repo-specific pattern -> note it for the repo's CLAUDE.md (add an entry: "ESCALATION CANDIDATE: consider adding to {repo} CLAUDE.md") - If it's a cross-repo pattern -> add to `docs/golden-principles.md` or the relevant convention doc 4. Log the escalation in your output summary diff --git a/agents/reviewer.md b/agents/reviewer.md index 755ea65..4705720 100644 --- a/agents/reviewer.md +++ b/agents/reviewer.md @@ -12,7 +12,8 @@ You start with a **completely fresh context**. You did not write the code — yo You receive from the orchestrator: -- **Task file path** — absolute path to the `.md` task file in `/Users/nicknisi/Developer/case/tasks/active/` +- **Case repo path** (`CASE_REPO`) — absolute path to the case harness repo +- **Task file path** — absolute path to the `.md` task file in `${CASE_REPO}/tasks/active/` - **Task JSON path** — the `.task.json` companion - **Target repo path** — absolute path to the repo where the fix was implemented @@ -22,7 +23,7 @@ You receive from the orchestrator: Run the session-start script to orient yourself: ```bash -SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh --task ) +SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh --task ) echo "$SESSION" ``` @@ -32,9 +33,9 @@ Read the output to understand: current branch, last commits, task status, which 1. Update task JSON: ```bash - bash /Users/nicknisi/Developer/case/scripts/task-status.sh status reviewing - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent reviewer status running - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent reviewer started now + bash ${CASE_REPO}/scripts/task-status.sh status reviewing + bash ${CASE_REPO}/scripts/task-status.sh agent reviewer status running + bash ${CASE_REPO}/scripts/task-status.sh agent reviewer started now ``` 2. Read the task file — understand the issue, objective, and acceptance criteria 3. Read the git diff to understand what the implementer changed: @@ -120,7 +121,7 @@ Format each finding as: 1. If **no critical findings**: create the evidence marker: ```bash - bash /Users/nicknisi/Developer/case/scripts/mark-reviewed.sh \ + bash ${CASE_REPO}/scripts/mark-reviewed.sh \ --critical 0 --warnings --info ``` @@ -138,8 +139,8 @@ Format each finding as: 4. **Update task JSON**: ```bash - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent reviewer status completed - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent reviewer completed now + bash ${CASE_REPO}/scripts/task-status.sh agent reviewer status completed + bash ${CASE_REPO}/scripts/task-status.sh agent reviewer completed now ``` ### 5. Output diff --git a/agents/verifier.md b/agents/verifier.md index cdbdaf2..5153726 100644 --- a/agents/verifier.md +++ b/agents/verifier.md @@ -12,7 +12,8 @@ You start with a **completely fresh context**. You did not write the code — yo You receive from the orchestrator: -- **Task file path** — absolute path to the `.md` task file in `/Users/nicknisi/Developer/case/tasks/active/` +- **Case repo path** (`CASE_REPO`) — absolute path to the case harness repo +- **Task file path** — absolute path to the `.md` task file in `${CASE_REPO}/tasks/active/` - **Task JSON path** — the `.task.json` companion - **Target repo path** — absolute path to the repo where the fix was implemented @@ -22,7 +23,7 @@ You receive from the orchestrator: Run the session-start script to orient yourself: ```bash -SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh --task ) +SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh --task ) echo "$SESSION" ``` @@ -32,9 +33,9 @@ Read the output to understand: current branch, last commits, task status, which 1. Update task JSON: ```bash - bash /Users/nicknisi/Developer/case/scripts/task-status.sh status verifying - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent verifier status running - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent verifier started now + bash ${CASE_REPO}/scripts/task-status.sh status verifying + bash ${CASE_REPO}/scripts/task-status.sh agent verifier status running + bash ${CASE_REPO}/scripts/task-status.sh agent verifier started now ``` 2. Read the task file — understand the issue, objective, and acceptance criteria 3. Read the git diff to understand what the implementer changed: @@ -61,7 +62,7 @@ git diff --name-only HEAD~1 | grep "^src/" || git diff --name-only main | grep " 1. Read the issue description from the task file's `## Issue Reference` or `## Objective` section 2. Identify the specific bug/feature scenario to reproduce -3. Read `/Users/nicknisi/Developer/case/projects.json` to find if the target repo has an example app +3. Read `${CASE_REPO}/projects.json` to find if the target repo has an example app **3a. Port hygiene — MANDATORY before starting any app:** ```bash @@ -120,12 +121,12 @@ If the implementer added a new export, alias, or API: 3. **Upload video and screenshots** for PR inclusion: ```bash # Upload video — the script auto-converts to GIF (inline) + mp4 (download) - VIDEO_MARKDOWN=$(/Users/nicknisi/Developer/case/scripts/upload-screenshot.sh /tmp/verification.webm) + VIDEO_MARKDOWN=$(${CASE_REPO}/scripts/upload-screenshot.sh /tmp/verification.webm) echo "$VIDEO_MARKDOWN" # Upload screenshot cp .playwright-cli/page-*.png /tmp/after.png - SCREENSHOT=$(/Users/nicknisi/Developer/case/scripts/upload-screenshot.sh /tmp/after.png) + SCREENSHOT=$(${CASE_REPO}/scripts/upload-screenshot.sh /tmp/after.png) echo "$SCREENSHOT" ``` @@ -137,7 +138,7 @@ If the implementer added a new export, alias, or API: 4. Create the manual testing evidence marker: ```bash - bash /Users/nicknisi/Developer/case/scripts/mark-manual-tested.sh + bash ${CASE_REPO}/scripts/mark-manual-tested.sh ``` This checks for recent playwright screenshots and creates `.case-manual-tested` with evidence. It also updates the task JSON `manualTested` field. You do NOT set `manualTested` directly. @@ -156,8 +157,8 @@ If the implementer added a new export, alias, or API: 2. **Update task JSON**: ```bash - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent verifier status completed - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent verifier completed now + bash ${CASE_REPO}/scripts/task-status.sh agent verifier status completed + bash ${CASE_REPO}/scripts/task-status.sh agent verifier completed now ``` ### 6. Output diff --git a/docs/ideation/case-multi-agent/spec-phase-1.md b/docs/ideation/case-multi-agent/spec-phase-1.md index ad2e9ec..193e515 100644 --- a/docs/ideation/case-multi-agent/spec-phase-1.md +++ b/docs/ideation/case-multi-agent/spec-phase-1.md @@ -214,7 +214,7 @@ closing → verifying (hook failure, re-verify) 1. Read current `scripts/mark-tested.sh` 2. After creating the `.case-tested` file (existing behavior), add: - Read `.case-active` for task ID - - If task ID found and `.task.json` exists: `bash /Users/nicknisi/Developer/case/scripts/task-status.sh tested true --from-marker` + - If task ID found and `.task.json` exists: `bash ${CASE_REPO}/scripts/task-status.sh tested true --from-marker` 3. Test: pipe test output through script, verify both `.case-tested` file and `.task.json` `tested` field are updated **Implementation steps — mark-manual-tested.sh**: @@ -222,7 +222,7 @@ closing → verifying (hook failure, re-verify) 1. Read current `scripts/mark-manual-tested.sh` 2. After creating the `.case-manual-tested` file (existing behavior), add: - Read `.case-active` for task ID - - If task ID found and `.task.json` exists: `bash /Users/nicknisi/Developer/case/scripts/task-status.sh manualTested true --from-marker` + - If task ID found and `.task.json` exists: `bash ${CASE_REPO}/scripts/task-status.sh manualTested true --from-marker` 3. Test: run after playwright screenshots exist, verify both `.case-manual-tested` file and `.task.json` `manualTested` field are updated ### Updated Post-PR Cleanup Hook @@ -242,11 +242,11 @@ closing → verifying (hook failure, re-verify) 1. Read current `hooks/post-pr-cleanup.sh` 2. **Deterministic task targeting**: instead of iterating all files in `tasks/active/`, identify the active task by: - Read `.case-active` marker file — update it to contain the task ID (e.g., `authkit-nextjs-1-issue-53`). The orchestrator writes the task ID into `.case-active` instead of bare `touch`. - - Use the task ID to find the specific `.task.json`: `/Users/nicknisi/Developer/case/tasks/active/{task-id}.task.json` - - If `.case-active` has no content (old-format bare touch), fall back to iterating all files in `/Users/nicknisi/Developer/case/tasks/active/` (backward compat) + - Use the task ID to find the specific `.task.json`: `${CASE_REPO}/tasks/active/{task-id}.task.json` + - If `.case-active` has no content (old-format bare touch), fall back to iterating all files in `${CASE_REPO}/tasks/active/` (backward compat) 3. Update the targeted task JSON: - - Run `bash /Users/nicknisi/Developer/case/scripts/task-status.sh status pr-opened` - - If a PR URL is available from the tool output, run `bash /Users/nicknisi/Developer/case/scripts/task-status.sh prUrl ` + - Run `bash ${CASE_REPO}/scripts/task-status.sh status pr-opened` + - If a PR URL is available from the tool output, run `bash ${CASE_REPO}/scripts/task-status.sh prUrl ` 4. Keep marker file cleanup (`rm -f .case-active .case-tested .case-manual-tested`) 5. Add fallback: if no `.task.json` found, move `.md` files as before (backward compat) diff --git a/docs/ideation/case-multi-agent/spec-phase-2.md b/docs/ideation/case-multi-agent/spec-phase-2.md index 1f95687..88b4482 100644 --- a/docs/ideation/case-multi-agent/spec-phase-2.md +++ b/docs/ideation/case-multi-agent/spec-phase-2.md @@ -27,7 +27,7 @@ Additionally, every agent must end its response with a structured `AGENT_RESULT` ### Implementer Agent -**Pattern to follow**: Ideation plugin's `agents/reviewer.md` and `agents/scout.md` (at `/Users/nicknisi/.claude/plugins/cache/nicknisi/ideation/0.9.0/agents/`) +**Pattern to follow**: Ideation plugin's `agents/reviewer.md` and `agents/scout.md` (in the ideation plugin's `agents/` directory) **Overview**: The implementer receives a task file path, target repo path, and issue details. It implements the fix, runs unit tests, commits with a conventional message, and updates the task progress log. It does NOT do manual testing, create evidence markers, or create PRs. @@ -197,7 +197,7 @@ tools: ["Read", "Bash", "Glob", "Grep"] - [ ] Verify implementer prompt does NOT mention Playwright, screenshots, or PR creation - [ ] Verify verifier prompt does NOT mention editing code or committing - [ ] Verify closer prompt does NOT mention editing code, running tests, or using Playwright -- [ ] Verify all three reference correct absolute script paths (`/Users/nicknisi/Developer/case/scripts/mark-tested.sh`, etc.) +- [ ] Verify all three reference correct absolute script paths (`${CASE_REPO}/scripts/mark-tested.sh`, etc.) - [ ] Verify all three include the AGENT_RESULT output format section ## Validation Commands diff --git a/docs/ideation/case-multi-agent/spec-phase-3.md b/docs/ideation/case-multi-agent/spec-phase-3.md index a3ef360..143dca7 100644 --- a/docs/ideation/case-multi-agent/spec-phase-3.md +++ b/docs/ideation/case-multi-agent/spec-phase-3.md @@ -23,13 +23,13 @@ The orchestrator uses the Claude Code `Agent` tool to spawn subagents, passing e ### Orchestrator SKILL.md Rewrite -**Pattern to follow**: Current `skills/case/SKILL.md` (preserve argument parsing, routing table, rules sections). Ideation's `execute-spec/SKILL.md` (for subagent dispatch pattern at `/Users/nicknisi/.claude/plugins/cache/nicknisi/ideation/0.9.0/skills/execute-spec/`). +**Pattern to follow**: Current `skills/case/SKILL.md` (preserve argument parsing, routing table, rules sections). Ideation's `execute-spec/SKILL.md` (for subagent dispatch pattern in the ideation plugin's `skills/execute-spec/` directory). **Overview**: The SKILL.md becomes an orchestrator document. It retains existing sections (Arguments, Rules, Always Load, Task Routing, Project Manifest, Verification Tools) but replaces the monolithic execution flow with a phased subagent dispatch. **Key decisions**: -- **Agent prompt paths are absolute**: The orchestrator reads agent prompt files from `/Users/nicknisi/Developer/case/agents/` (the `agents/` directory at the case repo root, NOT relative to CWD). SKILL.md must use the full absolute path since `/case` runs from target repos, not from the case repo. This matches how SKILL.md already references scripts with absolute paths. +- **Agent prompt paths are absolute**: The orchestrator reads agent prompt files from `${CASE_REPO}/agents/` (the `agents/` directory at the case repo root, NOT relative to CWD). SKILL.md must use the full absolute path since `/case` runs from target repos, not from the case repo. This matches how SKILL.md already references scripts with absolute paths. - Each subagent is spawned sequentially (implementer → verifier → closer). No parallelism within a single `/case` run — the pipeline is linear. - The orchestrator creates both the `.md` task file AND the `.task.json` companion at the same time. - Baseline smoke test uses `scripts/bootstrap.sh` which already exists and validates repo readiness. @@ -71,11 +71,11 @@ ORCHESTRATOR FLOW 0. CHECK FOR EXISTING TASK (idempotent re-entry) - Read .case-active — if it contains a task ID, look up that specific - /Users/nicknisi/Developer/case/tasks/active/{task-id}.task.json + ${CASE_REPO}/tasks/active/{task-id}.task.json directly (fastest, most reliable) - If .case-active missing or empty: derive repo name from git remote, then match by argument type: - GitHub issue → scan /Users/nicknisi/Developer/case/tasks/active/*.task.json + GitHub issue → scan ${CASE_REPO}/tasks/active/*.task.json for matching repo + issueType "github" + issue number Linear ID → scan for matching issueType "linear" + issue ID Free text → no automatic re-entry (ambiguous). Proceed to step 1. @@ -99,8 +99,8 @@ ORCHESTRATOR FLOW 2. TASK SETUP (updated for new format) - Find next sequential task number - - Create task file (.md) in /Users/nicknisi/Developer/case/tasks/active/ using appropriate template - - Create companion .task.json in /Users/nicknisi/Developer/case/tasks/active/ with initial values: + - Create task file (.md) in ${CASE_REPO}/tasks/active/ using appropriate template + - Create companion .task.json in ${CASE_REPO}/tasks/active/ with initial values: { "id": "--issue-", "status": "active", @@ -132,7 +132,7 @@ ORCHESTRATOR FLOW If exists: git checkout (resume) If not: git checkout -b (create) - Run baseline smoke test: - bash /Users/nicknisi/Developer/case/scripts/bootstrap.sh + bash ${CASE_REPO}/scripts/bootstrap.sh - If FAIL: stop, report broken baseline, suggest fixing before proceeding - If PASS: continue - Append to progress log: @@ -143,7 +143,7 @@ ORCHESTRATOR FLOW - Update task JSON: orchestrator status → completed 4. SPAWN IMPLEMENTER - - Read /Users/nicknisi/Developer/case/agents/implementer.md + - Read ${CASE_REPO}/agents/implementer.md - Use Agent tool: - prompt: + task context (file path, repo path, issue summary, playbook) @@ -154,7 +154,7 @@ ORCHESTRATOR FLOW - If status == "completed": continue 5. SPAWN VERIFIER - - Read /Users/nicknisi/Developer/case/agents/verifier.md + - Read ${CASE_REPO}/agents/verifier.md - Use Agent tool: - prompt: + task context (file path, repo path) - subagent_type: general-purpose @@ -179,8 +179,8 @@ ORCHESTRATOR FLOW 6. SPAWN CLOSER - Update task JSON: status → closing - bash /Users/nicknisi/Developer/case/scripts/task-status.sh status closing - - Read /Users/nicknisi/Developer/case/agents/closer.md + bash ${CASE_REPO}/scripts/task-status.sh status closing + - Read ${CASE_REPO}/agents/closer.md - Use Agent tool: - prompt: + task context (file path, repo path, verifier AGENT_RESULT) @@ -214,7 +214,7 @@ ORCHESTRATOR FLOW **Sections to add**: -- `## Agent Architecture` — brief overview of the four-agent pipeline, reference to agents/ directory at `/Users/nicknisi/Developer/case/agents/` +- `## Agent Architecture` — brief overview of the four-agent pipeline, reference to agents/ directory at `${CASE_REPO}/agents/` - `## Subagent Output Contract` — the AGENT_RESULT JSON schema that all subagents must produce - `## Baseline Smoke Test` — explain the bootstrap.sh check and what to do if it fails - `## Re-entry Semantics` — how the orchestrator resumes from `.task.json` state if a prior run was interrupted @@ -247,7 +247,7 @@ ORCHESTRATOR FLOW | Verifier fails + src/ changed | Verification is mandatory (hook blocks without it). Options: fix-and-retry or abort. No skip. | | Verifier fails + no src/ changed | Verification is optional. Options: fix-and-retry, skip, or abort. | | Closer fails (hooks block PR) | Report missing prerequisites. Suggest which steps to run (mark-tested.sh, mark-manual-tested.sh). User decides next step. | -| Agent prompt file not found | Stop with clear error: "Agent prompt file not found at /Users/nicknisi/Developer/case/agents/{name}.md — is the case plugin installed correctly?" | +| Agent prompt file not found | Stop with clear error: "Agent prompt file not found at ${CASE_REPO}/agents/{name}.md — is the case plugin installed correctly?" | | No AGENT_RESULT in subagent response | Treat as failed. Log the raw response for debugging. Report to user. | | Re-entry: existing task found | Resume from last completed phase. Do not recreate task file or branch. | | Task JSON companion missing | Orchestrator creates it. If it goes missing mid-flow, recreate with current known state. | diff --git a/docs/ideation/case-video-verification/spec.md b/docs/ideation/case-video-verification/spec.md index 9faf9af..d458794 100644 --- a/docs/ideation/case-video-verification/spec.md +++ b/docs/ideation/case-video-verification/spec.md @@ -38,7 +38,7 @@ Wire `playwright-cli video-start` / `video-stop` into the verifier agent's workf ``` 4. Add video upload after screenshots: ```bash - VIDEO=$(/Users/nicknisi/Developer/case/scripts/upload-screenshot.sh /tmp/verification.webm) + VIDEO=$(${CASE_REPO}/scripts/upload-screenshot.sh /tmp/verification.webm) echo "$VIDEO" ``` The upload script returns `` for video files. diff --git a/docs/ideation/context-engineering/spec-phase-3.md b/docs/ideation/context-engineering/spec-phase-3.md index 78c1bd3..5bef1ce 100644 --- a/docs/ideation/context-engineering/spec-phase-3.md +++ b/docs/ideation/context-engineering/spec-phase-3.md @@ -166,7 +166,7 @@ After updating learnings, scan the learnings file for patterns: **What to add** (after step 5 "Read projects.json"): ```markdown -6. Read `/Users/nicknisi/Developer/case/docs/learnings/{repo}.md` for tactical knowledge from previous tasks in this repo +6. Read `${CASE_REPO}/docs/learnings/{repo}.md` for tactical knowledge from previous tasks in this repo ``` **Implementation steps**: diff --git a/docs/ideation/harness-improvements/spec-phase-1.md b/docs/ideation/harness-improvements/spec-phase-1.md index c44d0a8..22f8bc8 100644 --- a/docs/ideation/harness-improvements/spec-phase-1.md +++ b/docs/ideation/harness-improvements/spec-phase-1.md @@ -131,9 +131,9 @@ Update the test piping command in `agents/implementer.md` to recommend JSON repo ```markdown # In the Validate section, add guidance: # Prefer JSON reporter for structured evidence: -pnpm test --reporter=json 2>&1 | bash /Users/nicknisi/Developer/case/scripts/mark-tested.sh +pnpm test --reporter=json 2>&1 | bash ${CASE_REPO}/scripts/mark-tested.sh # Fallback if JSON reporter unavailable: -pnpm test 2>&1 | bash /Users/nicknisi/Developer/case/scripts/mark-tested.sh +pnpm test 2>&1 | bash ${CASE_REPO}/scripts/mark-tested.sh ``` ## Testing Requirements diff --git a/docs/ideation/harness-improvements/spec-phase-2.md b/docs/ideation/harness-improvements/spec-phase-2.md index b29f564..045b806 100644 --- a/docs/ideation/harness-improvements/spec-phase-2.md +++ b/docs/ideation/harness-improvements/spec-phase-2.md @@ -11,7 +11,7 @@ The Anthropic article identified this as the single highest-leverage interventio ## Feedback Strategy -**Inner-loop command**: `bash scripts/session-start.sh /Users/nicknisi/Developer/case` +**Inner-loop command**: `bash scripts/session-start.sh ${CASE_REPO}` **Playground**: The script itself — run it against the case repo and inspect output. @@ -129,7 +129,7 @@ For each agent file, insert before the existing first numbered step: Run the session-start script to orient yourself: ```bash -SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh --task ) +SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh --task ) echo "$SESSION" ``` @@ -166,13 +166,13 @@ Read the output to understand: current branch, last commits, task status, which bash -n scripts/session-start.sh # Run against case repo -bash scripts/session-start.sh /Users/nicknisi/Developer/case +bash scripts/session-start.sh ${CASE_REPO} # Validate JSON output bash scripts/session-start.sh . | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log('branch:', d.repo.branch); console.log('Valid JSON: true')" # Run with task -bash scripts/session-start.sh . --task /Users/nicknisi/Developer/case/tasks/active/authkit-nextjs-1-issue-364-proxy-support.task.json +bash scripts/session-start.sh . --task ${CASE_REPO}/tasks/active/authkit-nextjs-1-issue-364-proxy-support.task.json # Verify agent files were updated for f in agents/implementer.md agents/verifier.md agents/closer.md agents/retrospective.md; do diff --git a/docs/ideation/harness-improvements/spec-phase-3.md b/docs/ideation/harness-improvements/spec-phase-3.md index 4eb5937..4447ce4 100644 --- a/docs/ideation/harness-improvements/spec-phase-3.md +++ b/docs/ideation/harness-improvements/spec-phase-3.md @@ -141,7 +141,7 @@ EOF echo ".case-reviewed created (${WARNINGS} warnings, ${INFO} info)" >&2 # Update task JSON if .case-active present -CASE_REPO="/Users/nicknisi/Developer/case" +CASE_REPO="${CASE_REPO}" if [[ -f ".case-active" ]]; then TASK_ID=$(cat .case-active | tr -d '[:space:]') TASK_JSON="${CASE_REPO}/tasks/active/${TASK_ID}.task.json" @@ -180,7 +180,7 @@ Insert after the manual testing check block (after the `fi` closing Check 3): # Check 5: Code review evidence (.case-reviewed marker) if [[ ! -f ".case-reviewed" ]]; then FAILURES+=("[FAIL] Code review not done — .case-reviewed marker missing") - FIXES+=(" FIX: Run the reviewer agent, then: bash /Users/nicknisi/Developer/case/scripts/mark-reviewed.sh --critical 0 --warnings N --info N") + FIXES+=(" FIX: Run the reviewer agent, then: bash ${CASE_REPO}/scripts/mark-reviewed.sh --critical 0 --warnings N --info N") elif ! grep -q "critical: 0" ".case-reviewed" 2>/dev/null; then FAILURES+=("[FAIL] Code review has unresolved critical findings") FIXES+=(" FIX: Address critical findings from the reviewer, then re-run the reviewer agent") diff --git a/docs/learnings/README.md b/docs/learnings/README.md index d47d6db..335919c 100644 --- a/docs/learnings/README.md +++ b/docs/learnings/README.md @@ -1,22 +1,40 @@ -# Repo Learnings +# Repo Learnings (External) -Tactical knowledge accumulated by the retrospective agent across pipeline runs. Each file corresponds to a repo in `projects.json`. +Per-repo tactical knowledge is stored in a separate GitHub repo, configured via the `CASE_LEARNINGS_REPO` environment variable. This keeps codebase-specific knowledge out of the open-source harness repo. + +## Setup + +1. Create a GitHub repo for learnings: + ```bash + gh repo create case-learnings --public --description "Per-repo tactical knowledge for case harness" + ``` + +2. Set the env var: + ```bash + export CASE_LEARNINGS_REPO='youruser/case-learnings' + ``` + Add this to your shell profile or Claude Code settings for persistence. ## How it works -1. After every `/case` pipeline run, the retrospective agent analyzes what happened -2. If it discovers tactical knowledge specific to a repo, it appends to that repo's learnings file -3. The implementer agent reads the relevant learnings file during setup, before writing code -4. If the same issue appears 3+ times in a learnings file, the retrospective escalates it to a convention or golden principle +1. After every pipeline run, the retrospective agent calls `scripts/write-learning.sh` to append tactical knowledge +2. Before coding, the implementer agent calls `scripts/read-learning.sh` to load tactical knowledge +3. If 3+ similar entries accumulate, the retrospective escalates to a convention or golden principle (in the case repo) +4. Each fork/user has their own learnings repo — knowledge doesn't leak across forks ## Format -Each entry is a dated bullet point with context: +Each entry is a dated bullet point: ```markdown -- **2026-03-08** — `src/middleware.ts`: Mock `next/headers` as a module, not individual exports. Individual mocks cause type errors in strict mode. (from task authkit-nextjs-1-issue-53) +- **2026-03-08** — `src/middleware.ts`: Mock `next/headers` as a module, not individual exports. (from task authkit-nextjs-1-issue-53) ``` +## Scripts + +- `scripts/read-learning.sh ` — read a repo's learnings (stdout) +- `scripts/write-learning.sh ` — append an entry and commit to the external repo + ## Rules - Agents append entries — never edit or remove existing ones diff --git a/docs/learnings/authkit-nextjs.md b/docs/learnings/authkit-nextjs.md deleted file mode 100644 index 0d63ad3..0000000 --- a/docs/learnings/authkit-nextjs.md +++ /dev/null @@ -1,5 +0,0 @@ -# AuthKit Next.js Learnings - -Tactical knowledge from completed tasks. Read by agents before working in this repo. - - diff --git a/docs/learnings/authkit-session.md b/docs/learnings/authkit-session.md deleted file mode 100644 index 5af1849..0000000 --- a/docs/learnings/authkit-session.md +++ /dev/null @@ -1,5 +0,0 @@ -# AuthKit Session Learnings - -Tactical knowledge from completed tasks. Read by agents before working in this repo. - - diff --git a/docs/learnings/authkit-tanstack-start.md b/docs/learnings/authkit-tanstack-start.md deleted file mode 100644 index 0dd9f96..0000000 --- a/docs/learnings/authkit-tanstack-start.md +++ /dev/null @@ -1,5 +0,0 @@ -# AuthKit TanStack Start Learnings - -Tactical knowledge from completed tasks. Read by agents before working in this repo. - - diff --git a/docs/learnings/cli.md b/docs/learnings/cli.md deleted file mode 100644 index 694d223..0000000 --- a/docs/learnings/cli.md +++ /dev/null @@ -1,5 +0,0 @@ -# CLI Learnings - -Tactical knowledge from completed tasks. Read by agents before working in this repo. - - diff --git a/docs/learnings/skills.md b/docs/learnings/skills.md deleted file mode 100644 index 9000b6d..0000000 --- a/docs/learnings/skills.md +++ /dev/null @@ -1,5 +0,0 @@ -# Skills Learnings - -Tactical knowledge from completed tasks. Read by agents before working in this repo. - - diff --git a/hooks/post-pr-cleanup.sh b/hooks/post-pr-cleanup.sh index a4934cf..016c687 100755 --- a/hooks/post-pr-cleanup.sh +++ b/hooks/post-pr-cleanup.sh @@ -7,7 +7,8 @@ set -euo pipefail -CASE_REPO="/Users/nicknisi/Developer/case" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CASE_REPO="$(cd "$SCRIPT_DIR/.." && pwd)" # Read hook input from stdin INPUT=$(cat) diff --git a/hooks/pre-pr-check.sh b/hooks/pre-pr-check.sh index 1faa668..3b24d73 100755 --- a/hooks/pre-pr-check.sh +++ b/hooks/pre-pr-check.sh @@ -5,6 +5,9 @@ set -uo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CASE_REPO="$(cd "$SCRIPT_DIR/.." && pwd)" + # Read hook input from stdin INPUT=$(cat) @@ -44,10 +47,10 @@ fi # Check 2: Tests were run (.case-tested marker with evidence) if [[ ! -f ".case-tested" ]]; then FAILURES+=("[FAIL] Tests not verified — .case-tested marker missing") - FIXES+=(" FIX: Run tests and pipe output: pnpm test 2>&1 | bash /Users/nicknisi/Developer/case/scripts/mark-tested.sh") + FIXES+=(" FIX: Run tests and pipe output: pnpm test 2>&1 | bash ${CASE_REPO}/scripts/mark-tested.sh") elif ! grep -q "output_hash:" ".case-tested" 2>/dev/null; then FAILURES+=("[FAIL] Tests marker has no evidence — was created with 'touch' instead of the mark-tested script") - FIXES+=(" FIX: Run tests properly: pnpm test 2>&1 | bash /Users/nicknisi/Developer/case/scripts/mark-tested.sh") + FIXES+=(" FIX: Run tests properly: pnpm test 2>&1 | bash ${CASE_REPO}/scripts/mark-tested.sh") fi # Check 3: Manual testing (smart — only required if src/ files changed) @@ -63,10 +66,10 @@ fi if [[ "$NEEDS_MANUAL_TEST" == "true" ]]; then if [[ ! -f ".case-manual-tested" ]]; then FAILURES+=("[FAIL] Manual testing not done — .case-manual-tested marker missing") - FIXES+=(" FIX: Test in the example app with playwright-cli, then: bash /Users/nicknisi/Developer/case/scripts/mark-manual-tested.sh") + FIXES+=(" FIX: Test in the example app with playwright-cli, then: bash ${CASE_REPO}/scripts/mark-manual-tested.sh") elif ! grep -q "evidence:" ".case-manual-tested" 2>/dev/null; then FAILURES+=("[FAIL] Manual testing marker has no evidence — was created with 'touch' instead of the mark script") - FIXES+=(" FIX: Use playwright-cli to test, then: bash /Users/nicknisi/Developer/case/scripts/mark-manual-tested.sh") + FIXES+=(" FIX: Use playwright-cli to test, then: bash ${CASE_REPO}/scripts/mark-manual-tested.sh") fi fi @@ -98,7 +101,7 @@ fi # Check 5: Code review evidence (.case-reviewed marker) if [[ ! -f ".case-reviewed" ]]; then FAILURES+=("[FAIL] Code review not done — .case-reviewed marker missing") - FIXES+=(" FIX: Run the reviewer agent, then: bash /Users/nicknisi/Developer/case/scripts/mark-reviewed.sh --critical 0 --warnings N --info N") + FIXES+=(" FIX: Run the reviewer agent, then: bash ${CASE_REPO}/scripts/mark-reviewed.sh --critical 0 --warnings N --info N") elif ! grep -q "critical: 0" ".case-reviewed" 2>/dev/null; then FAILURES+=("[FAIL] Code review has unresolved critical findings") FIXES+=(" FIX: Address critical findings from the reviewer, then re-run the reviewer agent") diff --git a/scripts/mark-manual-tested.sh b/scripts/mark-manual-tested.sh index 1cb7f23..1516252 100755 --- a/scripts/mark-manual-tested.sh +++ b/scripts/mark-manual-tested.sh @@ -54,7 +54,8 @@ EOF echo ".case-manual-tested created (${EVIDENCE_DETAILS})" >&2 # Update task JSON if .case-active contains a task ID -CASE_REPO="/Users/nicknisi/Developer/case" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CASE_REPO="$(cd "$SCRIPT_DIR/.." && pwd)" if [[ -f ".case-active" ]]; then TASK_ID=$(cat .case-active | tr -d '[:space:]') TASK_JSON="${CASE_REPO}/tasks/active/${TASK_ID}.task.json" diff --git a/scripts/mark-reviewed.sh b/scripts/mark-reviewed.sh index aa4e806..9588c4a 100755 --- a/scripts/mark-reviewed.sh +++ b/scripts/mark-reviewed.sh @@ -38,7 +38,8 @@ EOF echo ".case-reviewed created (${WARNINGS} warnings, ${INFO} info)" >&2 # Update task JSON if .case-active present -CASE_REPO="/Users/nicknisi/Developer/case" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CASE_REPO="$(cd "$SCRIPT_DIR/.." && pwd)" if [[ -f ".case-active" ]]; then TASK_ID=$(cat .case-active | tr -d '[:space:]') TASK_JSON="${CASE_REPO}/tasks/active/${TASK_ID}.task.json" diff --git a/scripts/mark-tested.sh b/scripts/mark-tested.sh index b236fae..26c981a 100755 --- a/scripts/mark-tested.sh +++ b/scripts/mark-tested.sh @@ -67,7 +67,7 @@ fi echo ".case-tested created (hash: ${OUTPUT_HASH:0:12}...)" >&2 # Update task JSON if .case-active contains a task ID -CASE_REPO="/Users/nicknisi/Developer/case" +CASE_REPO="$(cd "$SCRIPT_DIR/.." && pwd)" if [[ -f ".case-active" ]]; then TASK_ID=$(cat .case-active | tr -d '[:space:]') TASK_JSON="${CASE_REPO}/tasks/active/${TASK_ID}.task.json" diff --git a/scripts/read-learning.sh b/scripts/read-learning.sh new file mode 100755 index 0000000..a293c90 --- /dev/null +++ b/scripts/read-learning.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Read a repo's learnings file from the external learnings repo. +# Outputs the file content to stdout. If no file exists, outputs nothing. +# +# Usage: read-learning.sh +# +# Requires: +# - gh CLI authenticated +# - CASE_LEARNINGS_REPO env var set (e.g., 'youruser/case-learnings') + +set -euo pipefail + +if [[ -z "${CASE_LEARNINGS_REPO:-}" ]]; then + echo "ERROR: CASE_LEARNINGS_REPO is not set." >&2 + echo "" >&2 + echo "This script reads per-repo learnings from a GitHub repo." >&2 + echo "Set CASE_LEARNINGS_REPO to your own GitHub repo (e.g., 'youruser/case-learnings')." >&2 + echo "" >&2 + echo "Setup:" >&2 + echo " 1. Create a GitHub repo for learnings (e.g., gh repo create case-learnings --public)" >&2 + echo " 2. Export the env var: export CASE_LEARNINGS_REPO='youruser/case-learnings'" >&2 + echo " 3. Or add it to your shell profile / Claude Code settings" >&2 + exit 1 +fi + +if [[ $# -lt 1 ]]; then + echo "Usage: read-learning.sh " >&2 + exit 1 +fi + +REPO_NAME="$1" +FILE_PATH="${REPO_NAME}.md" + +# Fetch file content via GitHub API (base64-encoded). +# If the file doesn't exist (404), output nothing. +CONTENT=$(gh api "repos/${CASE_LEARNINGS_REPO}/contents/${FILE_PATH}" --jq '.content' 2>/dev/null) || true + +if [[ -z "$CONTENT" ]]; then + echo "No learnings file found for ${REPO_NAME} in ${CASE_LEARNINGS_REPO}." >&2 + exit 0 +fi + +# Decode base64 (macOS uses --decode, Linux uses -d) +echo "$CONTENT" | base64 --decode 2>/dev/null || echo "$CONTENT" | base64 -d diff --git a/scripts/upload-screenshot.sh b/scripts/upload-screenshot.sh index 5e65f7d..4e69aaf 100755 --- a/scripts/upload-screenshot.sh +++ b/scripts/upload-screenshot.sh @@ -18,7 +18,20 @@ set -euo pipefail -ASSETS_REPO="nicknisi/case-assets" +if [[ -z "${CASE_ASSETS_REPO:-}" ]]; then + echo "ERROR: CASE_ASSETS_REPO is not set." >&2 + echo "" >&2 + echo "This script uploads screenshots/videos to a GitHub repo as release assets." >&2 + echo "Set CASE_ASSETS_REPO to your own GitHub repo (e.g., 'youruser/case-assets')." >&2 + echo "" >&2 + echo "Setup:" >&2 + echo " 1. Create a GitHub repo for assets (e.g., gh repo create case-assets --public)" >&2 + echo " 2. Export the env var: export CASE_ASSETS_REPO='youruser/case-assets'" >&2 + echo " 3. Or add it to your shell profile / Claude Code settings" >&2 + exit 1 +fi + +ASSETS_REPO="$CASE_ASSETS_REPO" RELEASE_TAG="assets" if [[ $# -lt 1 ]]; then diff --git a/scripts/write-learning.sh b/scripts/write-learning.sh new file mode 100755 index 0000000..4d82282 --- /dev/null +++ b/scripts/write-learning.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash +# Append a learning entry to a repo's learnings file in the external repo. +# Creates the file with a standard header if it doesn't exist. +# +# Usage: write-learning.sh "" +# or: echo "" | write-learning.sh +# +# Requires: +# - gh CLI authenticated +# - CASE_LEARNINGS_REPO env var set (e.g., 'youruser/case-learnings') + +set -euo pipefail + +if [[ -z "${CASE_LEARNINGS_REPO:-}" ]]; then + echo "ERROR: CASE_LEARNINGS_REPO is not set." >&2 + echo "" >&2 + echo "This script writes per-repo learnings to a GitHub repo." >&2 + echo "Set CASE_LEARNINGS_REPO to your own GitHub repo (e.g., 'youruser/case-learnings')." >&2 + echo "" >&2 + echo "Setup:" >&2 + echo " 1. Create a GitHub repo for learnings (e.g., gh repo create case-learnings --public)" >&2 + echo " 2. Export the env var: export CASE_LEARNINGS_REPO='youruser/case-learnings'" >&2 + echo " 3. Or add it to your shell profile / Claude Code settings" >&2 + exit 1 +fi + +if [[ $# -lt 1 ]]; then + echo "Usage: write-learning.sh [entry]" >&2 + exit 1 +fi + +REPO_NAME="$1" +ENTRY="${2:-}" + +# If no entry argument, read from stdin +if [[ -z "$ENTRY" ]]; then + ENTRY=$(cat) +fi + +if [[ -z "$ENTRY" ]]; then + echo "ERROR: No entry provided. Pass as argument or pipe via stdin." >&2 + exit 1 +fi + +FILE_PATH="${REPO_NAME}.md" + +# Fetch existing file for SHA (required by GitHub API for updates) and content +EXISTING_SHA="" +EXISTING_CONTENT="" + +RESPONSE=$(gh api "repos/${CASE_LEARNINGS_REPO}/contents/${FILE_PATH}" 2>/dev/null) || true + +if [[ -n "$RESPONSE" ]]; then + EXISTING_SHA=$(echo "$RESPONSE" | gh api --input - --jq '.sha' 2>/dev/null || echo "$RESPONSE" | node -e "process.stdin.on('data',d=>{console.log(JSON.parse(d).sha||'')})" 2>/dev/null) || true + ENCODED_CONTENT=$(echo "$RESPONSE" | gh api --input - --jq '.content' 2>/dev/null || echo "$RESPONSE" | node -e "process.stdin.on('data',d=>{console.log(JSON.parse(d).content||'')})" 2>/dev/null) || true + if [[ -n "$ENCODED_CONTENT" ]]; then + EXISTING_CONTENT=$(echo "$ENCODED_CONTENT" | base64 --decode 2>/dev/null || echo "$ENCODED_CONTENT" | base64 -d 2>/dev/null) || true + fi +fi + +# Build new content +if [[ -z "$EXISTING_CONTENT" ]]; then + # Create new file with standard header + DISPLAY_NAME=$(echo "$REPO_NAME" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1') + NEW_CONTENT="# ${DISPLAY_NAME} Learnings + +Tactical knowledge from completed tasks. Read by agents before working in this repo. + + +${ENTRY} +" +else + NEW_CONTENT="${EXISTING_CONTENT}${ENTRY} +" +fi + +# Base64 encode the new content +ENCODED=$(printf '%s' "$NEW_CONTENT" | base64) + +COMMIT_MSG="learnings(${REPO_NAME}): append entry" + +# Write with retry for SHA conflicts (max 2 attempts) +MAX_RETRIES=2 +ATTEMPT=0 + +while [[ $ATTEMPT -lt $MAX_RETRIES ]]; do + ATTEMPT=$((ATTEMPT + 1)) + + if [[ -n "$EXISTING_SHA" ]]; then + # Update existing file + if gh api "repos/${CASE_LEARNINGS_REPO}/contents/${FILE_PATH}" \ + --method PUT \ + -f message="$COMMIT_MSG" \ + -f content="$ENCODED" \ + -f sha="$EXISTING_SHA" \ + > /dev/null 2>&1; then + echo "Appended learning to ${CASE_LEARNINGS_REPO}/${FILE_PATH}" >&2 + exit 0 + fi + else + # Create new file + if gh api "repos/${CASE_LEARNINGS_REPO}/contents/${FILE_PATH}" \ + --method PUT \ + -f message="$COMMIT_MSG" \ + -f content="$ENCODED" \ + > /dev/null 2>&1; then + echo "Created ${CASE_LEARNINGS_REPO}/${FILE_PATH} with learning entry" >&2 + exit 0 + fi + fi + + # On failure, refresh SHA and retry + if [[ $ATTEMPT -lt $MAX_RETRIES ]]; then + echo "Write conflict, retrying (attempt $((ATTEMPT + 1))/${MAX_RETRIES})..." >&2 + EXISTING_SHA=$(gh api "repos/${CASE_LEARNINGS_REPO}/contents/${FILE_PATH}" --jq '.sha' 2>/dev/null) || true + fi +done + +echo "ERROR: Failed to write learning after ${MAX_RETRIES} attempts." >&2 +exit 1 diff --git a/skills/case/SKILL.md b/skills/case/SKILL.md index 777c614..c3f4164 100644 --- a/skills/case/SKILL.md +++ b/skills/case/SKILL.md @@ -9,9 +9,15 @@ argument-hint: "[issue-number] or [LINEAR-ID]" You are operating within the Case harness for WorkOS open source projects. Humans steer. Agents execute. When agents struggle, fix the harness. -**Case repo**: `/Users/nicknisi/Developer/case` +**Case repo**: Resolve dynamically at the start of each `/case` invocation. This SKILL.md file lives at `skills/case/SKILL.md` within the case repo. Strip that suffix from this file's absolute path to get `CASE_REPO`. All `${CASE_REPO}` references below use this resolved path. -All paths below are relative to the skill's cache directory. For scripts, tasks, and project manifest, use the case repo path above. +Before running any scripts, resolve and verify the case repo path: +```bash +# CASE_REPO is the root of the case harness repo (parent of skills/, agents/, scripts/) +# Derive it from this skill file's location: strip skills/case/ from the path +CASE_REPO="" # Replace with actual path derived from this SKILL.md's location +ls "${CASE_REPO}/AGENTS.md" "${CASE_REPO}/projects.json" > /dev/null +``` ## Agent Architecture @@ -26,7 +32,7 @@ Case uses a **six-agent pipeline** to prevent context pollution and enable self- | **Closer** | Create PR with thorough description, satisfy hook gates, post review comments | Read, Bash, Glob, Grep | | **Retrospective** | Apply harness improvements directly, maintain per-repo learnings | Read, Edit, Write, Bash, Glob, Grep | -Agent prompt files: `/Users/nicknisi/Developer/case/agents/{implementer,verifier,reviewer,closer,retrospective}.md` +Agent prompt files: `${CASE_REPO}/agents/{implementer,verifier,reviewer,closer,retrospective}.md` The orchestrator spawns each agent sequentially using the `Agent` tool, passing the agent prompt file content as the prompt. Each agent ends its response with a structured `AGENT_RESULT` block (see below). @@ -91,7 +97,7 @@ After parsing and fetching the issue, execute this pipeline: **Explicit arguments always win over `.case-active`.** The `.case-active` shortcut is only used for no-arg `/case`. When an explicit issue number or Linear ID is provided, re-entry is matched by issue content, not by `.case-active`. 1. **If an explicit argument was provided** (issue number or Linear ID): - - Scan `/Users/nicknisi/Developer/case/tasks/active/*.task.json` for a match: + - Scan `${CASE_REPO}/tasks/active/*.task.json` for a match: - GitHub issue → matching `repo` + `issueType: "github"` + `issue` number - Linear ID → matching `issueType: "linear"` + `issue` ID - Ignore `.case-active` — it may be stale or from a different issue @@ -99,7 +105,7 @@ After parsing and fetching the issue, execute this pipeline: - If not found → proceed to step 1 (new task) 2. **If no argument** (`/case` with no args): - - Read `.case-active` — if it contains a task ID, look up `/Users/nicknisi/Developer/case/tasks/active/{task-id}.task.json` directly + - Read `.case-active` — if it contains a task ID, look up `${CASE_REPO}/tasks/active/{task-id}.task.json` directly - If found → resume - If not found → load harness context (no orchestrator flow) @@ -122,9 +128,9 @@ _(Already done in the Arguments section above)_ ### Step 2: Task Setup 1. Derive repo name from `git remote get-url origin` -2. Find next sequential task number: count existing `{repo}-*.md` files in `/Users/nicknisi/Developer/case/tasks/active/` + 1 -3. Create task file (`.md`) using the appropriate template from `/Users/nicknisi/Developer/case/tasks/templates/` -4. Create companion `.task.json` in `/Users/nicknisi/Developer/case/tasks/active/`: +2. Find next sequential task number: count existing `{repo}-*.md` files in `${CASE_REPO}/tasks/active/` + 1 +3. Create task file (`.md`) using the appropriate template from `${CASE_REPO}/tasks/templates/` +4. Create companion `.task.json` in `${CASE_REPO}/tasks/active/`: ```json { "id": "--issue-", @@ -163,7 +169,7 @@ _(Already done in the Arguments section above)_ - Not exists → `git checkout -b ` (create) 3. Run baseline smoke test: ```bash - bash /Users/nicknisi/Developer/case/scripts/bootstrap.sh + bash ${CASE_REPO}/scripts/bootstrap.sh ``` - If FAIL: Report broken baseline to user via `AskUserQuestion`. Do not spawn implementer. **Go to step 9 (Retrospective)** with outcome "failed" and failed agent "orchestrator/baseline". - If PASS: continue @@ -176,13 +182,13 @@ _(Already done in the Arguments section above)_ ``` 5. Update task JSON: ```bash - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent orchestrator status completed - bash /Users/nicknisi/Developer/case/scripts/task-status.sh agent orchestrator completed now + bash ${CASE_REPO}/scripts/task-status.sh agent orchestrator status completed + bash ${CASE_REPO}/scripts/task-status.sh agent orchestrator completed now ``` ### Step 4: Spawn Implementer -1. Read `/Users/nicknisi/Developer/case/agents/implementer.md` +1. Read `${CASE_REPO}/agents/implementer.md` 2. Use the `Agent` tool: - **prompt**: `` + task context: - Task file path (`.md` and `.task.json`) @@ -197,7 +203,7 @@ _(Already done in the Arguments section above)_ ### Step 5: Spawn Verifier -1. Read `/Users/nicknisi/Developer/case/agents/verifier.md` +1. Read `${CASE_REPO}/agents/verifier.md` 2. Use the `Agent` tool: - **prompt**: `` + task context (file path, repo path) - **subagent_type**: `general-purpose` @@ -217,7 +223,7 @@ _(Already done in the Arguments section above)_ ### Step 6: Spawn Reviewer -1. Read `/Users/nicknisi/Developer/case/agents/reviewer.md` +1. Read `${CASE_REPO}/agents/reviewer.md` 2. Use the `Agent` tool: - **prompt**: `` + task context: - Task file path (`.md` and `.task.json`) @@ -238,9 +244,9 @@ _(Already done in the Arguments section above)_ 1. Update task JSON status to `closing`: ```bash - bash /Users/nicknisi/Developer/case/scripts/task-status.sh status closing + bash ${CASE_REPO}/scripts/task-status.sh status closing ``` -2. Read `/Users/nicknisi/Developer/case/agents/closer.md` +2. Read `${CASE_REPO}/agents/closer.md` 3. Use the `Agent` tool: - **prompt**: `` + task context (file path, repo path, verifier `AGENT_RESULT`, reviewer `AGENT_RESULT`) - **subagent_type**: `general-purpose` @@ -259,7 +265,7 @@ Report to user: **Always runs** — after both successful and failed pipelines, at every failure class (baseline, implementer, verifier, reviewer, closer). Every failure branch in steps 3-8 routes here explicitly. This is how the harness improves itself. -1. Read `/Users/nicknisi/Developer/case/agents/retrospective.md` +1. Read `${CASE_REPO}/agents/retrospective.md` 2. Use the `Agent` tool: - **prompt**: `` + context: - Task file path (with progress log from all agents) @@ -292,7 +298,7 @@ If `/case` is invoked and a `.task.json` already exists for the issue, the orche Before spawning the implementer, the orchestrator runs the target repo's test/build suite to confirm a clean baseline. This prevents agents from building on broken foundations. ```bash -bash /Users/nicknisi/Developer/case/scripts/bootstrap.sh +bash ${CASE_REPO}/scripts/bootstrap.sh ``` The bootstrap script runs the repo's `setup`, `build`, `test`, `typecheck`, and `lint` commands (from `projects.json`). If any fail: @@ -337,25 +343,25 @@ Based on the user's request, load the relevant context: ## Project Manifest -Full repo metadata (paths, commands, remotes): `/Users/nicknisi/Developer/case/projects.json` +Full repo metadata (paths, commands, remotes): `${CASE_REPO}/projects.json` ## Task Dispatch To create a task for async agent execution: -1. Choose template from `/Users/nicknisi/Developer/case/tasks/templates/` +1. Choose template from `${CASE_REPO}/tasks/templates/` 2. Fill in `{placeholder}` fields -3. Save `.md` to `/Users/nicknisi/Developer/case/tasks/active/{repo}-{n}-{slug}.md` -4. Create companion `.task.json` with the same stem (see task schema: `/Users/nicknisi/Developer/case/tasks/task.schema.json`) -5. Update task JSON status as agents complete work via `/Users/nicknisi/Developer/case/scripts/task-status.sh` +3. Save `.md` to `${CASE_REPO}/tasks/active/{repo}-{n}-{slug}.md` +4. Create companion `.task.json` with the same stem (see task schema: `${CASE_REPO}/tasks/task.schema.json`) +5. Update task JSON status as agents complete work via `${CASE_REPO}/scripts/task-status.sh` Available templates: -- `/Users/nicknisi/Developer/case/tasks/templates/cli-command.md` — add a CLI command -- `/Users/nicknisi/Developer/case/tasks/templates/authkit-framework.md` — new AuthKit framework integration -- `/Users/nicknisi/Developer/case/tasks/templates/bug-fix.md` — fix a bug in any repo -- `/Users/nicknisi/Developer/case/tasks/templates/cross-repo-update.md` — coordinated cross-repo change +- `${CASE_REPO}/tasks/templates/cli-command.md` — add a CLI command +- `${CASE_REPO}/tasks/templates/authkit-framework.md` — new AuthKit framework integration +- `${CASE_REPO}/tasks/templates/bug-fix.md` — fix a bug in any repo +- `${CASE_REPO}/tasks/templates/cross-repo-update.md` — coordinated cross-repo change -Format spec: `/Users/nicknisi/Developer/case/tasks/README.md` +Format spec: `${CASE_REPO}/tasks/README.md` ## Working in a Target Repo @@ -363,9 +369,9 @@ Before making changes in any target repo: 1. Create a feature branch (or use `claude --worktree` for isolated work) 2. Read that repo's `CLAUDE.md` or `CLAUDE.local.md` for project-specific instructions -3. Run `/Users/nicknisi/Developer/case/scripts/bootstrap.sh {repo-name}` to verify readiness +3. Run `${CASE_REPO}/scripts/bootstrap.sh {repo-name}` to verify readiness 4. Follow the repo's PR checklist before opening a PR -5. Run `/Users/nicknisi/Developer/case/scripts/check.sh --repo {repo-name}` to verify conventions +5. Run `${CASE_REPO}/scripts/check.sh --repo {repo-name}` to verify conventions ## Verification Tools @@ -438,8 +444,8 @@ cp .playwright-cli/page-*.png /tmp/after.png # Upload and get markdown # For video: the script auto-converts to GIF (inline) + mp4 (download link) -VIDEO=$(/Users/nicknisi/Developer/case/scripts/upload-screenshot.sh /tmp/verification.webm) -SCREENSHOT=$(/Users/nicknisi/Developer/case/scripts/upload-screenshot.sh /tmp/after.png) +VIDEO=$(${CASE_REPO}/scripts/upload-screenshot.sh /tmp/verification.webm) +SCREENSHOT=$(${CASE_REPO}/scripts/upload-screenshot.sh /tmp/after.png) # Use in PR body — VIDEO contains both GIF embed and mp4 download link echo "## Verification" @@ -497,8 +503,8 @@ The orchestrator spawns the closer, which handles this checklist. If you're the When an agent struggles or produces poor output, the fix goes into case/, not the code: -- Missing pattern? Add to `/Users/nicknisi/Developer/case/docs/architecture/` -- Unclear convention? Update `/Users/nicknisi/Developer/case/docs/conventions/` -- Recurring task? Add a playbook + template in `/Users/nicknisi/Developer/case/` -- Agent violation? Add to `/Users/nicknisi/Developer/case/docs/golden-principles.md` and update `scripts/check.sh` +- Missing pattern? Add to `${CASE_REPO}/docs/architecture/` +- Unclear convention? Update `${CASE_REPO}/docs/conventions/` +- Recurring task? Add a playbook + template in `${CASE_REPO}/` +- Agent violation? Add to `${CASE_REPO}/docs/golden-principles.md` and update `scripts/check.sh` - Wrong approach? Update the relevant `CLAUDE.md` in the target repo diff --git a/tasks/README.md b/tasks/README.md index 659f210..853e553 100644 --- a/tasks/README.md +++ b/tasks/README.md @@ -52,7 +52,7 @@ The JSON file stores structured metadata that agents and scripts update programm Fields: `id`, `status`, `created`, `repo`, `issue`, `issueType`, `branch`, `agents`, `tested`, `manualTested`, `prUrl`, `prNumber`. -Read/write via: `bash /Users/nicknisi/Developer/case/scripts/task-status.sh [value]` +Read/write via: `bash ${CASE_REPO}/scripts/task-status.sh [value]` **Evidence flags** (`tested`, `manualTested`) can only be set by marker scripts (`mark-tested.sh`, `mark-manual-tested.sh`) — not by agents directly.