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
|
@@ -1,72 +1,75 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: capability-acquisition
|
|
3
|
-
description: The capability ladder — HAVE, ACQUIRE, CREATE, KEEP — for skills,
|
|
4
|
-
tags: [meta, capability, acquire, search, skill,
|
|
5
|
-
when: a task needs knowledge,
|
|
3
|
+
description: The capability ladder — HAVE, ACQUIRE, CREATE, KEEP — for skills, extensions and project scripts
|
|
4
|
+
tags: [meta, capability, acquire, search, skill, extension, tool, script, ladder, library]
|
|
5
|
+
when: a task needs knowledge, an integration, or an executable the project lacks
|
|
6
6
|
phases: []
|
|
7
|
+
kind: meta
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
# Capability Acquisition — The Ladder
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
The task needs something you do not have. Work the ladder in order, and leave
|
|
14
|
+
the result behind so the next task starts one rung higher.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
pi has three kinds of capability. Pick the right shape first — most wasted
|
|
17
|
+
effort here is building the wrong one.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
| You need | Build | Lives in |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| Knowledge or method — how to do X well | a **skill** | `.pi/skills/<name>.md` |
|
|
22
|
+
| A repeatable action — reset fixtures, run a codemod | a **script** | the repo, run through bash |
|
|
23
|
+
| A tool the model can call, or a slash command | an **extension** | its own package, `pi install`ed |
|
|
24
|
+
| A fact — does API X support Y? | neither | `research.md`, written into `harness/docs/` |
|
|
22
25
|
|
|
23
|
-
##
|
|
26
|
+
## 1 — HAVE: check before you build
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
the
|
|
27
|
-
|
|
28
|
+
- **Skills already loaded.** This package ships 28. The brief names the ones
|
|
29
|
+
that match the current task; `/skill:<name>` invokes any of them.
|
|
30
|
+
- **Scripts already in the repo.** `package.json` scripts, `Makefile`,
|
|
31
|
+
`scripts/`. Read before you write — the thing you are about to build is
|
|
32
|
+
often already there under a name you did not guess.
|
|
33
|
+
- **Extensions already installed.** `pi list`.
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
GitHub, crates, …). Browse-only sources are listed after — use them only
|
|
31
|
-
if you have web access.
|
|
35
|
+
## 2 — ACQUIRE: take what exists
|
|
32
36
|
|
|
33
|
-
**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
- **A skill** is plain markdown. Copy one in, then *adapt* it: trim to the
|
|
38
|
+
useful core, re-point its references at this project's surfaces, and add an
|
|
39
|
+
attribution line naming the source and its licence.
|
|
40
|
+
- **An extension**: `pi install npm:<pkg> -l` (project-local, so the team gets
|
|
41
|
+
it through `.pi/settings.json`) or `pi install git:<host>/<repo>`. Pin the
|
|
42
|
+
version, and read what it registers before you trust it.
|
|
38
43
|
|
|
39
|
-
**
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
**Choosing among candidates**, in order: actively maintained → widely used →
|
|
45
|
+
permissive licence (MIT/Apache/BSD) → small and composable. Never adopt
|
|
46
|
+
something that wants to own the whole process — the harness owns the process.
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
infinity-harness capability add skill <path> --from <url>
|
|
45
|
-
infinity-harness capability add mcp <name> --command npx --args -y,<pkg>@<exact-version> \
|
|
46
|
-
--tags ... --description "..." --trust curated
|
|
47
|
-
infinity-harness capability add tool <file> --run "..." --tags ... --description "..."
|
|
48
|
-
```
|
|
48
|
+
## 3 — CREATE: nothing usable exists
|
|
49
49
|
|
|
50
|
-
**
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
- **A skill** → write it per `writing-skills.md` into `.pi/skills/<name>.md`.
|
|
51
|
+
pi loads it on the next start. There is nothing to register.
|
|
52
|
+
- **A script** → build it per `building-tools.md`, and name it where a cold
|
|
53
|
+
reader will look (`AGENTS.md`, or `package.json` scripts).
|
|
54
|
+
- **An extension** → only when the capability has to be a tool the model calls
|
|
55
|
+
or a slash command. It is a package with a `pi.extensions` entry;
|
|
56
|
+
`pi install ./<dir> -l` loads it straight from a checkout.
|
|
53
57
|
|
|
54
|
-
##
|
|
58
|
+
## 4 — KEEP: or you will do this again
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
infinity-harness capability create skill|tool|mcp <name>
|
|
58
|
-
```
|
|
60
|
+
A capability that lives only in this session is not a capability.
|
|
59
61
|
|
|
60
|
-
- skill
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
|
|
62
|
+
- **Commit it.** A skill in `.pi/skills/` and a script in the repo both travel
|
|
63
|
+
with the project.
|
|
64
|
+
- **Make it findable.** Tags in a skill's frontmatter are how the brief
|
|
65
|
+
surfaces it later; a script nobody can find is a script nobody runs.
|
|
64
66
|
|
|
65
|
-
##
|
|
67
|
+
## 5 — Budget: never block the pipeline
|
|
66
68
|
|
|
67
|
-
Acquisition fits
|
|
69
|
+
Acquisition fits inside one working session. If it does not conclude, or you
|
|
68
70
|
have no network:
|
|
69
71
|
|
|
70
|
-
1. Record the gap
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
1. Record the gap in `harness/lessons-decisions.md` — what was needed, what
|
|
73
|
+
you tried, what you would try next.
|
|
74
|
+
2. Carry on with general best practice. A missing skill is not a blocked task,
|
|
75
|
+
and it is never a reason to mark work complete that is not.
|
|
@@ -4,6 +4,7 @@ description: Command-line tool design — argument conventions, output contracts
|
|
|
4
4
|
tags: [cli, command, terminal, flags, arguments, stdout, stdin, shell, script, tool]
|
|
5
5
|
when: task builds or extends a command-line interface
|
|
6
6
|
phases: [plan, build]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -30,9 +31,8 @@ provenance: { origin: built-in }
|
|
|
30
31
|
consistently; flags kebab-case with `--long` forms; `-` means stdin/
|
|
31
32
|
stdout where files are expected; respect `NO_COLOR` and non-TTY (no
|
|
32
33
|
spinners into pipes).
|
|
33
|
-
- **Errors say what + why + what next:** `✗ config not found:
|
|
34
|
-
|
|
35
|
-
for an expected failure.
|
|
34
|
+
- **Errors say what + why + what next:** `✗ config not found: ./app.config.json
|
|
35
|
+
— run: myapp init`. Never a bare stack trace for an expected failure.
|
|
36
36
|
- **Fast startup matters.** A CLI invoked in loops pays its startup cost
|
|
37
37
|
×N — lazy-load heavy imports per subcommand.
|
|
38
38
|
|
|
@@ -4,6 +4,7 @@ description: Two-axis review (spec fidelity + standards/smells) with the Fowler
|
|
|
4
4
|
tags: [review, quality, smell, refactor, standards, spec, diff, audit]
|
|
5
5
|
when: reviewing a diff, a branch, or the whole delivery before shipping
|
|
6
6
|
phases: [review, simplify]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Deep modules — small interfaces hiding lots of behavior, seams, t
|
|
|
4
4
|
tags: [design, architecture, module, interface, seam, refactor, coupling, abstraction, api]
|
|
5
5
|
when: designing module boundaries, planning features, refactoring for clarity
|
|
6
6
|
phases: [plan, simplify]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Concurrency and async correctness — races, idempotency, queues, c
|
|
|
4
4
|
tags: [concurrency, async, race, parallel, queue, lock, mutex, retry, idempotent, worker, thread, promise, deadlock, atomic]
|
|
5
5
|
when: task involves parallel work, background jobs, shared state, or retried operations
|
|
6
6
|
phases: [plan, build, verify]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Configuration discipline — env-driven config, validation at boot,
|
|
|
4
4
|
tags: [config, configuration, environment, env, secret, settings, deploy, dotenv, variable]
|
|
5
5
|
when: task adds configuration, environment handling, or deployment settings
|
|
6
6
|
phases: [build, ship]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Externalize state before it decays — write discoveries down, re-r
|
|
|
4
4
|
tags: [meta, context, memory, handoff, session, notes, playbook]
|
|
5
5
|
when: any long session, and always before ending one
|
|
6
6
|
phases: []
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: built-in, notes: frontier-playbook }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Relational database craft — schema design, migrations, transactio
|
|
|
4
4
|
tags: [database, db, sql, postgres, postgresql, mysql, sqlite, schema, migration, transaction, index, query, orm, persistence, storage]
|
|
5
5
|
when: task touches persistent data, schemas, queries, or migrations
|
|
6
6
|
phases: [plan, build, verify]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Feedback-loop-first debugging discipline for hard bugs and regressi
|
|
|
4
4
|
tags: [debug, debugging, bug, error, failure, crash, flaky, slow, performance, regression, bisect]
|
|
5
5
|
when: something is broken, throwing, failing intermittently, or slow
|
|
6
6
|
phases: [verify, build]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Pin down domain terminology — glossary discipline and decision re
|
|
|
4
4
|
tags: [domain, glossary, terminology, naming, model, ubiquitous, language, adr, decision]
|
|
5
5
|
when: defining specs, resolving fuzzy or conflicting terms, recording decisions
|
|
6
6
|
phases: [define, plan]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Error taxonomy, fail-loud handling, structured logging that debugs
|
|
|
4
4
|
tags: [error, exception, logging, log, observability, retry, crash, handling, monitoring, trace]
|
|
5
5
|
when: task defines error paths, adds logging, or hardens failure behavior
|
|
6
6
|
phases: [build, verify]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Frontend craft — state discipline, componentization, accessibilit
|
|
|
4
4
|
tags: [frontend, ui, component, react, vue, svelte, state, form, accessibility, a11y, css, browser, render]
|
|
5
5
|
when: task builds or changes user interface
|
|
6
6
|
phases: [plan, build]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Stress-test a spec or plan with relentless one-at-a-time questions
|
|
|
4
4
|
tags: [grill, spec, requirements, questions, stress, interview, scope, clarify]
|
|
5
5
|
when: before proposing the sprint contract, or when a plan feels underspecified
|
|
6
6
|
phases: [define]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: HTTP/REST API design — resources, status codes, errors, versionin
|
|
|
4
4
|
tags: [api, http, rest, endpoint, route, json, status, error, versioning, pagination, webhook, request, response]
|
|
5
5
|
when: task designs or implements HTTP endpoints or consumes external APIs
|
|
6
6
|
phases: [plan, build]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Performance work — measure first, fix the biggest cost, cache wit
|
|
|
4
4
|
tags: [performance, slow, latency, profiling, optimize, cache, memory, benchmark, throughput, speed]
|
|
5
5
|
when: something is slow, memory-hungry, or a task sets performance targets
|
|
6
6
|
phases: [verify, build]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: "Atomic infinity_plan pattern with omission deletion, baseRevision
|
|
|
4
4
|
tags: [harness, pi-todo, atomic, baseRevision, omission, deletion, compaction, widget, task-list, dependency]
|
|
5
5
|
when: "implementing infinity_plan, atomic revisioning, Pi widget with session persistence or task dependencies"
|
|
6
6
|
phases: [build, verify]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: "https://github.com/99percentpeople/pi-extensions", license: MIT, adapted: true, url: "https://github.com/99percentpeople/pi-extensions", contentHash: abf626df6a74a6fb }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Break specs into tracer-bullet vertical slices with checkable accep
|
|
|
4
4
|
tags: [plan, planning, slice, ticket, decompose, criteria, backlog, breakdown, refactor]
|
|
5
5
|
when: writing or restructuring the feature list from a spec
|
|
6
6
|
phases: [plan]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -3,7 +3,8 @@ name: prototype
|
|
|
3
3
|
description: Throwaway code that answers a design question fast, then gets deleted
|
|
4
4
|
tags: [prototype, spike, experiment, explore, poc, throwaway, design]
|
|
5
5
|
when: a state model, logic shape, or UI direction cannot be judged on paper
|
|
6
|
-
phases: [
|
|
6
|
+
phases: [plan, build]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Answer factual questions from primary sources; capture cited findin
|
|
|
4
4
|
tags: [research, docs, documentation, investigate, source, facts, api, spec, evidence]
|
|
5
5
|
when: a factual question about an API, library, protocol, or tool blocks progress
|
|
6
6
|
phases: [define, plan, build]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Resolve git merge/rebase conflicts by original intent, verify, and
|
|
|
4
4
|
tags: [git, merge, rebase, conflict, branch, hunk]
|
|
5
5
|
when: an in-progress git merge or rebase has conflicting hunks
|
|
6
6
|
phases: []
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -23,7 +24,7 @@ provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
|
23
24
|
trade-off. Do **not** invent new behaviour. Always resolve; never
|
|
24
25
|
`--abort`.
|
|
25
26
|
4. **Run the project's automated checks** — typecheck, then tests, then
|
|
26
|
-
lint (`
|
|
27
|
+
lint (`infinity_validate` runs the configured set). Fix anything the
|
|
27
28
|
merge broke.
|
|
28
29
|
5. **Finish the merge/rebase.** Stage everything and commit. If rebasing,
|
|
29
30
|
continue until all commits are rebased. Record anything surprising:
|
|
@@ -4,6 +4,7 @@ description: The contract is the boundary — park ideas, resist drive-by fixes,
|
|
|
4
4
|
tags: [meta, scope, creep, contract, focus, discipline, playbook]
|
|
5
5
|
when: mid-task ideas, adjacent problems, or "while I'm here" temptations appear
|
|
6
6
|
phases: []
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: built-in, notes: frontier-playbook }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Structured pass before claiming done — criteria re-check, real ru
|
|
|
4
4
|
tags: [meta, review, verify, done, quality, check, playbook]
|
|
5
5
|
when: before running validate on any task — every time
|
|
6
6
|
phases: [build, verify, simplify]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: built-in, notes: frontier-playbook }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: What to do after repeated failures — stop, write down, reframe on
|
|
|
4
4
|
tags: [meta, stuck, retry, failure, escalate, blocked, playbook]
|
|
5
5
|
when: the same step has failed 2-3 times, or you notice you are looping
|
|
6
6
|
phases: []
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: built-in, notes: frontier-playbook }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -28,7 +29,7 @@ catch any of these tells:
|
|
|
28
29
|
what you're trying to achieve, the exact error/failure, the attempts
|
|
29
30
|
made, and what each attempt ruled out. Writing this usually exposes the
|
|
30
31
|
gap — half the time you solve it here.
|
|
31
|
-
2. **Re-read the brief and the skill** (`
|
|
32
|
+
2. **Re-read the brief and the skill** (`infinity_brief`; the skill it
|
|
32
33
|
references). Stuck often means a constraint was missed, not that the
|
|
33
34
|
problem is hard.
|
|
34
35
|
3. **Reframe ONCE** — one genuinely different angle, not a variation:
|
package/harness/skills/tdd.md
CHANGED
|
@@ -4,6 +4,7 @@ description: Red → green test-driven loop — what a good test is, seams, anti
|
|
|
4
4
|
tags: [tdd, test, testing, unit, integration, red-green, seam, mock, coverage]
|
|
5
5
|
when: implementing any BUILD task, or fixing a bug that needs a regression test
|
|
6
6
|
phases: [build, verify]
|
|
7
|
+
kind: process
|
|
7
8
|
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: Test infrastructure — fixtures, isolation, flaky-test policy, CI
|
|
|
4
4
|
tags: [test, testing, fixture, ci, flaky, coverage, mock, isolation, pipeline, suite]
|
|
5
5
|
when: task sets up test tooling, fixtures, CI, or fights slow/flaky suites
|
|
6
6
|
phases: [build, verify]
|
|
7
|
+
kind: domain
|
|
7
8
|
provenance: { origin: built-in }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ description: How to author a skill worth keeping — scope, structure, frontmatt
|
|
|
4
4
|
tags: [meta, skill, writing, author, documentation, checklist]
|
|
5
5
|
when: creating a new skill or adapting an acquired one
|
|
6
6
|
phases: []
|
|
7
|
+
kind: meta
|
|
7
8
|
provenance: { origin: "mattpocock/skills writing-great-skills", license: MIT, adapted: true }
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -54,7 +55,7 @@ Frontmatter uses a strict subset: `key: value`, `key: [a, b]`,
|
|
|
54
55
|
|
|
55
56
|
## Checklist
|
|
56
57
|
|
|
57
|
-
- [ ] Frontmatter
|
|
58
|
+
- [ ] Frontmatter is complete: `name` matching the filename, `description`, `kind`, `tags`, `when`, `phases`
|
|
58
59
|
- [ ] A cold reader knows exactly what to do and how to check they did it
|
|
59
60
|
- [ ] Every rule is checkable; every anti-pattern has a fix
|
|
60
61
|
- [ ] Attribution line present if adapted from elsewhere
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "infinity-harness",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "A pi agent extension that runs a gated build pipeline unattended \u2014 enforces phases, validates with deterministic gates, and keeps working for hours or days without losing the plan.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
package/src/core/brief.ts
CHANGED
|
@@ -22,6 +22,23 @@ import { runChecks } from "./gates.ts";
|
|
|
22
22
|
import { getPhaseOrder, nextPhase, isFinalPhase } from "./phases.ts";
|
|
23
23
|
import * as P from "./paths.ts";
|
|
24
24
|
import { readText } from "./fsx.ts";
|
|
25
|
+
import { loadSkills, matchSkills } from "./skills.ts";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* What the agent calls to have its work judged.
|
|
29
|
+
*
|
|
30
|
+
* This said `harness validate` for a long time — a command line that has not
|
|
31
|
+
* existed since the CLI was ported into `src/`. A brief that ends by telling
|
|
32
|
+
* the model to run a command that does not exist is a brief that ends in a
|
|
33
|
+
* failed shell call and a confused retry, every single turn.
|
|
34
|
+
*/
|
|
35
|
+
const VALIDATE_TOOL = "infinity_validate";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Two is the number that gets read. One hides a better match; five is a
|
|
39
|
+
* reading list, and a reading list is a thing you skip.
|
|
40
|
+
*/
|
|
41
|
+
const SKILL_SUGGESTIONS = 2;
|
|
25
42
|
|
|
26
43
|
const PHASE_INTENT: Record<Phase, string> = {
|
|
27
44
|
init: "Set up the project skeleton and confirm the harness can see it.",
|
|
@@ -88,7 +105,7 @@ export async function buildBrief(targetDir: string, options: BuildBriefOptions =
|
|
|
88
105
|
}
|
|
89
106
|
: null,
|
|
90
107
|
criteria: collectCriteria(feature, nextTask?.criteria),
|
|
91
|
-
validateCommand:
|
|
108
|
+
validateCommand: VALIDATE_TOOL,
|
|
92
109
|
gate,
|
|
93
110
|
progress: {
|
|
94
111
|
tasksDone: progress.tasksDone,
|
|
@@ -102,10 +119,39 @@ export async function buildBrief(targetDir: string, options: BuildBriefOptions =
|
|
|
102
119
|
phase: config.phaseRetryCount ?? 0,
|
|
103
120
|
max: retry.tasks.max,
|
|
104
121
|
},
|
|
122
|
+
skills: suggestSkills(phase, {
|
|
123
|
+
goal: (list.goals ?? [])[0]?.title ?? null,
|
|
124
|
+
feature: feature?.name ?? null,
|
|
125
|
+
task: nextTask?.description ?? null,
|
|
126
|
+
criteria: collectCriteria(feature, nextTask?.criteria),
|
|
127
|
+
}),
|
|
105
128
|
notes,
|
|
106
129
|
};
|
|
107
130
|
}
|
|
108
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Which craft skills to point at, given what is being worked on.
|
|
134
|
+
*
|
|
135
|
+
* The skills ship with the package, so this works in an install with no
|
|
136
|
+
* project-level setup. If they are missing — someone vendored `src/` alone —
|
|
137
|
+
* the brief simply has no SKILLS section rather than failing to build.
|
|
138
|
+
*/
|
|
139
|
+
function suggestSkills(
|
|
140
|
+
phase: Phase | null,
|
|
141
|
+
work: { goal: string | null; feature: string | null; task: string | null; criteria: string[] },
|
|
142
|
+
): Brief["skills"] {
|
|
143
|
+
const text = [work.task, work.feature, work.goal, ...work.criteria].filter(Boolean).join(" \n ");
|
|
144
|
+
try {
|
|
145
|
+
return matchSkills(loadSkills(), { phase, text, limit: SKILL_SUGGESTIONS }).map((m) => ({
|
|
146
|
+
name: m.skill.name,
|
|
147
|
+
description: m.skill.description,
|
|
148
|
+
why: m.why,
|
|
149
|
+
}));
|
|
150
|
+
} catch {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
109
155
|
function collectCriteria(
|
|
110
156
|
feature: { criteria?: string[] } | null,
|
|
111
157
|
taskCriteria: string[] | undefined,
|
|
@@ -189,6 +235,15 @@ export function renderBrief(brief: Brief, config?: HarnessConfig): string {
|
|
|
189
235
|
for (const c of brief.criteria) L.push(` - ${c}`);
|
|
190
236
|
}
|
|
191
237
|
|
|
238
|
+
if (brief.skills.length) {
|
|
239
|
+
L.push("");
|
|
240
|
+
L.push("SKILLS read before you start — invoke by name");
|
|
241
|
+
for (const s of brief.skills) {
|
|
242
|
+
L.push(` - ${s.name} — ${s.description}`);
|
|
243
|
+
if (s.why) L.push(` (${s.why})`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
192
247
|
if (brief.gate) {
|
|
193
248
|
L.push("");
|
|
194
249
|
L.push(`GATE ${brief.gate.overall ? "PASS" : "FAIL"}`);
|
|
@@ -207,7 +262,7 @@ export function renderBrief(brief: Brief, config?: HarnessConfig): string {
|
|
|
207
262
|
L.push("");
|
|
208
263
|
L.push("THE LOOP");
|
|
209
264
|
L.push(" 1. Do the work described above.");
|
|
210
|
-
L.push(` 2.
|
|
265
|
+
L.push(` 2. Call the ${brief.validateCommand} tool (a human types /infinity:validate).`);
|
|
211
266
|
L.push(" 3. FAIL → fix the listed checks and validate again.");
|
|
212
267
|
L.push(" 4. PASS → the harness advances the phase and issues the next brief.");
|
|
213
268
|
L.push("");
|