Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
.case-active
.case-tested
.case-manual-tested

# Local project manifest (copy from projects.example.json and customize paths)
projects.json
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <target-repo-path> --task <task.json>)
SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh <target-repo-path> --task <task.json>)
echo "$SESSION"
```

Expand All @@ -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

Expand Down
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ Case depends on the skills plugin for product knowledge. They are complementary,
```
AGENTS.md # Entry point for agents (routing map)
CLAUDE.md # This file (meta-instructions for case itself)
projects.json # Manifest of target repos
projects.example.json # Example manifest (copy to projects.json)
projects.json # Local manifest (gitignored)
projects.schema.json # JSON Schema for the manifest
docs/
architecture/ # Canonical patterns per repo type
Expand Down
81 changes: 72 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ graph TD

## Self-Improvement

After every pipeline run — success or failure — the retrospective agent analyzes what happened and **applies improvements directly** to the harness. It also maintains per-repo learnings files so knowledge compounds across runs:
After every pipeline run — success or failure — the retrospective agent analyzes what happened and **applies improvements directly** to the harness. It also maintains per-repo learnings in an [external repo](#3-set-up-environment-variables) so knowledge compounds across runs:

```mermaid
graph LR
Expand All @@ -70,7 +70,7 @@ graph LR
C -->|agent skipped steps| F["Apply fix: agent prompt"]
C -->|hook too lenient| G["Apply fix: hook script"]
C -->|nothing| H["No improvements needed"]
D --> I["Update repo learnings"]
D --> I["Update repo learnings (external repo)"]
E --> I
F --> I
G --> I
Expand All @@ -79,9 +79,69 @@ graph LR
J -->|no| L["Done"]
```

## Quick Start
## Getting Started

### Install the plugin
### 1. Fork the repo

Case improves itself after every pipeline run — the retrospective agent edits harness files directly. Fork the repo so those improvements have somewhere to land and don't conflict with upstream.

```bash
gh repo fork workos/case --clone
```

Add upstream as a remote so you can pull future improvements:

```bash
cd case
git remote add upstream git@github.com:workos/case.git
```

### 2. Set up the project manifest

The project manifest (`projects.json`) tells case where your target repos live. It's gitignored so each user can customize paths without polluting the repo. Copy the example and edit it:

```bash
cp projects.example.json projects.json
```

The default paths assume target repos are siblings of case:

```
~/dev/
case/ # this repo (your fork)
cli/main/ # workos/workos-cli
skills/ # workos/skills
authkit-session/ # workos/authkit-ssr
authkit-tanstack-start/ # workos/authkit-tanstack-start
authkit-nextjs/ # workos/authkit-nextjs
```

If your repos live elsewhere, edit the `path` field for each repo in `projects.json` — paths are resolved relative to the case directory and can point anywhere (e.g., `../../other/path/cli`).

You only need entries for repos you plan to work in.

### 3. Set up environment variables

Some features require external GitHub repos for user-specific data. Set these in your shell profile or Claude Code settings:

| Variable | Purpose | Required for |
| --- | --- | --- |
| `CASE_ASSETS_REPO` | GitHub repo for PR screenshots/videos (e.g., `youruser/case-assets`) | `scripts/upload-screenshot.sh` |
| `CASE_LEARNINGS_REPO` | GitHub repo for per-repo tactical knowledge (e.g., `youruser/case-learnings`) | `scripts/read-learning.sh`, `scripts/write-learning.sh` |

```bash
# Create the repos
gh repo create case-assets --public --description "PR screenshots and videos for case harness"
gh repo create case-learnings --public --description "Per-repo tactical knowledge for case harness"

# Add to your shell profile
export CASE_ASSETS_REPO='youruser/case-assets'
export CASE_LEARNINGS_REPO='youruser/case-learnings'
```

Both are optional — scripts fail fast with setup instructions if the env var is missing. The pipeline works without them, but you won't get screenshot uploads or accumulated learnings.

### 4. Install the plugin

```bash
claude plugin marketplace add /path/to/case
Expand All @@ -95,7 +155,7 @@ To update after changes:
claude plugin uninstall case && claude plugin marketplace update && claude plugin install case
```

### Use with an issue
### 5. Use with an issue

From any target repo:

Expand Down Expand Up @@ -225,7 +285,8 @@ hooks/

AGENTS.md Entry point for agents (project landscape)
CLAUDE.md How to improve case itself
projects.json Manifest of target repos
projects.example.json Example manifest (copy to projects.json)
projects.json Your local manifest (gitignored)

docs/
architecture/ Canonical patterns per repo type
Expand All @@ -235,7 +296,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/
Expand All @@ -252,6 +313,8 @@ scripts/
mark-manual-tested.sh Evidence-based manual test marker
mark-reviewed.sh Review evidence marker (requires critical: 0)
upload-screenshot.sh Upload images to GitHub for PR descriptions
read-learning.sh Read per-repo learnings from external repo
write-learning.sh Append learnings to external repo
session-start.sh Session context for all agents (structured JSON)
parse-test-output.sh Parse vitest JSON reporter into structured evidence
entropy-scan.sh Convention drift scanner across repos
Expand All @@ -267,7 +330,7 @@ scripts/
| authkit-tanstack-start | `../authkit-tanstack-start` | AuthKit TanStack Start SDK |
| authkit-nextjs | `../authkit-nextjs` | AuthKit Next.js SDK |

The manifest (`projects.json`) and all tooling are designed to scale to 25+ repos. Add a new repo by appending to `projects.json`.
Default paths in `projects.example.json` assume sibling directories, but paths are configurable (see [Getting Started](#2-set-up-the-project-manifest)). The manifest and all tooling are designed to scale to 25+ repos. Add a new repo by appending to your `projects.json`.

## Philosophy

Expand Down Expand Up @@ -310,7 +373,7 @@ They're complementary. Case depends on skills for product knowledge.

## Adding a New Repo

1. Add entry to `projects.json` (follow the schema)
1. Add entry to your `projects.json` (follow `projects.schema.json`)
2. Ensure the repo has a `CLAUDE.md` with: commands, architecture, do/don't, PR checklist
3. Run `bash scripts/check.sh --repo <name>` to verify compliance
4. Add architecture doc to `docs/architecture/` if the repo introduces a new pattern
Expand Down
12 changes: 7 additions & 5 deletions agents/closer.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ 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

### 0. Session Context

Run the session-start script to orient yourself:
```bash
SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh <target-repo-path> --task <task.json>)
SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh <target-repo-path> --task <task.json>)
echo "$SESSION"
```

Expand All @@ -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 `<video` tags and `![` image tags)
5. Read `/Users/nicknisi/Developer/case/docs/conventions/pull-requests.md` for PR format rules
5. Read `${CASE_REPO}/docs/conventions/pull-requests.md` for PR format rules

### 2. Draft PR

Expand Down Expand Up @@ -151,8 +153,8 @@ Only post if there are actual findings to share. Skip this step if the reviewer

1. **Update task JSON** — agent phase only. The `status → pr-opened` transition is owned by the post-PR hook (fires automatically after `gh pr create` succeeds). Do NOT set status here — it creates duplicate ownership.
```bash
bash /Users/nicknisi/Developer/case/scripts/task-status.sh <task.json> agent closer status completed
bash /Users/nicknisi/Developer/case/scripts/task-status.sh <task.json> agent closer completed now
bash ${CASE_REPO}/scripts/task-status.sh <task.json> agent closer status completed
bash ${CASE_REPO}/scripts/task-status.sh <task.json> agent closer completed now
```
The hook will handle: `status → pr-opened` and `prUrl`.

Expand Down
29 changes: 17 additions & 12 deletions agents/implementer.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@ 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

### 0. Session Context

Run the session-start script to orient yourself:
```bash
SESSION=$(bash /Users/nicknisi/Developer/case/scripts/session-start.sh <target-repo-path> --task <task.json>)
SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh <target-repo-path> --task <task.json>)
echo "$SESSION"
```

Expand All @@ -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 <task.json> status implementing
bash /Users/nicknisi/Developer/case/scripts/task-status.sh <task.json> agent implementer status running
bash /Users/nicknisi/Developer/case/scripts/task-status.sh <task.json> agent implementer started now
bash ${CASE_REPO}/scripts/task-status.sh <task.json> status implementing
bash ${CASE_REPO}/scripts/task-status.sh <task.json> agent implementer status running
bash ${CASE_REPO}/scripts/task-status.sh <task.json> 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

Expand Down Expand Up @@ -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.

Expand All @@ -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 <task.json> agent implementer status completed
bash /Users/nicknisi/Developer/case/scripts/task-status.sh <task.json> agent implementer completed now
bash ${CASE_REPO}/scripts/task-status.sh <task.json> agent implementer status completed
bash ${CASE_REPO}/scripts/task-status.sh <task.json> agent implementer completed now
```

### 5. Output
Expand Down
26 changes: 17 additions & 9 deletions agents/retrospective.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 <target-repo-path> --task <task.json>)
SESSION=$(bash ${CASE_REPO}/scripts/session-start.sh <target-repo-path> --task <task.json>)
echo "$SESSION"
```

Expand Down Expand Up @@ -91,7 +92,7 @@ For each finding, apply the fix directly:
4. For script changes, verify syntax with `bash -n <file>` 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
Expand All @@ -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/`)
Expand All @@ -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

Expand Down
Loading