razzou-harness 0.1.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +215 -0
- package/README.md +263 -39
- package/dist/agents/claude-code.js +71 -14
- package/dist/anthropic/usage.js +54 -0
- package/dist/checks/runner.js +2 -1
- package/dist/ci/harness-ci.js +150 -29
- package/dist/cli.js +169 -30
- package/dist/daemon/architects.js +8 -2
- package/dist/daemon/channel.js +7 -1
- package/dist/daemon/design.js +20 -2
- package/dist/daemon/items.js +30 -7
- package/dist/daemon/main.js +84 -12
- package/dist/daemon/manager.js +115 -60
- package/dist/daemon/orchestrator.js +859 -162
- package/dist/daemon/requests.js +30 -21
- package/dist/daemon/review.js +340 -0
- package/dist/daemon/web-read.js +143 -33
- package/dist/dashboard/server.js +61 -16
- package/dist/dashboard/terminals.js +22 -5
- package/dist/design/owner-time.js +79 -0
- package/dist/design/schemas.js +108 -7
- package/dist/git/repo.js +52 -19
- package/dist/github/app.js +30 -4
- package/dist/github/artifacts.js +35 -0
- package/dist/github/forge.js +106 -0
- package/dist/github/setup.js +70 -13
- package/dist/review/cost-estimate.js +25 -0
- package/dist/review/paid-calls.js +93 -0
- package/dist/roles.js +8 -0
- package/dist/sandbox/openshell.js +74 -13
- package/dist/sandbox/policy.js +2 -1
- package/dist/setup/doctor.js +150 -17
- package/dist/setup/init.js +8 -6
- package/dist/setup/recover.js +11 -6
- package/dist/setup/setup.js +471 -0
- package/dist/state/events.js +5 -2
- package/dist/state/state.js +187 -38
- package/dist/util.js +2 -2
- package/dist/web/THIRD-PARTY-LICENSES.md +1 -1
- package/dist/web/assets/{index-D27gAaUJ.css → index-CMViLVQH.css} +1 -1
- package/dist/web/assets/index-CPJJsPL6.js +96 -0
- package/dist/web/index.html +2 -2
- package/images/agent/Dockerfile +11 -2
- package/package.json +3 -3
- package/roles/architect.md +29 -7
- package/roles/cost.md +43 -0
- package/roles/manager.md +6 -4
- package/roles/security.md +37 -0
- package/shim/harness-mcp.mjs +11 -2
- package/src/ci/harness-ci.ts +144 -30
- package/templates/harness.yml +69 -2
- package/dist/web/assets/index-DtxDOPz5.js +0 -96
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,221 @@
|
|
|
3
3
|
The notable changes in each release of razzou-harness. Before 1.0, a new minor version
|
|
4
4
|
may change how a project is set up, and its notes say how.
|
|
5
5
|
|
|
6
|
+
## 0.3.0 (2026-11-07)
|
|
7
|
+
|
|
8
|
+
**Upgrading a project from 0.2.x:** install the new version, then run `harness setup`
|
|
9
|
+
in the project, which does both steps, or do them by hand. Run `harness install-ci` and
|
|
10
|
+
commit the CI files it writes before the next `Arch:` pull request: the protected paths
|
|
11
|
+
changed, and the lock the daemon writes lists more, which the old CI script on `main`
|
|
12
|
+
would refuse. Rebuild the agents' image with `harness doctor --build-images`: its tag
|
|
13
|
+
now follows the harness's version. Then open the dashboard from the link the daemon
|
|
14
|
+
prints, once.
|
|
15
|
+
|
|
16
|
+
Fixes from a review of 0.2.0.
|
|
17
|
+
|
|
18
|
+
Protected files:
|
|
19
|
+
- Paths with a non-ASCII character, a quote or a backslash passed every protection rule,
|
|
20
|
+
in CI's `verify` and in the daemon's own checks, because git quoted them: a Developer
|
|
21
|
+
could add `.claude/skills/é/SKILL.md`, and a `CODE` plan could add Terraform in
|
|
22
|
+
`iac/ñ.tf`. Paths are now read NUL-separated.
|
|
23
|
+
- `CLAUDE.md`, `CLAUDE.local.md`, `AGENTS.md` and `.claude/` are protected in every
|
|
24
|
+
folder, as Claude Code reads them there; so are the configs that decide what a check
|
|
25
|
+
runs (`vitest.config.mts` overrode a protected `vitest.config.js`; Vite, Babel, Mocha,
|
|
26
|
+
pytest and tox configs, and package.json's `jest`, `babel` and `mocha` fields, weren't
|
|
27
|
+
protected), and the npm script of `npm run -s lint` or `npm --prefix . test`.
|
|
28
|
+
- A Plan or Fix PR may not add a local link to `package-lock.json`, which could swap a
|
|
29
|
+
check's tool for a stub. An Arch PR is judged by the base branch's rules, so it can't
|
|
30
|
+
protect `src/**` to change `src/` in the same PR.
|
|
31
|
+
- `protect.files` takes globs, `./x` and `dir/`, which matched nothing before, and
|
|
32
|
+
`terraform.dir` may be written `./iac` or `iac/`. `harness lock` leaves out what git
|
|
33
|
+
ignores.
|
|
34
|
+
|
|
35
|
+
Swarm mode:
|
|
36
|
+
- Every Developer under way reaches the Manager: `ask_manager` from a second or third
|
|
37
|
+
attempt at once was refused, and the Manager could answer or stop only the first. A
|
|
38
|
+
plan's Manager acts on its own plan only.
|
|
39
|
+
- Plans in parallel no longer stop on `progress.txt`: both add lines to it, and the
|
|
40
|
+
daemon keeps both sides' lines when it merges `main` into a plan branch. Before it
|
|
41
|
+
merges a pull request, it merges `main` into it when `main` moved since CI ran, so CI
|
|
42
|
+
and the reviewers judge what `main` gets.
|
|
43
|
+
- Modules are built one after another in Swarm too, as the design says: the first plan
|
|
44
|
+
of a second module started alongside the first module's plans, with its own
|
|
45
|
+
Developers, Manager and reviewers. Only the module being built has those now. Any
|
|
46
|
+
module's Architect still works meanwhile, so the next module can be designed while one
|
|
47
|
+
is built; its plans wait their turn. Two modules already under way at the upgrade are
|
|
48
|
+
finished one after the other, the older first: the other's attempts are interrupted,
|
|
49
|
+
and start again in its turn.
|
|
50
|
+
- A plan that a design change drops while it is built no longer holds a place under
|
|
51
|
+
`swarm.maxPlans`, and its Manager is no longer started over and over, each time in a
|
|
52
|
+
new sandbox and session.
|
|
53
|
+
- An `INFRA` or `MIXED` plan's estimate counts only for the head it was made on, and is
|
|
54
|
+
read only once the `cost` job itself succeeded: after a fix round, a head without its
|
|
55
|
+
own estimate merged on the earlier head's.
|
|
56
|
+
- `Arch:` and `Fix:` pull requests get the reviewers' statuses as "not reviewed", so the
|
|
57
|
+
owner merges them without bypassing the rules, which also skipped CI.
|
|
58
|
+
- A blocking finding blocks, whatever the reviewer's verdict says. A usage limit is not
|
|
59
|
+
one of a reviewer's two failures. Two reviews at once each keep their own transcript.
|
|
60
|
+
- Granting the App "Commit statuses: write" takes effect at its next token, within the
|
|
61
|
+
hour, without restarting the daemon; the doctor reads what the installation accepted.
|
|
62
|
+
Swarm's readiness note reads every ruleset on `main`, on every page.
|
|
63
|
+
- The pay-per-use calls the cost reviewer is told about are found in every SDK's
|
|
64
|
+
spelling, without false hits on words in comments.
|
|
65
|
+
|
|
66
|
+
Both modes:
|
|
67
|
+
- A usage limit never shortens a pause already there, such as the owner's or a brake's:
|
|
68
|
+
it replaced it with an hour's pause that lifted itself. An attempt that reports a usage
|
|
69
|
+
limit counts from the third time on the same feature, as other interruptions do.
|
|
70
|
+
- A plan whose step keeps failing, such as a push GitHub refuses, no longer stops every
|
|
71
|
+
other plan: it is tried again for a while, then the pipeline pauses with its error.
|
|
72
|
+
- In Manual, a module whose design lands while another is built waits for it, and the
|
|
73
|
+
other's pull request is still followed: a module whose id sorted first took over.
|
|
74
|
+
- A design change that redefines a feature under way interrupts its attempt in Manual
|
|
75
|
+
too. An accepted feature it redefines is built again while its plan is. A plan past its
|
|
76
|
+
build is frozen: `submit_design` refuses a change to its features. A feature a design
|
|
77
|
+
change drops no longer breaks the Manager's items.
|
|
78
|
+
- Dead ends after a failure: the owner's push to a plan's pull request branch is built
|
|
79
|
+
on, instead of pausing; a CI run the owner starts again on GitHub counts once it passes;
|
|
80
|
+
on resume, a failed deploy is looked at again, and a later successful apply on `main`
|
|
81
|
+
covers an earlier merge, as when GitHub cancels a pending run.
|
|
82
|
+
- An invalid design on `main` pauses the pipeline with the reason, instead of a log line.
|
|
83
|
+
- `harness budget --owner-hours` with the daemon down replaces hours already set, and
|
|
84
|
+
`harness mode` with the daemon down records the switch for it.
|
|
85
|
+
|
|
86
|
+
Setup and the CLI:
|
|
87
|
+
- `harness setup` on a machine without the App creates it and waits for its
|
|
88
|
+
installation before it writes `harness/config.json`: the config had no `project.repo`
|
|
89
|
+
or `project.bot`, and the project stayed local. A later run fills them in.
|
|
90
|
+
- The setup's commit holds the files it wrote, and nothing else you had staged, and it
|
|
91
|
+
pushes only from `main`: run on another branch, it pushed that branch's commits to
|
|
92
|
+
`main`. A setup commit that wasn't pushed is offered again. A ruleset GitHub refuses,
|
|
93
|
+
as on a free plan's private repository, no longer stops the setup.
|
|
94
|
+
- `harness recover` reads GitHub's `main`, not your checkout's, and says what it can't
|
|
95
|
+
rebuild.
|
|
96
|
+
- A daemon is running only if its process started when `daemon.json` says: after a crash
|
|
97
|
+
or a reboot, `harness down` could stop another process that reused the pid. A lock
|
|
98
|
+
keeps two `harness up` apart, and closing the terminal stops the daemon cleanly.
|
|
99
|
+
- The browser opens the dashboard with a code that works once, not the token, which
|
|
100
|
+
showed on xdg-open's command line.
|
|
101
|
+
- Refused owner actions and unknown commands exit with an error.
|
|
102
|
+
- The doctor: the probe's `web_read` check passes only on the harness's own refusal; the
|
|
103
|
+
workflow probe fails when the App's installation grants workflows; the ruleset must
|
|
104
|
+
apply to `main`; the statuses warning reads what the installation accepted; a Claude
|
|
105
|
+
token the usage endpoint refuses is reported; a half-created AWS provider is deleted
|
|
106
|
+
so the next run asks for the key again, and setup asks for the view role's ARN once.
|
|
107
|
+
- AWS providers are named after the repository: two projects in folders of the same name
|
|
108
|
+
shared one.
|
|
109
|
+
- The owner's time: a design without owner actions always fits, and actions done before
|
|
110
|
+
a redesign dropped them still count.
|
|
111
|
+
- Hashes no longer depend on the machine's locale, a failed `terraform show` fails the
|
|
112
|
+
check that needs the plan, and the usage endpoint has a timeout.
|
|
113
|
+
|
|
114
|
+
The sandboxes and the dashboard:
|
|
115
|
+
- `web_read` refuses this machine's own addresses and the networks it is on: over IPv6,
|
|
116
|
+
or with a public IPv4 on an interface, an agent could read the host's services or the
|
|
117
|
+
router. A compressed page past the size limit stops decompressing, instead of growing
|
|
118
|
+
the daemon's memory, and a page full of unclosed comments or tags no longer freezes
|
|
119
|
+
the daemon for minutes. One deadline of 75 seconds covers a read and its redirects,
|
|
120
|
+
within the 90 seconds an agent waits. claude.ai and chatgpt.com are never read. An
|
|
121
|
+
HTML comment ends at `--!>` too, as browsers read it: the text after one was lost.
|
|
122
|
+
- Usage limits are recognised in Claude Code 2.1's words ("You've hit your 5-hour
|
|
123
|
+
limit"): an attempt that hit one counted as failed.
|
|
124
|
+
- An agent can no longer crash the daemon with a line too long for its follower, and a
|
|
125
|
+
terminal whose sandbox ends at once no longer crashes it either. Transcripts and the
|
|
126
|
+
agents' channels pick up again after the OpenShell gateway restarts, a hung `openshell`
|
|
127
|
+
call is stopped, and a tool call too large gets an error, not a wait.
|
|
128
|
+
- A torn line in the Architect's inbox no longer breaks its prompt hook, and an
|
|
129
|
+
`extraHosts` entry for a bundle's host, such as github.com, no longer takes away its
|
|
130
|
+
git access.
|
|
131
|
+
- The dashboard's cookie is named after its port, so two projects' dashboards no longer
|
|
132
|
+
log each other out: after upgrading, open the printed link once. Agent-written
|
|
133
|
+
Markdown loses its styles, which could hide parts of Needs you. The reviewers' "Shell
|
|
134
|
+
in" button works while a review runs.
|
|
135
|
+
- The agents' image pins the AWS CLI, 2.39.6, by checksum.
|
|
136
|
+
|
|
137
|
+
Releases:
|
|
138
|
+
- The release workflow runs the install and the tests in a job without the npm OIDC
|
|
139
|
+
token, and a second job publishes the tarball the first one packed: no dependency's
|
|
140
|
+
code runs where the token can publish.
|
|
141
|
+
|
|
142
|
+
## 0.2.0 (2026-11-06)
|
|
143
|
+
|
|
144
|
+
**Upgrading a project from 0.1.x:** install the new version, then run `harness setup`
|
|
145
|
+
in the project: it writes the workflow with the new `cost` job (commit it), waits for
|
|
146
|
+
you to give the App "Commit statuses: write", and stores the token the usage probe
|
|
147
|
+
reads. Without Swarm on, nothing else changes: Manual mode works as before, with the
|
|
148
|
+
new attempt clock of 120 minutes and Manager turn of 90.
|
|
149
|
+
|
|
150
|
+
- **Swarm mode**, designed in `docs/architecture/proposal-v3.md`: a second mode, switched
|
|
151
|
+
in the dashboard or with `harness mode`, in which the daemon merges a plan's pull
|
|
152
|
+
request once CI and the reviewers' statuses pass. `CODE` plans merge when
|
|
153
|
+
`swarm.merge.code` is `daemon`; `INFRA` and `MIXED` plans need the cost job's
|
|
154
|
+
estimate under `swarm.merge.infraMonthlyUsdCeiling`, or the owner's button (both
|
|
155
|
+
below). A pull request the policy leaves to the owner shows the reason under Needs
|
|
156
|
+
you. `Arch:` and `Fix:` pull requests stay the owner's.
|
|
157
|
+
- A plan is `CODE`, `INFRA` or `MIXED`, from its features' kinds. Plan pull requests
|
|
158
|
+
carry the tag in their title, and CI's `verify` job keeps a `CODE` plan's pull
|
|
159
|
+
request off the Terraform folder.
|
|
160
|
+
- `harness github-setup` applies the ruleset of the daemon's mode, or of `--mode`: in
|
|
161
|
+
Swarm, no approval, and the reviewers' statuses required and pinned to the App.
|
|
162
|
+
`harness doctor` checks the ruleset against the mode, and that the App may write
|
|
163
|
+
commit statuses.
|
|
164
|
+
- Budgets in the Project view: your hours for the whole project, and a threshold for
|
|
165
|
+
the agent hours, the Developers' attempt clocks summed, red when over.
|
|
166
|
+
- Your time as a design constraint, in both modes, once you set your hours: owner
|
|
167
|
+
actions carry `estimatedMinutes`, a reserve of `ownerTime.reservePercent` stays out
|
|
168
|
+
of designs, and `submit_design` refuses a design whose actions take more than what
|
|
169
|
+
remains. Only owner actions count, not the proposals or pull requests you read. The
|
|
170
|
+
Architect gets `get_owner_time`, and a note when the budget changes.
|
|
171
|
+
- An attempt's deadline is 120 minutes, and the Manager's turn 90, by default.
|
|
172
|
+
- In Swarm, up to `swarm.maxDevelopers` Developers build a plan's independent features
|
|
173
|
+
at once. The plan's head is merged into an attempt before its checks when another
|
|
174
|
+
feature landed first, and the feature lands as one commit on the head; a conflict
|
|
175
|
+
interrupts the attempt, and the next one starts from the new head. A design change
|
|
176
|
+
merged while a feature is built interrupts its attempt the same way. The Architect is
|
|
177
|
+
told to declare every dependency in `dependsOn`, and hears in one line when a plan's
|
|
178
|
+
pull request opens, waits for the owner, is blocked by a reviewer, or merges.
|
|
179
|
+
- Plans in parallel, in Swarm: a plan's `dependsOn` names the plans that must be merged
|
|
180
|
+
first, or the previous plan without it; up to `swarm.maxPlans` plans build at once,
|
|
181
|
+
each with its own Manager, keyed `module/plan`; a feature may depend on an earlier
|
|
182
|
+
plan's feature as `P1/F03`. The Project view draws each module's features as a graph
|
|
183
|
+
with their dependencies, and the Agents view lists the reviewers' sessions.
|
|
184
|
+
- Two reviewers, security and cost, read every plan's pull request once CI passed, in
|
|
185
|
+
Swarm, or in Manual as comments only with `swarm.reviewersInManual`. Each runs in a
|
|
186
|
+
fresh read-only sandbox with a brief: the features, the files changed, the
|
|
187
|
+
pay-per-use AWS calls the change adds or removes, and the Terraform plan's JSON.
|
|
188
|
+
Their findings are posted on the pull request, their verdicts set as the commit
|
|
189
|
+
statuses `harness/security` and `harness/cost`, and a blocking verdict opens a fix
|
|
190
|
+
round, two per reviewer by default, before the pull request is the owner's. The App
|
|
191
|
+
needs "Commit statuses: write"; an older App's tokens fall back to read, and the
|
|
192
|
+
pull request waits for the owner with the reason.
|
|
193
|
+
- `harness setup`, designed in `docs/architecture/proposal-v4.md`: one command that
|
|
194
|
+
sets up this machine and the project, does every step the harness can, and asks only
|
|
195
|
+
for what is the owner's: a `gh` login, the Claude token at a hidden prompt, the
|
|
196
|
+
clicks GitHub needs for the App, three questions, and with AWS the role ARNs and the
|
|
197
|
+
gateway key. It commits and pushes the files it wrote once the owner agrees, runs the
|
|
198
|
+
doctor and fixes what it can, waits for the browser steps, runs the probe, and offers
|
|
199
|
+
to start the daemon. `harness init` and the checklist stay, for the steps by hand.
|
|
200
|
+
- `harness mode` applies the mode's ruleset on `main` in the same command, with your
|
|
201
|
+
own `gh`. In Swarm the daemon reads the rules in effect on `main` through the App,
|
|
202
|
+
and the dashboard's "Before you use Swarm" note lists only what is left: the rules,
|
|
203
|
+
the App's statuses permission, the usage probe's token; it goes once all are done.
|
|
204
|
+
`harness budget --owner-hours <n>` sets your hours, even with the daemon down.
|
|
205
|
+
- A button in the dashboard's header, in Swarm, that lets the daemon merge `INFRA` and
|
|
206
|
+
`MIXED` plans like `CODE` ones, once CI and both reviewers pass; an Infracost estimate
|
|
207
|
+
over the ceiling still waits for the owner. Off by default; the choice is an event.
|
|
208
|
+
- The dependencies with advisories moved past them: zod 4.6.6 or later, and dompurify
|
|
209
|
+
3.4.17 or later for the dashboard's Markdown.
|
|
210
|
+
- A `cost` job in the CI workflow, written by `harness install-ci`: on a pull request
|
|
211
|
+
with `iac/` and the `INFRACOST_API_KEY` secret, Infracost's estimate of the monthly cost
|
|
212
|
+
the change adds is uploaded as an artifact, which the daemon reads once CI passed.
|
|
213
|
+
`INFRA` and `MIXED` plans then merge themselves in Swarm under
|
|
214
|
+
`swarm.merge.infraMonthlyUsdCeiling`, and the cost reviewer gets the estimate in its
|
|
215
|
+
brief. Without the job's artifact they wait for the owner, with the reason.
|
|
216
|
+
- In Swarm, the daemon reads the subscription's usage before it starts an attempt, and
|
|
217
|
+
at or above `swarm.usageCeilingPercent` the pipeline waits for the window to reset.
|
|
218
|
+
`harness doctor` stores the provider's token in `~/.config/harness/claude.token` for
|
|
219
|
+
it, and asks for it on an older setup once Swarm is on. Spike 5 records the endpoint.
|
|
220
|
+
|
|
6
221
|
## 0.1.3 (2026-10-11)
|
|
7
222
|
|
|
8
223
|
- More npm keywords, for a team of agents in sandboxes.
|