infinity-harness 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +114 -0
- package/LICENSE +21 -0
- package/README.md +266 -0
- package/extensions/infinity-harness/index.ts +870 -0
- package/harness/docs/ARCHITECTURE.md +159 -0
- package/harness/docs/CONSTRAINTS.md +19 -0
- package/harness/docs/DECISIONS.md +107 -0
- package/harness/docs/DOMAIN.md +13 -0
- package/harness/docs/agents/evaluator.md +14 -0
- package/harness/docs/agents/generator.md +13 -0
- package/harness/docs/agents/planner.md +13 -0
- package/harness/docs/agents/simplifier.md +13 -0
- package/harness/docs/api-patterns.md +23 -0
- package/harness/docs/phases/build.md +47 -0
- package/harness/docs/phases/define.md +58 -0
- package/harness/docs/phases/plan.md +50 -0
- package/harness/docs/phases/review.md +47 -0
- package/harness/docs/phases/ship.md +43 -0
- package/harness/docs/phases/simplify.md +45 -0
- package/harness/docs/phases/verify.md +46 -0
- package/harness/model-router.json +28 -0
- package/harness/skills/README.md +60 -0
- package/harness/skills/auth-security.md +56 -0
- package/harness/skills/building-mcp-servers.md +70 -0
- package/harness/skills/building-tools.md +60 -0
- package/harness/skills/capability-acquisition.md +72 -0
- package/harness/skills/cli-design.md +55 -0
- package/harness/skills/code-review.md +57 -0
- package/harness/skills/codebase-design.md +70 -0
- package/harness/skills/concurrency-async.md +61 -0
- package/harness/skills/config-and-secrets.md +52 -0
- package/harness/skills/context-hygiene.md +51 -0
- package/harness/skills/databases.md +63 -0
- package/harness/skills/diagnosing-bugs.md +84 -0
- package/harness/skills/domain-modeling.md +65 -0
- package/harness/skills/error-handling-logging.md +56 -0
- package/harness/skills/frontend-ui.md +56 -0
- package/harness/skills/grilling.md +48 -0
- package/harness/skills/http-apis.md +60 -0
- package/harness/skills/performance.md +53 -0
- package/harness/skills/pi-todo-adapted.md +41 -0
- package/harness/skills/planning-tasks.md +86 -0
- package/harness/skills/prototype.md +39 -0
- package/harness/skills/research.md +32 -0
- package/harness/skills/resolving-merge-conflicts.md +30 -0
- package/harness/skills/scope-discipline.md +49 -0
- package/harness/skills/self-review.md +45 -0
- package/harness/skills/stuck-protocol.md +51 -0
- package/harness/skills/tdd.md +80 -0
- package/harness/skills/testing-infra.md +57 -0
- package/harness/skills/writing-skills.md +60 -0
- package/package.json +61 -0
- package/src/core/brief.ts +242 -0
- package/src/core/config.ts +265 -0
- package/src/core/exec.ts +130 -0
- package/src/core/featureList.ts +286 -0
- package/src/core/fsx.ts +119 -0
- package/src/core/gates.ts +444 -0
- package/src/core/lock.ts +192 -0
- package/src/core/paths.ts +95 -0
- package/src/core/phases.ts +143 -0
- package/src/core/settings.ts +445 -0
- package/src/core/types.ts +245 -0
- package/src/goalLoop.ts +628 -0
- package/src/goalSpec.ts +679 -0
- package/src/goalState.ts +338 -0
- package/src/loop.ts +355 -0
- package/src/modelRouter.ts +184 -0
- package/src/remote.ts +244 -0
- package/src/replan.ts +300 -0
- package/src/review.ts +53 -0
- package/src/rework.ts +274 -0
- package/src/taskList.ts +355 -0
- package/src/ui/config.ts +286 -0
- package/src/ui/dashboard.ts +1066 -0
- package/src/ui/theme.ts +317 -0
- package/src/ui/widget.ts +370 -0
- package/src/unstuck.ts +214 -0
- package/src/worker.ts +351 -0
- package/types/proper-lockfile.d.ts +19 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
infinity-harness is a pi extension that drives an agent through a gated build pipeline and keeps it
|
|
4
|
+
going, unattended, for hours or days.
|
|
5
|
+
|
|
6
|
+
The whole design rests on one idea: **take two decisions away from the model.** When work is done is
|
|
7
|
+
decided by a deterministic gate, not the agent's judgement. What happens next is decided by a
|
|
8
|
+
forward-only phase machine, not the agent's preference. Everything else exists to keep those two
|
|
9
|
+
decisions honest across a very long run.
|
|
10
|
+
|
|
11
|
+
## Shape
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌──────────────────────────────────┐
|
|
15
|
+
pi lifecycle ──────► │ extensions/infinity-harness │ thin adapter
|
|
16
|
+
│ hooks · tools · commands │ no logic of its own
|
|
17
|
+
└───────────────┬──────────────────┘
|
|
18
|
+
│
|
|
19
|
+
┌───────────────────────────────┼───────────────────────────────┐
|
|
20
|
+
▼ ▼ ▼
|
|
21
|
+
┌─────────┐ ┌─────────────┐ ┌───────────┐
|
|
22
|
+
│ loop.ts │ │ taskList │ │ ui/ │
|
|
23
|
+
│ decide │ │ atomic │ │ widget │
|
|
24
|
+
│ next │ │ plan edit │ │ dashboard │
|
|
25
|
+
└────┬────┘ └──────┬──────┘ └─────┬─────┘
|
|
26
|
+
│ │ │
|
|
27
|
+
└───────────────┬───────────────┴──────────────────────────────┘
|
|
28
|
+
▼
|
|
29
|
+
┌───────────────────────────────────────────────┐
|
|
30
|
+
│ src/core/ │
|
|
31
|
+
│ types · paths · fsx · lock · exec │
|
|
32
|
+
│ config · phases · gates · brief · featureList │
|
|
33
|
+
└───────────────────────┬───────────────────────┘
|
|
34
|
+
▼
|
|
35
|
+
harness/ (state on disk)
|
|
36
|
+
config.json · features/feature-list.json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**The extension is thin on purpose.** An earlier version inlined its own copies of the plan engine
|
|
40
|
+
and the widget, so the tested code and the shipped code were two different implementations that
|
|
41
|
+
drifted apart. There is one implementation now, in `src/`, and the adapter calls it. The same rule
|
|
42
|
+
applies to every module: if you find yourself writing a private `loadFeatureList`, stop — that
|
|
43
|
+
mistake has already been made twice and fixed twice.
|
|
44
|
+
|
|
45
|
+
## Layers
|
|
46
|
+
|
|
47
|
+
### `src/core/` — owned foundations
|
|
48
|
+
|
|
49
|
+
| Module | Responsibility |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `types.ts` | Every shape crossing a module boundary. No I/O; safe to import anywhere. |
|
|
52
|
+
| `paths.ts` | The only place a `harness/…` path is spelled out. |
|
|
53
|
+
| `fsx.ts` | Atomic JSON writes, `.bak` snapshots, absent-vs-corrupt reads. |
|
|
54
|
+
| `exec.ts` | Every shell-out, bounded by a timeout. Never throws; failures are data. |
|
|
55
|
+
| `lock.ts` | `withLockSync` (exclusive, fail-closed) and `withLock` (advisory, best-effort). |
|
|
56
|
+
| `config.ts` | `harness/config.json` — pipeline state, retry budgets, gate history. |
|
|
57
|
+
| `phases.ts` | The forward-only state machine and `transitionPhase`. |
|
|
58
|
+
| `gates.ts` | The deterministic checks and the runner. |
|
|
59
|
+
| `featureList.ts` | The plan on disk: load, save, flatten, progress, dependency integrity. |
|
|
60
|
+
| `brief.ts` | "What do I do now?", assembled from state and rendered for a model. |
|
|
61
|
+
|
|
62
|
+
These were ported to TypeScript from a sibling CLI project that used to be reached through a symlink.
|
|
63
|
+
The symlink made the package unshippable — it pointed at an absolute path on one developer's
|
|
64
|
+
machine — so the needed logic is now owned, typed, and tested here.
|
|
65
|
+
|
|
66
|
+
### `src/` — the harness proper
|
|
67
|
+
|
|
68
|
+
- **`taskList.ts`** — the atomic plan editor. The agent submits the complete list; omission means
|
|
69
|
+
deletion; `baseRevision` guards the write; unknown fields survive.
|
|
70
|
+
- **`loop.ts`** — `decideNext()`: given state on disk, continue, advance, wait, or stop.
|
|
71
|
+
- **`worker.ts`** — isolated per-task workers under `tmp/infinity-harness/<run>/`.
|
|
72
|
+
- **`modelRouter.ts`** — optional difficulty ladder, disabled and vendor-neutral by default.
|
|
73
|
+
- **`rework.ts` / `replan.ts`** — bounded backward movement: BFS impact analysis, DAG-guarded
|
|
74
|
+
mid-build amendment.
|
|
75
|
+
- **`unstuck.ts` / `review.ts`** — escalation strategy matrix; the REVIEW bounce guard.
|
|
76
|
+
- **`remote.ts`** — the read-only dashboard server.
|
|
77
|
+
|
|
78
|
+
### `src/ui/` — the visible surface
|
|
79
|
+
|
|
80
|
+
- **`theme.ts`** — ANSI-aware width, wrapping, truncation, colour degradation, glyph fallback.
|
|
81
|
+
- **`widget.ts`** — the terminal plan view.
|
|
82
|
+
- **`dashboard.ts`** — the web plan view, same information design.
|
|
83
|
+
|
|
84
|
+
## Data flow
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
session_start ──► buildBrief ──► renderBrief ──► sendMessage the agent is told what to do
|
|
88
|
+
▲
|
|
89
|
+
│
|
|
90
|
+
agent works ─────────┼──► infinity_plan ──► writeTaskList ──► feature-list.json
|
|
91
|
+
│ (locked) │
|
|
92
|
+
│ ▼
|
|
93
|
+
agent_settled ──► decideNext ──► runChecks ──► gate verdict widget · dashboard
|
|
94
|
+
│ │
|
|
95
|
+
│ ├── pass ──► advancePhase ──► new brief ──► next turn
|
|
96
|
+
│ └── fail ──► re-brief with the failing checks
|
|
97
|
+
│
|
|
98
|
+
└── budgets exhausted / no progress / paused ──► stop, with a reason
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Nothing caches a second copy of the plan. The widget, the dashboard and the brief all read
|
|
102
|
+
`feature-list.json`, so the visible state is always the real state — even when the agent's own
|
|
103
|
+
narration has drifted.
|
|
104
|
+
|
|
105
|
+
## Concurrency
|
|
106
|
+
|
|
107
|
+
Parallel workers write the same plan file. `baseRevision` detects a stale **read**; it cannot
|
|
108
|
+
serialise a read-modify-write. Two processes that both read revision N both pass the check and both
|
|
109
|
+
write N+1, and one set of edits is gone — measured at 2 lost updates in a 6-way fan-out.
|
|
110
|
+
|
|
111
|
+
So `writeTaskList` holds an exclusive lock across the entire read-apply-write, and **fails closed**:
|
|
112
|
+
if the lock cannot be taken, the write is refused with an error the caller can retry, rather than
|
|
113
|
+
racing and losing an edit silently.
|
|
114
|
+
|
|
115
|
+
Two details that cost real debugging time:
|
|
116
|
+
|
|
117
|
+
- The sync lock uses `<path>.ilock`, **not** `<path>.lock` — the latter is what `proper-lockfile`
|
|
118
|
+
uses, and it is a directory there too. Sharing the name made a nested async+sync lock deadlock
|
|
119
|
+
against itself.
|
|
120
|
+
- Locks are held for the duration of the *work*, never across an agent turn. An earlier version took
|
|
121
|
+
a lock at the start of a turn with an 8-second staleness timeout, so every turn longer than eight
|
|
122
|
+
seconds left a lock another process was entitled to steal.
|
|
123
|
+
|
|
124
|
+
## Stopping
|
|
125
|
+
|
|
126
|
+
Continuing is easy; knowing when to stop is the hard part, and the difference between a useful
|
|
127
|
+
overnight run and a wasted weekend of tokens.
|
|
128
|
+
|
|
129
|
+
| Guard | Catches |
|
|
130
|
+
|---|---|
|
|
131
|
+
| No-progress detector | The gate keeps failing and the tree fingerprint hasn't moved — spinning, not working |
|
|
132
|
+
| Wall clock | A run nobody remembered to stop |
|
|
133
|
+
| Iteration ceiling | Runaway loops that stay under the clock |
|
|
134
|
+
| Retry budgets | One impossible task consuming the run |
|
|
135
|
+
| Human brake | `paused`, `/infinity:halt`, or `harness/STOP` |
|
|
136
|
+
|
|
137
|
+
The fingerprint is `git status --porcelain` + HEAD + the plan revision and task statuses. The first
|
|
138
|
+
failing iteration establishes a baseline and never counts as a stall — there is nothing to compare
|
|
139
|
+
against yet.
|
|
140
|
+
|
|
141
|
+
Every stop carries a reason. A human coming back finds an explanation, not a mystery.
|
|
142
|
+
|
|
143
|
+
## Failure posture
|
|
144
|
+
|
|
145
|
+
- **Reads distinguish absent from corrupt.** A missing plan seeds an empty one; a corrupt plan
|
|
146
|
+
recovers the previous good revision from `.bak` rather than silently starting over.
|
|
147
|
+
- **Advisory checks never fail a gate.** A gate that fails for a reason the agent cannot fix
|
|
148
|
+
deadlocks the loop, so an unconfigured lint command is reported, not enforced.
|
|
149
|
+
- **Errors are data where the caller can continue** (`{ ok, error }`), thrown where it cannot.
|
|
150
|
+
- **The dashboard cannot perturb the run.** Read-only, loopback-only, and it never runs the gate —
|
|
151
|
+
running lint and tests because someone opened a web page would be a surprising side effect.
|
|
152
|
+
|
|
153
|
+
## Verification
|
|
154
|
+
|
|
155
|
+
- `npm test` — 20 unit files, plain `node:assert`, no framework.
|
|
156
|
+
- `npm run e2e` — 11 scenarios over real temp projects, real git repos, real child processes: the
|
|
157
|
+
full pipeline walkthrough, loop convergence, every stop condition, SIGKILL-and-restart, a 6-way
|
|
158
|
+
concurrent write fan-out with an unlocked control, data round-trip, the dashboard, widget
|
|
159
|
+
rendering across shapes, adversarial input, and the extension adapter itself.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Constraints
|
|
2
|
+
|
|
3
|
+
## Technical
|
|
4
|
+
|
|
5
|
+
- **Language:** node
|
|
6
|
+
- **Platform:** <!-- target platform -->
|
|
7
|
+
- **Dependencies:** <!-- key dependency constraints -->
|
|
8
|
+
|
|
9
|
+
## Process
|
|
10
|
+
|
|
11
|
+
- Commits must be atomic (one concern per commit)
|
|
12
|
+
- All code reviewed before merging
|
|
13
|
+
- Tests must pass before shipping
|
|
14
|
+
|
|
15
|
+
## Design
|
|
16
|
+
|
|
17
|
+
- Favor simplicity over generality
|
|
18
|
+
- Explicit over implicit
|
|
19
|
+
- Fail fast, fail loud
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Decisions
|
|
2
|
+
|
|
3
|
+
Architectural decisions and the reasoning behind them. Outcomes without reasons are useless to the
|
|
4
|
+
next person — record why, and what it cost.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. The gate is the only referee
|
|
9
|
+
|
|
10
|
+
**Context.** An agent asked whether its work is finished will say yes. Repeatedly, and wrongly, over
|
|
11
|
+
a long run.
|
|
12
|
+
|
|
13
|
+
**Decision.** Completion is decided by deterministic checks that are a pure function of the project
|
|
14
|
+
on disk. The agent cannot mark its own work complete, and the extension blocks hand-edits to
|
|
15
|
+
`currentPhase` while the gate is failing.
|
|
16
|
+
|
|
17
|
+
**Cost.** Gates must be cheap enough to run every iteration, and must never fail for a reason the
|
|
18
|
+
agent cannot fix — a gate that deadlocks the loop is worse than no gate. Hence advisory checks:
|
|
19
|
+
an unconfigured lint command is reported, not enforced.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Phases move forward, one step at a time
|
|
24
|
+
|
|
25
|
+
**Decision.** `isValidTransition` permits only the next enabled phase, or re-running the current one.
|
|
26
|
+
Backward movement exists only as an explicit, budgeted rework that records why it happened.
|
|
27
|
+
|
|
28
|
+
**Why.** It removes a decision the model is bad at. Without it, a struggling agent reorders the
|
|
29
|
+
pipeline to reach a phase whose gate it can pass.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 3. The plan is submitted whole; omission means deletion
|
|
34
|
+
|
|
35
|
+
**Decision.** `infinity_plan` takes the complete task list, not a patch.
|
|
36
|
+
|
|
37
|
+
**Why.** Incremental edits require the model to track what exists. Over hours it stops being able to:
|
|
38
|
+
it re-adds deleted tasks, forgets others, and the file diverges from reality. A full submission is
|
|
39
|
+
self-correcting, and one unambiguous rule beats a set of merge semantics nobody can predict.
|
|
40
|
+
|
|
41
|
+
**Cost.** Every write carries the whole plan. Capped at 200 tasks, which is far beyond a sensible
|
|
42
|
+
sprint.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 4. `baseRevision` is not a compare-and-swap
|
|
47
|
+
|
|
48
|
+
**Context.** The original write did read → check `baseRevision` → write, with no mutual exclusion,
|
|
49
|
+
and the docs claimed this protected parallel workers. It does not. Two processes that both read
|
|
50
|
+
revision N both pass the check and both write N+1. Measured: 2 lost updates in a 6-way fan-out.
|
|
51
|
+
|
|
52
|
+
**Decision.** `writeTaskList` holds an exclusive lock across the whole read-apply-write and fails
|
|
53
|
+
closed — a write that cannot take the lock is refused, not raced.
|
|
54
|
+
|
|
55
|
+
**Cost.** Plan writes serialise. The critical section is milliseconds, so this is not felt; a
|
|
56
|
+
`LockTimeoutError` is retryable and names the stuck lock.
|
|
57
|
+
|
|
58
|
+
**Also.** The sync lock uses `<path>.ilock`. `proper-lockfile` owns `<path>.lock` and it is a
|
|
59
|
+
directory there too, so sharing the name made a nested async+sync lock deadlock against itself.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 5. One implementation, in `src/`
|
|
64
|
+
|
|
65
|
+
**Context.** The extension carried inlined copies of the plan engine and the widget. The tests
|
|
66
|
+
exercised `src/`; the shipped code path never called it. The two drifted, and the drift was
|
|
67
|
+
invisible because the suite was green. The same pattern later reappeared in `rework.ts` and
|
|
68
|
+
`replan.ts`, which kept private plan loaders — and one of them mishandled status aliases, rejecting
|
|
69
|
+
every amendment to a plan that used `"done"`.
|
|
70
|
+
|
|
71
|
+
**Decision.** `src/` is the single implementation. The extension owns pi's lifecycle and nothing
|
|
72
|
+
else. A private `loadFeatureList` is a bug, not a shortcut.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 6. Knowing when to stop is the product
|
|
77
|
+
|
|
78
|
+
**Decision.** The loop halts on no-progress, wall clock, iteration count, retry budgets, or a human
|
|
79
|
+
brake — and every stop names its reason.
|
|
80
|
+
|
|
81
|
+
**Why.** Continuing is trivial. The default failure mode of an autonomous loop with a weak model is
|
|
82
|
+
re-running a failing gate against an unchanged tree until the budget is gone. The no-progress
|
|
83
|
+
detector compares a fingerprint of the working tree and the plan; the first failing iteration is a
|
|
84
|
+
baseline and never counts as a stall.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 7. Ship vendor-neutral defaults
|
|
89
|
+
|
|
90
|
+
**Context.** The router shipped enabled, with one third-party vendor's model ids hardcoded in every
|
|
91
|
+
slot.
|
|
92
|
+
|
|
93
|
+
**Decision.** Routing is disabled by default and every slot is empty, meaning "use whatever model pi
|
|
94
|
+
is already configured with". Installing an extension must never silently redirect someone's work to
|
|
95
|
+
a model they did not choose.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 8. The dashboard cannot perturb the run
|
|
100
|
+
|
|
101
|
+
**Decision.** Read-only, loopback-only, and it does not run the gate — it reports the last recorded
|
|
102
|
+
verdict instead.
|
|
103
|
+
|
|
104
|
+
**Why.** Running lint and the test suite because someone opened a web page is a surprising and
|
|
105
|
+
expensive side effect. And a page rendering model output on a public interface leaks the project;
|
|
106
|
+
binding elsewhere requires an explicit opt-in, and the CSP is tight enough that an escaping slip
|
|
107
|
+
cannot become script execution.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Domain Glossary
|
|
2
|
+
|
|
3
|
+
<!-- The project's ubiquitous language. One concept, one name — everywhere:
|
|
4
|
+
spec, code, tests, docs. Add terms the moment they're resolved (see
|
|
5
|
+
harness/skills/domain-modeling.md). Glossary ONLY — no implementation
|
|
6
|
+
details, no scratch notes. -->
|
|
7
|
+
|
|
8
|
+
## Terms
|
|
9
|
+
|
|
10
|
+
### ExampleTerm
|
|
11
|
+
<!-- Definition. What it IS, what it is NOT, and which nearby concept it
|
|
12
|
+
must not be confused with. Delete this example when adding the first
|
|
13
|
+
real term. -->
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Evaluator Role
|
|
2
|
+
|
|
3
|
+
Tone: Skeptical and thorough. Accept only compelling evidence.
|
|
4
|
+
|
|
5
|
+
You verify. You gate. You are the final authority.
|
|
6
|
+
|
|
7
|
+
- Do NOT trust "seems right" — require proof
|
|
8
|
+
- Run the verification commands yourself
|
|
9
|
+
- If criteria are ambiguous, reject with specific reason
|
|
10
|
+
- "Pass" means all checks pass; "Fail" means at least one check is insufficient
|
|
11
|
+
- In DEFINE: review sprint-contract.md for clarity and testability
|
|
12
|
+
- In REVIEW: check all phase gates, branch alignment, changelog
|
|
13
|
+
- Use `evaluator-rubric.md` to score quality across 6 dimensions
|
|
14
|
+
- Gate failures escalate to human after max retries
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Generator Role
|
|
2
|
+
|
|
3
|
+
Tone: Focused and practical. Build what's specified.
|
|
4
|
+
|
|
5
|
+
You implement. You produce artifacts. You self-check.
|
|
6
|
+
|
|
7
|
+
- Build exactly what the Planner specified
|
|
8
|
+
- Do not add scope or "future-proof"
|
|
9
|
+
- Run lint + tests before handoff
|
|
10
|
+
- In BUILD: implement ONE task at a time, then validate
|
|
11
|
+
- In VERIFY: run the full test suite
|
|
12
|
+
- In SIMPLIFY: adopt the Simplifier persona (see simplifier.md)
|
|
13
|
+
- When done: call `the infinity_validate tool`
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Planner Role
|
|
2
|
+
|
|
3
|
+
Tone: Analytical and precise. Define clear boundaries.
|
|
4
|
+
|
|
5
|
+
You design the approach. You write criteria. You set scope.
|
|
6
|
+
|
|
7
|
+
- Propose what to build in sprint-contract.md
|
|
8
|
+
- Define unambiguous acceptance criteria
|
|
9
|
+
- Set exclusions explicitly ("We will NOT build X")
|
|
10
|
+
- Hand off to Generator when criteria are clear
|
|
11
|
+
- In DEFINE: interview the user, write PRD in specs/*.md
|
|
12
|
+
- In PLAN: decompose features into tasks in harness/features/feature-list.json
|
|
13
|
+
- Review gate criteria with Evaluator before proceeding
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Simplifier (Generator Persona for SIMPLIFY Phase)
|
|
2
|
+
|
|
3
|
+
Tone: Relentless about clarity. Delete more than you add.
|
|
4
|
+
|
|
5
|
+
You refactor. You clean. You never change behavior.
|
|
6
|
+
|
|
7
|
+
- Flatten nesting — max 4 levels
|
|
8
|
+
- Remove dead code and commented-out blocks
|
|
9
|
+
- Extract repeated logic into shared functions
|
|
10
|
+
- Break long functions (~40 line threshold)
|
|
11
|
+
- Rename unclear variables
|
|
12
|
+
- ⚠ All tests must still pass after your changes
|
|
13
|
+
- Run `the infinity_validate tool` after each feature to confirm gate
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# API Patterns
|
|
2
|
+
|
|
3
|
+
## Conventions
|
|
4
|
+
|
|
5
|
+
<!-- Document API conventions: URL structure, auth, error format, pagination -->
|
|
6
|
+
|
|
7
|
+
## Endpoints
|
|
8
|
+
|
|
9
|
+
| Method | Path | Description |
|
|
10
|
+
|--------|------|-------------|
|
|
11
|
+
| GET | /api/v1/... | ... |
|
|
12
|
+
| POST | /api/v1/... | ... |
|
|
13
|
+
|
|
14
|
+
## Error Format
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"error": {
|
|
19
|
+
"code": "ERROR_CODE",
|
|
20
|
+
"message": "Human-readable description"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# BUILD Phase
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Implement each feature task-by-task. The task loop iterates features and tasks,
|
|
5
|
+
producing instructions for each. Validate after each task before advancing.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
- PLAN phase complete (feature list + sprint contract exist)
|
|
9
|
+
- Ready to write code
|
|
10
|
+
|
|
11
|
+
## Craft Skills (read before working)
|
|
12
|
+
- `harness/skills/tdd.md` — red → green loop; what makes a test worth keeping
|
|
13
|
+
- `harness/skills/prototype.md` — when a design question can't be answered on paper
|
|
14
|
+
- `harness/skills/diagnosing-bugs.md` — when something breaks mid-build
|
|
15
|
+
|
|
16
|
+
## Process
|
|
17
|
+
1. Read `harness/progress.md`, `AGENTS.md`, and `harness/features/feature-list.json`
|
|
18
|
+
2. Run `the infinity_brief tool` to get the current task brief (feature, task, criteria)
|
|
19
|
+
3. For each incomplete feature → for each pending task:
|
|
20
|
+
a. Implement the task **test-first** (see `harness/skills/tdd.md`): failing
|
|
21
|
+
test → minimal code to pass → next slice
|
|
22
|
+
b. Run `the infinity_validate tool --feature <id> --task <id>` to validate
|
|
23
|
+
c. If PASS → task marked complete, advance to next task
|
|
24
|
+
d. If FAIL → fix issues, re-validate (retry up to `retry.tasks.maxRetries`)
|
|
25
|
+
4. When all tasks in a feature pass → feature marked complete
|
|
26
|
+
5. When all features pass → phase gate passes
|
|
27
|
+
6. Run `the infinity_advance tool` to advance to VERIFY
|
|
28
|
+
|
|
29
|
+
## Rationalizations to Avoid
|
|
30
|
+
| Excuse | Rebuttal |
|
|
31
|
+
|--------|----------|
|
|
32
|
+
| "I'll validate at the end" | Late validation catches problems when they're expensive to fix |
|
|
33
|
+
| "This task is trivial, skip validation" | Trivial tasks still have edge cases |
|
|
34
|
+
| "The tests pass, so it works" | Tests must cover acceptance criteria, not just happy path |
|
|
35
|
+
|
|
36
|
+
## Red Flags
|
|
37
|
+
- Tasks marked complete without validation
|
|
38
|
+
- Features with all tasks complete but `passes: false` — run validate
|
|
39
|
+
- Tests that only test the implementation, not the behavior
|
|
40
|
+
|
|
41
|
+
## Verification
|
|
42
|
+
- [ ] Each task validated with `the infinity_validate tool --feature X --task Y`
|
|
43
|
+
- [ ] All features marked `passes: true` in feature-list.json
|
|
44
|
+
- [ ] `the infinity_validate tool` passes (full phase gates)
|
|
45
|
+
|
|
46
|
+
## Handoff
|
|
47
|
+
On gate pass: `the infinity_advance tool` (Generator → Evaluator for VERIFY)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# DEFINE Phase
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Interview the user, capture intent, and write a bounded PRD. The output is a
|
|
5
|
+
short, unambiguous specification that the PLAN phase can decompose into a
|
|
6
|
+
feature list.
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
- Pipeline is at DEFINE phase (first phase after INIT)
|
|
10
|
+
- No `specs/prd.md` exists yet
|
|
11
|
+
- User needs to define what to build before planning how
|
|
12
|
+
|
|
13
|
+
## Craft Skills (read before working)
|
|
14
|
+
- `harness/skills/grilling.md` — stress-test the spec with relentless questions before committing to it
|
|
15
|
+
- `harness/skills/domain-modeling.md` — pin down domain terms in `harness/docs/DOMAIN.md`
|
|
16
|
+
- `harness/skills/research.md` — answer blocking factual questions from primary sources
|
|
17
|
+
|
|
18
|
+
## Process
|
|
19
|
+
1. Read `harness/progress.md` and `AGENTS.md` for context
|
|
20
|
+
2. Interview the user to surface objectives, constraints, and exclusions
|
|
21
|
+
(follow `harness/skills/grilling.md`; in autopilot, self-grill and record
|
|
22
|
+
the Q&A in the PRD)
|
|
23
|
+
3. **If stack is custom/unknown**, fill `stackMeta` in `harness/config.json`:
|
|
24
|
+
- `testCmd`, `lintCmd`, `buildCmd`, `installCmd`, `coverageCmd`, `configFile`, `extensions`
|
|
25
|
+
4. **Define project folder structure** — agree on directory layout:
|
|
26
|
+
- `src/` for source, `tests/` for tests, `docs/` for docs, `scripts/` for automation
|
|
27
|
+
- No source files in project root
|
|
28
|
+
5. Write `specs/prd.md` — scope, success criteria, non-goals
|
|
29
|
+
6. Keep the PRD bounded: no vague verbs ("improve", "enhance")
|
|
30
|
+
7. **Negotiate the sprint contract** (the DEFINE gate requires it agreed):
|
|
31
|
+
- `infinity-harness contract propose --scope "..." --criteria "tests pass|feature X works"`
|
|
32
|
+
- `infinity-harness contract review --agreed` (put on the evaluator hat: would
|
|
33
|
+
these criteria really prove the sprint worked?)
|
|
34
|
+
8. **Create a feature branch**: `git checkout -b feature/<short-slug>` (the
|
|
35
|
+
gate rejects work on main/master)
|
|
36
|
+
9. Run `the infinity_validate tool` to check gates
|
|
37
|
+
10. If PASS → `the infinity_advance tool` to advance to PLAN
|
|
38
|
+
|
|
39
|
+
## Rationalizations to Avoid
|
|
40
|
+
| Excuse | Rebuttal |
|
|
41
|
+
|--------|----------|
|
|
42
|
+
| "The spec is obvious, let's just build" | Without a PRD, scope creeps and features drift |
|
|
43
|
+
| "I'll define it as I go" | Ambiguity compounds — define boundaries upfront |
|
|
44
|
+
|
|
45
|
+
## Red Flags
|
|
46
|
+
- PRD longer than 2 pages — scope is too broad
|
|
47
|
+
- Vague success criteria ("works well", "fast enough")
|
|
48
|
+
- No non-goals section — everything is in scope
|
|
49
|
+
|
|
50
|
+
## Verification
|
|
51
|
+
- [ ] `specs/prd.md` exists with scope, success criteria, non-goals
|
|
52
|
+
- [ ] Sprint contract agreed with non-placeholder verification criteria
|
|
53
|
+
- [ ] On a feature branch (not main/master)
|
|
54
|
+
- [ ] Folder structure agreed and documented
|
|
55
|
+
- [ ] `the infinity_validate tool` passes
|
|
56
|
+
|
|
57
|
+
## Handoff
|
|
58
|
+
On gate pass: `the infinity_advance tool` (Planner → continues as Planner for PLAN)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# PLAN Phase
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Decompose the PRD into a feature list with bounded tasks. Each feature becomes
|
|
5
|
+
a unit of work that BUILD can implement and VERIFY can validate independently.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
- DEFINE phase complete (PRD exists)
|
|
9
|
+
- Need to break PRD into implementable features and tasks
|
|
10
|
+
|
|
11
|
+
## Craft Skills (read before working)
|
|
12
|
+
- `harness/skills/planning-tasks.md` — tracer-bullet vertical slices + the feature-list format
|
|
13
|
+
- `harness/skills/codebase-design.md` — shape features around deep modules with small interfaces
|
|
14
|
+
|
|
15
|
+
## Process
|
|
16
|
+
1. Read `harness/progress.md`, `AGENTS.md`, and `specs/prd.md`
|
|
17
|
+
2. Decompose the PRD into features — each a **vertical slice** that is
|
|
18
|
+
demoable on its own (see `harness/skills/planning-tasks.md`)
|
|
19
|
+
3. For each feature, define tasks — each a single, testable change sized to
|
|
20
|
+
one working session
|
|
21
|
+
4. Write `harness/features/feature-list.json`. Every task needs
|
|
22
|
+
`acceptanceCriteria` (1–3 concrete, checkable statements); every feature
|
|
23
|
+
needs `definitionOfDone` (user-visible outcomes). Gates reject
|
|
24
|
+
placeholders.
|
|
25
|
+
5. Commit the plan (`git commit -am "plan: feature list"`)
|
|
26
|
+
6. Run `the infinity_validate tool` to check gates
|
|
27
|
+
7. If PASS → `the infinity_advance tool` to advance to BUILD
|
|
28
|
+
|
|
29
|
+
> The sprint contract was agreed in DEFINE. If PLAN reveals the scope was
|
|
30
|
+
> wrong, renegotiate it now (`contract propose` → `contract review`) — not
|
|
31
|
+
> silently during BUILD.
|
|
32
|
+
|
|
33
|
+
## Rationalizations to Avoid
|
|
34
|
+
| Excuse | Rebuttal |
|
|
35
|
+
|--------|----------|
|
|
36
|
+
| "Tasks are obvious from the PRD" | Undecomposed tasks lead to incomplete implementations |
|
|
37
|
+
| "I'll plan during build" | Context switching kills momentum — plan first |
|
|
38
|
+
|
|
39
|
+
## Red Flags
|
|
40
|
+
- Features with more than 7 tasks — too coarse, decompose further
|
|
41
|
+
- Tasks with vague descriptions ("handle edge cases") — specify what
|
|
42
|
+
- No sprint contract — no agreement on scope
|
|
43
|
+
|
|
44
|
+
## Verification
|
|
45
|
+
- [ ] `feature-list.json` exists with features and tasks
|
|
46
|
+
- [ ] Sprint contract proposed and agreed
|
|
47
|
+
- [ ] `the infinity_validate tool` passes
|
|
48
|
+
|
|
49
|
+
## Handoff
|
|
50
|
+
On gate pass: `the infinity_advance tool` (Planner → Generator for BUILD)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# REVIEW Phase
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Final quality gate before shipping. The Evaluator reviews the complete codebase
|
|
5
|
+
against the evaluator rubric, checks documentation, and ensures the branch is
|
|
6
|
+
up-to-date with upstream.
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
- BUILD/VERIFY/SIMPLIFY phases complete
|
|
10
|
+
- Ready for final quality review before release
|
|
11
|
+
|
|
12
|
+
## Craft Skills (read before working)
|
|
13
|
+
- `harness/skills/code-review.md` — two-axis review: spec fidelity + standards/smells
|
|
14
|
+
|
|
15
|
+
## Process
|
|
16
|
+
1. Read `harness/progress.md`, `AGENTS.md`, and `harness/evaluator-rubric.md`
|
|
17
|
+
2. Run `the infinity_status command` to see current state
|
|
18
|
+
3. Run the two-axis review from `harness/skills/code-review.md`:
|
|
19
|
+
spec axis (against `specs/prd.md` + sprint contract + acceptance criteria)
|
|
20
|
+
and standards axis (repo conventions + smell baseline). Fix what's real.
|
|
21
|
+
4. Review codebase against evaluator rubric (6 dimensions, 0-2 each):
|
|
22
|
+
- Architecture, test coverage, code quality, documentation, performance, security
|
|
23
|
+
5. Check documentation: README.md, CHANGELOG.md, architecture docs
|
|
24
|
+
6. Ensure branch is up-to-date: `git push` if needed
|
|
25
|
+
7. Run `the infinity_validate tool` to check gates
|
|
26
|
+
8. If PASS → `the infinity_advance tool` to advance to SHIP
|
|
27
|
+
|
|
28
|
+
## Rationalizations to Avoid
|
|
29
|
+
| Excuse | Rebuttal |
|
|
30
|
+
|--------|----------|
|
|
31
|
+
| "Build and verify already checked quality" | Review is holistic — catches cross-cutting issues |
|
|
32
|
+
| "Documentation can be added post-ship" | Docs shipped late are docs shipped never |
|
|
33
|
+
| "The rubric is too strict" | The rubric encodes minimum quality — meet it |
|
|
34
|
+
|
|
35
|
+
## Red Flags
|
|
36
|
+
- Rubric score below 8/12 — quality is marginal
|
|
37
|
+
- Missing README, CHANGELOG, or architecture docs
|
|
38
|
+
- Branch behind upstream — merge before shipping
|
|
39
|
+
|
|
40
|
+
## Verification
|
|
41
|
+
- [ ] Evaluator rubric score >= 8/12
|
|
42
|
+
- [ ] README.md, CHANGELOG.md exist and are current
|
|
43
|
+
- [ ] Branch up-to-date with upstream
|
|
44
|
+
- [ ] `the infinity_validate tool` passes
|
|
45
|
+
|
|
46
|
+
## Handoff
|
|
47
|
+
On gate pass: `the infinity_advance tool` (Evaluator → Generator for SHIP)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# SHIP Phase
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Prepare and execute the release. Tag the version, finalize changelog, verify
|
|
5
|
+
clean working tree, and ensure all ship gates pass.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
- REVIEW phase complete
|
|
9
|
+
- Ready to release
|
|
10
|
+
|
|
11
|
+
## Process
|
|
12
|
+
1. Read `harness/progress.md` and `AGENTS.md`
|
|
13
|
+
2. Run `the infinity_status command` to see current state
|
|
14
|
+
3. Finalize `CHANGELOG.md` with version, date, and changes
|
|
15
|
+
4. Verify working tree is clean: `git status`
|
|
16
|
+
5. Create version tag: `git tag v<version>`
|
|
17
|
+
6. Ensure LICENSE, CONTRIBUTING.md exist
|
|
18
|
+
7. Run `the infinity_validate tool` to check ship gates
|
|
19
|
+
8. If PASS → `the infinity_advance tool` (pipeline complete!)
|
|
20
|
+
9. Create checkpoint: `infinity-harness checkpoint create release-<version>`
|
|
21
|
+
|
|
22
|
+
## Rationalizations to Avoid
|
|
23
|
+
| Excuse | Rebuttal |
|
|
24
|
+
|--------|----------|
|
|
25
|
+
| "I'll tag after deploying" | Tag before deploying — you want a known-good rollback point |
|
|
26
|
+
| "CHANGELOG can wait" | Users need to know what changed — write it now |
|
|
27
|
+
| "Working tree has minor changes" | Ship from clean tree only — commit or stash first |
|
|
28
|
+
|
|
29
|
+
## Red Flags
|
|
30
|
+
- Uncommitted changes in working tree
|
|
31
|
+
- No version tag created
|
|
32
|
+
- CHANGELOG.md missing or empty
|
|
33
|
+
- LICENSE or CONTRIBUTING.md missing
|
|
34
|
+
|
|
35
|
+
## Verification
|
|
36
|
+
- [ ] Working tree clean: `git status` shows no changes
|
|
37
|
+
- [ ] Version tag created: `git tag -l "v*"`
|
|
38
|
+
- [ ] CHANGELOG.md updated with version + changes
|
|
39
|
+
- [ ] README.md, LICENSE, CONTRIBUTING.md exist
|
|
40
|
+
- [ ] `the infinity_validate tool` passes
|
|
41
|
+
|
|
42
|
+
## Handoff
|
|
43
|
+
On gate pass: Pipeline complete! `the infinity_status command` shows "Pipeline complete".
|