diff --git a/.agents/architecture.md b/.agents/architecture.md new file mode 100644 index 0000000..7a34499 --- /dev/null +++ b/.agents/architecture.md @@ -0,0 +1,30 @@ +# agents-2026 architecture + + + +## Purpose + +Describe what this system exists to do, who uses it, and what success means. + +## System context + +List upstream callers, downstream services, data stores, queues, files, and trust boundaries. + +## Components + +- Component: responsibility, owner, key files. + +## Data flow + +1. Input source. +2. Validation and transformation. +3. Persistence or external calls. +4. Output and observability. + +## Key invariants + +- Invariant: why it must hold, where enforced, how verified. + +## Decision log (ADRs) + + diff --git a/.agents/conventions.md b/.agents/conventions.md new file mode 100644 index 0000000..7803846 --- /dev/null +++ b/.agents/conventions.md @@ -0,0 +1,38 @@ +# agents-2026 conventions + + + +## Code style + +- Prefer simple control flow and explicit names. +- Keep side effects at boundaries. + +## Naming + +- Use domain terms consistently. +- Name files after their primary responsibility. + +## Testing + +- Cover changed behaviour with the smallest meaningful test. +- Add regression tests for fixed bugs. + +## Error handling + +- Fail fast on invalid inputs. +- Preserve actionable error context without leaking secrets. + +## Commit format + +- Use concise conventional commits when possible. +- Explain why in the body when not obvious. + +## Directory layout + +- Keep generated artifacts out of source directories. +- Put shared deterministic helpers in library modules. + +## Review rules + +- Verify scoped files only. +- Flag correctness, security, and contract drift before style. diff --git a/.agents/harness.config.json b/.agents/harness.config.json new file mode 100644 index 0000000..5756b4f --- /dev/null +++ b/.agents/harness.config.json @@ -0,0 +1,94 @@ +{ + "version": 1, + "memory": { + "root": ".agents", + "committed": [ + "architecture.md", + "conventions.md", + "memory", + "specs", + "runs/*/journal.md" + ], + "ignored": [ + ".cache", + "runs/*/events.ndjson", + "runs/*/board.md" + ], + "tokenBudget": 8000, + "compactAtPercent": 85 + }, + "artifacts": { + "architecture": true, + "conventions": true, + "adr": true, + "journal": true, + "spec": true + }, + "index": { + "include": [ + "**/*" + ], + "exclude": [ + "**/node_modules/**", + "**/.git/**", + "**/dist/**", + "**/build/**", + "**/target/**", + "**/vendor/**", + "**/*.min.*", + "**/.agents/**" + ], + "depth": 3, + "budget": 1200 + }, + "models": { + "tiers": { + "cheap": "claude-haiku-4.5", + "mid": "claude-sonnet-5", + "strong": "claude-opus-5" + }, + "roles": { + "conductor": "strong", + "interrogator": "strong", + "scout": "cheap", + "architect": "strong", + "splitter": "mid", + "builder": "mid", + "verifier": "cheap", + "reviewer": "strong", + "integrator": "strong", + "scribe": "cheap" + } + }, + "ralph": { + "maxIterations": 4, + "exitCriteria": [ + "verify-commands-exit-zero", + "acceptance-criteria-checked", + "structural-gate-passes", + "reviewer-approves", + "no-out-of-scope-files" + ], + "onMaxIterations": "escalate" + }, + "verify": { + "commands": [ + { + "name": "test", + "command": "npm run test" + } + ], + "autodetected": true + }, + "concurrency": { + "maxWriteLanes": 4, + "readOnlyFanOut": 6 + }, + "isolation": { + "backend": "worktree" + }, + "context7": { + "required": true, + "envVar": "CONTEXT7_API_KEY" + } +} diff --git a/.agents/memory/INDEX.md b/.agents/memory/INDEX.md new file mode 100644 index 0000000..469983f --- /dev/null +++ b/.agents/memory/INDEX.md @@ -0,0 +1,15 @@ +# Memory index + +Only this file is always loaded. Open shard files only when needed. + +updated: 2026-09-09T20:49:13.380Z +total_tokens: 228 + +| shard | entries | tokens | updated | summary | +| --- | ---: | ---: | --- | --- | +| seed | 0 | 35 | 2026-09-09T20:49:13.379Z | Stable repo facts and bootstrap knowledge. | +| failures | 0 | 38 | 2026-09-09T20:49:13.379Z | Known failures, regressions, and broken approaches. | +| corrections | 0 | 36 | 2026-09-09T20:49:13.379Z | User corrections and changed assumptions. | +| insights | 0 | 37 | 2026-09-09T20:49:13.379Z | Reusable discoveries and design observations. | +| conventions | 0 | 42 | 2026-09-09T20:49:13.379Z | Project-specific conventions not yet promoted to conventions.md. | +| quirks | 0 | 40 | 2026-09-09T20:49:13.379Z | Sharp edges, environment quirks, and non-obvious constraints. | diff --git a/.agents/memory/conventions.md b/.agents/memory/conventions.md new file mode 100644 index 0000000..d3b7d3c --- /dev/null +++ b/.agents/memory/conventions.md @@ -0,0 +1,9 @@ +# conventions memory + +Project-specific conventions not yet promoted to conventions.md. + +Entries use: + +`## — ` + +Optional next line: `tags: a, b` diff --git a/.agents/memory/corrections.md b/.agents/memory/corrections.md new file mode 100644 index 0000000..b2064b0 --- /dev/null +++ b/.agents/memory/corrections.md @@ -0,0 +1,9 @@ +# corrections memory + +User corrections and changed assumptions. + +Entries use: + +`## <ISO timestamp> — <title>` + +Optional next line: `tags: a, b` diff --git a/.agents/memory/failures.md b/.agents/memory/failures.md new file mode 100644 index 0000000..b002447 --- /dev/null +++ b/.agents/memory/failures.md @@ -0,0 +1,9 @@ +# failures memory + +Known failures, regressions, and broken approaches. + +Entries use: + +`## <ISO timestamp> — <title>` + +Optional next line: `tags: a, b` diff --git a/.agents/memory/insights.md b/.agents/memory/insights.md new file mode 100644 index 0000000..36d5ed7 --- /dev/null +++ b/.agents/memory/insights.md @@ -0,0 +1,9 @@ +# insights memory + +Reusable discoveries and design observations. + +Entries use: + +`## <ISO timestamp> — <title>` + +Optional next line: `tags: a, b` diff --git a/.agents/memory/quirks.md b/.agents/memory/quirks.md new file mode 100644 index 0000000..7404a5d --- /dev/null +++ b/.agents/memory/quirks.md @@ -0,0 +1,9 @@ +# quirks memory + +Sharp edges, environment quirks, and non-obvious constraints. + +Entries use: + +`## <ISO timestamp> — <title>` + +Optional next line: `tags: a, b` diff --git a/.agents/memory/seed.md b/.agents/memory/seed.md new file mode 100644 index 0000000..0c7889c --- /dev/null +++ b/.agents/memory/seed.md @@ -0,0 +1,9 @@ +# seed memory + +Stable repo facts and bootstrap knowledge. + +Entries use: + +`## <ISO timestamp> — <title>` + +Optional next line: `tags: a, b` diff --git a/.github/agents/architect.agent.md b/.github/agents/architect.agent.md index 35a625d..4edaa92 100644 --- a/.github/agents/architect.agent.md +++ b/.github/agents/architect.agent.md @@ -16,7 +16,7 @@ Write the spec. Make every acceptance criterion checkable. 1. Read `.agents/specs/<slug>/decisions.md` first. 2. Stop if decisions are missing or incomplete. 3. Run `lh index --budget 6000 --focus <relevant-glob>`. -4. Run `lh graph --brief`. +4. Run `lh graph`. 5. Delegate focused read-only reconnaissance to `scout` when needed. 6. Consult Context7 before using any external library or framework API. 7. Use `resolve-library-id` before `query-docs`. diff --git a/.github/agents/conductor.agent.md b/.github/agents/conductor.agent.md index b4c61a5..0380b64 100644 --- a/.github/agents/conductor.agent.md +++ b/.github/agents/conductor.agent.md @@ -30,7 +30,7 @@ Run the full lean harness pipeline. Edit no product files. 15. For plan, invoke `architect`. 16. Require `.agents/specs/<slug>/spec.md`. 17. Invoke `splitter` to write `.agents/specs/<slug>/plan.dag.json`. -18. Validate the DAG with `lh graph --brief`. +18. Validate the DAG with `lh graph`. 19. Own the dynamic DAG after splitter returns. 20. For every checkpoint, read lane status and verifier output. 21. Re-plan at every checkpoint. @@ -73,7 +73,7 @@ Run the full lean harness pipeline. Edit no product files. - Stop when `lh run end` completes and final verify passes. - Stop when design answers remain missing. - Stop when max Ralph iterations are reached. -- Stop when `lh graph --brief` keeps failing after re-plan. +- Stop when `lh graph` keeps failing after re-plan. - Stop when host strategy forbids required action. ## NEVER DO THIS diff --git a/.github/agents/reviewer.agent.md b/.github/agents/reviewer.agent.md index 3ec44cb..00076bb 100644 --- a/.github/agents/reviewer.agent.md +++ b/.github/agents/reviewer.agent.md @@ -16,7 +16,7 @@ Approve or reject. Check every criterion. 2. Read `.agents/specs/<slug>/spec.md`. 3. Read `.agents/specs/<slug>/plan.dag.json`. 4. Read verifier output. -5. Run `lh graph --brief` unless fresh passing output exists. +5. Run `lh graph` unless fresh passing output exists. 6. List assigned acceptance criteria by id. 7. Check each criterion individually. 8. Check changed files against declared scope globs. @@ -34,7 +34,7 @@ Approve or reject. Check every criterion. 1. All declared verify commands pass. 2. Every assigned `AC-###` passes. -3. `lh graph --brief` passes. +3. `lh graph` passes. 4. Changed files stay inside declared scope. 5. Decisions from `.agents/specs/<slug>/decisions.md` are honored. diff --git a/.github/agents/scout.agent.md b/.github/agents/scout.agent.md index 606d12a..1984cf6 100644 --- a/.github/agents/scout.agent.md +++ b/.github/agents/scout.agent.md @@ -14,7 +14,7 @@ Recon the repo. Return facts, not dumps. 1. Treat the assignment as read-only. 2. Run `lh index --budget <N> --focus <glob>` before manual reads. -3. Run `lh graph --brief` before manual reads. +3. Run `lh graph` before manual reads. 4. Read `.agents/memory/INDEX.md` only if the assignment needs history. 5. Pull memory shards only by explicit relevance. 6. Search by symbol, path, or glob before opening files. diff --git a/.github/agents/splitter.agent.md b/.github/agents/splitter.agent.md index 9d39b0f..cde2c79 100644 --- a/.github/agents/splitter.agent.md +++ b/.github/agents/splitter.agent.md @@ -15,7 +15,7 @@ Emit the lane DAG. Keep write scopes disjoint. 1. Read `.agents/specs/<slug>/spec.md`. 2. Read `.agents/architecture.md` when present. 3. Run `lh index --budget 6000 --focus <relevant-glob>`. -4. Run `lh graph --brief`. +4. Run `lh graph`. 5. Extract every acceptance criterion id. 6. Group work by independently verifiable outcomes. 7. Create read lanes for discovery-only work. @@ -29,7 +29,7 @@ Emit the lane DAG. Keep write scopes disjoint. 15. Add verify commands when known. 16. Add checkpoint hints for risky lanes. 17. Write `.agents/specs/<slug>/plan.dag.json`. -18. Run `lh graph --brief` after writing. +18. Run `lh graph` after writing. 19. If graph fails, revise the DAG until it passes or report blocker. 20. Return lane count, dependency shape, and risk lanes. @@ -65,7 +65,7 @@ Emit the lane DAG. Keep write scopes disjoint. - Stop when spec is missing. - Stop when acceptance criteria are unnumbered. - Stop when write scopes overlap and cannot be separated. -- Stop when `lh graph --brief` blocks the DAG. +- Stop when `lh graph` blocks the DAG. ## NEVER DO THIS diff --git a/.github/instructions/harness.instructions.md b/.github/instructions/harness.instructions.md index 0268041..17954eb 100644 --- a/.github/instructions/harness.instructions.md +++ b/.github/instructions/harness.instructions.md @@ -8,7 +8,7 @@ description: Always-on lean harness behavior, token discipline, style, self-docu ## Token discipline 1. Prefer `lh index --budget <N>` over raw tree reads. -2. Prefer `lh graph --brief` over verbose diagnostics. +2. Prefer `lh graph` over verbose diagnostics. 3. Load only `.agents/memory/INDEX.md` by default. 4. Pull memory shards only on demand with `lh memory get`. 5. Return summaries, tables, and paths instead of file dumps. diff --git a/.github/prompts/onboard.prompt.md b/.github/prompts/onboard.prompt.md index a24d5cb..34269ed 100644 --- a/.github/prompts/onboard.prompt.md +++ b/.github/prompts/onboard.prompt.md @@ -6,6 +6,6 @@ description: Produce a concise lean harness onboarding summary from doctor, inde Invoke the `onboard` skill. -Run `lh doctor`, `lh index --stats --budget 4000`, and `lh graph --brief`. +Run `lh doctor`, `lh index --stats --budget 4000`, and `lh graph`. Read only `.agents/memory/INDEX.md` by default. If VS Code cannot fan out scouts, inspect sequentially. diff --git a/.github/skills/doctor/SKILL.md b/.github/skills/doctor/SKILL.md index 56c13d5..6375290 100644 --- a/.github/skills/doctor/SKILL.md +++ b/.github/skills/doctor/SKILL.md @@ -7,7 +7,7 @@ description: Use when checking harness environment, configuration, host capabili 1. Run `lh doctor`. 2. Run `lh host` when orchestration capability matters. -3. Run `lh graph --brief` when repository structure matters. +3. Run `lh graph` when repository structure matters. 4. Report failures with exact commands and exit status. 5. Suggest the smallest next fix. diff --git a/.github/skills/index/SKILL.md b/.github/skills/index/SKILL.md index a3a7920..5273fa8 100644 --- a/.github/skills/index/SKILL.md +++ b/.github/skills/index/SKILL.md @@ -8,7 +8,7 @@ description: Use when needing repository understanding under a token budget befo 1. Run `lh index --budget <N> --focus <glob>`. 2. Add `--stats` when onboarding or sizing work. 3. Prefer index output before raw reads. -4. Follow with `lh graph --brief` when structure matters. +4. Follow with `lh graph` when structure matters. 5. Read files by hand only after narrowing scope. Return paths and facts, not dumps. diff --git a/.github/skills/onboard/SKILL.md b/.github/skills/onboard/SKILL.md index 199b8c9..8c47550 100644 --- a/.github/skills/onboard/SKILL.md +++ b/.github/skills/onboard/SKILL.md @@ -8,7 +8,7 @@ description: Use when a new contributor or agent needs a concise map of harness 1. Run `lh doctor`. 2. Run `lh index --stats --budget 4000`. 3. Read `.agents/memory/INDEX.md` only. -4. Run `lh graph --brief`. +4. Run `lh graph`. 5. Summarize commands, state paths, conventions, and blockers. Pull shards only when the user asks for deeper history. diff --git a/.github/skills/plan/SKILL.md b/.github/skills/plan/SKILL.md index 60f9586..7d38e4c 100644 --- a/.github/skills/plan/SKILL.md +++ b/.github/skills/plan/SKILL.md @@ -8,7 +8,7 @@ description: Use when decisions are complete and the harness must produce a spec 1. Read `.agents/specs/<slug>/decisions.md`. 2. Invoke `.github/agents/architect.agent.md` for `.agents/specs/<slug>/spec.md`. 3. Invoke `.github/agents/splitter.agent.md` for `.agents/specs/<slug>/plan.dag.json`. -4. Run `lh graph --brief`. +4. Run `lh graph`. 5. Report spec path, DAG path, acceptance ids, and blockers. Do not build before the DAG passes structural gates. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6af1d91 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: ['20', '22'] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm run validate + - run: npm test diff --git a/.gitignore b/.gitignore index f1177a1..dd81c32 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,10 @@ dist/ *.log .DS_Store report.*.json +tests/.tmp/ -# Harness runtime artifacts (per-consumer-repo; here only for fixtures) -.agents/.cache/ +# redsen-lean-harness +.agents/.cache .agents/runs/*/events.ndjson .agents/runs/*/board.md -tests/.tmp/ +# /redsen-lean-harness diff --git a/README.md b/README.md index a43eaaf..58bfe2c 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ exploration is deliberately pushed onto the cheap tier; only summaries return to | --- | --- | | `lh init` | First-run wizard → `.agents/harness.config.json` | | `lh index [--budget N] [--focus g] [--fetch]` | Token-budgeted tree-sitter repo map | -| `lh graph [--brief]` | Structural gate. **Exit 1 on violations** | +| `lh graph` | Structural gate, terse output by default. **Exit 1 on violations** | | `lh lane create\|list\|status\|merge\|drop` | Worktree lanes + file-scope leases | | `lh run start\|event\|end` | NDJSON telemetry + live board | | `lh memory get\|put\|compact\|scan\|list` | Memory shards, compaction, secret scanning | diff --git a/src/commands/memory.mjs b/src/commands/memory.mjs index b1e735b..e5d1074 100644 --- a/src/commands/memory.mjs +++ b/src/commands/memory.mjs @@ -83,7 +83,7 @@ export default async function memory({ flags, positional }) { title: flags.title, body, tags: flags.tags ?? [], - allowSecrets: Boolean(flags.allowSecrets), + allowSecrets: Boolean(flags['allow-secrets']), }); if (!result.ok) { if (json) asJson({ ok: false, findings: result.findings });