@plainconceptsplatform/agent-harness 3.8.1 → 3.8.3

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.
Files changed (144) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +551 -549
  3. package/cli/commands/join.js +259 -259
  4. package/cli/commands/migrate.js +310 -310
  5. package/cli/commands/shared.js +27 -27
  6. package/cli/commands/single.js +79 -79
  7. package/cli/commands/update.js +121 -121
  8. package/cli/commands/wizard.js +134 -134
  9. package/cli/fragments/archive/az.md +97 -97
  10. package/cli/fragments/archive/gh.md +96 -96
  11. package/cli/fragments/archive/gl.md +96 -96
  12. package/cli/fragments/archive/none.md +75 -75
  13. package/cli/fragments/guardrails/codegraph.md +5 -5
  14. package/cli/fragments/guardrails/humanizer.md +4 -4
  15. package/cli/fragments/guardrails/memory.md +4 -4
  16. package/cli/fragments/guardrails/rtk.md +3 -3
  17. package/cli/fragments/guardrails/simple-english.md +4 -4
  18. package/cli/fragments/ops-backlog/az.md +28 -28
  19. package/cli/fragments/ops-backlog/gh.md +28 -28
  20. package/cli/fragments/ops-backlog/jira.md +28 -28
  21. package/cli/fragments/ops-review/az.md +62 -62
  22. package/cli/fragments/ops-review/gh.md +51 -51
  23. package/cli/fragments/ops-review/gl.md +55 -55
  24. package/cli/fragments/ops-ship/az.md +81 -81
  25. package/cli/fragments/ops-ship/gh.md +67 -67
  26. package/cli/fragments/ops-ship/gl.md +84 -84
  27. package/cli/index.js +116 -116
  28. package/cli/presets/agents-content.json +34 -34
  29. package/cli/presets/browser.json +10 -10
  30. package/cli/presets/clean.json +21 -21
  31. package/cli/presets/models.json +68 -68
  32. package/cli/presets/optimization.json +32 -32
  33. package/cli/presets/platforms.json +76 -76
  34. package/cli/presets/source.json +23 -23
  35. package/cli/steps/browser/index.js +48 -48
  36. package/cli/steps/clean/index.js +120 -120
  37. package/cli/steps/copy/agents.js +176 -159
  38. package/cli/steps/copy/commands.js +79 -79
  39. package/cli/steps/copy/fullstack-engineer.js +89 -89
  40. package/cli/steps/copy/index.js +88 -88
  41. package/cli/steps/copy/opencode-json.js +324 -324
  42. package/cli/steps/copy/skills.js +316 -316
  43. package/cli/steps/metadata/index.js +115 -115
  44. package/cli/steps/models/format.js +88 -88
  45. package/cli/steps/models/index.js +64 -64
  46. package/cli/steps/models/write.js +38 -38
  47. package/cli/steps/openspec/index.js +136 -136
  48. package/cli/steps/optimization/codegraph.js +141 -141
  49. package/cli/steps/optimization/detect.js +66 -66
  50. package/cli/steps/optimization/humanizer.js +17 -17
  51. package/cli/steps/optimization/index.js +158 -158
  52. package/cli/steps/optimization/memory.js +91 -91
  53. package/cli/steps/optimization/patch-guardrails.js +111 -111
  54. package/cli/steps/optimization/simple-english.js +17 -17
  55. package/cli/steps/optimization/skills-lock.js +30 -30
  56. package/cli/steps/platform/index.js +109 -109
  57. package/cli/steps/source/index.js +123 -123
  58. package/cli/utils/agent-color.js +111 -111
  59. package/cli/utils/copy.js +134 -134
  60. package/cli/utils/exec-spinner.js +47 -47
  61. package/cli/utils/exec.js +134 -134
  62. package/cli/utils/legacy-check.js +30 -30
  63. package/cli/utils/models-cache.js +58 -58
  64. package/cli/utils/models-pricing.js +42 -42
  65. package/cli/utils/paths.js +82 -82
  66. package/cli/utils/process.js +3 -3
  67. package/cli/utils/terminal.js +6 -6
  68. package/cli/utils/update-manifest.js +75 -75
  69. package/harness/.opencode/_gitignore +10 -10
  70. package/harness/.opencode/commands/init.md +5 -5
  71. package/harness/.opencode/commands/make-architecture.md +5 -5
  72. package/harness/.opencode/commands/make-design.md +5 -5
  73. package/harness/.opencode/commands/make-engineer.md +5 -5
  74. package/harness/.opencode/commands/make-guardrails.md +5 -5
  75. package/harness/.opencode/commands/make-user-model.md +5 -5
  76. package/harness/.opencode/commands/ops-backlog.md +10 -10
  77. package/harness/.opencode/commands/ops-review.md +10 -10
  78. package/harness/.opencode/commands/ops-ship.md +9 -9
  79. package/harness/.opencode/commands/plan-apply.md +9 -9
  80. package/harness/.opencode/commands/plan-archive.md +7 -7
  81. package/harness/.opencode/commands/plan-explore.md +11 -11
  82. package/harness/.opencode/commands/plan-goal.md +5 -5
  83. package/harness/.opencode/commands/plan-propose.md +11 -11
  84. package/harness/.opencode/commands/plan-quick.md +7 -7
  85. package/harness/.opencode/commands/plan-story.md +11 -11
  86. package/harness/.opencode/commands/repo-audit.md +7 -7
  87. package/harness/.opencode/commands/repo-help.md +5 -5
  88. package/harness/.opencode/commands/repo-initialize.md +5 -5
  89. package/harness/.opencode/commands/repo-onboard.md +5 -5
  90. package/harness/.opencode/commands/repo-verify.md +5 -5
  91. package/harness/.opencode/package.json +5 -5
  92. package/harness/.opencode/plugins/pc-commit-coauthor.js +41 -41
  93. package/harness/.opencode/plugins/pc-subagent-monitor.js +184 -184
  94. package/harness/.opencode/plugins/pc-subagent-tiers.js +367 -367
  95. package/harness/.opencode/plugins/pc-system-reminders.js +424 -424
  96. package/harness/.opencode/scripts/check-diff.mjs +305 -304
  97. package/harness/.opencode/scripts/code-rules.mjs +288 -288
  98. package/harness/.opencode/scripts/platform-contract.mjs +366 -339
  99. package/harness/AGENTS.md +55 -49
  100. package/harness/ARCHITECTURE.md +13 -13
  101. package/harness/DESIGN.md +13 -13
  102. package/harness/opencode.jsonc +36 -36
  103. package/harness/openspec/config.yaml +20 -20
  104. package/harness/skills-lock.json +17 -17
  105. package/package.json +12 -14
  106. package/skills/README.md +18 -18
  107. package/skills/agent-harness-cli/SKILL.md +86 -86
  108. package/skills/browser-automation/SKILL.md +72 -72
  109. package/skills/pc-guardrails-generic/SKILL.md +53 -53
  110. package/skills/pc-guardrails-project/SKILL.md +8 -8
  111. package/skills/pc-make-architecture/SKILL.md +33 -33
  112. package/skills/pc-make-architecture/structure-template.md +64 -64
  113. package/skills/pc-make-design/SKILL.md +45 -45
  114. package/skills/pc-make-engineer/SKILL.md +59 -59
  115. package/skills/pc-make-engineer/signal-mapping.md +53 -53
  116. package/skills/pc-make-engineer/template.md +36 -36
  117. package/skills/pc-make-guardrails/SKILL.md +44 -44
  118. package/skills/pc-make-guardrails/category-reference.md +112 -112
  119. package/skills/pc-make-merge-risk-assess/SKILL.md +70 -70
  120. package/skills/pc-make-merge-risk-assess/category-reference.md +114 -114
  121. package/skills/pc-make-user-model/SKILL.md +56 -56
  122. package/skills/pc-ops-ship/SKILL.md +22 -22
  123. package/skills/pc-plan-apply/SKILL.md +90 -90
  124. package/skills/pc-plan-apply/simple-mode.md +21 -21
  125. package/skills/pc-plan-archive/SKILL.md +66 -66
  126. package/skills/pc-plan-explore/SKILL.md +21 -21
  127. package/skills/pc-plan-goal/SKILL.md +91 -91
  128. package/skills/pc-plan-goal/branching.md +39 -39
  129. package/skills/pc-plan-goal/failure-policy.md +30 -30
  130. package/skills/pc-plan-goal/output-mode.md +10 -10
  131. package/skills/pc-plan-goal/output.md +71 -71
  132. package/skills/pc-plan-propose/SKILL.md +127 -127
  133. package/skills/pc-plan-propose/task-annotation.md +39 -39
  134. package/skills/pc-plan-quick/SKILL.md +46 -46
  135. package/skills/pc-plan-story/SKILL.md +93 -93
  136. package/skills/pc-repo-audit/SKILL.md +44 -44
  137. package/skills/pc-repo-help/SKILL.md +87 -87
  138. package/skills/pc-repo-initialize/SKILL.md +119 -119
  139. package/skills/pc-repo-onboard/SKILL.md +32 -32
  140. package/skills/pc-repo-verify/SKILL.md +150 -150
  141. package/skills/pc-userstory-az/SKILL.md +71 -71
  142. package/skills/pc-userstory-browser/SKILL.md +64 -64
  143. package/skills/pc-userstory-gh/SKILL.md +63 -63
  144. package/skills/pc-userstory-jira/SKILL.md +74 -74
package/README.md CHANGED
@@ -1,549 +1,551 @@
1
- <div align="center">
2
-
3
- <img src="https://raw.githubusercontent.com/PlainConceptsPlatform/agent-harness/refs/heads/main/docs/public/assets/logo.png" alt="agent-harness" width="160" />
4
-
5
- # 🧰 agent-harness
6
-
7
- **Installs the Plain Concepts Platform Harness into any codebase, and keeps it up to date. Wires [OpenCode](https://opencode.ai), [OpenSpec](https://github.com/fission-ai/openspec), [codegraph](https://github.com/colbymchenry/codegraph), and [agentmemory](https://github.com/rohitg00/agentmemory) into a multi-agent workflow that runs on native parallel subagents.**
8
-
9
- GitHub, Azure DevOps, Jira, GitLab, browser-based backlog, or combinations (for example, Jira backlog plus GitHub repository, or browser backlog plus GitLab repository).
10
-
11
- **[harness.platform.plainconcepts.dev](https://harness.platform.plainconcepts.dev)**
12
-
13
- [![npm version](https://img.shields.io/npm/v/@plainconceptsplatform/agent-harness?style=flat-square&color=black)](https://www.npmjs.com/package/@plainconceptsplatform/agent-harness) [![npm downloads](https://img.shields.io/npm/dm/@plainconceptsplatform/agent-harness?style=flat-square&color=black)](https://www.npmjs.com/package/@plainconceptsplatform/agent-harness) [![license](https://img.shields.io/npm/l/@plainconceptsplatform/agent-harness?style=flat-square&color=black)](./LICENSE) [![node](https://img.shields.io/node/v/@plainconceptsplatform/agent-harness?style=flat-square&color=black)](https://nodejs.org)
14
-
15
- </div>
16
-
17
- ## What is this?
18
-
19
- Most codebases have no `AGENTS.md`, no architecture documentation an agent can read, and no defined workflow for picking up a task. So agents improvise, and you get a different answer every run.
20
-
21
- **agent-harness** is the CLI that installs the **Plain Concepts Platform Harness** into a repository and keeps it up to date.
22
-
23
- The harness is ours. We build it, our projects run on it, and this CLI is how it gets into a codebase. It is the set of files agents work from: slash commands, `pc-*` skills (the `pc-` is Plain Concepts), an agent team, OpenCode plugins, an OpenSpec workspace, and generated `ARCHITECTURE.md` and `DESIGN.md`.
24
-
25
- Underneath, it wires OpenCode to OpenSpec for change management, native subagent waves for parallel work, codegraph for code intelligence, and agentmemory for context that survives between sessions.
26
-
27
- The CLI has three jobs:
28
-
29
- | Command | What it does |
30
- | --- | --- |
31
- | `npx @plainconceptsplatform/agent-harness` | Installs the harness. A wizard runs once and saves your answers to `.opencode/harness.json`. |
32
- | `npx @plainconceptsplatform/agent-harness update` | Reinstalls the harness from those saved answers, no questions asked. Keeps files you edited. |
33
- | `npx @plainconceptsplatform/agent-harness join` | Sets up a teammate's machine. Touches no committed file. |
34
-
35
- You run the first one once per repository, and the second whenever we ship a release.
36
-
37
- <div align="center">
38
- <img src="https://raw.githubusercontent.com/PlainConceptsPlatform/agent-harness/refs/heads/main/docs/public/assets/demo.gif" alt="agent-harness demo" width="700" />
39
- </div>
40
-
41
- ## Quick start
42
-
43
- ```bash
44
- npx @plainconceptsplatform/agent-harness@latest
45
- ```
46
-
47
- Requires **Node.js 18 or higher**.
48
-
49
- ### Run specific steps
50
-
51
- You can run individual setup or maintenance steps without running the full wizard:
52
-
53
- ```bash
54
- # Run one step directly
55
- npx @plainconceptsplatform/agent-harness clean
56
- npx @plainconceptsplatform/agent-harness platform
57
- npx @plainconceptsplatform/agent-harness copy
58
- npx @plainconceptsplatform/agent-harness openspec
59
- npx @plainconceptsplatform/agent-harness models
60
- npx @plainconceptsplatform/agent-harness optimization
61
- npx @plainconceptsplatform/agent-harness browser
62
- npx @plainconceptsplatform/agent-harness metadata
63
- npx @plainconceptsplatform/agent-harness join
64
-
65
- # Show CLI help and all commands
66
- npx @plainconceptsplatform/agent-harness --help
67
- npx @plainconceptsplatform/agent-harness -h
68
- ```
69
-
70
- When available, step commands reuse context from `.opencode/harness.json`.
71
-
72
- ### Keeping the harness current
73
-
74
- A new release of agent-harness ships new commands, skills and plugins. To pull them into a project that already has the harness:
75
-
76
- ```bash
77
- npx @plainconceptsplatform/agent-harness@latest update
78
- ```
79
-
80
- `update` re-runs every file patch from `.opencode/harness.json` and asks nothing. It keeps a hash of each file it manages in `.opencode/harness-managed.json`, so it leaves your hand edits alone and reports them as preserved. It also skips generated skills like `pc-guardrails-project`, whose contents came from a `/make-*` command rather than from us.
81
-
82
- Reach for individual steps when you want something narrower:
83
-
84
- - `clean` to reset old AI files
85
- - `copy` if templates or skills changed in a new agent-harness release
86
- - `optimization` to reconfigure RTK, quota, Simple English, codegraph, agentmemory, or humanizer, and the guardrails optimization markers
87
- - `metadata` last, to refresh `.opencode/harness.json`
88
- - `join` if you are new to a project that already has the harness and want the local tooling it expects
89
-
90
- > **Upgrading from `opencode-onboard` v1?** v2 renamed the config files and the skill prefix (`ob-` became `pc-`), and it does not migrate v1 projects. The CLI detects one and refuses to run rather than half-patching it. Re-onboard on a clean branch: remove `.opencode/` and `.agents/skills/ob-*`, then run the wizard again.
91
-
92
- > **Browser tooling changed in v2.4.** The `@different-ai/opencode-browser` plugin (and its Chrome extension) was replaced by [`agent-browser`](https://github.com/vercel-labs/agent-browser), wired in as an MCP server in `opencode.jsonc`. Running `update` strips the old plugin entry, adds the MCP block, and installs the new binary — no manual unloading of the extension is needed, though you can remove it from `chrome://extensions` yourself. Skills you wrote that call `browser_*` tools directly must switch to the `agent-browser` CLI or the `agent_browser_*` MCP tools. Backlog-browser users: agent-browser runs its own Chrome, so log in once per project using the `--session backlog --restore` flow described in `pc-userstory-browser`.
93
-
94
- ---
95
-
96
- ## Installing the harness
97
-
98
- The first run is a 10-step wizard. It keeps the current step visible, plus the last two completed steps, so progress is always clear.
99
-
100
- | Step | What happens |
101
- | --- | --- |
102
- | **1. Source scope** | Choose current repository or sibling source roots for code analysis |
103
- | **2. Clean AI files** | Detects existing `AGENTS.md`, `.cursorrules`, `CLAUDE.md`, `.agents/` and so on, then removes them. Preserves your `.agents/skills/` directory. |
104
- | **3. Choose platform** | Backlog (GitHub, Azure DevOps, Jira, browser-based, or None) plus repository (GitHub, Azure DevOps, GitLab, or None). Supports mixed platforms, for example browser backlog plus GitHub repository, or Jira backlog plus GitLab repository. |
105
- | **4. Check platform CLI** | Verifies `gh` (GitHub), or `az` plus `azure-devops` extension (Azure DevOps), or `acli` (Jira), or `glab` (GitLab). Skips CLI checks for browser-based or None platforms. |
106
- | **5. Copy scaffolding** | Copies agents, built-in skills, bootstrap documentation, writes source-roots metadata, applies AGENTS bootstrap patching, copies `skills-lock.json`, then runs `npx skills` |
107
- | **6. Initialize OpenSpec** | Runs `npx @fission-ai/openspec init` silently for structured change management |
108
- | **7. Choose models** | Fetches live model list from [models.dev](https://models.dev), lets you pick plan, build, and fast models with cost indicators and canonical pricing |
109
- | **8. Token optimization tools** | Optional and recommended. One checklist step for RTK check, opencode-quota setup, Simple English install, codegraph install, agentmemory install, humanizer install, and token-optimization rule injection into guardrails |
110
- | **9. Install browser tooling** | Installs `agent-browser` globally and downloads its Chrome for Testing binary |
111
- | **10. Write onboarding metadata** | Writes `.opencode/harness.json` with selected setup details |
112
-
113
- When it finishes, open OpenCode in your project and type:
114
-
115
- ```
116
- /repo-initialize
117
- ```
118
-
119
- OpenCode asks if this is a greenfield or brownfield project. For brownfield projects it generates `ARCHITECTURE.md` and `DESIGN.md` from your actual codebase, archives project history, then activates the full agent team. For greenfield projects it skips documentation generation and leaves placeholder files you can populate later with `/make-architecture` and `/make-design`.
120
-
121
- ---
122
-
123
- ## Commands
124
-
125
- Custom slash commands are installed into `.opencode/commands/` and are available directly in OpenCode.
126
-
127
- Commands that other commands (or agents) need to execute are thin wrappers around `pc-*` skills in `.agents/skills/`. The command handles user invocation and arguments, and the skill holds the procedure. OpenCode has no mechanism for a command to run another command, but any agent can load a skill mid-conversation, which is what makes pipelines like `/plan-goal` composable.
128
-
129
- | Command | Description |
130
- | ------- | ----------- |
131
- | `/repo-help` | Show all commands and when to use each one. Start here if you are unsure. |
132
- | `/repo-onboard` | Guided tour of the project and its agentic infrastructure. Explains agents, commands, skills, OpenSpec workflow, and configuration. Read-only. |
133
- | `/repo-audit` | Read-only audit of every configured source root against fullstack abilities and guardrails. Reports prioritized architecture, quality, dependency, lockfile, tooling, and CI findings. |
134
- | `/repo-initialize` | Initialize the project. Asks greenfield versus brownfield, then activates the agent team. |
135
- | `/plan-explore` | Think through an idea or investigate a problem before committing to a plan. |
136
- | `/plan-propose <url or idea>` | Parse a GitHub Issue, Azure DevOps, Jira, or browser URL, or a direct idea, into a structured plan (proposal, specs, tasks). Enriches each task with agent and model assignments. |
137
- | `/plan-quick <task>` | Quick plan for focused changes. Reads the codebase, creates a task checklist in the Todo pane, and stops. No OpenSpec, no proposals, no specs. |
138
- | `/plan-apply` | Implement tasks from the current plan. Detects format automatically: OpenSpec-annotated tasks run as parallel subagent waves; plain checkboxes run sequentially in-session. |
139
- | `/ops-ship` | Create a pull request for the current branch with screenshots if the user interface changed. |
140
- | `/ops-review` | Read and triage pull request review feedback. Reports what needs fixing. |
141
- | `/ops-backlog` | Create an issue in the backlog platform (GitHub, Azure DevOps, or Jira) from a description. |
142
- | `/plan-archive` | Archive a completed OpenSpec change. |
143
- | `/plan-goal <feature or URL>` | Autonomous, no-confirmation pipeline: branch off main, then explore, propose, apply, archive (one commit per phase). Default mode: merge to main and delete the feature branch. Add `branch` to keep the feature branch without merging or pushing. `push` pushes the branch; `pr` pushes and opens a PR. For loop-engineering. |
144
- | `/make-engineer` | Interactive persona-driven form to add a custom specialist engineer. Pick a persona, then confirm an inspected-and-recommended skill set (architecture/patterns like FSD or design patterns, framework, testing, infra) before it installs. |
145
- | `/make-architecture` | Generate or regenerate `ARCHITECTURE.md` from the codebase. |
146
- | `/make-design` | Generate or regenerate `DESIGN.md` from the design system. |
147
- | `/make-guardrails` | Generate a `pc-guardrails-project` skill from `ARCHITECTURE.md` and project config files. Extracts architecture boundaries, naming, code style, testing, and git workflow rules. Updates all `*-engineer.md` to load the skill. |
148
- | `/repo-verify` | Write the verification plan for the current branch's change: a journey through the new functionality as a fenced YAML block in `verification-plan.md`, stored with the change. The evidence workflow from `@plainconceptsplatform/workflows` replays it in headless Chromium when the pull request merges and archives one screenshot per waypoint in an `evidence/` folder beside the plan. Backend-only changes are traced through to the frontend when their contract is consumed there; a `not-applicable` stub is written when no UI surface is reachable. Does not run checks or take screenshots. Runs automatically in `/plan-goal`. |
149
- | `/make-user-model [user] <tier> <model>` | Set the model for a tier (`plan`, `build`, `fast`). Writes to `harness.json` (team) or `harness.user.json` (user override, gitignored) when `user` prefix is used. Restart to pick up changes: the `pc-subagent-tiers` plugin rebuilds tier agents at startup. Pass a model id or `current` for the active session model. |
150
-
151
- ---
152
-
153
- ## Agents and Skills
154
-
155
- agent-harness draws a hard line between two concepts:
156
-
157
- ### Agents, universal behaviors
158
-
159
- Agents define _how to work_. They are universal personas (same behavior across projects and stacks).
160
-
161
- Current baseline uses a generic execution model:
162
-
163
- ```
164
- build primary. Implements. Full write access. The default.
165
- plan primary. Same body as build, but cannot edit or spawn.
166
- fullstack-engineer subagent. The body build and plan share, and the fallback worker.
167
- *-engineer subagent. User-created specialists, spawned for parallel implementation.
168
- *-engineer.<tier> subagent. The same specialist pinned to a plan/build/fast model.
169
- ```
170
-
171
- `build` and `plan` are the only agents a human selects, and they are overrides of opencode's own two primaries rather than new names. The `pc-subagent-tiers` plugin regenerates both from `fullstack-engineer.md` on every startup, so they always carry the current abilities, each on its own tier model. `plan` differs from `build` in two frontmatter lines: `edit: deny` and `task: deny`; spawning is denied because a plan session that can call `task()` can have a build worker make the change for it. It keeps `bash` so planning can read git and openspec state, and `pc-system-reminders` holds that shell to inspection commands. Everything else is `mode: subagent` and reached through `task()`, never picked from the agent list. Project-specific specialization comes from user-created engineers via `/make-engineer`. During `/plan-apply` the lead inspects the engineers that actually exist in `.opencode/agents/` and spawns matching specialists. Prefer a specialist over `fullstack-engineer`; if none matches, create one.
172
-
173
- ### Skills, platform knowledge
174
-
175
- Skills define _what to know_. They provide project rules, platform behavior, and task-specific execution guidance. Agents auto-detect and load relevant skills; **you do not manually choose skills per prompt**.
176
-
177
- If you choose backlog platform `None`, no userstory skills are injected into the workflow. The project works from direct conversation, local repository context, and optional OpenSpec artifacts only. If you choose repository platform `None`, no pull request skills are injected.
178
-
179
- Current loading model:
180
-
181
- - `pc-guardrails-generic` is mandatory baseline for every agent (git, secrets, quality rules, plus the engineer workflow)
182
- - Baseline context rules and token-optimization guidance live in `AGENTS.md` (always in context), not in a skill
183
-
184
- Default `fullstack-engineer` abilities:
185
-
186
- ```
187
- ## Abilities
188
- - Guardrails: @pc-guardrails-generic, @pc-guardrails-project
189
- ```
190
-
191
- Users are expected to create additional skills and map them into abilities over time.
192
-
193
- Built-in skills (`pc-` prefix) shipped with agent-harness:
194
-
195
- | Skill | Purpose |
196
- | ----- | ------- |
197
- | `pc-guardrails-generic` | Foundation for user guardrails skills |
198
- | `pc-guardrails-project` | Project-specific guardrails, populated by `/make-guardrails` |
199
- | `pc-userstory-gh` | Parse a GitHub Issue URL into a structured work item |
200
- | `pc-userstory-az` | Parse an Azure DevOps work item URL |
201
- | `pc-userstory-jira` | Parse a Jira issue URL via `acli` CLI |
202
- | `pc-userstory-browser` | Parse work item from any URL via browser automation (Linear, Trello, and so on) |
203
- | `browser-automation` | Browser control via `agent-browser` (localhost and browser backlog exception) |
204
- | `pc-plan-explore` | Read-only exploration procedure behind `/plan-explore`; autonomous mode used by `/plan-goal` |
205
- | `pc-plan-propose` | Proposal + task-enrichment procedure behind `/plan-propose`; autonomous mode used by `/plan-goal` |
206
- | `pc-plan-apply` | Wave-implementation procedure behind `/plan-apply`; autonomous mode used by `/plan-goal` |
207
- | `pc-plan-archive` | Archive procedure behind `/plan-archive` (platform flow injected at onboarding); autonomous mode used by `/plan-goal` |
208
- | `pc-ops-ship` | PR-creation procedure behind `/ops-ship` (platform flow injected at onboarding); used by `/plan-goal` pr mode |
209
- | `pc-make-architecture` | ARCHITECTURE.md generation behind `/make-architecture`; used by `/repo-initialize` |
210
- | `pc-make-design` | DESIGN.md generation behind `/make-design`; used by `/repo-initialize` |
211
- | `pc-make-guardrails` | Guardrails generation behind `/make-guardrails`; used by `/repo-initialize` |
212
- | `pc-make-engineer` | Custom engineer creation behind `/make-engineer` |
213
- | `pc-make-user-model` | Tier model configuration behind `/make-user-model` |
214
- | `pc-plan-goal` | Autonomous full-lifecycle pipeline behind `/plan-goal` |
215
- | `pc-plan-quick` | Quick task checklist behind `/plan-quick` |
216
- | `pc-repo-audit` | Read-only health audit across configured source roots and fullstack abilities |
217
- | `pc-repo-verify` | Writes the verification plan (`verification-plan.md`): a journey as a fenced YAML block, replayed in headless Chromium by the evidence workflow when the pull request merges. Its `PC-PROJECT-ENVIRONMENT` slot records how the project starts and signs in. Used by `/repo-verify` and `/plan-goal` |
218
- | `pc-repo-initialize` | Project initialization behind `/repo-initialize` |
219
- | `pc-repo-onboard` | Guided project tour behind `/repo-onboard` |
220
- | `pc-repo-help` | The command reference displayed by `/repo-help`; used by `/repo-initialize` |
221
-
222
- Platform operations are injected during onboarding: pull request creation into the `pc-ops-ship` skill (loaded by `/ops-ship`, and by `/plan-goal` in `pr` mode), archive PR flow into the `pc-plan-archive` skill, and pull request review / issue creation directly into the `/ops-review` and `/ops-backlog` command files.
223
-
224
- Skills live in `.agents/skills/`. Any `SKILL.md` file in a subdirectory is automatically discoverable. Write your own and agents will pick them up.
225
-
226
- ### Models, plan / build / fast
227
-
228
- During onboarding you pick three models:
229
-
230
- | Role | Used by | Pick |
231
- | ---- | ------- | ---- |
232
- | **plan** | Main OpenCode session (the lead) | Something capable with strong reasoning |
233
- | **build** | Specialist engineers (default tier) | Something capable for implementation |
234
- | **fast** | Light helpers (fast tier) | Something fast and cheap |
235
-
236
- Models are fetched live from [models.dev](https://models.dev) (3000+ models, cached weekly). Cost tiers `[$]` `[$$]` `[$$$]` always reflect the canonical provider price, so `github-copilot/claude-opus-4.7` shows `[$$]` not `[$]`.
237
-
238
- ---
239
-
240
- ## The pipeline
241
-
242
- When you give the lead agent a work item URL, execution follows this pipeline. If backlog platform is `None`, skip the work item stage. If repository platform is `None`, skip the pull request stage:
243
-
244
- ```
245
- lead
246
- ↓
247
- parse work item via userstory skill
248
- ↓
249
- plan-propose
250
- proposal + specs + tasks
251
- ↓
252
- [confirm with user]
253
- ↓
254
- wave of subagents (*-engineer, per-tier model)
255
- each implements its assigned tasks → returns result → lead commits group
256
- ↓
257
- verify (tests, build, lint as needed)
258
- ↓
259
- lead (ship mode, if configured)
260
- commit → push → pull request → feedback loop
261
- ```
262
-
263
- 1. Load the platform userstory skill (installed as `pc-userstory`, from the variant matching your backlog platform)
264
- 2. Run `/plan-propose` to produce `proposal.md`, specs, and `tasks.md`
265
- 3. Confirm with user before implementation
266
- 4. Run `/plan-apply` to orchestrate implementation in waves
267
- 5. Each wave spawns engineers in parallel (custom `*-engineer` specialists, each carrying its own tier model), capped at `agents.maxConcurrent`
268
- 6. Each subagent receives its task IDs in its prompt, loads relevant abilities, implements, and returns; the lead commits each group
269
- 7. Verify with tests, build, and lint according to task scope
270
- 8. Ship or update pull request via lead flow
271
-
272
- For unattended Loop Task runs, keep a concrete shell verification task as the final exit-code gate. Inside `/plan-goal`, `/plan-apply` step 10 runs lint, typecheck, test, and build commands and is the checks gate; `/repo-verify` then writes `verification-plan.md` (the journey the evidence workflow replays in headless Chromium once the pull request merges). The final shell task independently proves the critical commands passed before commit or pull request actions.
273
-
274
- Agents run as native OpenCode subagents in parallel waves: no external plugin, no git worktrees. The lead's Todo pane is the live board, and the `pc-subagent-monitor` plugin mirrors state to `.opencode/harness-run.json`. Navigate into any running subagent with `ctrl+x ↓` then `←`/`→`.
275
-
276
- ---
277
-
278
- ## What gets installed
279
-
280
- ```
281
- your-project/
282
- ├── AGENTS.md ← bootstrap mode, replaced after first "/repo-initialize"
283
- ├── ARCHITECTURE.md ← prompt for agents to fill in from your codebase
284
- ├── DESIGN.md ← prompt for agents to fill in from your codebase
285
- ├── opencode.jsonc ← native OpenCode 2 config: agents, permissions, MCP servers
286
- ├── .opencode/
287
- │ ├── harness.json ← harness config: platform, models, maxConcurrentAgents
288
- │ ├── harness-managed.json ← hashes of every managed file, so "update" spares your edits
289
- │ ├── agents/ ← build.md + plan.md (generated primaries), fullstack-engineer,
290
- │ │ and user-created *-engineer files (all subagents)
291
- │ ├── plugins/
292
- │ │ ├── pc-commit-coauthor.js ← server plugin: adds the opencode Co-Authored-By trailer to every agent commit
293
- │ │ ├── pc-subagent-monitor.js ← server plugin: subagent state → .opencode/harness-run.json, and the wave cap
294
- │ │ ├── pc-subagent-tiers.js ← server plugin: derives tier agents and the two primaries
295
- │ │ └── pc-system-reminders.js ← server plugin: gates work on the agent's abilities, denies the never-rules
296
- │ └── scripts/
297
- │ ├── check-diff.mjs ← the comments and tests gate on the current diff (see below)
298
- │ ├── code-rules.mjs ← its rules, the same ones Project-Health scores a repository with
299
- │ └── platform-contract.mjs ← reads .platform/contract.yml, the platform contract (see below)
300
- └── .agents/
301
- └── skills/
302
- ├── pc-guardrails-generic/ ← foundation for user guardrails
303
- ├── pc-guardrails-project/ ← populated by /make-guardrails
304
- ├── pc-userstory/ ← the variant matching your backlog platform, renamed on install
305
- └── browser-automation/
306
- ```
307
-
308
- On OpenCode 2 the terminal client is configured globally (`~/.config/opencode/cli.json`), so the harness ships no project-local `tui.json`; the native session sidebar shows subagents without a sidecar panel.
309
-
310
- Platform skills ship as suffixed variants (`pc-userstory-gh`, `pc-userstory-az`, `pc-userstory-jira`, `pc-userstory-browser`) and the installer copies only the matching one, renamed to its generic name. Platform operations (ship, review, backlog) are injected directly into the `/ops-*` command files from `cli/fragments/ops-*/` during onboarding. Source-roots metadata lands in `.opencode/source-roots.json`. The always-shipped reminder plugin holds editing, shell and spawning until every ability under the agent's `## Abilities` is loaded, guardrails first, and re-arms after compaction. Token-optimization guidance is injected into `pc-guardrails-generic` marker blocks during onboarding.
311
-
312
- ---
313
-
314
- ## Comments and tests gate
315
-
316
- `node .opencode/scripts/check-diff.mjs [--base <ref>] [--json]` reads the diff against the merge base with `origin/HEAD` (committed, uncommitted and untracked) and exits 1 when it:
317
-
318
- - adds more comment lines than 10% of the code lines it adds (2 are always allowed);
319
- - adds a slop shape (banner, region, untracked TODO, a doc comment that repeats the name, commented-out code, an apology), a comment block of five lines or more, an incident story, or a doc comment on an internal symbol;
320
- - touches a file and leaves slop in it, or leaves it with more comments per code line than before;
321
- - grows the tests more than the code: test lines beyond the code lines added (40 always allowed), more than 40 cases per 1,000 code lines (3 always allowed), or any new skipped, focused, snapshot, assertion-less or mock-only test;
322
- - changes a path the platform contract says a template owns, or finds a contract it cannot read (see [Platform contracts](#platform-contracts)).
323
-
324
- It also warns, without failing, on a new file named like something the contract marks for reuse (`reuse-shadow`).
325
-
326
- A tool directive (`nosemgrep`, `biome-ignore`, `eslint-disable`, `@ts-expect-error`, coverage ignores) is not a comment and costs nothing. Code added to a file that has methods in the complexity baseline (`scripts/complexity-baseline.json`, keys `path::method`) counts twice toward the test budget: that gate fails a method whose coverage drops, so its new branches need tests.
327
-
328
- `pc-plan-apply` runs it with the other checks, and the workflows run it before a bot pull request can merge. A project changes the limits in `.opencode/harness.json`:
329
-
330
- ```json
331
- "codeRules": { "commentRatio": 0.1, "commentAllowance": 2, "testRatio": 1, "testAllowance": 40, "casesPerKloc": 40, "caseAllowance": 3, "complexityBaseline": "scripts/complexity-baseline.json" }
332
- ```
333
-
334
- ## Platform contracts
335
-
336
- A repository that receives shared code from an upstream template can describe that relationship in `.platform/contract.yml`. The template can be delivered by Copier, cookiecutter, a git subtree or by hand; the harness reads only the file. It uses the contract to keep agents off the shared code and to point them at what the template already provides.
337
-
338
- The format is open. Other tools may read the same file, such as a workflow that syncs the template or a dashboard of template versions. None of them is required, and the harness never calls them.
339
-
340
- ```yaml
341
- version: 1
342
- source:
343
- name: Acme app template
344
- url: https://github.com/acme/app-template
345
- changes: https://github.com/acme/app-template/issues/new
346
- owned:
347
- - .platform/contract.yml
348
- - src/platform/**
349
- reuse:
350
- docs: [docs/platform/]
351
- packages: ["@acme/ui"]
352
- names: [DataTable]
353
- exceptions: .platform/exceptions.yml
354
- sync:
355
- marker: .copier-answers.yml
356
- version:
357
- file: .copier-answers.yml
358
- key: _commit
359
- update: copier update --trust --defaults --conflict inline
360
- ```
361
-
362
- The template delivers the file, so the template owns it and lists it under `owned`.
363
-
364
- | Field | Required | What the harness does with it |
365
- | --- | --- | --- |
366
- | `version` | yes | Reads `1`. Any other value is an error. |
367
- | `source.name` | yes | Names the owner in every message. |
368
- | `source.url` | yes | Shown in the AGENTS.md block, and the default for `source.changes`. |
369
- | `source.changes` | no | Where every message tells the agent to ask for a change. |
370
- | `owned` | yes | gitwildmatch globs, repository-relative; a leading `/` anchors to the root and `!` excludes. `pc-system-reminders` denies agent edits to these paths, and `check-diff` reports `platform-file` for each one the diff changes. |
371
- | `reuse.docs` | no | Listed in the AGENTS.md block as reading before building something new. `pc-make-architecture` links to these pages instead of describing their topics again. |
372
- | `reuse.packages` | no | Listed in the AGENTS.md block. `check-diff` reads each package from `node_modules` and takes its reusable names from the `exports` subpaths and from the identifiers its type declarations export. |
373
- | `reuse.names` | no | More reusable names, for what cannot be derived from a package. |
374
- | `exceptions` | no | The exceptions file. Default `.platform/exceptions.yml`. |
375
- | `sync.marker` | no | A diff that changes this file is a template sync. `check-diff` lets it rewrite owned paths, and `pc-system-reminders` allows edits to them while the file has uncommitted changes, so a sync's conflicts can be resolved. |
376
- | `sync.version`, `sync.update` | no | Validated but not used: they are for the tool that updates the repository from the template. |
377
-
378
- ### Reuse before you build
379
-
380
- When the contract has `reuse`, `agent-harness` install and `update` write this block into AGENTS.md between `<!-- PC-PLATFORM-CONTRACT-START -->` and `<!-- PC-PLATFORM-CONTRACT-END -->`, appending the pair when AGENTS.md has none. For the example above:
381
-
382
- ```markdown
383
- ## Reuse before you build
384
-
385
- This repository receives shared code from Acme app template (https://github.com/acme/app-template), declared in `.platform/contract.yml`.
386
-
387
- - Never design something new before reading `docs/platform/`.
388
- - Never re-implement an export of `@acme/ui`; import it.
389
- - Never write your own `DataTable`; reuse the existing one.
390
- - Never edit a path listed under `owned`. Ask for the change at https://github.com/acme/app-template/issues/new, or add a dated exception to `.platform/exceptions.yml`.
391
- ```
392
-
393
- Without a contract, or without `reuse`, the block is empty. With `reuse`, `pc-plan-propose` gives every proposal a `## What is reused` section, and `pc-plan-apply` stops on a proposal that lacks it. `check-diff` warns with `reuse-shadow`, without failing, when a new source file's name matches a reusable name: `data-table.tsx`, `DataTable.tsx` and `data_table.ts` all match `DataTable`.
394
-
395
- ### Exceptions
396
-
397
- An app that needs to diverge from an owned path for a while records it in the exceptions file:
398
-
399
- ```yaml
400
- exceptions:
401
- - path: src/platform/audit/**
402
- reason: Local audit sink until the template supports it
403
- issue: https://github.com/acme/app-template/issues/12
404
- expires: 2026-12-31
405
- ```
406
-
407
- An exception covers the owned paths its glob matches until the end of its `expires` day, in both `pc-system-reminders` and `check-diff`. An expired entry no longer applies.
408
-
409
- ### Errors
410
-
411
- A contract that does not read gives one error that names the file and the field, such as ``.platform/contract.yml: `source.name` is required and must be a non-empty string.`` The guards never pass silently on it: `check-diff` fails with `platform-contract`, and `pc-system-reminders` denies every edit outside `.platform/` until the file is fixed. Install and update warn and leave the AGENTS.md block as it was.
412
-
413
- ### The legacy implicit contract
414
-
415
- Harness 3.7.0 read `.copier-answers.yml` and `.platform/manifest`, one glob per line. A repository with both files and no `contract.yml` is still read, as this contract:
416
-
417
- - `source.name` is the repository name at the end of `_src_path`, and `source.url` and `source.changes` are `_src_path`;
418
- - `owned` is the manifest's lines;
419
- - `sync.marker` and `sync.version.file` are `.copier-answers.yml`, with `sync.version.key` `_commit`;
420
- - there is no `reuse`.
421
-
422
- When both exist, `contract.yml` wins. A repository with neither sees no change in any tool.
423
-
424
- ## The bootstrap sequence
425
-
426
- The first time you type `init` in OpenCode after onboarding, the agent asks whether this is a **greenfield** or **brownfield** project:
427
-
428
- ### Brownfield (existing codebase)
429
-
430
- 1. Bootstrap-mode `AGENTS.md` triggers the initialization workflow
431
- 2. OpenCode archives existing project context into OpenSpec (`project-history`)
432
- 3. OpenCode runs `/make-architecture` to generate real `ARCHITECTURE.md` from your codebase
433
- 4. OpenCode runs `/make-design` to generate real `DESIGN.md` from your design system
434
- 5. OpenSpec `config.yaml` is populated with discovered tech stack and domain context
435
- 6. Bootstrap `AGENTS.md` is replaced with production guidance
436
- 7. Team workflows become fully active for normal implementation tasks
437
-
438
- ### Greenfield (new project, little or no existing code)
439
-
440
- 1. Bootstrap-mode `AGENTS.md` triggers the initialization workflow
441
- 2. OpenSpec `config.yaml` is populated with what is known (intended stack, domain)
442
- 3. Bootstrap `AGENTS.md` is replaced with production guidance
443
- 4. `ARCHITECTURE.md` and `DESIGN.md` are left as placeholder files
444
-
445
- Once your codebase has meaningful content, run:
446
- - `/make-architecture` to generate architecture documentation
447
- - `/make-design` to generate design system documentation
448
-
449
- Both commands are safe to rerun at any time as the project evolves.
450
-
451
- ---
452
-
453
- ## Token Budget Controls
454
-
455
- Long unattended agent sessions can consume significant tokens. Set these controls up **before** first use:
456
-
457
- 1. **Set provider-side limits first**: monthly soft-limit plus hard usage cap in your provider dashboard:
458
- - OpenAI: [platform.openai.com/account/limits](https://platform.openai.com/account/limits)
459
- - Anthropic: [console.anthropic.com](https://console.anthropic.com)
460
- - Google AI Studio: [aistudio.google.com/app/usage](https://aistudio.google.com/app/usage)
461
-
462
- 2. **Route models by task type**: use a fast and cheap model (for example `haiku`, `gpt-4o-mini`) for orchestration and status loops; reserve expensive models (for example `sonnet`, `opus`, `gpt-4o`) for implementation tasks only.
463
-
464
- 3. **Monitor provider dashboards**: check usage at your provider's dashboard before and during `/plan-apply` sessions.
465
-
466
- 4. **Confirm before large runs**: the onboarded `/plan-apply` workflow will ask for your confirmation before spawning agents for Medium (4 to 7 tasks) or High (8 or more tasks) scope sessions.
467
-
468
- ---
469
-
470
- ## Prerequisites
471
-
472
- | Requirement | Notes |
473
- | ----------- | ----- |
474
- | **Node.js 18 or higher** | Required |
475
- | **[OpenCode](https://opencode.ai)** | The agent runtime |
476
- | **[gh CLI](https://cli.github.com)** | GitHub platform, must be authenticated |
477
- | **[az CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)** plus azure-devops extension | Azure DevOps platform |
478
- | **[acli](https://developer.atlassian.com/cloud/acli/guides/install-acli/)** | Jira (Atlassian) backlog platform, must be authenticated |
479
- | **[glab](https://gitlab.com/gitlab-org/cli/#installation)** | GitLab repository platform, must be authenticated |
480
-
481
- ---
482
-
483
- ## Development
484
-
485
- The repository splits along one line: **`harness/` is the product, `cli/` is the machinery that installs it.**
486
-
487
- ```
488
- harness/ what lands in your repository, copied verbatim
489
- cli/ the installer: commands, wizard steps, presets, fragments
490
- skills/ skills about this CLI, for agents that operate it
491
- docs/ the documentation site
492
- ```
493
-
494
- Browse `harness/` to see what the Plain Concepts Platform Harness actually is, without reading a line of installer code.
495
-
496
- Inside `cli/`, the layout follows the ten wizard steps: one directory per step under `cli/steps/`, each owning its prompts and its file writes, with `cli/commands/` holding the top-level entry points (`wizard`, `update`, `join`, `migrate`, `single`).
497
-
498
- Data the CLI reads lives in two places, split by kind:
499
-
500
- **`cli/presets/`** holds JSON that shapes the wizard's questions and defaults:
501
-
502
- - `source.json` controls source-scope prompt options
503
- - `platforms.json` controls platform labels, CLI checks, and backlog-only flags
504
- - `clean.json` controls AI file detection and preservation
505
- - `models.json` controls model role prompts and agent assignments
506
- - `optimization.json` controls RTK, quota, Simple English, codegraph, agentmemory, and humanizer checklist defaults
507
- - `quota.json` controls opencode-quota defaults
508
- - `browser.json` controls the agent-browser installer (npm package + Chrome setup)
509
-
510
- **`cli/fragments/`** holds Markdown injected into the installed harness, one directory per marker family: `archive/`, `guardrails/`, `ops-backlog/`, `ops-review/`, `ops-ship/`. Each file is the platform-specific body that replaces a `<!-- PC-PLATFORM-*-START -->` block.
511
-
512
- Every filename the harness writes into a project is declared once in `cli/utils/paths.js`. Change it there, and remember the OpenCode plugins under `harness/.opencode/plugins/` read those same names at runtime.
513
-
514
- `skills/` holds both the installable `pc-*` skills and the `agent-harness-cli` skill for agents operating this CLI. See [skills/README.md](./skills/README.md). All of them ship to npm and are discoverable by `npx skills`, so you can install individual skills into any project without the full harness:
515
-
516
- ```bash
517
- npx skills add PlainConceptsPlatform/agent-harness
518
- # or scope to a single skill:
519
- npx skills add PlainConceptsPlatform/agent-harness --skill pc-ops-ship
520
- ```
521
-
522
- ```bash
523
- git clone https://github.com/PlainConceptsPlatform/agent-harness.git
524
- cd agent-harness
525
- pnpm install
526
-
527
- # Run the CLI locally
528
- node cli/index.js
529
-
530
- # Run tests
531
- pnpm test
532
-
533
- # Run linting
534
- pnpm lint
535
-
536
- # Fix auto-fixable lint issues
537
- pnpm lint:fix
538
-
539
- # Watch mode
540
- pnpm test:watch
541
- ```
542
-
543
- Tests are written with [Vitest](https://vitest.dev). Linting uses ESLint flat config with Node ESM defaults and stricter correctness rules.
544
-
545
- ---
546
-
547
- ## License
548
-
549
- MIT © [Plain Concepts](https://github.com/PlainConceptsPlatform)
1
+ <div align="center">
2
+
3
+ <img src="https://raw.githubusercontent.com/PlainConceptsPlatform/agent-harness/refs/heads/main/docs/public/assets/logo.png" alt="agent-harness" width="160" />
4
+
5
+ # 🧰 agent-harness
6
+
7
+ **Installs the Plain Concepts Platform Harness into any codebase, and keeps it up to date. Wires [OpenCode](https://opencode.ai), [OpenSpec](https://github.com/fission-ai/openspec), [codegraph](https://github.com/colbymchenry/codegraph), and [agentmemory](https://github.com/rohitg00/agentmemory) into a multi-agent workflow that runs on native parallel subagents.**
8
+
9
+ GitHub, Azure DevOps, Jira, GitLab, browser-based backlog, or combinations (for example, Jira backlog plus GitHub repository, or browser backlog plus GitLab repository).
10
+
11
+ **[harness.platform.plainconcepts.dev](https://harness.platform.plainconcepts.dev)**
12
+
13
+ [![npm version](https://img.shields.io/npm/v/@plainconceptsplatform/agent-harness?style=flat-square&color=black)](https://www.npmjs.com/package/@plainconceptsplatform/agent-harness) [![npm downloads](https://img.shields.io/npm/dm/@plainconceptsplatform/agent-harness?style=flat-square&color=black)](https://www.npmjs.com/package/@plainconceptsplatform/agent-harness) [![license](https://img.shields.io/npm/l/@plainconceptsplatform/agent-harness?style=flat-square&color=black)](./LICENSE) [![node](https://img.shields.io/node/v/@plainconceptsplatform/agent-harness?style=flat-square&color=black)](https://nodejs.org)
14
+
15
+ </div>
16
+
17
+ ## What is this?
18
+
19
+ Most codebases have no `AGENTS.md`, no architecture documentation an agent can read, and no defined workflow for picking up a task. So agents improvise, and you get a different answer every run.
20
+
21
+ **agent-harness** is the CLI that installs the **Plain Concepts Platform Harness** into a repository and keeps it up to date.
22
+
23
+ The harness is ours. We build it, our projects run on it, and this CLI is how it gets into a codebase. It is the set of files agents work from: slash commands, `pc-*` skills (the `pc-` is Plain Concepts), an agent team, OpenCode plugins, an OpenSpec workspace, and generated `ARCHITECTURE.md` and `DESIGN.md`.
24
+
25
+ Underneath, it wires OpenCode to OpenSpec for change management, native subagent waves for parallel work, codegraph for code intelligence, and agentmemory for context that survives between sessions.
26
+
27
+ The CLI has three jobs:
28
+
29
+ | Command | What it does |
30
+ | --- | --- |
31
+ | `npx @plainconceptsplatform/agent-harness` | Installs the harness. A wizard runs once and saves your answers to `.opencode/harness.json`. |
32
+ | `npx @plainconceptsplatform/agent-harness update` | Reinstalls the harness from those saved answers, no questions asked. Keeps files you edited. |
33
+ | `npx @plainconceptsplatform/agent-harness join` | Sets up a teammate's machine. Touches no committed file. |
34
+
35
+ You run the first one once per repository, and the second whenever we ship a release.
36
+
37
+ <div align="center">
38
+ <img src="https://raw.githubusercontent.com/PlainConceptsPlatform/agent-harness/refs/heads/main/docs/public/assets/demo.gif" alt="agent-harness demo" width="700" />
39
+ </div>
40
+
41
+ ## Quick start
42
+
43
+ ```bash
44
+ npx @plainconceptsplatform/agent-harness@latest
45
+ ```
46
+
47
+ Requires **Node.js 18 or higher**.
48
+
49
+ ### Run specific steps
50
+
51
+ You can run individual setup or maintenance steps without running the full wizard:
52
+
53
+ ```bash
54
+ # Run one step directly
55
+ npx @plainconceptsplatform/agent-harness clean
56
+ npx @plainconceptsplatform/agent-harness platform
57
+ npx @plainconceptsplatform/agent-harness copy
58
+ npx @plainconceptsplatform/agent-harness openspec
59
+ npx @plainconceptsplatform/agent-harness models
60
+ npx @plainconceptsplatform/agent-harness optimization
61
+ npx @plainconceptsplatform/agent-harness browser
62
+ npx @plainconceptsplatform/agent-harness metadata
63
+ npx @plainconceptsplatform/agent-harness join
64
+
65
+ # Show CLI help and all commands
66
+ npx @plainconceptsplatform/agent-harness --help
67
+ npx @plainconceptsplatform/agent-harness -h
68
+ ```
69
+
70
+ When available, step commands reuse context from `.opencode/harness.json`.
71
+
72
+ ### Keeping the harness current
73
+
74
+ A new release of agent-harness ships new commands, skills and plugins. To pull them into a project that already has the harness:
75
+
76
+ ```bash
77
+ npx @plainconceptsplatform/agent-harness@latest update
78
+ ```
79
+
80
+ `update` re-runs every file patch from `.opencode/harness.json` and asks nothing. It keeps a hash of each file it manages in `.opencode/harness-managed.json`, so it leaves your hand edits alone and reports them as preserved. It also skips generated skills like `pc-guardrails-project`, whose contents came from a `/make-*` command rather than from us.
81
+
82
+ Reach for individual steps when you want something narrower:
83
+
84
+ - `clean` to reset old AI files
85
+ - `copy` if templates or skills changed in a new agent-harness release
86
+ - `optimization` to reconfigure RTK, quota, Simple English, codegraph, agentmemory, or humanizer, and the guardrails optimization markers
87
+ - `metadata` last, to refresh `.opencode/harness.json`
88
+ - `join` if you are new to a project that already has the harness and want the local tooling it expects
89
+
90
+ > **Upgrading from `opencode-onboard` v1?** v2 renamed the config files and the skill prefix (`ob-` became `pc-`), and it does not migrate v1 projects. The CLI detects one and refuses to run rather than half-patching it. Re-onboard on a clean branch: remove `.opencode/` and `.agents/skills/ob-*`, then run the wizard again.
91
+
92
+ > **Browser tooling changed in v2.4.** The `@different-ai/opencode-browser` plugin (and its Chrome extension) was replaced by [`agent-browser`](https://github.com/vercel-labs/agent-browser), wired in as an MCP server in `opencode.jsonc`. Running `update` strips the old plugin entry, adds the MCP block, and installs the new binary — no manual unloading of the extension is needed, though you can remove it from `chrome://extensions` yourself. Skills you wrote that call `browser_*` tools directly must switch to the `agent-browser` CLI or the `agent_browser_*` MCP tools. Backlog-browser users: agent-browser runs its own Chrome, so log in once per project using the `--session backlog --restore` flow described in `pc-userstory-browser`.
93
+
94
+ ---
95
+
96
+ ## Installing the harness
97
+
98
+ The first run is a 10-step wizard. It keeps the current step visible, plus the last two completed steps, so progress is always clear.
99
+
100
+ | Step | What happens |
101
+ | --- | --- |
102
+ | **1. Source scope** | Choose current repository or sibling source roots for code analysis |
103
+ | **2. Clean AI files** | Detects existing `AGENTS.md`, `.cursorrules`, `CLAUDE.md`, `.agents/` and so on, then removes them. Preserves your `.agents/skills/` directory. |
104
+ | **3. Choose platform** | Backlog (GitHub, Azure DevOps, Jira, browser-based, or None) plus repository (GitHub, Azure DevOps, GitLab, or None). Supports mixed platforms, for example browser backlog plus GitHub repository, or Jira backlog plus GitLab repository. |
105
+ | **4. Check platform CLI** | Verifies `gh` (GitHub), or `az` plus `azure-devops` extension (Azure DevOps), or `acli` (Jira), or `glab` (GitLab). Skips CLI checks for browser-based or None platforms. |
106
+ | **5. Copy scaffolding** | Copies agents, built-in skills, bootstrap documentation, writes source-roots metadata, applies AGENTS bootstrap patching, copies `skills-lock.json`, then runs `npx skills` |
107
+ | **6. Initialize OpenSpec** | Runs `npx @fission-ai/openspec init` silently for structured change management |
108
+ | **7. Choose models** | Fetches live model list from [models.dev](https://models.dev), lets you pick plan, build, and fast models with cost indicators and canonical pricing |
109
+ | **8. Token optimization tools** | Optional and recommended. One checklist step for RTK check, opencode-quota setup, Simple English install, codegraph install, agentmemory install, humanizer install, and token-optimization rule injection into guardrails |
110
+ | **9. Install browser tooling** | Installs `agent-browser` globally and downloads its Chrome for Testing binary |
111
+ | **10. Write onboarding metadata** | Writes `.opencode/harness.json` with selected setup details |
112
+
113
+ When it finishes, open OpenCode in your project and type:
114
+
115
+ ```
116
+ /repo-initialize
117
+ ```
118
+
119
+ OpenCode asks if this is a greenfield or brownfield project. For brownfield projects it generates `ARCHITECTURE.md` and `DESIGN.md` from your actual codebase, archives project history, then activates the full agent team. For greenfield projects it skips documentation generation and leaves placeholder files you can populate later with `/make-architecture` and `/make-design`.
120
+
121
+ ---
122
+
123
+ ## Commands
124
+
125
+ Custom slash commands are installed into `.opencode/commands/` and are available directly in OpenCode.
126
+
127
+ Commands that other commands (or agents) need to execute are thin wrappers around `pc-*` skills in `.agents/skills/`. The command handles user invocation and arguments, and the skill holds the procedure. OpenCode has no mechanism for a command to run another command, but any agent can load a skill mid-conversation, which is what makes pipelines like `/plan-goal` composable.
128
+
129
+ | Command | Description |
130
+ | ------- | ----------- |
131
+ | `/repo-help` | Show all commands and when to use each one. Start here if you are unsure. |
132
+ | `/repo-onboard` | Guided tour of the project and its agentic infrastructure. Explains agents, commands, skills, OpenSpec workflow, and configuration. Read-only. |
133
+ | `/repo-audit` | Read-only audit of every configured source root against fullstack abilities and guardrails. Reports prioritized architecture, quality, dependency, lockfile, tooling, and CI findings. |
134
+ | `/repo-initialize` | Initialize the project. Asks greenfield versus brownfield, then activates the agent team. |
135
+ | `/plan-explore` | Think through an idea or investigate a problem before committing to a plan. |
136
+ | `/plan-propose <url or idea>` | Parse a GitHub Issue, Azure DevOps, Jira, or browser URL, or a direct idea, into a structured plan (proposal, specs, tasks). Enriches each task with agent and model assignments. |
137
+ | `/plan-quick <task>` | Quick plan for focused changes. Reads the codebase, creates a task checklist in the Todo pane, and stops. No OpenSpec, no proposals, no specs. |
138
+ | `/plan-apply` | Implement tasks from the current plan. Detects format automatically: OpenSpec-annotated tasks run as parallel subagent waves; plain checkboxes run sequentially in-session. |
139
+ | `/ops-ship` | Create a pull request for the current branch with screenshots if the user interface changed. |
140
+ | `/ops-review` | Read and triage pull request review feedback. Reports what needs fixing. |
141
+ | `/ops-backlog` | Create an issue in the backlog platform (GitHub, Azure DevOps, or Jira) from a description. |
142
+ | `/plan-archive` | Archive a completed OpenSpec change. |
143
+ | `/plan-goal <feature or URL>` | Autonomous, no-confirmation pipeline: branch off main, then explore, propose, apply, archive (one commit per phase). Default mode: merge to main and delete the feature branch. Add `branch` to keep the feature branch without merging or pushing. `push` pushes the branch; `pr` pushes and opens a PR. For loop-engineering. |
144
+ | `/make-engineer` | Interactive persona-driven form to add a custom specialist engineer. Pick a persona, then confirm an inspected-and-recommended skill set (architecture/patterns like FSD or design patterns, framework, testing, infra) before it installs. |
145
+ | `/make-architecture` | Generate or regenerate `ARCHITECTURE.md` from the codebase. |
146
+ | `/make-design` | Generate or regenerate `DESIGN.md` from the design system. |
147
+ | `/make-guardrails` | Generate a `pc-guardrails-project` skill from `ARCHITECTURE.md` and project config files. Extracts architecture boundaries, naming, code style, testing, and git workflow rules. Updates all `*-engineer.md` to load the skill. |
148
+ | `/repo-verify` | Write the verification plan for the current branch's change: a journey through the new functionality as a fenced YAML block in `verification-plan.md`, stored with the change. The evidence workflow from `@plainconceptsplatform/workflows` replays it in headless Chromium when the pull request merges and archives one screenshot per waypoint in an `evidence/` folder beside the plan. Backend-only changes are traced through to the frontend when their contract is consumed there; a `not-applicable` stub is written when no UI surface is reachable. Does not run checks or take screenshots. Runs automatically in `/plan-goal`. |
149
+ | `/make-user-model [user] <tier> <model>` | Set the model for a tier (`plan`, `build`, `fast`). Writes to `harness.json` (team) or `harness.user.json` (user override, gitignored) when `user` prefix is used. Restart to pick up changes: the `pc-subagent-tiers` plugin rebuilds tier agents at startup. Pass a model id or `current` for the active session model. |
150
+
151
+ ---
152
+
153
+ ## Agents and Skills
154
+
155
+ agent-harness draws a hard line between two concepts:
156
+
157
+ ### Agents, universal behaviors
158
+
159
+ Agents define _how to work_. They are universal personas (same behavior across projects and stacks).
160
+
161
+ Current baseline uses a generic execution model:
162
+
163
+ ```
164
+ build primary. Implements. Full write access. The default.
165
+ plan primary. Same body as build, but cannot edit or spawn.
166
+ fullstack-engineer subagent. The body build and plan share, and the fallback worker.
167
+ *-engineer subagent. User-created specialists, spawned for parallel implementation.
168
+ *-engineer.<tier> subagent. The same specialist pinned to a plan/build/fast model.
169
+ ```
170
+
171
+ `build` and `plan` are the only agents a human selects, and they are overrides of opencode's own two primaries rather than new names. The `pc-subagent-tiers` plugin regenerates both from `fullstack-engineer.md` on every startup, so they always carry the current abilities, each on its own tier model. `plan` differs from `build` in two frontmatter lines: `edit: deny` and `task: deny`; spawning is denied because a plan session that can call `task()` can have a build worker make the change for it. It keeps `bash` so planning can read git and openspec state, and `pc-system-reminders` holds that shell to inspection commands. Everything else is `mode: subagent` and reached through `task()`, never picked from the agent list. Project-specific specialization comes from user-created engineers via `/make-engineer`. During `/plan-apply` the lead inspects the engineers that actually exist in `.opencode/agents/` and spawns matching specialists. Prefer a specialist over `fullstack-engineer`; if none matches, create one.
172
+
173
+ ### Skills, platform knowledge
174
+
175
+ Skills define _what to know_. They provide project rules, platform behavior, and task-specific execution guidance. Agents auto-detect and load relevant skills; **you do not manually choose skills per prompt**.
176
+
177
+ If you choose backlog platform `None`, no userstory skills are injected into the workflow. The project works from direct conversation, local repository context, and optional OpenSpec artifacts only. If you choose repository platform `None`, no pull request skills are injected.
178
+
179
+ Current loading model:
180
+
181
+ - `pc-guardrails-generic` is mandatory baseline for every agent (git, secrets, quality rules, plus the engineer workflow)
182
+ - `AGENTS.md` states the file paths to read before any edit, shell command or subagent spawn, so agents that do not discover `.agents/skills` natively (Claude Code reads `.claude/skills`) still load the guardrails
183
+ - Baseline context rules and token-optimization guidance live in `AGENTS.md` (always in context), not in a skill
184
+ - Humanizer and Simple English are read on demand before writing prose; they are not transitive requirements of the guardrails
185
+
186
+ Default `fullstack-engineer` abilities:
187
+
188
+ ```
189
+ ## Abilities
190
+ - Guardrails: @pc-guardrails-generic, @pc-guardrails-project
191
+ ```
192
+
193
+ Users are expected to create additional skills and map them into abilities over time.
194
+
195
+ Built-in skills (`pc-` prefix) shipped with agent-harness:
196
+
197
+ | Skill | Purpose |
198
+ | ----- | ------- |
199
+ | `pc-guardrails-generic` | Foundation for user guardrails skills |
200
+ | `pc-guardrails-project` | Project-specific guardrails, populated by `/make-guardrails` |
201
+ | `pc-userstory-gh` | Parse a GitHub Issue URL into a structured work item |
202
+ | `pc-userstory-az` | Parse an Azure DevOps work item URL |
203
+ | `pc-userstory-jira` | Parse a Jira issue URL via `acli` CLI |
204
+ | `pc-userstory-browser` | Parse work item from any URL via browser automation (Linear, Trello, and so on) |
205
+ | `browser-automation` | Browser control via `agent-browser` (localhost and browser backlog exception) |
206
+ | `pc-plan-explore` | Read-only exploration procedure behind `/plan-explore`; autonomous mode used by `/plan-goal` |
207
+ | `pc-plan-propose` | Proposal + task-enrichment procedure behind `/plan-propose`; autonomous mode used by `/plan-goal` |
208
+ | `pc-plan-apply` | Wave-implementation procedure behind `/plan-apply`; autonomous mode used by `/plan-goal` |
209
+ | `pc-plan-archive` | Archive procedure behind `/plan-archive` (platform flow injected at onboarding); autonomous mode used by `/plan-goal` |
210
+ | `pc-ops-ship` | PR-creation procedure behind `/ops-ship` (platform flow injected at onboarding); used by `/plan-goal` pr mode |
211
+ | `pc-make-architecture` | ARCHITECTURE.md generation behind `/make-architecture`; used by `/repo-initialize` |
212
+ | `pc-make-design` | DESIGN.md generation behind `/make-design`; used by `/repo-initialize` |
213
+ | `pc-make-guardrails` | Guardrails generation behind `/make-guardrails`; used by `/repo-initialize` |
214
+ | `pc-make-engineer` | Custom engineer creation behind `/make-engineer` |
215
+ | `pc-make-user-model` | Tier model configuration behind `/make-user-model` |
216
+ | `pc-plan-goal` | Autonomous full-lifecycle pipeline behind `/plan-goal` |
217
+ | `pc-plan-quick` | Quick task checklist behind `/plan-quick` |
218
+ | `pc-repo-audit` | Read-only health audit across configured source roots and fullstack abilities |
219
+ | `pc-repo-verify` | Writes the verification plan (`verification-plan.md`): a journey as a fenced YAML block, replayed in headless Chromium by the evidence workflow when the pull request merges. Its `PC-PROJECT-ENVIRONMENT` slot records how the project starts and signs in. Used by `/repo-verify` and `/plan-goal` |
220
+ | `pc-repo-initialize` | Project initialization behind `/repo-initialize` |
221
+ | `pc-repo-onboard` | Guided project tour behind `/repo-onboard` |
222
+ | `pc-repo-help` | The command reference displayed by `/repo-help`; used by `/repo-initialize` |
223
+
224
+ Platform operations are injected during onboarding: pull request creation into the `pc-ops-ship` skill (loaded by `/ops-ship`, and by `/plan-goal` in `pr` mode), archive PR flow into the `pc-plan-archive` skill, and pull request review / issue creation directly into the `/ops-review` and `/ops-backlog` command files.
225
+
226
+ Skills live in `.agents/skills/`. Any `SKILL.md` file in a subdirectory is automatically discoverable. Write your own and agents will pick them up.
227
+
228
+ ### Models, plan / build / fast
229
+
230
+ During onboarding you pick three models:
231
+
232
+ | Role | Used by | Pick |
233
+ | ---- | ------- | ---- |
234
+ | **plan** | Main OpenCode session (the lead) | Something capable with strong reasoning |
235
+ | **build** | Specialist engineers (default tier) | Something capable for implementation |
236
+ | **fast** | Light helpers (fast tier) | Something fast and cheap |
237
+
238
+ Models are fetched live from [models.dev](https://models.dev) (3000+ models, cached weekly). Cost tiers `[$]` `[$$]` `[$$$]` always reflect the canonical provider price, so `github-copilot/claude-opus-4.7` shows `[$$]` not `[$]`.
239
+
240
+ ---
241
+
242
+ ## The pipeline
243
+
244
+ When you give the lead agent a work item URL, execution follows this pipeline. If backlog platform is `None`, skip the work item stage. If repository platform is `None`, skip the pull request stage:
245
+
246
+ ```
247
+ lead
248
+ ↓
249
+ parse work item via userstory skill
250
+ ↓
251
+ plan-propose
252
+ proposal + specs + tasks
253
+ ↓
254
+ [confirm with user]
255
+ ↓
256
+ wave of subagents (*-engineer, per-tier model)
257
+ each implements its assigned tasks → returns result → lead commits group
258
+ ↓
259
+ verify (tests, build, lint as needed)
260
+ ↓
261
+ lead (ship mode, if configured)
262
+ commit → push → pull request → feedback loop
263
+ ```
264
+
265
+ 1. Load the platform userstory skill (installed as `pc-userstory`, from the variant matching your backlog platform)
266
+ 2. Run `/plan-propose` to produce `proposal.md`, specs, and `tasks.md`
267
+ 3. Confirm with user before implementation
268
+ 4. Run `/plan-apply` to orchestrate implementation in waves
269
+ 5. Each wave spawns engineers in parallel (custom `*-engineer` specialists, each carrying its own tier model), capped at `agents.maxConcurrent`
270
+ 6. Each subagent receives its task IDs in its prompt, loads relevant abilities, implements, and returns; the lead commits each group
271
+ 7. Verify with tests, build, and lint according to task scope
272
+ 8. Ship or update pull request via lead flow
273
+
274
+ For unattended Loop Task runs, keep a concrete shell verification task as the final exit-code gate. Inside `/plan-goal`, `/plan-apply` step 10 runs lint, typecheck, test, and build commands and is the checks gate; `/repo-verify` then writes `verification-plan.md` (the journey the evidence workflow replays in headless Chromium once the pull request merges). The final shell task independently proves the critical commands passed before commit or pull request actions.
275
+
276
+ Agents run as native OpenCode subagents in parallel waves: no external plugin, no git worktrees. The lead's Todo pane is the live board, and the `pc-subagent-monitor` plugin mirrors state to `.opencode/harness-run.json`. Navigate into any running subagent with `ctrl+x ↓` then `←`/`→`.
277
+
278
+ ---
279
+
280
+ ## What gets installed
281
+
282
+ ```
283
+ your-project/
284
+ ├── AGENTS.md ← bootstrap mode, replaced after first "/repo-initialize"
285
+ ├── ARCHITECTURE.md ← prompt for agents to fill in from your codebase
286
+ ├── DESIGN.md ← prompt for agents to fill in from your codebase
287
+ ├── opencode.jsonc ← native OpenCode 2 config: agents, permissions, MCP servers
288
+ ├── .opencode/
289
+ │ ├── harness.json ← harness config: platform, models, maxConcurrentAgents
290
+ │ ├── harness-managed.json ← hashes of every managed file, so "update" spares your edits
291
+ │ ├── agents/ ← build.md + plan.md (generated primaries), fullstack-engineer,
292
+ │ │ and user-created *-engineer files (all subagents)
293
+ │ ├── plugins/
294
+ │ │ ├── pc-commit-coauthor.js ← server plugin: adds the opencode Co-Authored-By trailer to every agent commit
295
+ │ │ ├── pc-subagent-monitor.js ← server plugin: subagent state → .opencode/harness-run.json, and the wave cap
296
+ │ │ ├── pc-subagent-tiers.js ← server plugin: derives tier agents and the two primaries
297
+ │ │ └── pc-system-reminders.js ← server plugin: gates work on the agent's abilities, denies the never-rules
298
+ │ └── scripts/
299
+ │ ├── check-diff.mjs ← the comments and tests gate on the current diff (see below)
300
+ │ ├── code-rules.mjs ← its rules, the same ones Project-Health scores a repository with
301
+ │ └── platform-contract.mjs ← reads .platform/contract.yml, the platform contract (see below)
302
+ └── .agents/
303
+ └── skills/
304
+ ├── pc-guardrails-generic/ ← foundation for user guardrails
305
+ ├── pc-guardrails-project/ ← populated by /make-guardrails
306
+ ├── pc-userstory/ ← the variant matching your backlog platform, renamed on install
307
+ └── browser-automation/
308
+ ```
309
+
310
+ On OpenCode 2 the terminal client is configured globally (`~/.config/opencode/cli.json`), so the harness ships no project-local `tui.json`; the native session sidebar shows subagents without a sidecar panel.
311
+
312
+ Platform skills ship as suffixed variants (`pc-userstory-gh`, `pc-userstory-az`, `pc-userstory-jira`, `pc-userstory-browser`) and the installer copies only the matching one, renamed to its generic name. Platform operations (ship, review, backlog) are injected directly into the `/ops-*` command files from `cli/fragments/ops-*/` during onboarding. Source-roots metadata lands in `.opencode/source-roots.json`. The always-shipped reminder plugin holds editing, shell and spawning until every ability under the agent's `## Abilities` is loaded, guardrails first, and re-arms after compaction. `AGENTS.md` names the guardrails files by path so the same contract survives in agents that only have a read tool. Token-optimization guidance is injected into `pc-guardrails-generic` marker blocks during onboarding; Humanizer and Simple English are named by path and loaded when prose is written, not held as transitive requirements.
313
+
314
+ ---
315
+
316
+ ## Comments and tests gate
317
+
318
+ `node .opencode/scripts/check-diff.mjs [--base <ref>] [--json]` reads the diff against the merge base with `origin/HEAD` (committed, uncommitted and untracked) and exits 1 when it:
319
+
320
+ - adds more comment lines than 10% of the code lines it adds (2 are always allowed);
321
+ - adds a slop shape (banner, region, untracked TODO, a doc comment that repeats the name, commented-out code, an apology), a comment block of five lines or more, an incident story, or a doc comment on an internal symbol;
322
+ - touches a file and leaves slop in it, or leaves it with more comments per code line than before;
323
+ - grows the tests more than the code: test lines beyond the code lines added (40 always allowed), more than 40 cases per 1,000 code lines (3 always allowed), or any new skipped, focused, snapshot, assertion-less or mock-only test;
324
+ - changes a path the platform contract says a template owns, or finds a contract it cannot read (see [Platform contracts](#platform-contracts)).
325
+
326
+ It also warns, without failing, on a new file named like something the contract marks for reuse (`reuse-shadow`).
327
+
328
+ A tool directive (`nosemgrep`, `biome-ignore`, `eslint-disable`, `@ts-expect-error`, coverage ignores) is not a comment and costs nothing. Code added to a file that has methods in the complexity baseline (`scripts/complexity-baseline.json`, keys `path::method`) counts twice toward the test budget: that gate fails a method whose coverage drops, so its new branches need tests.
329
+
330
+ `pc-plan-apply` runs it with the other checks, and the workflows run it before a bot pull request can merge. A project changes the limits in `.opencode/harness.json`:
331
+
332
+ ```json
333
+ "codeRules": { "commentRatio": 0.1, "commentAllowance": 2, "testRatio": 1, "testAllowance": 40, "casesPerKloc": 40, "caseAllowance": 3, "complexityBaseline": "scripts/complexity-baseline.json" }
334
+ ```
335
+
336
+ ## Platform contracts
337
+
338
+ A repository that receives shared code from an upstream template can describe that relationship in `.platform/contract.yml`. The template can be delivered by Copier, cookiecutter, a git subtree or by hand; the harness reads only the file. It uses the contract to keep agents off the shared code and to point them at what the template already provides.
339
+
340
+ The format is open. Other tools may read the same file, such as a workflow that syncs the template or a dashboard of template versions. None of them is required, and the harness never calls them.
341
+
342
+ ```yaml
343
+ version: 1
344
+ source:
345
+ name: Acme app template
346
+ url: https://github.com/acme/app-template
347
+ changes: https://github.com/acme/app-template/issues/new
348
+ owned:
349
+ - .platform/contract.yml
350
+ - src/platform/**
351
+ reuse:
352
+ docs: [docs/platform/]
353
+ packages: ["@acme/ui"]
354
+ names: [DataTable]
355
+ exceptions: .platform/exceptions.yml
356
+ sync:
357
+ marker: .copier-answers.yml
358
+ version:
359
+ file: .copier-answers.yml
360
+ key: _commit
361
+ update: copier update --trust --defaults --conflict inline
362
+ ```
363
+
364
+ The template delivers the file, so the template owns it and lists it under `owned`.
365
+
366
+ | Field | Required | What the harness does with it |
367
+ | --- | --- | --- |
368
+ | `version` | yes | Reads `1`. Any other value is an error. |
369
+ | `source.name` | yes | Names the owner in every message. |
370
+ | `source.url` | yes | Shown in the AGENTS.md block, and the default for `source.changes`. |
371
+ | `source.changes` | no | Where every message tells the agent to ask for a change. |
372
+ | `owned` | yes | gitwildmatch globs, repository-relative; a leading `/` anchors to the root and `!` excludes. `pc-system-reminders` denies agent edits to these paths, and `check-diff` reports `platform-file` for each one the diff changes. |
373
+ | `reuse.docs` | no | Listed in the AGENTS.md block as reading before building something new. `pc-make-architecture` links to these pages instead of describing their topics again. |
374
+ | `reuse.packages` | no | Listed in the AGENTS.md block. `check-diff` reads each package from `node_modules` and takes its reusable names from the `exports` subpaths and from the identifiers its type declarations export. |
375
+ | `reuse.names` | no | More reusable names, for what cannot be derived from a package. |
376
+ | `exceptions` | no | The exceptions file. Default `.platform/exceptions.yml`. |
377
+ | `sync.marker` | no | A diff that changes this file is a template sync. `check-diff` lets it rewrite owned paths, and `pc-system-reminders` allows edits to them while the file has uncommitted changes, so a sync's conflicts can be resolved. |
378
+ | `sync.version`, `sync.update` | no | Validated but not used: they are for the tool that updates the repository from the template. |
379
+
380
+ ### Reuse before you build
381
+
382
+ When the contract has `reuse`, `agent-harness` install and `update` write this block into AGENTS.md between `<!-- PC-PLATFORM-CONTRACT-START -->` and `<!-- PC-PLATFORM-CONTRACT-END -->`, appending the pair when AGENTS.md has none. For the example above:
383
+
384
+ ```markdown
385
+ ## Reuse before you build
386
+
387
+ This repository receives shared code from Acme app template (https://github.com/acme/app-template), declared in `.platform/contract.yml`.
388
+
389
+ - Never design something new before reading `docs/platform/`.
390
+ - Never re-implement an export of `@acme/ui`; import it.
391
+ - Never write your own `DataTable`; reuse the existing one.
392
+ - Never edit a path listed under `owned`. Ask for the change at https://github.com/acme/app-template/issues/new, or add a dated exception to `.platform/exceptions.yml`.
393
+ ```
394
+
395
+ Without a contract, or without `reuse`, the block is empty. With `reuse`, `pc-plan-propose` gives every proposal a `## What is reused` section, and `pc-plan-apply` stops on a proposal that lacks it. `check-diff` warns with `reuse-shadow`, without failing, when a new source file's name matches a reusable name: `data-table.tsx`, `DataTable.tsx` and `data_table.ts` all match `DataTable`.
396
+
397
+ ### Exceptions
398
+
399
+ An app that needs to diverge from an owned path for a while records it in the exceptions file:
400
+
401
+ ```yaml
402
+ exceptions:
403
+ - path: src/platform/audit/**
404
+ reason: Local audit sink until the template supports it
405
+ issue: https://github.com/acme/app-template/issues/12
406
+ expires: 2026-12-31
407
+ ```
408
+
409
+ An exception covers the owned paths its glob matches until the end of its `expires` day, in both `pc-system-reminders` and `check-diff`. An expired entry no longer applies.
410
+
411
+ ### Errors
412
+
413
+ A contract that does not read gives one error that names the file and the field, such as ``.platform/contract.yml: `source.name` is required and must be a non-empty string.`` The guards never pass silently on it: `check-diff` fails with `platform-contract`, and `pc-system-reminders` denies every edit outside `.platform/` until the file is fixed. Install and update warn and leave the AGENTS.md block as it was.
414
+
415
+ ### The legacy implicit contract
416
+
417
+ Harness 3.7.0 read `.copier-answers.yml` and `.platform/manifest`, one glob per line. A repository with both files and no `contract.yml` is still read, as this contract:
418
+
419
+ - `source.name` is the repository name at the end of `_src_path`, and `source.url` and `source.changes` are `_src_path`;
420
+ - `owned` is the manifest's lines;
421
+ - `sync.marker` and `sync.version.file` are `.copier-answers.yml`, with `sync.version.key` `_commit`;
422
+ - there is no `reuse`.
423
+
424
+ When both exist, `contract.yml` wins. A repository with neither sees no change in any tool.
425
+
426
+ ## The bootstrap sequence
427
+
428
+ The first time you type `init` in OpenCode after onboarding, the agent asks whether this is a **greenfield** or **brownfield** project:
429
+
430
+ ### Brownfield (existing codebase)
431
+
432
+ 1. Bootstrap-mode `AGENTS.md` triggers the initialization workflow
433
+ 2. OpenCode archives existing project context into OpenSpec (`project-history`)
434
+ 3. OpenCode runs `/make-architecture` to generate real `ARCHITECTURE.md` from your codebase
435
+ 4. OpenCode runs `/make-design` to generate real `DESIGN.md` from your design system
436
+ 5. OpenSpec `config.yaml` is populated with discovered tech stack and domain context
437
+ 6. Bootstrap `AGENTS.md` is replaced with production guidance
438
+ 7. Team workflows become fully active for normal implementation tasks
439
+
440
+ ### Greenfield (new project, little or no existing code)
441
+
442
+ 1. Bootstrap-mode `AGENTS.md` triggers the initialization workflow
443
+ 2. OpenSpec `config.yaml` is populated with what is known (intended stack, domain)
444
+ 3. Bootstrap `AGENTS.md` is replaced with production guidance
445
+ 4. `ARCHITECTURE.md` and `DESIGN.md` are left as placeholder files
446
+
447
+ Once your codebase has meaningful content, run:
448
+ - `/make-architecture` to generate architecture documentation
449
+ - `/make-design` to generate design system documentation
450
+
451
+ Both commands are safe to rerun at any time as the project evolves.
452
+
453
+ ---
454
+
455
+ ## Token Budget Controls
456
+
457
+ Long unattended agent sessions can consume significant tokens. Set these controls up **before** first use:
458
+
459
+ 1. **Set provider-side limits first**: monthly soft-limit plus hard usage cap in your provider dashboard:
460
+ - OpenAI: [platform.openai.com/account/limits](https://platform.openai.com/account/limits)
461
+ - Anthropic: [console.anthropic.com](https://console.anthropic.com)
462
+ - Google AI Studio: [aistudio.google.com/app/usage](https://aistudio.google.com/app/usage)
463
+
464
+ 2. **Route models by task type**: use a fast and cheap model (for example `haiku`, `gpt-4o-mini`) for orchestration and status loops; reserve expensive models (for example `sonnet`, `opus`, `gpt-4o`) for implementation tasks only.
465
+
466
+ 3. **Monitor provider dashboards**: check usage at your provider's dashboard before and during `/plan-apply` sessions.
467
+
468
+ 4. **Confirm before large runs**: the onboarded `/plan-apply` workflow will ask for your confirmation before spawning agents for Medium (4 to 7 tasks) or High (8 or more tasks) scope sessions.
469
+
470
+ ---
471
+
472
+ ## Prerequisites
473
+
474
+ | Requirement | Notes |
475
+ | ----------- | ----- |
476
+ | **Node.js 18 or higher** | Required |
477
+ | **[OpenCode](https://opencode.ai)** | The agent runtime |
478
+ | **[gh CLI](https://cli.github.com)** | GitHub platform, must be authenticated |
479
+ | **[az CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)** plus azure-devops extension | Azure DevOps platform |
480
+ | **[acli](https://developer.atlassian.com/cloud/acli/guides/install-acli/)** | Jira (Atlassian) backlog platform, must be authenticated |
481
+ | **[glab](https://gitlab.com/gitlab-org/cli/#installation)** | GitLab repository platform, must be authenticated |
482
+
483
+ ---
484
+
485
+ ## Development
486
+
487
+ The repository splits along one line: **`harness/` is the product, `cli/` is the machinery that installs it.**
488
+
489
+ ```
490
+ harness/ what lands in your repository, copied verbatim
491
+ cli/ the installer: commands, wizard steps, presets, fragments
492
+ skills/ skills about this CLI, for agents that operate it
493
+ docs/ the documentation site
494
+ ```
495
+
496
+ Browse `harness/` to see what the Plain Concepts Platform Harness actually is, without reading a line of installer code.
497
+
498
+ Inside `cli/`, the layout follows the ten wizard steps: one directory per step under `cli/steps/`, each owning its prompts and its file writes, with `cli/commands/` holding the top-level entry points (`wizard`, `update`, `join`, `migrate`, `single`).
499
+
500
+ Data the CLI reads lives in two places, split by kind:
501
+
502
+ **`cli/presets/`** holds JSON that shapes the wizard's questions and defaults:
503
+
504
+ - `source.json` controls source-scope prompt options
505
+ - `platforms.json` controls platform labels, CLI checks, and backlog-only flags
506
+ - `clean.json` controls AI file detection and preservation
507
+ - `models.json` controls model role prompts and agent assignments
508
+ - `optimization.json` controls RTK, quota, Simple English, codegraph, agentmemory, and humanizer checklist defaults
509
+ - `quota.json` controls opencode-quota defaults
510
+ - `browser.json` controls the agent-browser installer (npm package + Chrome setup)
511
+
512
+ **`cli/fragments/`** holds Markdown injected into the installed harness, one directory per marker family: `archive/`, `guardrails/`, `ops-backlog/`, `ops-review/`, `ops-ship/`. Each file is the platform-specific body that replaces a `<!-- PC-PLATFORM-*-START -->` block.
513
+
514
+ Every filename the harness writes into a project is declared once in `cli/utils/paths.js`. Change it there, and remember the OpenCode plugins under `harness/.opencode/plugins/` read those same names at runtime.
515
+
516
+ `skills/` holds both the installable `pc-*` skills and the `agent-harness-cli` skill for agents operating this CLI. See [skills/README.md](./skills/README.md). All of them ship to npm and are discoverable by `npx skills`, so you can install individual skills into any project without the full harness:
517
+
518
+ ```bash
519
+ npx skills add PlainConceptsPlatform/agent-harness
520
+ # or scope to a single skill:
521
+ npx skills add PlainConceptsPlatform/agent-harness --skill pc-ops-ship
522
+ ```
523
+
524
+ ```bash
525
+ git clone https://github.com/PlainConceptsPlatform/agent-harness.git
526
+ cd agent-harness
527
+ pnpm install
528
+
529
+ # Run the CLI locally
530
+ node cli/index.js
531
+
532
+ # Run tests
533
+ pnpm test
534
+
535
+ # Run linting
536
+ pnpm lint
537
+
538
+ # Fix auto-fixable lint issues
539
+ pnpm lint:fix
540
+
541
+ # Watch mode
542
+ pnpm test:watch
543
+ ```
544
+
545
+ Tests are written with [Vitest](https://vitest.dev). Linting uses ESLint flat config with Node ESM defaults and stricter correctness rules.
546
+
547
+ ---
548
+
549
+ ## License
550
+
551
+ MIT © [Plain Concepts](https://github.com/PlainConceptsPlatform)