agent-merge-broker 0.9.0 → 0.11.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 +417 -0
- package/CODE_OF_CONDUCT.md +28 -0
- package/CONTRIBUTING.md +36 -0
- package/README.md +83 -27
- package/SUPPORT.md +25 -0
- package/dist/bootstrap.d.ts +17 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +362 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/broker.d.ts +8 -0
- package/dist/broker.d.ts.map +1 -1
- package/dist/broker.js +96 -12
- package/dist/broker.js.map +1 -1
- package/dist/cli.js +58 -18
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +26 -3
- package/dist/config.js.map +1 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +28 -12
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-cli.d.ts +3 -0
- package/dist/mcp-cli.d.ts.map +1 -0
- package/dist/mcp-cli.js +21 -0
- package/dist/mcp-cli.js.map +1 -0
- package/dist/mcp.d.ts +13 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +373 -0
- package/dist/mcp.js.map +1 -0
- package/dist/process.d.ts +12 -1
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +45 -14
- package/dist/process.js.map +1 -1
- package/dist/service.d.ts +8 -3
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +138 -7
- package/dist/service.js.map +1 -1
- package/dist/status.d.ts +4 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +81 -0
- package/dist/status.js.map +1 -0
- package/dist/store.d.ts +12 -3
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +51 -9
- package/dist/store.js.map +1 -1
- package/dist/support.d.ts +32 -0
- package/dist/support.d.ts.map +1 -0
- package/dist/support.js +44 -0
- package/dist/support.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +4 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +79 -46
- package/dist/validation.js.map +1 -1
- package/docs/ARCHITECTURE.md +6 -2
- package/docs/COMPATIBILITY.md +127 -0
- package/docs/GETTING_STARTED.md +87 -11
- package/docs/PROTOCOL.md +6 -0
- package/docs/RELEASING.md +1 -1
- package/docs/SECURITY.md +15 -5
- package/examples/two-agents/README.md +4 -1
- package/examples/two-agents/run.mjs +146 -0
- package/examples/two-agents/run.sh +1 -1
- package/package.json +11 -4
- package/schemas/config.schema.json +12 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.11.0 — 2026-09-03
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- First-class Windows support: non-profile PowerShell validation, process-tree timeout cleanup,
|
|
8
|
+
per-user Task Scheduler services, a cross-platform Node acceptance demo, and release-gating CI.
|
|
9
|
+
- A stdio MCP adapter with separate worker and operator tool profiles. Worker calls use locally held
|
|
10
|
+
lease tokens without returning them to the model, and merge-authorizing tools exist only in the
|
|
11
|
+
operator profile.
|
|
12
|
+
- Actionable human status, sanitized `doctor --support-bundle` output, and archive-aware audit and
|
|
13
|
+
metrics reads.
|
|
14
|
+
- Conservative Go, Rust, and Python bootstrap detection plus repository-relative validator working
|
|
15
|
+
directories for nested packages.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Hook installation composes with repository-local hook directories and preserves unrelated default
|
|
20
|
+
hooks. `install-hooks --print` supports explicit composition when another tool owns `pre-push`.
|
|
21
|
+
- Background-service installation fails early when publication is disabled.
|
|
22
|
+
- Documentation now publishes a platform matrix, Windows operating notes, MCP capability guidance,
|
|
23
|
+
safe support-bundle workflow, release-availability notice, and an explicit list of functionality
|
|
24
|
+
that is not included today.
|
|
25
|
+
|
|
26
|
+
## 0.10.0 — 2026-09-02
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- `init` now detects declared JavaScript and SwiftPM validation entry points, installs a managed
|
|
31
|
+
root `AGENTS.md` contract, reports unresolved project-specific configuration, and returns an
|
|
32
|
+
explicit operational-readiness result.
|
|
33
|
+
- Validators can request native hardware execution on translated macOS processes and receive an
|
|
34
|
+
isolated `MERGE_BROKER_CACHE_DIR` shared across one integration transaction.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- Initialization is idempotent for existing repositories: it preserves configured validation and
|
|
39
|
+
owner instructions while repairing missing managed files and legacy unsigned provenance.
|
|
40
|
+
- `doctor` distinguishes component health from operational readiness and reports the process and
|
|
41
|
+
native host architectures, validation readiness, and whether the root agent contract is installed
|
|
42
|
+
and committed.
|
|
43
|
+
|
|
44
|
+
## 0.9.0 — 2026-08-31
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- Candidate revision intents make branch publication recoverable across an interrupted state
|
|
49
|
+
finalization, and integration now rejects a task receipt replaced after planning.
|
|
50
|
+
- `ForgePublisher` is an injectable Node API boundary; the GitHub CLI publisher remains built in.
|
|
51
|
+
- `doctor` reports toolchain, remote/base, forge authentication, committed policy, hooks, service,
|
|
52
|
+
locks, provenance, and unfinished transaction readiness.
|
|
53
|
+
- A full getting-started guide, community support/conduct files, and structured issue templates.
|
|
54
|
+
|
|
55
|
+
### Security
|
|
56
|
+
|
|
57
|
+
- Validator output is memory-bounded while commands run, and timeouts terminate the POSIX process
|
|
58
|
+
group. Runtime directories/files now receive explicit 0700/0600 modes without changing a
|
|
59
|
+
caller-owned custom token directory.
|
|
60
|
+
- Auto-merge defaults off, every auto-merge call carries an exact head SHA, and service installers
|
|
61
|
+
refuse to overwrite or remove unowned supervisor files.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- systemd user services now write stdout and stderr to the log path reported by the CLI.
|
|
66
|
+
- The generated config is validated against the published JSON Schema during tests, packaged demos
|
|
67
|
+
are included in npm tarballs, numeric CLI options fail closed, and documentation edit links point
|
|
68
|
+
at their real source files.
|
|
69
|
+
|
|
70
|
+
## 0.8.1 — 2026-08-30
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- SHA-bound approval now works with GitHub CLI versions that do not expose `baseRefOid` through
|
|
75
|
+
`gh pr view --json`. The broker detects that specific capability gap, retrieves the exact head
|
|
76
|
+
and base refs through `gh api`, and fails closed if the pull request head changes between the two
|
|
77
|
+
snapshots.
|
|
78
|
+
|
|
79
|
+
## 0.8.0 — 2026-08-28
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
|
|
83
|
+
- **Exact candidate approval.** Optional approval policy binds required GitHub checks, named manual
|
|
84
|
+
evidence, and explicit authorization to the integrated candidate SHA, base SHA, and policy
|
|
85
|
+
revision. Publishing no longer enables auto-merge before that gate when the policy is required.
|
|
86
|
+
- `batch verify`, `batch approve`, and `batch request-changes` expose verification and authorization
|
|
87
|
+
as separate, auditable capabilities. Approvers can be restricted by configured actor identity.
|
|
88
|
+
- `task candidate` replaces ambiguous completion language while `task submit` remains a compatible
|
|
89
|
+
alias. `task abandon` is the explicit cancellation alias.
|
|
90
|
+
- `task reopen` and `task revise` keep corrective work on the same integration branch and pull
|
|
91
|
+
request. The guarded force update archives the former candidate as `superseded` and starts the new
|
|
92
|
+
revision with no inherited evidence or approval.
|
|
93
|
+
- Candidate state and evidence have a published JSON schema, and human/JSON status surfaces show
|
|
94
|
+
verification progress, exact bindings, approval, and blocking reasons.
|
|
95
|
+
|
|
96
|
+
### Security
|
|
97
|
+
|
|
98
|
+
- Approval re-reads the live pull request, requires an exact head/base binding, rejects conflicts or
|
|
99
|
+
requested changes, verifies every task remains outside an editing lease, and passes the candidate
|
|
100
|
+
SHA to GitHub's merge head guard. External PR-head mutations block the candidate; an out-of-band
|
|
101
|
+
merge without matching approval is recorded as an invariant violation.
|
|
102
|
+
- Base or candidate changes invalidate all prior verification and approval. Editing leases remain
|
|
103
|
+
enforceable during revision without being kept artificially alive through long CI and review.
|
|
104
|
+
|
|
105
|
+
### Compatibility
|
|
106
|
+
|
|
107
|
+
- Existing version-one configurations receive `approval.required: false` defaults and retain the
|
|
108
|
+
pre-0.8 publication behavior until they opt into the gate.
|
|
109
|
+
|
|
110
|
+
## 0.7.1 — 2026-08-28
|
|
111
|
+
|
|
112
|
+
### Fixed
|
|
113
|
+
|
|
114
|
+
- Closing a pull request without merging now pauses every affected task as `failed` instead of
|
|
115
|
+
automatically re-queueing its unchanged receipt. This prevents eager services from repeatedly
|
|
116
|
+
publishing rejected work; corrected commits can be reclaimed and submitted normally, while
|
|
117
|
+
`task retry` remains the explicit escape hatch for a deliberate unchanged-receipt retry.
|
|
118
|
+
|
|
119
|
+
## 0.7.0 — 2026-08-28
|
|
120
|
+
|
|
121
|
+
### Added
|
|
122
|
+
|
|
123
|
+
- **Explicit validation authority.** Repositories can select `validation.authority: required-ci` to
|
|
124
|
+
publish an immutable signed pull-request batch after changed-scope preflight, leaving the complete
|
|
125
|
+
suite to protected required CI checks instead of running it serially twice. The mode fails closed
|
|
126
|
+
unless publication uses pull requests, signed provenance is required, and the local authoritative
|
|
127
|
+
list is empty. Existing configurations default to `broker` and keep their current behavior.
|
|
128
|
+
|
|
129
|
+
## 0.6.0 — 2026-08-25
|
|
130
|
+
|
|
131
|
+
### Added
|
|
132
|
+
|
|
133
|
+
- **Authenticated provenance.** New repositories receive an Ed25519 signing identity during `init`.
|
|
134
|
+
The public key is committed as protected-base policy; the mode-0600 private key stays under Git's
|
|
135
|
+
common runtime directory. Remote verification rejects forged, unsigned, or tampered manifests
|
|
136
|
+
when signature policy is required. Existing repositories can migrate with `merge-broker
|
|
137
|
+
provenance setup-signing`, and supervised hosts may supply the key through a file or environment
|
|
138
|
+
secret that validators never inherit.
|
|
139
|
+
- **Abandoned integration recovery.** `serve` and `integrate` now recover a durable `running` batch
|
|
140
|
+
left by a killed process after safely acquiring the integration lock. Its tasks return to
|
|
141
|
+
`submitted` without spending their attempt budget, and broker-owned worktree and branch artifacts
|
|
142
|
+
are cleaned. `merge-broker recover` exposes the same operation explicitly, while `doctor` reports
|
|
143
|
+
incomplete transaction state and missing signing credentials.
|
|
144
|
+
- `merge-broker install-service` runs the integration loop as a per-user background service — a
|
|
145
|
+
launchd agent on macOS, a systemd user unit on Linux. `serve` already did the work, but only
|
|
146
|
+
while somebody kept a terminal open, so a submitted task could sit in `submitted` for as long as
|
|
147
|
+
nobody happened to look. An agent cannot tell that state apart from having its work rejected, and
|
|
148
|
+
the repository this was written against had a verified batch waiting with nothing driving it. The
|
|
149
|
+
service is scoped per repository, because two checkouts of one project sharing a label would
|
|
150
|
+
leave one of them silently unserved. It is a user service on both platforms: a system daemon
|
|
151
|
+
would need root and would publish as a user who holds neither the SSH key nor the forge
|
|
152
|
+
credentials. On macOS the agent carries an explicit `PATH` — a launchd job inherits almost none,
|
|
153
|
+
and without it the loop starts, cannot see `git`, and does nothing, which looks exactly like
|
|
154
|
+
having nothing to do.
|
|
155
|
+
- `serve` now reports what it is doing. It previously wrote only on a merge, a closure, an error, or
|
|
156
|
+
a *completed* integration — so a batch spending minutes in validators produced an empty log, and a
|
|
157
|
+
healthy busy service could not be told apart from a dead one. That was survivable while the loop
|
|
158
|
+
lived in a terminal and fatal once `install-service` moved it into the background, where the log
|
|
159
|
+
file is the only window on it. It now announces startup and its settings, announces a batch
|
|
160
|
+
*before* the work rather than after, reports idleness on a slower clock than the poll so a quiet
|
|
161
|
+
loop still proves it is alive without writing thousands of lines a day, and says it is stopping
|
|
162
|
+
instead of vanishing. Failures and batches returned to the queue go to stderr, progress to stdout,
|
|
163
|
+
and `--json` emits one object per line. `--once` keeps its original single-result output.
|
|
164
|
+
|
|
165
|
+
### Security
|
|
166
|
+
|
|
167
|
+
- **Post-assembly merge commits are rejected.** The former update-branch allowance compared changed
|
|
168
|
+
paths, which could not detect malicious conflict resolution inside a path the base also changed.
|
|
169
|
+
The provenance commit must now remain the branch head. A stale batch is closed, re-cut from the
|
|
170
|
+
current base, revalidated, and re-signed with `batch refresh`.
|
|
171
|
+
- Remote provenance claims now distinguish cryptographically authenticated manifests from legacy
|
|
172
|
+
structural-only verification. Authenticated enforcement requires a protected-base public key and
|
|
173
|
+
private-key custody outside untrusted worker environments.
|
|
174
|
+
|
|
175
|
+
### Fixed
|
|
176
|
+
|
|
177
|
+
- The documented composite action now uses the real exact `v0.6.0` release tag, and the action runs
|
|
178
|
+
the matching package version instead of silently defaulting to `0.3.0`.
|
|
179
|
+
- Architecture and protocol documentation now describe the local token vault and signing-key
|
|
180
|
+
custody accurately.
|
|
181
|
+
- Service logs resolve through Git's common directory, so `install-service` works from linked
|
|
182
|
+
worktrees where `.git` is a file rather than a directory.
|
|
183
|
+
- `batch refresh` now refuses to requeue or create a replacement when the superseded pull request
|
|
184
|
+
could not be closed. The previous best-effort close could leave two remotely mergeable copies of
|
|
185
|
+
the same tasks after a forge failure.
|
|
186
|
+
- Runtime dependencies now honor the documented Node 20 minimum instead of installing a Commander
|
|
187
|
+
release whose engine declaration requires Node 22.
|
|
188
|
+
|
|
189
|
+
## 0.5.0 — 2026-08-17
|
|
190
|
+
|
|
191
|
+
Surviving a bad afternoon at the forge. A GitHub outage interrupted a publication midway, and the
|
|
192
|
+
broker turned a transient 503 into a batch that could not be landed at all.
|
|
193
|
+
|
|
194
|
+
### Added
|
|
195
|
+
|
|
196
|
+
- `merge-broker batch refresh <id>` re-cuts a batch the base branch moved past, so it can merge
|
|
197
|
+
again. Previously there was no way back: the operator closed the pull request by hand, reconciled
|
|
198
|
+
state by hand, and integrated again. It re-cuts the same tasks from the current tip and
|
|
199
|
+
re-validates them, which is the point — a stale batch was only ever checked against a base nobody
|
|
200
|
+
merges into any more. Re-cutting rather than merging the base into the branch keeps every batch an
|
|
201
|
+
immutable artifact whose manifest describes exactly the base it was assembled on. The superseded
|
|
202
|
+
pull request is closed first, so nobody can still merge the batch being replaced. Attempts are not
|
|
203
|
+
incremented: nothing about the work failed, the world moved, and charging it against
|
|
204
|
+
`maxAttempts` would eventually retire a task for being unlucky about merge order. A batch that is
|
|
205
|
+
already current is a no-op.
|
|
206
|
+
|
|
207
|
+
### Fixed
|
|
208
|
+
|
|
209
|
+
- **Publication records the pull request before attempting auto-merge.** It used to create the pull
|
|
210
|
+
request and enable auto-merge as one step, so a failure at the second threw away the first: the
|
|
211
|
+
batch stayed `prepared` while its pull request existed on the forge. `batch sync` only reconciles
|
|
212
|
+
`published` batches, so the one command built to notice the merge could not see it. Auto-merge is
|
|
213
|
+
now its own step, and failing it leaves a published batch carrying `publishWarning` — something
|
|
214
|
+
that needs a hand, not a publication that did not happen.
|
|
215
|
+
- **Publication is idempotent.** It looks for the branch's open pull request before opening one, so
|
|
216
|
+
retrying after a partial failure finishes the job instead of opening a duplicate. A lookup that
|
|
217
|
+
*fails* is not treated as "there is none" — publication stops with `PULL_REQUEST_LOOKUP_FAILED`,
|
|
218
|
+
because the response to none is to create one, and that is how retrying during an outage produces
|
|
219
|
+
duplicates. `batch publish` accepts an already-`published` batch so it can be used to retry.
|
|
220
|
+
- **One batch in flight at a time.** `integrate` cut a new batch whenever tasks were queued, even
|
|
221
|
+
with an earlier batch still open. A batch is cut from the base tip so it is born mergeable;
|
|
222
|
+
cutting another while the first is unmerged makes that expire, and whichever merges first strands
|
|
223
|
+
the other behind a base that requires branches to be up to date. Integration now refuses with
|
|
224
|
+
`BATCH_OUTSTANDING` and names the batch to land first. `--force` overrides, and `--dry-run` is
|
|
225
|
+
unaffected — a rehearsal retains nothing, so it can strand nothing.
|
|
226
|
+
|
|
227
|
+
## 0.4.1 — 2026-08-17
|
|
228
|
+
|
|
229
|
+
Toolchain maintenance. No behaviour changes.
|
|
230
|
+
|
|
231
|
+
### Fixed
|
|
232
|
+
|
|
233
|
+
- Named the node types explicitly in `tsconfig.json`. TypeScript 7 stopped inferring ambient node
|
|
234
|
+
types from `NodeNext` module resolution alone, so every `node:` import failed to resolve and the
|
|
235
|
+
compiler read the specifiers as bare names. The build would have broken on the compiler upgrade
|
|
236
|
+
whether or not the dependency bump arrived with it.
|
|
237
|
+
|
|
238
|
+
### Changed
|
|
239
|
+
|
|
240
|
+
- Moved to TypeScript 7.0.2 and `@types/node` 26, the current stable line.
|
|
241
|
+
- Updated `commander` to 15. This is the one runtime dependency, so consumers resolving it
|
|
242
|
+
transitively will see the major change.
|
|
243
|
+
|
|
244
|
+
## 0.4.0 — 2026-08-15
|
|
245
|
+
|
|
246
|
+
Recovery. Everything here came out of one repository's week of fighting the lifecycle rather than the
|
|
247
|
+
merge: the broker was strict in places where strictness protected nothing, and the way out of an
|
|
248
|
+
ordinary mistake was to rebuild the task.
|
|
249
|
+
|
|
250
|
+
### Added
|
|
251
|
+
|
|
252
|
+
- `merge-broker validate` runs the configured validators against a working tree, before anything is
|
|
253
|
+
submitted. Integration was previously the only thing that knew what "ready" meant, so adopters
|
|
254
|
+
wrote a cheaper approximation for workers to run first — and an approximation is exactly the thing
|
|
255
|
+
that passes locally and fails at integration. This runs the same validators from the same
|
|
256
|
+
configuration, covers uncommitted and untracked files, writes no state, requires no lease, and
|
|
257
|
+
exits non-zero on failure so a worker script can gate on it. Validators see
|
|
258
|
+
`MERGE_BROKER_BATCH_ID=local`.
|
|
259
|
+
|
|
260
|
+
### Fixed
|
|
261
|
+
|
|
262
|
+
- `integrate --dry-run` no longer marks tasks `failed` when validation fails. A rehearsal consumed
|
|
263
|
+
the queue: the next integrate found nothing to do and reported `EMPTY_BATCH`, with no indication
|
|
264
|
+
that the dry run had emptied it. The success path already restored `submitted` for this reason;
|
|
265
|
+
the failure path did not.
|
|
266
|
+
- A task may be submitted again while `submitted`, replacing its receipt, until its batch is
|
|
267
|
+
assembled. Nothing downstream has read it yet, so the refusal protected only the worker's own
|
|
268
|
+
earlier list of commits — while making "I need one more commit" unrecoverable, since the sole
|
|
269
|
+
remaining lever was `cancel`, which is final and ends the lease.
|
|
270
|
+
- `task extend` accepts a `failed` task, as `task claim` already did. Fixing what validation caught
|
|
271
|
+
routinely means touching a file the original scope did not cover, and refusing to widen scope at
|
|
272
|
+
exactly that moment left rebuilding the task as the only way forward.
|
|
273
|
+
- Lifecycle refusals name the command that moves the task instead of only reporting its status. The
|
|
274
|
+
state machine is invisible from outside, so `cannot be submitted while batched` was a riddle.
|
|
275
|
+
Submission checks status before the lease for the same reason: batching ends the lease, so the
|
|
276
|
+
honest answer was "its batch is assembled", not "you hold no lease".
|
|
277
|
+
|
|
278
|
+
## 0.3.0 — 2026-08-15
|
|
279
|
+
|
|
280
|
+
First public release. The versions below are development history and were never published to npm.
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
The adoption layer. Everything here already existed as bespoke glue around the broker in the
|
|
284
|
+
repository that pilots it; this release moves the generic parts into the tool so a new adopter does
|
|
285
|
+
not have to rebuild them.
|
|
286
|
+
|
|
287
|
+
### Added
|
|
288
|
+
|
|
289
|
+
- `merge-broker verify-provenance --branch <ref> --head <sha> --base <sha>` proves that a pull
|
|
290
|
+
request head is an unaltered broker batch: assembled on real base history, changing exactly the
|
|
291
|
+
paths its receipts account for, carrying every submitted commit, and validated. It reads only Git,
|
|
292
|
+
so it runs on any forge and before any dependency is installed. It accepts the "update branch"
|
|
293
|
+
merges a protected base produces, and rejects a merge that brings in anything the base does not
|
|
294
|
+
already contain. Verification policy is read from the configuration committed on the base branch,
|
|
295
|
+
never from the change under review.
|
|
296
|
+
- A composite GitHub Action at `verify/action.yml`, so requiring the gate is two lines:
|
|
297
|
+
`uses: WeSpitfire/agent-merge-broker/verify@v1`.
|
|
298
|
+
- `merge-broker task submit --since-base` submits the linear commits made after the base the broker
|
|
299
|
+
handed out. Commits whose change is already upstream are skipped by patch identity, so a rebased
|
|
300
|
+
branch does not resubmit landed work.
|
|
301
|
+
- The broker now holds the lease token for the worker, mode 0600, beside the state it authorizes.
|
|
302
|
+
Lease-aware commands find it automatically; `--token`, `--token-file`, and `MERGE_BROKER_TOKEN`
|
|
303
|
+
still work, and `task claim --no-store-token` opts out. Previously the token was shown once and
|
|
304
|
+
every adopter had to build a credential store, with the obvious implementation putting a live
|
|
305
|
+
token in the working tree where `git add` and validator commands can reach it.
|
|
306
|
+
- `merge-broker install-hooks` installs a pre-push guard that refuses direct pushes of
|
|
307
|
+
implementation branches, with `MERGE_BROKER_ALLOW_DIRECT_PUSH=1` as the deliberate bypass. It
|
|
308
|
+
refuses to run when the repository already has hooks that moving `core.hooksPath` would silently
|
|
309
|
+
disable, and `--uninstall` reverses it.
|
|
310
|
+
- `examples/two-agents` is a runnable demonstration: two workers in parallel worktrees, one refused
|
|
311
|
+
overlapping claim, four commits, one validated branch. It runs in CI as an acceptance test.
|
|
312
|
+
- Batch provenance manifests record the `history` mode used to assemble them, so a verifier knows
|
|
313
|
+
whether submitted commits are traceable in the integrated history. Manifests written before this
|
|
314
|
+
field are treated as `preserve`, which is what they were.
|
|
315
|
+
|
|
316
|
+
## 0.2.0 — Unreleased
|
|
317
|
+
|
|
318
|
+
Correctness pass ahead of the first public release. Everything below was found by reviewing the
|
|
319
|
+
package as an outside adopter would receive it, rather than as it is used in its home repository.
|
|
320
|
+
|
|
321
|
+
### Changed
|
|
322
|
+
|
|
323
|
+
- **Validators no longer run under the operator's login shell.** They previously ran under
|
|
324
|
+
`$SHELL -lc`, which made every integration decision depend on whose machine assembled the batch:
|
|
325
|
+
a non-POSIX `$SHELL` such as fish or nushell broke validation outright, and personal login
|
|
326
|
+
profiles could silently reshape the result. Validators now run under `/bin/sh -c`
|
|
327
|
+
(`%ComSpec% /d /s /c` on Windows), configurable with `validation.shell`. The environment still
|
|
328
|
+
comes from the calling process, so PATH and toolchain managers keep working; a validator that
|
|
329
|
+
needs more should set its own `env`.
|
|
330
|
+
- Auto-merge no longer decides by pattern-matching the GitHub CLI's prose. It queries
|
|
331
|
+
`mergeStateStatus` and merges directly only when GitHub reports `CLEAN`. The previous English
|
|
332
|
+
regular expression turned a clean pull request into a hard failure under a different `gh` version
|
|
333
|
+
or locale.
|
|
334
|
+
|
|
335
|
+
### Added
|
|
336
|
+
|
|
337
|
+
- `merge-broker prune [--older-than <days>] [--dry-run]` retires completed tasks and batches into
|
|
338
|
+
`<state>/archive/`. `state.json` is rewritten in full on every transaction, including heartbeats,
|
|
339
|
+
so an unbounded history made routine operations progressively slower. A completed task that a
|
|
340
|
+
retained task still depends on is never pruned: the scheduler cannot tell a pruned dependency from
|
|
341
|
+
one that has never merged, and the dependent would wait forever.
|
|
342
|
+
- `merge-broker unlock [state|integration] [--force]` releases a lock left by a crashed process.
|
|
343
|
+
A holder on another machine cannot be probed, so integration could previously stall for the full
|
|
344
|
+
24-hour stale window with no recourse. Without `--force` the lock is released only when its owner
|
|
345
|
+
is provably gone.
|
|
346
|
+
- `doctor` now reports lock state and warns when no validators are configured, which otherwise
|
|
347
|
+
assembles batches without checking anything and says nothing about it.
|
|
348
|
+
- `validation.shell` configuration field and JSON-schema entry.
|
|
349
|
+
|
|
350
|
+
### Fixed
|
|
351
|
+
|
|
352
|
+
- One truncated line no longer makes the entire audit trail unreadable. `events` skips malformed
|
|
353
|
+
records and reads a bounded tail instead of loading the whole file, and the active audit file is
|
|
354
|
+
rotated into `<state>/archive/` once it grows large. Rotated segments are never deleted.
|
|
355
|
+
- The lease token is no longer passed to validator commands. Repository configuration is trusted to
|
|
356
|
+
run commands, but no validator needs a worker credential that can submit or cancel on its behalf.
|
|
357
|
+
- A task with more commits than `scheduling.maxCommits` now reports that it can never be scheduled
|
|
358
|
+
instead of repeating the same transient-looking deferral on every planning pass.
|
|
359
|
+
|
|
360
|
+
### Platform support
|
|
361
|
+
|
|
362
|
+
- CI now covers Ubuntu and macOS on Node 20 and 22. Windows runs as an informational job:
|
|
363
|
+
the shell selection and command quoting differ there and are not yet a supported platform.
|
|
364
|
+
|
|
365
|
+
## 0.1.6 — Unreleased
|
|
366
|
+
|
|
367
|
+
- Added `--force` to `task cancel` and `task release`, so an integration owner can reclaim a lease
|
|
368
|
+
whose one-time token was lost with its worker. Previously such a scope stayed locked until its TTL
|
|
369
|
+
expired. Forced revocation is recorded in the audit stream with the holder it was taken from.
|
|
370
|
+
|
|
371
|
+
- Merged a published pull request directly when GitHub refuses to queue auto-merge because the pull
|
|
372
|
+
request is already mergeable. A "clean" status means the required checks have passed, so the batch
|
|
373
|
+
no longer stalls when checks finish before publication returns.
|
|
374
|
+
- Fixed cross-machine lock recovery. Liveness was probed with a process ID, but the state directory
|
|
375
|
+
is shared across machines while process IDs are not, so one machine could reclaim a lock that
|
|
376
|
+
another machine was actively holding. Owner records now carry a hostname: a crashed holder on this
|
|
377
|
+
machine is reclaimed after a short grace period, and a holder elsewhere waits out the full stale
|
|
378
|
+
timeout. Records written without a hostname keep the previous behaviour.
|
|
379
|
+
|
|
380
|
+
## 0.1.5 — Unreleased
|
|
381
|
+
|
|
382
|
+
- Added `publish.autoMerge` and `publish.mergeMethod`. The broker now asks GitHub to merge a
|
|
383
|
+
published batch once required checks pass, so integration completes without a human step.
|
|
384
|
+
- Rejected the `publish.autoMerge` + `publish.draft` combination during configuration validation.
|
|
385
|
+
GitHub can never merge a draft pull request, so the previous default silently stalled every batch.
|
|
386
|
+
- Changed the generated default to `publish.draft: false` with `publish.autoMerge: true`.
|
|
387
|
+
Configurations written before this release keep auto-merge off until they opt in.
|
|
388
|
+
- Added `integration.refreshBase`, which fetches the remote base branch before a batch is cut.
|
|
389
|
+
Batches were previously born behind the base branch and became unmergeable under
|
|
390
|
+
"require branches to be up to date" protection.
|
|
391
|
+
- Reconciled pull requests that are closed without merging. The batch becomes `closed` and its tasks
|
|
392
|
+
return to the queue instead of remaining `published` forever, which silently discarded the work.
|
|
393
|
+
- Limited failure blast radius: a cherry-pick or focused-validation failure now fails only the task
|
|
394
|
+
responsible and returns its batch-mates to the queue. Authoritative failures still fail the batch.
|
|
395
|
+
- Added `integration.maxAttempts` to bound automatic re-queueing.
|
|
396
|
+
- Added committed batch-provenance manifests that bind a published integration
|
|
397
|
+
branch to its base SHA, integrated parent, task receipts, and broker validators.
|
|
398
|
+
- Made provenance opt-in compatible for existing version-one configurations and
|
|
399
|
+
enabled it by default for new installations.
|
|
400
|
+
- Added token-authenticated active-lease scope extension for coordinator adapters.
|
|
401
|
+
|
|
402
|
+
## 0.1.1 — Unreleased
|
|
403
|
+
|
|
404
|
+
- Separated the integration `baseRef` from the forge target `baseBranch` so passive local main branches cannot produce stale batches.
|
|
405
|
+
|
|
406
|
+
## 0.1.0 — Unreleased
|
|
407
|
+
|
|
408
|
+
- Added versioned repository configuration and generated agent instructions.
|
|
409
|
+
- Added atomic cross-worktree state, expiring leases, heartbeats, and audit events.
|
|
410
|
+
- Added immutable commit receipts with expected/actual path enforcement.
|
|
411
|
+
- Added dependency-aware, conflict-aware bounded batch scheduling.
|
|
412
|
+
- Added transactional Git worktree integration with cherry-pick provenance.
|
|
413
|
+
- Added focused and authoritative repository-defined validation.
|
|
414
|
+
- Added local branch, remote branch, and GitHub pull-request publication.
|
|
415
|
+
- Added explicit merge reconciliation and a polling broker service.
|
|
416
|
+
- Added local throughput, batch, and validation metrics.
|
|
417
|
+
- Added JSON CLI and exported Node API for adapters.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Code of conduct
|
|
2
|
+
|
|
3
|
+
Agent Merge Broker is committed to a respectful, useful, and harassment-free project community.
|
|
4
|
+
Participation includes issues, pull requests, reviews, discussions, release work, and other spaces
|
|
5
|
+
the maintainers represent as part of this project.
|
|
6
|
+
|
|
7
|
+
## Expected behavior
|
|
8
|
+
|
|
9
|
+
- Be considerate, specific, and constructive.
|
|
10
|
+
- Critique ideas and code without attacking people.
|
|
11
|
+
- Respect differing experience levels, identities, backgrounds, and communication styles.
|
|
12
|
+
- Assume good intent while remaining accountable for impact.
|
|
13
|
+
- Keep private information, credentials, and vulnerability details out of public reports.
|
|
14
|
+
- Accept a maintainer's request to pause, refocus, or leave a discussion.
|
|
15
|
+
|
|
16
|
+
Harassment, discrimination, threats, sexualized attention, deliberate intimidation, repeated
|
|
17
|
+
personal attacks, and publishing another person's private information are not acceptable.
|
|
18
|
+
|
|
19
|
+
## Enforcement
|
|
20
|
+
|
|
21
|
+
Maintainers may edit or remove contributions, limit participation, or ban a participant when needed
|
|
22
|
+
to protect the community. Enforcement decisions should consider context, severity, repetition, and
|
|
23
|
+
the safety of people affected.
|
|
24
|
+
|
|
25
|
+
Report conduct concerns privately to the repository owner or maintainers. Include links and enough
|
|
26
|
+
context to investigate; do not start a public thread about the people involved. Maintainers will
|
|
27
|
+
limit disclosure to the people needed to respond and will avoid conflicts of interest where
|
|
28
|
+
practical.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Contributions are welcome. Small bug fixes, recovery fixtures, documentation improvements, and
|
|
4
|
+
adapter work are all useful.
|
|
5
|
+
|
|
6
|
+
Before starting a large protocol or persisted-state change, open a feature request so compatibility
|
|
7
|
+
and migration expectations can be agreed before implementation. Use a security advisory rather
|
|
8
|
+
than a public issue for exploitable findings.
|
|
9
|
+
|
|
10
|
+
## Development
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install
|
|
14
|
+
npm run verify
|
|
15
|
+
node dist/cli.js --help
|
|
16
|
+
npm run example
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Tests use temporary real Git repositories rather than mocks for transaction behavior. Add a regression fixture for changes to leases, receipts, cherry-picking, validation, batching, or lifecycle transitions.
|
|
20
|
+
|
|
21
|
+
## Pull requests
|
|
22
|
+
|
|
23
|
+
- Keep changes focused and explain any state or protocol compatibility impact.
|
|
24
|
+
- Update JSON schemas and documentation with persisted-format changes.
|
|
25
|
+
- Avoid agent-specific behavior in the core; expose it through an adapter boundary.
|
|
26
|
+
- Preserve the invariant that no branch is retained after failed validation.
|
|
27
|
+
- Include tests for both the successful transaction and its recovery path.
|
|
28
|
+
|
|
29
|
+
Run `npm run verify` before submitting. CI also runs `npm pack --dry-run` to verify the distributable package.
|
|
30
|
+
|
|
31
|
+
See [SUPPORT.md](SUPPORT.md) for usage questions and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for the
|
|
32
|
+
project's participation expectations.
|
|
33
|
+
|
|
34
|
+
## Compatibility
|
|
35
|
+
|
|
36
|
+
Until version 1.0, breaking changes are allowed but must increment the relevant on-disk `version` field and include a migration or a clear reset procedure. Never silently reinterpret existing state.
|