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,45 @@
|
|
|
1
|
+
# SIMPLIFY Phase
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Reduce code complexity without changing behavior. Remove dead code, consolidate
|
|
5
|
+
duplicates, flatten deep nesting, and ensure tests still pass after changes.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
- VERIFY phase complete (optional phase — only if enabled in config)
|
|
9
|
+
- Code works but has accumulated complexity during build
|
|
10
|
+
|
|
11
|
+
## Craft Skills (read before working)
|
|
12
|
+
- `harness/skills/codebase-design.md` — deepen modules: more behavior behind smaller interfaces
|
|
13
|
+
- `harness/skills/code-review.md` — the smell baseline (what to hunt for)
|
|
14
|
+
|
|
15
|
+
## Process
|
|
16
|
+
1. Read `harness/progress.md` and `AGENTS.md`
|
|
17
|
+
2. Run `the infinity_brief tool` to see the current step
|
|
18
|
+
3. For each feature:
|
|
19
|
+
a. Review code for: code smells, deep nesting, DRY violations, dead code
|
|
20
|
+
b. Simplify: consolidate duplicate logic, flatten conditionals, remove unused
|
|
21
|
+
c. Run `npm test` to ensure tests still pass after simplification
|
|
22
|
+
d. Run `the infinity_validate tool --feature <id> --task <id>` per task
|
|
23
|
+
4. When all features simplified → run `the infinity_validate tool` (full phase)
|
|
24
|
+
5. If PASS → `the infinity_advance tool` to advance to REVIEW
|
|
25
|
+
|
|
26
|
+
## Rationalizations to Avoid
|
|
27
|
+
| Excuse | Rebuttal |
|
|
28
|
+
|--------|----------|
|
|
29
|
+
| "It works, don't touch it" | Working code with high complexity is a liability |
|
|
30
|
+
| "Simplification risks breaking things" | Tests catch breakage — that's what they're for |
|
|
31
|
+
| "I'll clean up later" | Later never comes — simplify now while context is fresh |
|
|
32
|
+
|
|
33
|
+
## Red Flags
|
|
34
|
+
- Tests fail after simplification — you changed behavior, not just structure
|
|
35
|
+
- Simplification removed more than 20% of code — may have removed needed logic
|
|
36
|
+
- No tests to verify behavior preserved — add tests before simplifying
|
|
37
|
+
|
|
38
|
+
## Verification
|
|
39
|
+
- [ ] Code smells reduced (subjective — use judgment)
|
|
40
|
+
- [ ] No new dead code introduced
|
|
41
|
+
- [ ] Tests still pass: `npm test`
|
|
42
|
+
- [ ] `the infinity_validate tool` passes
|
|
43
|
+
|
|
44
|
+
## Handoff
|
|
45
|
+
On gate pass: `the infinity_advance tool` (Simplifier → Evaluator for REVIEW)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# VERIFY Phase
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Independently verify that built features meet acceptance criteria. The Evaluator
|
|
5
|
+
role runs tests, checks coverage, and validates behavior against the PRD.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
- BUILD phase complete (all features pass)
|
|
9
|
+
- Need to verify quality before review
|
|
10
|
+
|
|
11
|
+
## Craft Skills (read before working)
|
|
12
|
+
- `harness/skills/diagnosing-bugs.md` — build a feedback loop BEFORE hypothesizing about any failure
|
|
13
|
+
- `harness/skills/tdd.md` — regression tests for anything you fix
|
|
14
|
+
|
|
15
|
+
## Process
|
|
16
|
+
1. Read `harness/progress.md`, `AGENTS.md`, and `specs/prd.md`
|
|
17
|
+
2. Run `the infinity_brief tool` to see the current verification step
|
|
18
|
+
3. For each feature:
|
|
19
|
+
a. Run the test suite: `npm test`
|
|
20
|
+
b. Check coverage: `{{coverageCmd}}` (if coverage gate enabled)
|
|
21
|
+
c. Verify behavior matches acceptance criteria from PRD
|
|
22
|
+
d. Run `the infinity_validate tool --feature <id> --task <id>` per task
|
|
23
|
+
4. If any task fails → fix and re-validate (retry)
|
|
24
|
+
5. When all features verified → run `the infinity_validate tool` (full phase)
|
|
25
|
+
6. If PASS → `the infinity_advance tool` to advance to SIMPLIFY or REVIEW
|
|
26
|
+
|
|
27
|
+
## Rationalizations to Avoid
|
|
28
|
+
| Excuse | Rebuttal |
|
|
29
|
+
|--------|----------|
|
|
30
|
+
| "Build already validated, no need to re-verify" | Build validates implementation; VERIFY validates behavior |
|
|
31
|
+
| "Coverage is high enough" | Check against configured threshold, not gut feeling |
|
|
32
|
+
| "Edge cases are unlikely" | Unlikely ≠ impossible — test them |
|
|
33
|
+
|
|
34
|
+
## Red Flags
|
|
35
|
+
- Tests pass but behavior doesn't match PRD acceptance criteria
|
|
36
|
+
- Coverage below configured threshold
|
|
37
|
+
- Missing tests for error/edge cases
|
|
38
|
+
|
|
39
|
+
## Verification
|
|
40
|
+
- [ ] All tests pass: `npm test`
|
|
41
|
+
- [ ] Coverage meets threshold (if gate enabled)
|
|
42
|
+
- [ ] Behavior matches PRD acceptance criteria
|
|
43
|
+
- [ ] `the infinity_validate tool` passes
|
|
44
|
+
|
|
45
|
+
## Handoff
|
|
46
|
+
On gate pass: `the infinity_advance tool` (Evaluator → Simplifier for SIMPLIFY, or Evaluator for REVIEW)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Optional per-task model routing. Disabled by default: every empty string means 'use whatever model pi is configured with'. Set enabled:true and fill in model ids to route cheap tasks to a small model and hard ones to a large one. Read fresh on every resolution, so edits take effect without restarting the session.",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"enabled": false,
|
|
5
|
+
"default": "",
|
|
6
|
+
"byDifficulty": {
|
|
7
|
+
"easy": "",
|
|
8
|
+
"moderate": "",
|
|
9
|
+
"difficult": ""
|
|
10
|
+
},
|
|
11
|
+
"master": "",
|
|
12
|
+
"byPhase": {},
|
|
13
|
+
"byRole": {},
|
|
14
|
+
"byFeature": {},
|
|
15
|
+
"bySprint": {},
|
|
16
|
+
"byTask": {},
|
|
17
|
+
"consultation": {
|
|
18
|
+
"enabled": true,
|
|
19
|
+
"maxPerTask": 1,
|
|
20
|
+
"oneStepOnly": true,
|
|
21
|
+
"requireExhaustion": true
|
|
22
|
+
},
|
|
23
|
+
"budgets": {
|
|
24
|
+
"maxReworksPerRun": 3,
|
|
25
|
+
"maxReplansPerRun": 2,
|
|
26
|
+
"maxReviewBounces": 2
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Craft Skills
|
|
2
|
+
|
|
3
|
+
How to do the work WELL — the engineering discipline behind each pipeline
|
|
4
|
+
phase. The phase docs (`harness/docs/phases/`) say *what* to produce; these
|
|
5
|
+
skills say *how* an expert produces it.
|
|
6
|
+
|
|
7
|
+
`the infinity_brief tool` matches skills to your current task and points you at
|
|
8
|
+
the right ones. Read the referenced skill BEFORE working — it is short and
|
|
9
|
+
it will change what you do. Find skills yourself:
|
|
10
|
+
`infinity-harness capability match "<your task>"`.
|
|
11
|
+
|
|
12
|
+
## Process skills (phase-mapped)
|
|
13
|
+
|
|
14
|
+
| Skill | Use during | One-liner |
|
|
15
|
+
|-------|-----------|-----------|
|
|
16
|
+
| `grilling.md` | DEFINE | Stress-test the spec with relentless questions |
|
|
17
|
+
| `domain-modeling.md` | DEFINE | Pin down domain terms before writing code |
|
|
18
|
+
| `research.md` | DEFINE, anytime | Answer questions from primary sources only |
|
|
19
|
+
| `planning-tasks.md` | PLAN | Break specs into tracer-bullet vertical slices |
|
|
20
|
+
| `codebase-design.md` | PLAN, SIMPLIFY | Design deep modules behind small interfaces |
|
|
21
|
+
| `tdd.md` | BUILD | Red → green loop; tests worth keeping |
|
|
22
|
+
| `prototype.md` | BUILD | Throwaway code that answers a design question |
|
|
23
|
+
| `diagnosing-bugs.md` | VERIFY, anytime | Build a feedback loop before hypothesizing |
|
|
24
|
+
| `code-review.md` | REVIEW | Two-axis review: standards + spec |
|
|
25
|
+
| `resolving-merge-conflicts.md` | anytime | Resolve conflicts by original intent |
|
|
26
|
+
|
|
27
|
+
## Domain skills (task-matched by tags)
|
|
28
|
+
|
|
29
|
+
`databases` · `http-apis` · `auth-security` · `frontend-ui` ·
|
|
30
|
+
`testing-infra` · `concurrency-async` · `performance` ·
|
|
31
|
+
`error-handling-logging` · `config-and-secrets` · `cli-design`
|
|
32
|
+
|
|
33
|
+
## Frontier playbook (how a strong model operates)
|
|
34
|
+
|
|
35
|
+
| Skill | Delivery surface |
|
|
36
|
+
|-------|-----------------|
|
|
37
|
+
| `self-review.md` | Its pass runs before EVERY validate (briefs remind you) |
|
|
38
|
+
| `stuck-protocol.md` | Referenced when retries fail — stop thrashing, escalate cleanly |
|
|
39
|
+
| `context-hygiene.md` | Externalize discoveries the moment they happen |
|
|
40
|
+
| `scope-discipline.md` | The contract is the boundary; park everything else |
|
|
41
|
+
|
|
42
|
+
## The capability ladder (meta-skills)
|
|
43
|
+
|
|
44
|
+
| Skill | Purpose |
|
|
45
|
+
|-------|---------|
|
|
46
|
+
| `capability-acquisition.md` | HAVE → ACQUIRE → CREATE → KEEP, for skills/MCP/tools |
|
|
47
|
+
| `writing-skills.md` | How to author a skill worth keeping |
|
|
48
|
+
| `building-mcp-servers.md` | Scaffold, fill handlers, self-test, register |
|
|
49
|
+
| `building-tools.md` | Project tool standards + registration |
|
|
50
|
+
|
|
51
|
+
Growing the library IS part of the job: acquired and created capabilities
|
|
52
|
+
are registered (`infinity-harness capability add ...`) so the next task starts
|
|
53
|
+
ahead. Export your accumulated skills across projects:
|
|
54
|
+
`infinity-harness capability export`.
|
|
55
|
+
|
|
56
|
+
## Attribution
|
|
57
|
+
|
|
58
|
+
Skills marked "Adapted from mattpocock/skills" derive from
|
|
59
|
+
[Matt Pocock's skills repository](https://github.com/mattpocock/skills)
|
|
60
|
+
(MIT License, © 2026 Matt Pocock), adapted for the infinity-harness pipeline.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: auth-security
|
|
3
|
+
description: Authentication, authorization, secrets, and the injection/XSS/CSRF baseline
|
|
4
|
+
tags: [auth, authentication, authorization, security, login, password, token, jwt, session, oauth, secret, csrf, xss, injection, permission]
|
|
5
|
+
when: task touches login, sessions, tokens, permissions, user input, or secrets
|
|
6
|
+
phases: [plan, build, verify]
|
|
7
|
+
provenance: { origin: built-in }
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Auth & Security
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
|
|
14
|
+
- **Never roll your own crypto or password hashing.** Passwords: argon2id
|
|
15
|
+
or bcrypt via the platform's vetted library. Compare with constant-time
|
|
16
|
+
functions. No MD5/SHA for passwords, ever.
|
|
17
|
+
- **AuthN ≠ AuthZ.** Authentication says who you are; EVERY endpoint still
|
|
18
|
+
checks what you may do — on the server, against the resource ("is this
|
|
19
|
+
order YOURS?"), not just the route. Client-side checks are UI hints only.
|
|
20
|
+
- **Sessions:** httpOnly + Secure + SameSite cookies; regenerate the ID on
|
|
21
|
+
login; server-side revocation on logout/password change.
|
|
22
|
+
- **JWTs (if you must):** short-lived access (≤15 min) + rotating refresh;
|
|
23
|
+
verify `alg` (reject `none`), `exp`, `aud`, `iss`; keys from env/KMS.
|
|
24
|
+
If you need instant revocation, you wanted sessions.
|
|
25
|
+
- **Secrets live in the environment** (or a secrets manager) — never in
|
|
26
|
+
code, configs, logs, error messages, or git history. `.env` is
|
|
27
|
+
gitignored; ship `.env.example` with dummy values.
|
|
28
|
+
- **All user input is hostile:** parameterized SQL (see `databases.md`);
|
|
29
|
+
context-aware output encoding (frameworks' default escaping — don't
|
|
30
|
+
bypass with innerHTML/dangerouslySetInnerHTML); path traversal checks on
|
|
31
|
+
any filename input; allowlists over blocklists.
|
|
32
|
+
- **CSRF:** any cookie-authenticated state change needs SameSite plus a
|
|
33
|
+
CSRF token (or requires a custom header). Token-in-header APIs are
|
|
34
|
+
exempt; cookie APIs are not.
|
|
35
|
+
- **Rate-limit auth endpoints** (login, reset, signup) and return uniform
|
|
36
|
+
errors — "invalid credentials", never "no such user" (enumeration).
|
|
37
|
+
- **Fail closed.** Auth error / lookup failure / config missing → deny.
|
|
38
|
+
|
|
39
|
+
## Anti-patterns
|
|
40
|
+
|
|
41
|
+
- **Logging tokens/passwords** — scrub auth headers and bodies at the
|
|
42
|
+
logger, once, centrally.
|
|
43
|
+
- **Role checks sprinkled inline** (`if user.role == "admin"`) → one
|
|
44
|
+
authorization function/policy layer, called everywhere, testable alone.
|
|
45
|
+
- **Long-lived static API keys in client code** — anything shipped to a
|
|
46
|
+
browser/app is public.
|
|
47
|
+
- **Home-grown password reset** — tokens must be single-use, expiring,
|
|
48
|
+
hashed at rest, invalidated on use AND on password change.
|
|
49
|
+
|
|
50
|
+
## Checklist
|
|
51
|
+
|
|
52
|
+
- [ ] Every state-changing endpoint has an explicit server-side authZ check
|
|
53
|
+
- [ ] Secrets only via env; repo greps clean of keys (`git log -p` too)
|
|
54
|
+
- [ ] Auth failures uniform + rate-limited; nothing enumerable
|
|
55
|
+
- [ ] Tests include the NEGATIVE cases: wrong user, expired token, missing role
|
|
56
|
+
- [ ] Dependency audit run (npm audit / pip-audit) with highs resolved
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: building-mcp-servers
|
|
3
|
+
description: When and how to build a project MCP server — scaffold, handlers, self-test, register
|
|
4
|
+
tags: [meta, mcp, server, protocol, stdio, integration, build]
|
|
5
|
+
when: a needed external-system integration has no existing MCP server
|
|
6
|
+
phases: []
|
|
7
|
+
provenance: { origin: built-in }
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Building MCP Servers
|
|
11
|
+
|
|
12
|
+
## Build vs. script — decide first
|
|
13
|
+
|
|
14
|
+
- Capability is **reused across sessions/tasks** and benefits from being a
|
|
15
|
+
native agent tool → build an MCP server.
|
|
16
|
+
- **One-off or shell-shaped** action → a tool script is cheaper
|
|
17
|
+
(`building-tools.md`). Don't build a server to wrap one command.
|
|
18
|
+
|
|
19
|
+
## Process
|
|
20
|
+
|
|
21
|
+
1. **Scaffold** (a WORKING server — protocol plumbing done):
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
infinity-harness capability create mcp <name>
|
|
25
|
+
→ harness/mcp/<name>/server.mjs + self-test.mjs
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. **Define tools.** Edit the `TOOLS` object in `server.mjs`. Per tool:
|
|
29
|
+
- `description` written FOR the consuming model — say when to call it
|
|
30
|
+
and what comes back
|
|
31
|
+
- `inputSchema` — JSON Schema; mark required params
|
|
32
|
+
- `handler(args)` — async, returns a string
|
|
33
|
+
Keep it zero-dep if possible; if you need a client library, add it to
|
|
34
|
+
the project and pin the version.
|
|
35
|
+
|
|
36
|
+
3. **Self-test until green:**
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
node harness/mcp/<name>/self-test.mjs
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
It runs initialize → tools/list → tools/call. Extend it with one call
|
|
43
|
+
per real tool you added.
|
|
44
|
+
|
|
45
|
+
4. **Register** (adds it to the index AND every MCP client config):
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
infinity-harness capability add mcp <name> --command node \
|
|
49
|
+
--args harness/mcp/<name>/server.mjs \
|
|
50
|
+
--tags db,postgres --description "Query the dev database" --trust curated
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Rules
|
|
54
|
+
|
|
55
|
+
- **stdout is the protocol.** Never `console.log` in a handler — one stray
|
|
56
|
+
line corrupts the JSON-RPC stream. Log to stderr if you must.
|
|
57
|
+
- **Secrets via environment** (`process.env.X`), never hardcoded, never in
|
|
58
|
+
client configs.
|
|
59
|
+
- **Handlers fail soft:** return an error message string, don't throw the
|
|
60
|
+
server down.
|
|
61
|
+
- **Errors are content.** A tool that errors should return actionable text
|
|
62
|
+
("connection refused on :5432 — is the dev DB running?").
|
|
63
|
+
|
|
64
|
+
## Checklist
|
|
65
|
+
|
|
66
|
+
- [ ] Self-test green, one case per tool
|
|
67
|
+
- [ ] No stdout pollution (run self-test — parse errors reveal it)
|
|
68
|
+
- [ ] Secrets via env; version pins for any deps
|
|
69
|
+
- [ ] Registered with tags + description (matcher-visible)
|
|
70
|
+
- [ ] `infinity-harness capability doctor --type mcp` passes
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: building-tools
|
|
3
|
+
description: Project tool standards — idempotent, self-documenting, non-interactive executables
|
|
4
|
+
tags: [meta, tool, script, cli, automation, executable]
|
|
5
|
+
when: a repeatable action deserves a registered executable instead of ad-hoc shell
|
|
6
|
+
phases: []
|
|
7
|
+
provenance: { origin: built-in }
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Building Tools
|
|
11
|
+
|
|
12
|
+
A tool is a registered executable under `harness/tools/` that future
|
|
13
|
+
sessions (and other agents) can find and run. Build one when you catch
|
|
14
|
+
yourself doing the same multi-step shell dance twice.
|
|
15
|
+
|
|
16
|
+
## Process
|
|
17
|
+
|
|
18
|
+
1. `infinity-harness capability create tool <name>` → stub at
|
|
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)
|
|
31
|
+
|
|
32
|
+
- **Idempotent** — running it twice is safe and converges to the same state.
|
|
33
|
+
- **`--help` works** — prints usage + purpose, exits 0. (`capability
|
|
34
|
+
doctor` checks exactly this.)
|
|
35
|
+
- **`--json` where output is consumed** — machine-readable when another
|
|
36
|
+
tool or agent reads the result.
|
|
37
|
+
- **Exit codes:** 0 success · 1 operation failed · 2 usage error.
|
|
38
|
+
- **Never interactive** — no prompts, no confirmations; flags only. An
|
|
39
|
+
unattended agent runs this at 3am.
|
|
40
|
+
- **Fail loud and specific** — errors name the thing that's wrong and the
|
|
41
|
+
likely fix, on stderr.
|
|
42
|
+
- **Self-contained** — resolve paths relative to the project root, not the
|
|
43
|
+
caller's cwd.
|
|
44
|
+
|
|
45
|
+
## Anti-patterns
|
|
46
|
+
|
|
47
|
+
- **The snowflake** — works only on the author's machine (hardcoded paths,
|
|
48
|
+
undeclared deps). Fix: check prerequisites at startup, fail with install
|
|
49
|
+
instructions.
|
|
50
|
+
- **The chatterbox** — pages of output hiding the result. Fix: one summary
|
|
51
|
+
line by default, `--verbose` for the rest.
|
|
52
|
+
- **The mutation surprise** — destructive with no dry-run. Fix: anything
|
|
53
|
+
destructive gets `--dry-run` and defaults to showing what it would do.
|
|
54
|
+
|
|
55
|
+
## Checklist
|
|
56
|
+
|
|
57
|
+
- [ ] Idempotent (ran it twice to prove it)
|
|
58
|
+
- [ ] `--help` exit 0; exit codes correct
|
|
59
|
+
- [ ] Registered with ≥2 tags + description
|
|
60
|
+
- [ ] `infinity-harness capability doctor --type tool` passes
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: capability-acquisition
|
|
3
|
+
description: The capability ladder — HAVE, ACQUIRE, CREATE, KEEP — for skills, MCP servers, and tools
|
|
4
|
+
tags: [meta, capability, acquire, search, skill, mcp, tool, ladder, library]
|
|
5
|
+
when: a task needs knowledge, system access, or an executable the project lacks
|
|
6
|
+
phases: []
|
|
7
|
+
provenance: { origin: built-in }
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Capability Acquisition — The Ladder
|
|
11
|
+
|
|
12
|
+
Your task needs something the library lacks. Resolve it with the ladder —
|
|
13
|
+
and register what you find so the NEXT task starts at Tier 0.
|
|
14
|
+
|
|
15
|
+
## Step 1 — Decide the capability TYPE
|
|
16
|
+
|
|
17
|
+
- Need **knowledge or method** (how to do X well) → a **skill**
|
|
18
|
+
- Need to **interact with an external system** (DB, API, browser, tracker) → an **MCP server**
|
|
19
|
+
- Need a **repeatable executable action** (reset fixtures, run a codemod) → a **tool**
|
|
20
|
+
- Need a **fact** (does API X support Y?) → follow `research.md` — findings
|
|
21
|
+
saved under `docs/research/` with frontmatter become matchable facts
|
|
22
|
+
|
|
23
|
+
## Step 2 — ACQUIRE: search the sources
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
the capability index "<2-4 keywords>" --type skill|mcp|tool
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This queries the machine-queryable registries directly (npm, MCP registry,
|
|
30
|
+
GitHub, crates, …). Browse-only sources are listed after — use them only
|
|
31
|
+
if you have web access.
|
|
32
|
+
|
|
33
|
+
**Choosing among hits** (in order): trust tier (official > curated >
|
|
34
|
+
community) → actively maintained → widely used → known author →
|
|
35
|
+
permissive license (MIT/Apache/BSD) → small and composable. NEVER adopt a
|
|
36
|
+
framework that wants to own your whole process — the harness owns the
|
|
37
|
+
process.
|
|
38
|
+
|
|
39
|
+
**Adapt, don't adopt.** Whatever you take: trim it to the useful core,
|
|
40
|
+
re-point references to harness surfaces (DOMAIN.md, feature-list,
|
|
41
|
+
learn/decision), add an attribution line (source + license), then register:
|
|
42
|
+
|
|
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
|
+
```
|
|
49
|
+
|
|
50
|
+
**MCP security (hard rules):** pin exact versions (`pkg@1.2.3`, never
|
|
51
|
+
`@latest`); community-tier servers need `--force` after you review their
|
|
52
|
+
source; secrets go through env indirection, never into configs.
|
|
53
|
+
|
|
54
|
+
## Step 3 — CREATE: nothing usable exists
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
infinity-harness capability create skill|tool|mcp <name>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- skill → fill the stub per `writing-skills.md`
|
|
61
|
+
- tool → implement per `building-tools.md`
|
|
62
|
+
- mcp → the scaffold is a WORKING server; fill in handlers per
|
|
63
|
+
`building-mcp-servers.md`, verify with its self-test, then register
|
|
64
|
+
|
|
65
|
+
## Step 4 — Budget and fallback (never block the pipeline)
|
|
66
|
+
|
|
67
|
+
Acquisition fits ONE working session. If the search didn't conclude, or you
|
|
68
|
+
have no network:
|
|
69
|
+
|
|
70
|
+
1. Record the gap: `harness/lessons-decisions.md "capability gap: <what was needed>"`
|
|
71
|
+
2. Proceed with general best practices — a missing skill is not a blocked task
|
|
72
|
+
3. The gap resurfaces via `infinity-harness capability gaps` for a later pass
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cli-design
|
|
3
|
+
description: Command-line tool design — argument conventions, output contracts, exit codes, composability
|
|
4
|
+
tags: [cli, command, terminal, flags, arguments, stdout, stdin, shell, script, tool]
|
|
5
|
+
when: task builds or extends a command-line interface
|
|
6
|
+
phases: [plan, build]
|
|
7
|
+
provenance: { origin: built-in }
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# CLI Design
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
|
|
14
|
+
- **stdout is the product; stderr is the commentary.** Results (the thing
|
|
15
|
+
a pipe consumes) go to stdout; progress, warnings, and errors go to
|
|
16
|
+
stderr. Mixing them breaks every script that consumes you.
|
|
17
|
+
- **Exit codes are the API:** 0 success · 1 operation failed · 2 usage
|
|
18
|
+
error. Scripts branch on these; a CLI that exits 0 on failure is lying
|
|
19
|
+
to automation.
|
|
20
|
+
- **`--help` on everything**, including subcommands: one-line purpose,
|
|
21
|
+
usage line, every flag with its default. Help exits 0; unknown flags
|
|
22
|
+
exit 2 naming the flag and suggesting help.
|
|
23
|
+
- **Machine mode:** `--json` emits one parseable object/line to stdout
|
|
24
|
+
with a stable shape — additive changes only; renames are breaking
|
|
25
|
+
changes. (Agents and scripts are your biggest users.)
|
|
26
|
+
- **Non-interactive by default.** Prompts hang cron jobs and agents. Take
|
|
27
|
+
input via flags/stdin; destructive actions get `--dry-run` (show, don't
|
|
28
|
+
do) and require `--force` instead of asking "are you sure?".
|
|
29
|
+
- **Follow the grain:** `tool <noun> <verb>` or `tool <verb>` —
|
|
30
|
+
consistently; flags kebab-case with `--long` forms; `-` means stdin/
|
|
31
|
+
stdout where files are expected; respect `NO_COLOR` and non-TTY (no
|
|
32
|
+
spinners into pipes).
|
|
33
|
+
- **Errors say what + why + what next:** `✗ config not found:
|
|
34
|
+
harness/config.json — run: infinity-harness init`. Never a bare stack trace
|
|
35
|
+
for an expected failure.
|
|
36
|
+
- **Fast startup matters.** A CLI invoked in loops pays its startup cost
|
|
37
|
+
×N — lazy-load heavy imports per subcommand.
|
|
38
|
+
|
|
39
|
+
## Anti-patterns
|
|
40
|
+
|
|
41
|
+
- **Chatty stdout** — banner + tips drowning the result → result only;
|
|
42
|
+
decorations to stderr or behind `--verbose`.
|
|
43
|
+
- **Boolean flags taking values** (`--force true`) → presence = true.
|
|
44
|
+
- **Positional soup** (`tool a b c d`) — 3+ positionals nobody remembers →
|
|
45
|
+
named flags for all but the primary argument.
|
|
46
|
+
- **Config file required to run at all** → flags work standalone; config
|
|
47
|
+
file provides defaults, flags override.
|
|
48
|
+
|
|
49
|
+
## Checklist
|
|
50
|
+
|
|
51
|
+
- [ ] Piping stdout to a file captures exactly the result, nothing else
|
|
52
|
+
- [ ] Exit codes verified: success=0, failure=1, bad usage=2
|
|
53
|
+
- [ ] `--json` output parses and has a documented shape
|
|
54
|
+
- [ ] Runs unattended: zero prompts anywhere
|
|
55
|
+
- [ ] Every destructive path has --dry-run and needs --force
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-review
|
|
3
|
+
description: Two-axis review (spec fidelity + standards/smells) with the Fowler smell baseline
|
|
4
|
+
tags: [review, quality, smell, refactor, standards, spec, diff, audit]
|
|
5
|
+
when: reviewing a diff, a branch, or the whole delivery before shipping
|
|
6
|
+
phases: [review, simplify]
|
|
7
|
+
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Code Review — Two Axes
|
|
11
|
+
|
|
12
|
+
> Adapted from [mattpocock/skills](https://github.com/mattpocock/skills) (MIT © Matt Pocock).
|
|
13
|
+
> Use during: REVIEW (whole-delivery review) and when reviewing any diff.
|
|
14
|
+
|
|
15
|
+
Review the diff since a fixed point along two independent axes. Never merge
|
|
16
|
+
them — a change can pass one and fail the other, and one axis must not mask
|
|
17
|
+
the other.
|
|
18
|
+
|
|
19
|
+
- **Spec axis** — does the code faithfully implement what was asked?
|
|
20
|
+
- **Standards axis** — does the code follow this repo's conventions and
|
|
21
|
+
avoid the smell baseline below?
|
|
22
|
+
|
|
23
|
+
## Process
|
|
24
|
+
|
|
25
|
+
1. **Pin the fixed point.** `git diff <fixed-point>...HEAD` (three-dot) and
|
|
26
|
+
`git log <fixed-point>..HEAD --oneline`. In the harness pipeline the fixed
|
|
27
|
+
point is usually the phase-start or sprint-start commit/tag
|
|
28
|
+
(`infinity-harness rollback list` shows checkpoints).
|
|
29
|
+
2. **Spec review.** The spec sources are `specs/prd.md`, the sprint contract
|
|
30
|
+
(`harness/sprint-contract.md`), and the feature list's acceptance
|
|
31
|
+
criteria. Report: (a) requirements missing or partial; (b) behaviour
|
|
32
|
+
nobody asked for (scope creep); (c) requirements that look implemented
|
|
33
|
+
but wrong. Quote the spec line for each finding.
|
|
34
|
+
3. **Standards review.** Sources: the repo's documented conventions
|
|
35
|
+
(CONTRIBUTING, lint config, `harness/docs/CONSTRAINTS.md`) plus the smell
|
|
36
|
+
baseline below. Documented repo standards override the baseline; skip
|
|
37
|
+
anything tooling already enforces. Smells are judgement calls — label
|
|
38
|
+
them, don't treat them as violations.
|
|
39
|
+
4. **Report both axes separately**, then fix what's real. Fill in
|
|
40
|
+
`harness/evaluator-rubric.md` with evidence, not vibes.
|
|
41
|
+
|
|
42
|
+
## Smell baseline (Fowler, Refactoring ch. 3)
|
|
43
|
+
|
|
44
|
+
Each reads *what it is* → *how to fix*:
|
|
45
|
+
|
|
46
|
+
- **Mysterious Name** — name doesn't reveal what it does/holds → rename; if no honest name comes, the design is murky.
|
|
47
|
+
- **Duplicated Code** — same logic shape in more than one place → extract the shared shape.
|
|
48
|
+
- **Feature Envy** — a method reaches into another object's data more than its own → move it onto the data it envies.
|
|
49
|
+
- **Data Clumps** — the same few fields/params keep travelling together → bundle into one type.
|
|
50
|
+
- **Primitive Obsession** — a primitive standing in for a domain concept → give the concept its own type.
|
|
51
|
+
- **Repeated Switches** — same switch/if-cascade recurs → polymorphism or one shared map.
|
|
52
|
+
- **Shotgun Surgery** — one logical change forces scattered edits everywhere → gather into one module.
|
|
53
|
+
- **Divergent Change** — one module edited for several unrelated reasons → split it.
|
|
54
|
+
- **Speculative Generality** — abstraction for needs the spec doesn't have → delete it.
|
|
55
|
+
- **Message Chains** — long `a.b().c().d()` navigation → hide the walk behind one method.
|
|
56
|
+
- **Middle Man** — a thing that mostly delegates onward → cut it.
|
|
57
|
+
- **Refused Bequest** — an implementer ignoring most of what it inherits → composition over inheritance.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codebase-design
|
|
3
|
+
description: Deep modules — small interfaces hiding lots of behavior, seams, testability
|
|
4
|
+
tags: [design, architecture, module, interface, seam, refactor, coupling, abstraction, api]
|
|
5
|
+
when: designing module boundaries, planning features, refactoring for clarity
|
|
6
|
+
phases: [plan, simplify]
|
|
7
|
+
provenance: { origin: "mattpocock/skills", license: MIT, adapted: true }
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Codebase Design — Deep Modules
|
|
11
|
+
|
|
12
|
+
> Adapted from [mattpocock/skills](https://github.com/mattpocock/skills) (MIT © Matt Pocock).
|
|
13
|
+
> Use during: PLAN (shaping features into modules) and SIMPLIFY (finding deepening opportunities).
|
|
14
|
+
|
|
15
|
+
Design **deep modules**: a lot of behaviour behind a small interface, placed
|
|
16
|
+
at a clean seam, testable through that interface.
|
|
17
|
+
|
|
18
|
+
## Vocabulary (use these terms exactly)
|
|
19
|
+
|
|
20
|
+
- **Module** — anything with an interface and an implementation: a function,
|
|
21
|
+
class, package, or tier-spanning slice. (Avoid: unit, component, service.)
|
|
22
|
+
- **Interface** — everything a caller must know to use the module correctly:
|
|
23
|
+
the signature, plus invariants, ordering constraints, error modes, config,
|
|
24
|
+
performance characteristics. (Avoid: API — too narrow.)
|
|
25
|
+
- **Seam** — a place where you can alter behaviour without editing in that
|
|
26
|
+
place; where a module's interface lives. (Avoid: boundary.)
|
|
27
|
+
- **Adapter** — a concrete thing that satisfies an interface at a seam.
|
|
28
|
+
- **Depth** — leverage at the interface: how much behaviour a caller (or
|
|
29
|
+
test) can exercise per unit of interface they must learn.
|
|
30
|
+
|
|
31
|
+
## Deep vs shallow
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Deep (aim for this): Shallow (avoid):
|
|
35
|
+
┌───────────────┐ ┌───────────────────────────────┐
|
|
36
|
+
│ Small interface│ │ Large interface │
|
|
37
|
+
├───────────────┤ ├───────────────────────────────┤
|
|
38
|
+
│ │ │ Thin implementation │
|
|
39
|
+
│ Deep impl │ └───────────────────────────────┘
|
|
40
|
+
│ │
|
|
41
|
+
└───────────────┘
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
When designing an interface, ask: Can I reduce the number of methods? Can I
|
|
45
|
+
simplify the parameters? Can I hide more complexity inside?
|
|
46
|
+
|
|
47
|
+
## Principles
|
|
48
|
+
|
|
49
|
+
- **Depth is a property of the interface, not the implementation.** A deep
|
|
50
|
+
module can be internally composed of small parts — they just aren't part
|
|
51
|
+
of the interface.
|
|
52
|
+
- **The deletion test.** Imagine deleting the module. If complexity
|
|
53
|
+
vanishes, it was a pass-through. If complexity reappears across N callers,
|
|
54
|
+
it was earning its keep.
|
|
55
|
+
- **The interface is the test surface.** Callers and tests cross the same
|
|
56
|
+
seam. If you want to test *past* the interface, the module is probably
|
|
57
|
+
the wrong shape.
|
|
58
|
+
- **One adapter means a hypothetical seam. Two adapters means a real one.**
|
|
59
|
+
Don't introduce a seam unless something actually varies across it.
|
|
60
|
+
|
|
61
|
+
## Designing for testability
|
|
62
|
+
|
|
63
|
+
1. **Accept dependencies, don't create them.**
|
|
64
|
+
`processOrder(order, paymentGateway)` — testable.
|
|
65
|
+
`processOrder(order)` that news up `StripeGateway()` inside — not.
|
|
66
|
+
2. **Return results, don't produce side effects.**
|
|
67
|
+
`calculateDiscount(cart): Discount` — testable.
|
|
68
|
+
`applyDiscount(cart): void` that mutates — harder.
|
|
69
|
+
3. **Small surface area.** Fewer methods = fewer tests needed. Fewer params
|
|
70
|
+
= simpler test setup.
|