infinity-harness 2.0.0 → 2.0.2
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 +95 -4
- package/README.md +30 -3
- package/harness/docs/ARCHITECTURE.md +1 -1
- package/harness/docs/agents/generator.md +1 -1
- package/harness/docs/agents/simplifier.md +1 -1
- package/harness/docs/phases/build.md +6 -6
- package/harness/docs/phases/define.md +4 -4
- package/harness/docs/phases/plan.md +4 -4
- package/harness/docs/phases/review.md +5 -5
- package/harness/docs/phases/ship.md +5 -5
- package/harness/docs/phases/simplify.md +6 -6
- package/harness/docs/phases/verify.md +6 -6
- package/harness/docs/skills.md +89 -0
- package/harness/skills/auth-security.md +1 -0
- package/harness/skills/building-tools.md +35 -39
- package/harness/skills/capability-acquisition.md +51 -48
- package/harness/skills/cli-design.md +3 -3
- package/harness/skills/code-review.md +1 -0
- package/harness/skills/codebase-design.md +1 -0
- package/harness/skills/concurrency-async.md +1 -0
- package/harness/skills/config-and-secrets.md +1 -0
- package/harness/skills/context-hygiene.md +1 -0
- package/harness/skills/databases.md +1 -0
- package/harness/skills/diagnosing-bugs.md +1 -0
- package/harness/skills/domain-modeling.md +1 -0
- package/harness/skills/error-handling-logging.md +1 -0
- package/harness/skills/frontend-ui.md +1 -0
- package/harness/skills/grilling.md +1 -0
- package/harness/skills/http-apis.md +1 -0
- package/harness/skills/performance.md +1 -0
- package/harness/skills/pi-todo-adapted.md +1 -0
- package/harness/skills/planning-tasks.md +1 -0
- package/harness/skills/prototype.md +2 -1
- package/harness/skills/research.md +1 -0
- package/harness/skills/resolving-merge-conflicts.md +2 -1
- package/harness/skills/scope-discipline.md +1 -0
- package/harness/skills/self-review.md +1 -0
- package/harness/skills/stuck-protocol.md +2 -1
- package/harness/skills/tdd.md +1 -0
- package/harness/skills/testing-infra.md +1 -0
- package/harness/skills/writing-skills.md +2 -1
- package/package.json +1 -1
- package/src/core/brief.ts +57 -2
- package/src/core/skills.ts +386 -0
- package/src/core/skillsAudit.ts +223 -0
- package/src/core/types.ts +2 -0
- package/harness/skills/README.md +0 -60
- package/harness/skills/building-mcp-servers.md +0 -70
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,97 @@ All notable changes to this project are documented here.
|
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.0.2] — 2026-08-23
|
|
8
|
+
|
|
9
|
+
Everything here is one bug: the package told people to run commands it does not have. 2.0.1 fixed
|
|
10
|
+
some of them; this fixes the rest, and adds the test that makes the whole class impossible.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Every brief ended by telling the model to run a command that does not exist.** The last thing
|
|
15
|
+
each brief said was `2. Run: harness validate` — a CLI that stopped existing when it was ported
|
|
16
|
+
into `src/`. The brief is injected at session start and after every phase change; the model read
|
|
17
|
+
that instruction, ran it, and got "command not found" every single turn. It now names the
|
|
18
|
+
`infinity_validate` tool, and `/infinity:validate` for the human.
|
|
19
|
+
- **Three phase docs referenced `infinity_status`, which is not a tool.** It is `/infinity:status`.
|
|
20
|
+
- **36 mechanical-rename artefacts across 11 shipped documents** — "Run `the infinity_validate tool`"
|
|
21
|
+
and friends, in the phase and role docs the brief points the agent at every phase.
|
|
22
|
+
- **`capability-acquisition.md` did not actually get rewritten in 2.0.1.** A `git rm` earlier in the
|
|
23
|
+
same command failed, `&&` short-circuited, and the heredoc that was supposed to replace the file
|
|
24
|
+
never ran — so 2.0.1 shipped the old text, still pointing at `infinity-harness capability add …`
|
|
25
|
+
and at MCP servers pi cannot use. Rewritten, and verified this time.
|
|
26
|
+
- **`cli-design.md` used `infinity-harness init` as its example error message.**
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **`tests/surface.test.ts`** — the guard for all of it. It parses the tools and commands the
|
|
31
|
+
extension actually registers, then holds every rendered brief and all 48 shipped documents to that
|
|
32
|
+
list: no `infinity_*` tool or `/infinity:*` command may be named unless it exists, nothing may
|
|
33
|
+
point at a command line this package does not have, and the rename artefact cannot come back. The
|
|
34
|
+
changelog is exempt — its job is to name what a release removed. It found four defects the moment
|
|
35
|
+
it was written.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## [2.0.1] — 2026-08-23
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- **pi printed a skill conflict on every start.** `harness/skills/README.md` was a README, and pi
|
|
44
|
+
loads *every* `.md` in a declared skills directory as a skill — so every session opened with
|
|
45
|
+
`[Skill conflicts] … description is required`. The README moved to `harness/docs/skills.md`, and
|
|
46
|
+
`tests/skills.test.ts` now audits the shipped skills against pi's own rules (frontmatter present,
|
|
47
|
+
`description` non-empty and within length, `name` lowercase-and-hyphens, matching its filename, no
|
|
48
|
+
duplicates, no UTF-8 BOM hiding the header). A warning the user saw at runtime is a failure we see
|
|
49
|
+
at test time.
|
|
50
|
+
- **Four shipped skills told the agent to run a CLI that does not exist.**
|
|
51
|
+
`capability-acquisition`, `building-tools`, `writing-skills` and the deleted MCP skill all
|
|
52
|
+
instructed the model to register capabilities with `infinity-harness capability add …` — a command
|
|
53
|
+
from the `dev-harness` ancestor that this package never had. An agent following them got stuck at
|
|
54
|
+
3am on a command not found. Rewritten around what pi actually provides: a skill file in
|
|
55
|
+
`.pi/skills/`, a script in the repo, or an extension via `pi install`.
|
|
56
|
+
|
|
57
|
+
### Removed
|
|
58
|
+
|
|
59
|
+
- **`building-mcp-servers.md`**, and every other reference to MCP. pi has no MCP client — no
|
|
60
|
+
dependency, no configuration, no code — so a skill about scaffolding MCP servers and registering
|
|
61
|
+
them could only send the agent somewhere pi cannot follow. This is a pi extension; MCP was
|
|
62
|
+
another system's answer.
|
|
63
|
+
- **`harness/capability/sources.json` and `harness/tools/`.** Neither was read by any code, neither
|
|
64
|
+
was published, and both documented the same missing CLI.
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- **The brief names the skills that match the work.** The docs claimed it did; nothing implemented
|
|
69
|
+
it. Every skill now declares a `kind` — `process` (belongs to its phase), `domain` (needs to share
|
|
70
|
+
vocabulary with the task) or `meta` (asked for explicitly) — and the brief ranks them by phase
|
|
71
|
+
position, tag hits and name mentions, showing the best two. A task about *"two workers racing on
|
|
72
|
+
the lock"* gets `concurrency-async`; a bare BUILD task gets `tdd`; a task that matches nothing gets
|
|
73
|
+
no section at all, because a padded section teaches the model to skip it.
|
|
74
|
+
- **`src/core/skills.ts`** — skill loading, header parsing and matching, resolved from the package so
|
|
75
|
+
it works in an install with no project setup.
|
|
76
|
+
- **`src/core/skillsAudit.ts`** — pi's validation rules, reproduced strictly enough that a clean
|
|
77
|
+
audit means a clean start. Also catches what pi does not: a duplicate name (pi keys skills by name,
|
|
78
|
+
so one silently ceases to exist), a mistyped phase, a missing `kind`, and a name that disagrees
|
|
79
|
+
with its filename.
|
|
80
|
+
- **A `package` E2E scenario** — `npm pack`, extracted and inspected. Every bug it looks for was
|
|
81
|
+
found by a user after install and by nothing in this repository: a file pi rejects, a symlink out
|
|
82
|
+
of the tree, a module the extension imports that npm did not publish, a UTF-8 BOM. The repo working
|
|
83
|
+
tree is not the product; the tarball is.
|
|
84
|
+
- **A reachability guard.** "The tested code was not the shipped code" was this project's worst bug.
|
|
85
|
+
The `package` scenario now also walks every import from the extension entry point and fails on any
|
|
86
|
+
*new* module that ships without a path to it. Nine modules are unreachable today — `worker`,
|
|
87
|
+
`unstuck`, `review`, `rework`, `replan`, the three `goal*` modules and the audit itself — and they
|
|
88
|
+
are named in the test with the reason, so the debt is visible and cannot grow quietly.
|
|
89
|
+
|
|
90
|
+
### Changed
|
|
91
|
+
|
|
92
|
+
- `prototype` now leads with PLAN rather than BUILD — it answers a design question before you commit
|
|
93
|
+
to one, and the phase a skill leads with is what decides its rank.
|
|
94
|
+
- Tag matching tolerates plurals, so a task about "two workers" matches the `worker` tag.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
7
98
|
## [2.0.0] — 2026-08-23
|
|
8
99
|
|
|
9
100
|
Renamed from `pi-harness` to **infinity-harness**, and rebuilt from a working prototype into
|
|
@@ -13,10 +104,10 @@ changed, and the extension no longer depends on an external repository.
|
|
|
13
104
|
### Breaking
|
|
14
105
|
|
|
15
106
|
- **Package renamed** `pi-harness` → `infinity-harness`.
|
|
16
|
-
- **Tools renamed.** `harness_task_list` → `infinity_plan`, `
|
|
17
|
-
`
|
|
18
|
-
|
|
19
|
-
`
|
|
107
|
+
- **Tools renamed.** `harness_task_list` → `infinity_plan`, `pi_harness_remote`/`harness_remote` →
|
|
108
|
+
`infinity_dashboard`. New: `infinity_brief`, `infinity_validate`, `infinity_advance`. The goal-loop
|
|
109
|
+
and worker-spawn tools were not carried over — their modules ship but nothing registers them (see
|
|
110
|
+
the reachability guard in the `package` E2E scenario).
|
|
20
111
|
- **Commands renamed** to the `/infinity:*` namespace, and `/infinity:run` / `/infinity:halt` added.
|
|
21
112
|
- **The `cli`, `prompts` and `skills` symlinks are gone.** They pointed at absolute paths inside a
|
|
22
113
|
sibling `dev-harness` checkout, which made the package impossible to install anywhere else. The
|
package/README.md
CHANGED
|
@@ -186,6 +186,32 @@ verdict. It refreshes itself every 5 seconds and reconnects with backoff if the
|
|
|
186
186
|
The dashboard is strictly read-only and binds to `127.0.0.1`. It never writes, and never bumps
|
|
187
187
|
`baseRevision` — opening it can't perturb the run you're watching.
|
|
188
188
|
|
|
189
|
+
## Craft skills
|
|
190
|
+
|
|
191
|
+
28 short documents on how to do the work well — how to write a test worth
|
|
192
|
+
keeping, how to debug something intermittent, how to design a module boundary.
|
|
193
|
+
They ship with the package, so pi loads them wherever it's installed and the
|
|
194
|
+
model can invoke any of them by name.
|
|
195
|
+
|
|
196
|
+
A model with 28 skills available and no idea which one applies reads none of
|
|
197
|
+
them, so **the brief names the ones that match the work in hand**. Each skill
|
|
198
|
+
declares what it's for:
|
|
199
|
+
|
|
200
|
+
```yaml
|
|
201
|
+
kind: domain # process | domain | meta
|
|
202
|
+
phases: [plan, build, verify] # the phase it leads counts most
|
|
203
|
+
tags: [concurrency, race, lock, mutex, deadlock] # vocabulary a task would use
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
A `process` skill belongs to its phase — TDD is the right answer for a BUILD
|
|
207
|
+
task whatever the task says. A `domain` skill has to share vocabulary with the
|
|
208
|
+
task: nobody needs the database skill because they happen to be in BUILD. So a
|
|
209
|
+
task called *"serialise plan writes so two workers can't race on the lock"*
|
|
210
|
+
gets `concurrency-async`, and a bare BUILD task gets `tdd`.
|
|
211
|
+
|
|
212
|
+
When nothing matches, the brief has no skills section. An empty section is
|
|
213
|
+
honest; a padded one teaches the model to skip it.
|
|
214
|
+
|
|
189
215
|
## Model routing (optional)
|
|
190
216
|
|
|
191
217
|
Send cheap tasks to a small model and hard ones to a large one. Pick them with `/infinity:config` →
|
|
@@ -229,6 +255,7 @@ infinity-harness/
|
|
|
229
255
|
├── src/
|
|
230
256
|
│ ├── core/ types · paths · fsx · config · phases · gates · brief
|
|
231
257
|
│ │ · featureList (the SSOT) · lock · exec
|
|
258
|
+
│ │ · skills (match) · skillsAudit (guard)
|
|
232
259
|
│ ├── ui/ theme · widget (terminal) · dashboard (web)
|
|
233
260
|
│ ├── loop.ts the continuous-run driver and its stop conditions
|
|
234
261
|
│ ├── taskList.ts atomic plan editor
|
|
@@ -242,8 +269,8 @@ infinity-harness/
|
|
|
242
269
|
│ ├── config.json pipeline state and settings
|
|
243
270
|
│ ├── model-router.json optional routing
|
|
244
271
|
│ ├── docs/ architecture · decisions · phase and role docs
|
|
245
|
-
│ └── skills/
|
|
246
|
-
├── tests/
|
|
272
|
+
│ └── skills/ 28 craft skills the brief points at
|
|
273
|
+
├── tests/ 23 files, plain node:assert
|
|
247
274
|
└── scripts/run-tests.mjs
|
|
248
275
|
```
|
|
249
276
|
|
|
@@ -255,7 +282,7 @@ there is one implementation, and the adapter calls it.
|
|
|
255
282
|
```bash
|
|
256
283
|
npm install
|
|
257
284
|
npm run check # tsc --noEmit
|
|
258
|
-
npm test #
|
|
285
|
+
npm test # 23 test files
|
|
259
286
|
npm run e2e # end-to-end against a live model
|
|
260
287
|
```
|
|
261
288
|
|
|
@@ -153,7 +153,7 @@ Every stop carries a reason. A human coming back finds an explanation, not a mys
|
|
|
153
153
|
## Verification
|
|
154
154
|
|
|
155
155
|
- `npm test` — 20 unit files, plain `node:assert`, no framework.
|
|
156
|
-
- `npm run e2e` —
|
|
156
|
+
- `npm run e2e` — 12 scenarios over real temp projects, real git repos, real child processes: the
|
|
157
157
|
full pipeline walkthrough, loop convergence, every stop condition, SIGKILL-and-restart, a 6-way
|
|
158
158
|
concurrent write fan-out with an unlocked control, data round-trip, the dashboard, widget
|
|
159
159
|
rendering across shapes, adversarial input, and the extension adapter itself.
|
|
@@ -10,4 +10,4 @@ You implement. You produce artifacts. You self-check.
|
|
|
10
10
|
- In BUILD: implement ONE task at a time, then validate
|
|
11
11
|
- In VERIFY: run the full test suite
|
|
12
12
|
- In SIMPLIFY: adopt the Simplifier persona (see simplifier.md)
|
|
13
|
-
- When done: call `
|
|
13
|
+
- When done: call `infinity_validate`
|
|
@@ -10,4 +10,4 @@ You refactor. You clean. You never change behavior.
|
|
|
10
10
|
- Break long functions (~40 line threshold)
|
|
11
11
|
- Rename unclear variables
|
|
12
12
|
- ⚠ All tests must still pass after your changes
|
|
13
|
-
- Run `
|
|
13
|
+
- Run `infinity_validate` after each feature to confirm gate
|
|
@@ -15,16 +15,16 @@ producing instructions for each. Validate after each task before advancing.
|
|
|
15
15
|
|
|
16
16
|
## Process
|
|
17
17
|
1. Read `harness/progress.md`, `AGENTS.md`, and `harness/features/feature-list.json`
|
|
18
|
-
2. Run `
|
|
18
|
+
2. Run `infinity_brief` to get the current task brief (feature, task, criteria)
|
|
19
19
|
3. For each incomplete feature → for each pending task:
|
|
20
20
|
a. Implement the task **test-first** (see `harness/skills/tdd.md`): failing
|
|
21
21
|
test → minimal code to pass → next slice
|
|
22
|
-
b. Run `
|
|
22
|
+
b. Run `infinity_validate` with `{feature, task}` to validate
|
|
23
23
|
c. If PASS → task marked complete, advance to next task
|
|
24
24
|
d. If FAIL → fix issues, re-validate (retry up to `retry.tasks.maxRetries`)
|
|
25
25
|
4. When all tasks in a feature pass → feature marked complete
|
|
26
26
|
5. When all features pass → phase gate passes
|
|
27
|
-
6. Run `
|
|
27
|
+
6. Run `infinity_advance` to advance to VERIFY
|
|
28
28
|
|
|
29
29
|
## Rationalizations to Avoid
|
|
30
30
|
| Excuse | Rebuttal |
|
|
@@ -39,9 +39,9 @@ producing instructions for each. Validate after each task before advancing.
|
|
|
39
39
|
- Tests that only test the implementation, not the behavior
|
|
40
40
|
|
|
41
41
|
## Verification
|
|
42
|
-
- [ ] Each task validated with `
|
|
42
|
+
- [ ] Each task validated with `infinity_validate` scoped to that feature and task
|
|
43
43
|
- [ ] All features marked `passes: true` in feature-list.json
|
|
44
|
-
- [ ] `
|
|
44
|
+
- [ ] `infinity_validate` passes (full phase gates)
|
|
45
45
|
|
|
46
46
|
## Handoff
|
|
47
|
-
On gate pass: `
|
|
47
|
+
On gate pass: `infinity_advance` (Generator → Evaluator for VERIFY)
|
|
@@ -33,8 +33,8 @@ feature list.
|
|
|
33
33
|
these criteria really prove the sprint worked?)
|
|
34
34
|
8. **Create a feature branch**: `git checkout -b feature/<short-slug>` (the
|
|
35
35
|
gate rejects work on main/master)
|
|
36
|
-
9. Run `
|
|
37
|
-
10. If PASS → `
|
|
36
|
+
9. Run `infinity_validate` to check gates
|
|
37
|
+
10. If PASS → `infinity_advance` to advance to PLAN
|
|
38
38
|
|
|
39
39
|
## Rationalizations to Avoid
|
|
40
40
|
| Excuse | Rebuttal |
|
|
@@ -52,7 +52,7 @@ feature list.
|
|
|
52
52
|
- [ ] Sprint contract agreed with non-placeholder verification criteria
|
|
53
53
|
- [ ] On a feature branch (not main/master)
|
|
54
54
|
- [ ] Folder structure agreed and documented
|
|
55
|
-
- [ ] `
|
|
55
|
+
- [ ] `infinity_validate` passes
|
|
56
56
|
|
|
57
57
|
## Handoff
|
|
58
|
-
On gate pass: `
|
|
58
|
+
On gate pass: `infinity_advance` (Planner → continues as Planner for PLAN)
|
|
@@ -23,8 +23,8 @@ a unit of work that BUILD can implement and VERIFY can validate independently.
|
|
|
23
23
|
needs `definitionOfDone` (user-visible outcomes). Gates reject
|
|
24
24
|
placeholders.
|
|
25
25
|
5. Commit the plan (`git commit -am "plan: feature list"`)
|
|
26
|
-
6. Run `
|
|
27
|
-
7. If PASS → `
|
|
26
|
+
6. Run `infinity_validate` to check gates
|
|
27
|
+
7. If PASS → `infinity_advance` to advance to BUILD
|
|
28
28
|
|
|
29
29
|
> The sprint contract was agreed in DEFINE. If PLAN reveals the scope was
|
|
30
30
|
> wrong, renegotiate it now (`contract propose` → `contract review`) — not
|
|
@@ -44,7 +44,7 @@ a unit of work that BUILD can implement and VERIFY can validate independently.
|
|
|
44
44
|
## Verification
|
|
45
45
|
- [ ] `feature-list.json` exists with features and tasks
|
|
46
46
|
- [ ] Sprint contract proposed and agreed
|
|
47
|
-
- [ ] `
|
|
47
|
+
- [ ] `infinity_validate` passes
|
|
48
48
|
|
|
49
49
|
## Handoff
|
|
50
|
-
On gate pass: `
|
|
50
|
+
On gate pass: `infinity_advance` (Planner → Generator for BUILD)
|
|
@@ -14,7 +14,7 @@ up-to-date with upstream.
|
|
|
14
14
|
|
|
15
15
|
## Process
|
|
16
16
|
1. Read `harness/progress.md`, `AGENTS.md`, and `harness/evaluator-rubric.md`
|
|
17
|
-
2. Run `
|
|
17
|
+
2. Run `/infinity:status` to see current state
|
|
18
18
|
3. Run the two-axis review from `harness/skills/code-review.md`:
|
|
19
19
|
spec axis (against `specs/prd.md` + sprint contract + acceptance criteria)
|
|
20
20
|
and standards axis (repo conventions + smell baseline). Fix what's real.
|
|
@@ -22,8 +22,8 @@ up-to-date with upstream.
|
|
|
22
22
|
- Architecture, test coverage, code quality, documentation, performance, security
|
|
23
23
|
5. Check documentation: README.md, CHANGELOG.md, architecture docs
|
|
24
24
|
6. Ensure branch is up-to-date: `git push` if needed
|
|
25
|
-
7. Run `
|
|
26
|
-
8. If PASS → `
|
|
25
|
+
7. Run `infinity_validate` to check gates
|
|
26
|
+
8. If PASS → `infinity_advance` to advance to SHIP
|
|
27
27
|
|
|
28
28
|
## Rationalizations to Avoid
|
|
29
29
|
| Excuse | Rebuttal |
|
|
@@ -41,7 +41,7 @@ up-to-date with upstream.
|
|
|
41
41
|
- [ ] Evaluator rubric score >= 8/12
|
|
42
42
|
- [ ] README.md, CHANGELOG.md exist and are current
|
|
43
43
|
- [ ] Branch up-to-date with upstream
|
|
44
|
-
- [ ] `
|
|
44
|
+
- [ ] `infinity_validate` passes
|
|
45
45
|
|
|
46
46
|
## Handoff
|
|
47
|
-
On gate pass: `
|
|
47
|
+
On gate pass: `infinity_advance` (Evaluator → Generator for SHIP)
|
|
@@ -10,13 +10,13 @@ clean working tree, and ensure all ship gates pass.
|
|
|
10
10
|
|
|
11
11
|
## Process
|
|
12
12
|
1. Read `harness/progress.md` and `AGENTS.md`
|
|
13
|
-
2. Run `
|
|
13
|
+
2. Run `/infinity:status` to see current state
|
|
14
14
|
3. Finalize `CHANGELOG.md` with version, date, and changes
|
|
15
15
|
4. Verify working tree is clean: `git status`
|
|
16
16
|
5. Create version tag: `git tag v<version>`
|
|
17
17
|
6. Ensure LICENSE, CONTRIBUTING.md exist
|
|
18
|
-
7. Run `
|
|
19
|
-
8. If PASS → `
|
|
18
|
+
7. Run `infinity_validate` to check ship gates
|
|
19
|
+
8. If PASS → `infinity_advance` (pipeline complete!)
|
|
20
20
|
9. Create checkpoint: `infinity-harness checkpoint create release-<version>`
|
|
21
21
|
|
|
22
22
|
## Rationalizations to Avoid
|
|
@@ -37,7 +37,7 @@ clean working tree, and ensure all ship gates pass.
|
|
|
37
37
|
- [ ] Version tag created: `git tag -l "v*"`
|
|
38
38
|
- [ ] CHANGELOG.md updated with version + changes
|
|
39
39
|
- [ ] README.md, LICENSE, CONTRIBUTING.md exist
|
|
40
|
-
- [ ] `
|
|
40
|
+
- [ ] `infinity_validate` passes
|
|
41
41
|
|
|
42
42
|
## Handoff
|
|
43
|
-
On gate pass: Pipeline complete! `
|
|
43
|
+
On gate pass: Pipeline complete! `/infinity:status` shows "Pipeline complete".
|
|
@@ -14,14 +14,14 @@ duplicates, flatten deep nesting, and ensure tests still pass after changes.
|
|
|
14
14
|
|
|
15
15
|
## Process
|
|
16
16
|
1. Read `harness/progress.md` and `AGENTS.md`
|
|
17
|
-
2. Run `
|
|
17
|
+
2. Run `infinity_brief` to see the current step
|
|
18
18
|
3. For each feature:
|
|
19
19
|
a. Review code for: code smells, deep nesting, DRY violations, dead code
|
|
20
20
|
b. Simplify: consolidate duplicate logic, flatten conditionals, remove unused
|
|
21
21
|
c. Run `npm test` to ensure tests still pass after simplification
|
|
22
|
-
d. Run `
|
|
23
|
-
4. When all features simplified → run `
|
|
24
|
-
5. If PASS → `
|
|
22
|
+
d. Run `infinity_validate` with `{feature, task}` per task
|
|
23
|
+
4. When all features simplified → run `infinity_validate` (full phase)
|
|
24
|
+
5. If PASS → `infinity_advance` to advance to REVIEW
|
|
25
25
|
|
|
26
26
|
## Rationalizations to Avoid
|
|
27
27
|
| Excuse | Rebuttal |
|
|
@@ -39,7 +39,7 @@ duplicates, flatten deep nesting, and ensure tests still pass after changes.
|
|
|
39
39
|
- [ ] Code smells reduced (subjective — use judgment)
|
|
40
40
|
- [ ] No new dead code introduced
|
|
41
41
|
- [ ] Tests still pass: `npm test`
|
|
42
|
-
- [ ] `
|
|
42
|
+
- [ ] `infinity_validate` passes
|
|
43
43
|
|
|
44
44
|
## Handoff
|
|
45
|
-
On gate pass: `
|
|
45
|
+
On gate pass: `infinity_advance` (Simplifier → Evaluator for REVIEW)
|
|
@@ -14,15 +14,15 @@ role runs tests, checks coverage, and validates behavior against the PRD.
|
|
|
14
14
|
|
|
15
15
|
## Process
|
|
16
16
|
1. Read `harness/progress.md`, `AGENTS.md`, and `specs/prd.md`
|
|
17
|
-
2. Run `
|
|
17
|
+
2. Run `infinity_brief` to see the current verification step
|
|
18
18
|
3. For each feature:
|
|
19
19
|
a. Run the test suite: `npm test`
|
|
20
20
|
b. Check coverage: `{{coverageCmd}}` (if coverage gate enabled)
|
|
21
21
|
c. Verify behavior matches acceptance criteria from PRD
|
|
22
|
-
d. Run `
|
|
22
|
+
d. Run `infinity_validate` with `{feature, task}` per task
|
|
23
23
|
4. If any task fails → fix and re-validate (retry)
|
|
24
|
-
5. When all features verified → run `
|
|
25
|
-
6. If PASS → `
|
|
24
|
+
5. When all features verified → run `infinity_validate` (full phase)
|
|
25
|
+
6. If PASS → `infinity_advance` to advance to SIMPLIFY or REVIEW
|
|
26
26
|
|
|
27
27
|
## Rationalizations to Avoid
|
|
28
28
|
| Excuse | Rebuttal |
|
|
@@ -40,7 +40,7 @@ role runs tests, checks coverage, and validates behavior against the PRD.
|
|
|
40
40
|
- [ ] All tests pass: `npm test`
|
|
41
41
|
- [ ] Coverage meets threshold (if gate enabled)
|
|
42
42
|
- [ ] Behavior matches PRD acceptance criteria
|
|
43
|
-
- [ ] `
|
|
43
|
+
- [ ] `infinity_validate` passes
|
|
44
44
|
|
|
45
45
|
## Handoff
|
|
46
|
-
On gate pass: `
|
|
46
|
+
On gate pass: `infinity_advance` (Evaluator → Simplifier for SIMPLIFY, or Evaluator for REVIEW)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Kept in docs/, not in harness/skills/.
|
|
3
|
+
|
|
4
|
+
pi loads every .md in a declared skills directory as a skill and requires
|
|
5
|
+
`name` and `description` frontmatter on each. A README has neither, so leaving
|
|
6
|
+
it beside the skills made pi print a skill conflict on every start.
|
|
7
|
+
`tests/skills.test.ts` now fails if anything in harness/skills/ would do that.
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
# Craft Skills
|
|
11
|
+
|
|
12
|
+
How to do the work WELL — the engineering discipline behind each pipeline
|
|
13
|
+
phase. The phase docs (`harness/docs/phases/`) say *what* to produce; these
|
|
14
|
+
skills say *how* an expert produces it.
|
|
15
|
+
|
|
16
|
+
They ship with the package, so pi loads them wherever it is installed: the
|
|
17
|
+
model can invoke any of them by name, and `/skill:<name>` lists them.
|
|
18
|
+
|
|
19
|
+
**The brief names the ones that match the work in hand.** Each skill declares
|
|
20
|
+
what it is for, so the brief can route:
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
kind: domain # process | domain | meta
|
|
24
|
+
phases: [plan, build, verify] # leading phase counts most
|
|
25
|
+
tags: [concurrency, race, lock, mutex, deadlock] # vocabulary a task would use
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- **`process`** — how to work in a phase. Belonging to the phase is enough;
|
|
29
|
+
TDD is the right answer for a BUILD task whatever the task says.
|
|
30
|
+
- **`domain`** — a subject area. Surfaces only when the task shares its
|
|
31
|
+
vocabulary. Nobody needs the database skill for being in BUILD.
|
|
32
|
+
- **`meta`** — growing the toolkit. Vocabulary only, never a phase.
|
|
33
|
+
|
|
34
|
+
Read the one the brief names before you start. Each is short, and it changes
|
|
35
|
+
what you do.
|
|
36
|
+
|
|
37
|
+
## Process skills
|
|
38
|
+
|
|
39
|
+
| Skill | Leads | One-liner |
|
|
40
|
+
|-------|-------|-----------|
|
|
41
|
+
| `grilling.md` | DEFINE | Stress-test the spec with relentless questions |
|
|
42
|
+
| `domain-modeling.md` | DEFINE | Pin down domain terms before writing code |
|
|
43
|
+
| `research.md` | DEFINE | Answer questions from primary sources only |
|
|
44
|
+
| `planning-tasks.md` | PLAN | Break specs into tracer-bullet vertical slices |
|
|
45
|
+
| `codebase-design.md` | PLAN | Design deep modules behind small interfaces |
|
|
46
|
+
| `prototype.md` | PLAN | Throwaway code that answers a design question |
|
|
47
|
+
| `tdd.md` | BUILD | Red → green loop; tests worth keeping |
|
|
48
|
+
| `self-review.md` | BUILD | The pass that runs before every validate |
|
|
49
|
+
| `diagnosing-bugs.md` | VERIFY | Build a feedback loop before hypothesising |
|
|
50
|
+
| `code-review.md` | REVIEW | Two-axis review: standards + spec |
|
|
51
|
+
| `resolving-merge-conflicts.md` | any | Resolve conflicts by original intent |
|
|
52
|
+
| `context-hygiene.md` | any | Externalise discoveries the moment they happen |
|
|
53
|
+
| `scope-discipline.md` | any | The contract is the boundary; park everything else |
|
|
54
|
+
| `stuck-protocol.md` | any | Stop thrashing, escalate cleanly |
|
|
55
|
+
|
|
56
|
+
## Domain skills
|
|
57
|
+
|
|
58
|
+
Matched by vocabulary, not by phase:
|
|
59
|
+
|
|
60
|
+
`databases` · `http-apis` · `auth-security` · `frontend-ui` ·
|
|
61
|
+
`testing-infra` · `concurrency-async` · `performance` ·
|
|
62
|
+
`error-handling-logging` · `config-and-secrets` · `cli-design` ·
|
|
63
|
+
`pi-todo-adapted`
|
|
64
|
+
|
|
65
|
+
## Meta skills
|
|
66
|
+
|
|
67
|
+
| Skill | Purpose |
|
|
68
|
+
|-------|---------|
|
|
69
|
+
| `capability-acquisition.md` | HAVE → ACQUIRE → CREATE → KEEP |
|
|
70
|
+
| `writing-skills.md` | How to author a skill worth keeping |
|
|
71
|
+
| `building-tools.md` | Standards for a project script anyone can run |
|
|
72
|
+
|
|
73
|
+
Growing the library is part of the job. A skill you write into
|
|
74
|
+
`.pi/skills/<name>.md` is loaded by pi on the next start — there is nothing to
|
|
75
|
+
register — and committing it means the next session starts one rung higher.
|
|
76
|
+
|
|
77
|
+
## Adding one here
|
|
78
|
+
|
|
79
|
+
Frontmatter is a strict subset: `key: value`, `key: [a, b]`, `key: { k: v }`.
|
|
80
|
+
No block scalars, no multi-line values. `name` must match the filename, be
|
|
81
|
+
lowercase `a-z0-9-`, and `description`, `kind` and `phases` must all be
|
|
82
|
+
present and valid — `npm test` enforces every one of those, because pi only
|
|
83
|
+
warns and it warns on every single start.
|
|
84
|
+
|
|
85
|
+
## Attribution
|
|
86
|
+
|
|
87
|
+
Skills marked "Adapted from mattpocock/skills" derive from
|
|
88
|
+
[Matt Pocock's skills repository](https://github.com/mattpocock/skills)
|
|
89
|
+
(MIT License, © 2026 Matt Pocock), adapted for the infinity-harness pipeline.
|
|
@@ -4,6 +4,7 @@ description: Authentication, authorization, secrets, and the injection/XSS/CSRF
|
|
|
4
4
|
tags: [auth, authentication, authorization, security, login, password, token, jwt, session, oauth, secret, csrf, xss, injection, permission]
|
|
5
5
|
when: task touches login, sessions, tokens, permissions, user input, or secrets
|
|
6
6
|
phases: [plan, build, verify]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -1,60 +1,56 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: building-tools
|
|
3
|
-
description: Project
|
|
4
|
-
tags: [meta, tool, script, cli, automation, executable]
|
|
5
|
-
when: a repeatable action deserves a
|
|
3
|
+
description: Project script standards — idempotent, self-documenting, non-interactive executables
|
|
4
|
+
tags: [meta, tool, script, cli, automation, executable, makefile]
|
|
5
|
+
when: a repeatable action deserves a script instead of the same shell dance twice
|
|
6
6
|
phases: []
|
|
7
|
+
kind: meta
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
# Building Tools
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
Build one when you catch yourself doing the same multi-step shell dance
|
|
14
|
+
twice. The bar is not "it worked once on my machine" — an unattended agent
|
|
15
|
+
will run this at 3am with no one watching.
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
There is nothing to register. A script in the repo, named in `AGENTS.md` or
|
|
18
|
+
`package.json`, is discoverable by the next session; a script nobody can
|
|
19
|
+
find is a script nobody runs.
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
`harness/tools/<name>.sh` (any language works — .mjs, .py; the stub is
|
|
20
|
-
bash).
|
|
21
|
-
2. Implement to the standards below.
|
|
22
|
-
3. Register:
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
infinity-harness capability add tool harness/tools/<name>.sh \
|
|
26
|
-
--run "bash harness/tools/<name>.sh" \
|
|
27
|
-
--tags db,fixtures --description "Reset local db to fixtures"
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Standards (the registration bar)
|
|
21
|
+
## Standards
|
|
31
22
|
|
|
32
23
|
- **Idempotent** — running it twice is safe and converges to the same state.
|
|
33
|
-
- **`--help` works** — prints usage
|
|
34
|
-
|
|
35
|
-
- **`--json` where output is consumed** — machine-readable when
|
|
36
|
-
|
|
37
|
-
- **Exit codes
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
24
|
+
- **`--help` works** — prints usage and purpose, exits 0. This is the first
|
|
25
|
+
thing anyone runs, human or model.
|
|
26
|
+
- **`--json` where output is consumed** — machine-readable when something
|
|
27
|
+
downstream reads the result. Humans get the summary line.
|
|
28
|
+
- **Exit codes** — `0` success · `1` the operation failed · `2` you were
|
|
29
|
+
called wrong. An agent branches on these; get them right.
|
|
30
|
+
- **Never interactive** — no prompts, no confirmations, no "are you sure".
|
|
31
|
+
Flags only.
|
|
32
|
+
- **Fail loud and specific** — errors name the thing that is wrong and the
|
|
33
|
+
likely fix, on stderr. "Error: 1" costs someone an hour.
|
|
34
|
+
- **Self-contained** — resolve paths from the project root, not the
|
|
35
|
+
caller's cwd. Check prerequisites at startup and fail with the install
|
|
36
|
+
command.
|
|
44
37
|
|
|
45
38
|
## Anti-patterns
|
|
46
39
|
|
|
47
|
-
- **The snowflake** —
|
|
48
|
-
|
|
40
|
+
- **The snowflake** — hardcoded paths, undeclared dependencies, works only
|
|
41
|
+
where it was written. Fix: check prerequisites first, fail with
|
|
49
42
|
instructions.
|
|
50
43
|
- **The chatterbox** — pages of output hiding the result. Fix: one summary
|
|
51
44
|
line by default, `--verbose` for the rest.
|
|
52
|
-
- **The mutation surprise** — destructive with no dry
|
|
53
|
-
destructive gets `--dry-run
|
|
45
|
+
- **The mutation surprise** — destructive with no dry run. Fix: anything
|
|
46
|
+
destructive gets `--dry-run`, and says what it would do.
|
|
47
|
+
- **The second source of truth** — a script that keeps its own copy of state
|
|
48
|
+
the project already stores. Fix: read the real file.
|
|
54
49
|
|
|
55
50
|
## Checklist
|
|
56
51
|
|
|
57
|
-
- [ ]
|
|
58
|
-
- [ ] `--help`
|
|
59
|
-
- [ ]
|
|
60
|
-
- [ ]
|
|
52
|
+
- [ ] Ran it twice; the second run was a no-op
|
|
53
|
+
- [ ] `--help` exits 0 and explains the purpose
|
|
54
|
+
- [ ] Exit codes are 0 / 1 / 2 and mean what they should
|
|
55
|
+
- [ ] No prompt, no confirmation, no TTY assumption
|
|
56
|
+
- [ ] Named somewhere a cold reader will find it
|