agent-merge-broker 0.12.0 → 0.13.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 +69 -2
- package/README.md +219 -77
- package/ROADMAP.md +118 -0
- package/VISION.md +140 -0
- package/dist/broker.d.ts +24 -2
- package/dist/broker.d.ts.map +1 -1
- package/dist/broker.js +254 -54
- package/dist/broker.js.map +1 -1
- package/dist/cli.js +167 -21
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +86 -4
- package/dist/config.js.map +1 -1
- package/dist/gate-authority.d.ts +22 -0
- package/dist/gate-authority.d.ts.map +1 -0
- package/dist/gate-authority.js +288 -0
- package/dist/gate-authority.js.map +1 -0
- package/dist/git.d.ts +137 -7
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +2106 -51
- package/dist/git.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/publisher.js +1 -1
- package/dist/publisher.js.map +1 -1
- package/dist/serve-log.d.ts +2 -0
- package/dist/serve-log.d.ts.map +1 -1
- package/dist/serve-log.js +7 -2
- package/dist/serve-log.js.map +1 -1
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +21 -0
- package/dist/status.js.map +1 -1
- package/dist/store.d.ts +21 -3
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +141 -28
- package/dist/store.js.map +1 -1
- package/dist/submission.d.ts +30 -0
- package/dist/submission.d.ts.map +1 -0
- package/dist/submission.js +619 -0
- package/dist/submission.js.map +1 -0
- package/dist/types.d.ts +127 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/dist/validation.d.ts +4 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +178 -12
- package/dist/validation.js.map +1 -1
- package/docs/ARCHITECTURE.md +301 -25
- package/docs/COMPATIBILITY.md +200 -19
- package/docs/GETTING_STARTED.md +194 -19
- package/docs/PROTOCOL.md +348 -27
- package/docs/RELEASING.md +1 -1
- package/docs/SECURITY.md +177 -8
- package/package.json +8 -3
- package/schemas/config.schema.json +16 -4
- package/schemas/gate-authority.schema.json +39 -0
- package/schemas/submission.schema.json +160 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.0 — 2026-09-04
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Added validation-only Gate intake for trusted Git refs already present in the broker repository.
|
|
8
|
+
`candidate authority setup` first records a versioned protected-target trust root at a fixed path
|
|
9
|
+
in Git's common directory; `candidate adopt --ref` then pins the exact commit, derives its
|
|
10
|
+
base-relative history and paths, loads committed policy from the registered base, and records a
|
|
11
|
+
standalone, schema-backed submission without manufacturing tasks, leases, receipts, or batches.
|
|
12
|
+
- Added `candidate list` and `candidate show`, plus recovery of interrupted `received` and
|
|
13
|
+
`validating` submissions.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Validator environments now expose `MERGE_BROKER_SUBMISSION_ID` during trusted local-ref intake.
|
|
18
|
+
- Validators now receive an owner-readable UTF-8 JSON path list through
|
|
19
|
+
`MERGE_BROKER_FILES_FILE`, `MERGE_BROKER_FILES_FILE_FORMAT=json`, and shell-safe `{filesFile}`.
|
|
20
|
+
Inline input remains the compatibility default but fails closed when either legacy representation
|
|
21
|
+
exceeds 4 KiB; `filesInput: "json"` explicitly selects file-only transport for large path sets.
|
|
22
|
+
- Gate requires Git 2.46 or newer, binds protected-base refresh to the canonical fetch URL (separate
|
|
23
|
+
from any publication `pushurl`), rejects and scrubs Git repository/index/object/history and
|
|
24
|
+
configuration-injection or transport-command overrides, refuses configured URL/transport
|
|
25
|
+
rewrites, proxy/TLS/routing overrides, and exact-locator remote shorthand collisions, physically
|
|
26
|
+
binds local transport paths, rejects URL forms whose Git and web interpretations differ,
|
|
27
|
+
recursively inspects the owned object store, recomputes commit/tree/blob identities,
|
|
28
|
+
applies documented aggregate diff/tree/path ceilings, materializes raw filter-free blob bytes,
|
|
29
|
+
binds state/worktree/cache/hook directories to physical filesystem identities, journals retained-ref
|
|
30
|
+
establishment and later loss, bounds untracked-path diagnostics, and serializes authority
|
|
31
|
+
replacement against adoption and recovery.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Kept exact-target checks compatible with Git for Windows' standard unscoped Schannel TLS backend,
|
|
36
|
+
and made lock release retry transient Windows sharing violations without weakening nonce fencing.
|
|
37
|
+
|
|
38
|
+
## 0.12.1 — 2026-09-04
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- Added a truthful product vision and capability-based roadmap that distinguish today's Coordinate
|
|
43
|
+
mode from planned external-candidate Gate and generalized Verify modes.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Reframed the README, package metadata, and website around crash-recoverable exact-candidate
|
|
48
|
+
repository transactions while preserving the current package, CLI, and project identities.
|
|
49
|
+
- Expanded the architecture, protocol, security, compatibility, and operations documentation to
|
|
50
|
+
cover v0.12 locks, durable intents, reconciliation, topology proofs, adapter obligations, upgrade
|
|
51
|
+
boundaries, and actionable error recovery.
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- Aligned the published configuration schema with runtime support for declaring auto-merge while
|
|
56
|
+
publication remains disabled, while continuing to reject branch-mode and draft auto-merge.
|
|
57
|
+
- Made the documentation site redeploy for every canonical content source and replaced its
|
|
58
|
+
inaccurate source-declaration test count with the supported cross-platform CI matrix.
|
|
59
|
+
- Replaced a historical but copyable nonexistent `verify@v1` reference with an existing immutable
|
|
60
|
+
action tag.
|
|
61
|
+
- Made abandoned-integration cleanup replayable across another process stop, use the persisted
|
|
62
|
+
branch name and expected SHA, remove partial worktree directories, and preserve branches checked
|
|
63
|
+
out for operator inspection.
|
|
64
|
+
- Made JSON CLI usage errors follow the documented machine-readable error envelope and made
|
|
65
|
+
`serve --once --json` return exactly one summary document.
|
|
66
|
+
- Made human refresh output distinguish an already-current batch, terminal reconciliation, and a
|
|
67
|
+
pull request that a reviewer had already closed.
|
|
68
|
+
|
|
3
69
|
## 0.12.0 — 2026-09-04
|
|
4
70
|
|
|
5
71
|
### Added
|
|
@@ -28,7 +94,8 @@
|
|
|
28
94
|
- Merge reconciliation proves the accepted fast-forward, squash, two-parent merge, or linear rebase
|
|
29
95
|
topology before releasing dependent tasks.
|
|
30
96
|
- Revocation, reviewer closure, force-push, reopened pull request, remote retargeting, and
|
|
31
|
-
configuration-downgrade races now fail closed without leaving a possibly-live merge
|
|
97
|
+
configuration-downgrade races now fail closed without leaving a possibly-live auto-merge request
|
|
98
|
+
behind.
|
|
32
99
|
|
|
33
100
|
### Fixed
|
|
34
101
|
|
|
@@ -332,7 +399,7 @@ not have to rebuild them.
|
|
|
332
399
|
already contain. Verification policy is read from the configuration committed on the base branch,
|
|
333
400
|
never from the change under review.
|
|
334
401
|
- A composite GitHub Action at `verify/action.yml`, so requiring the gate is two lines:
|
|
335
|
-
`uses: WeSpitfire/agent-merge-broker/verify@
|
|
402
|
+
`uses: WeSpitfire/agent-merge-broker/verify@v0.3.0`.
|
|
336
403
|
- `merge-broker task submit --since-base` submits the linear commits made after the base the broker
|
|
337
404
|
handed out. Commits whose change is already upstream are skipped by patch identity, so a rebased
|
|
338
405
|
branch does not resubmit landed work.
|
package/README.md
CHANGED
|
@@ -1,18 +1,61 @@
|
|
|
1
1
|
# Agent Merge Broker
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Crash-recoverable repository transactions for code-producing agents and humans.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Many producers can create code. The repository still needs one contract for deciding what is safe to
|
|
6
|
+
validate, publish, and merge. Agent Merge Broker is a local-first transaction coordinator for that
|
|
7
|
+
boundary: participating workers submit receipts naming immutable commits, while Gate intake can
|
|
8
|
+
submit one retained trusted-local Git ref for validation without fabricated coordination history.
|
|
9
|
+
The complete Coordinate path derives one batch candidate and keeps
|
|
10
|
+
publication bound to the recorded Git and forge target.
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
In Coordinate mode, exact-candidate approval ties evidence and authorization to the candidate SHA,
|
|
13
|
+
base SHA, and policy revision. Durable operation state lets the broker reconcile a crash or lost
|
|
14
|
+
forge response before it releases dependent work.
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
It does not spawn agents, decide policy with AI, or replace CI, review, protected branches, or a
|
|
17
|
+
native forge queue. The forge remains the final branch authority.
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
## What ships today
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
### Coordinate mode
|
|
14
22
|
|
|
15
|
-
The
|
|
23
|
+
The current workflow coordinates workers that participate through the broker's claim and receipt
|
|
24
|
+
protocol:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
claim → lease → commit → nominate → batch → validate → publish → reconcile
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- Expiring, cross-worktree leases prevent predictable collisions before editing.
|
|
31
|
+
- Commit receipts separate implementation from integration authority.
|
|
32
|
+
- A deterministic conflict/dependency scheduler forms bounded batches.
|
|
33
|
+
- Every batch is tested through real cherry-picks in a disposable worktree.
|
|
34
|
+
- Focused checks run after each task; the complete gate runs either in the broker or as required CI.
|
|
35
|
+
- Successful work becomes one local branch, remote branch, or GitHub pull request.
|
|
36
|
+
- Optional exact-candidate policy separates nomination, verification, approval, and mechanical merge.
|
|
37
|
+
- Published branches can carry a signed provenance manifest for remote policy checks.
|
|
38
|
+
- Target fingerprints, durable intents, and forge observation make interrupted publication recoverable.
|
|
39
|
+
- Automatic completion waits until the accepted Git history proves that the batch merged.
|
|
40
|
+
|
|
41
|
+
### Gate intake for trusted local refs
|
|
42
|
+
|
|
43
|
+
Version `0.13.0` adds a first Gate slice for a Git ref whose objects are already available in the
|
|
44
|
+
broker's local repository. An explicit `candidate authority setup` ceremony records the reviewed
|
|
45
|
+
protected-target locator outside candidate commits. `candidate adopt` then resolves and retains the
|
|
46
|
+
exact commit, independently resolves that registered base, loads committed policy from the base,
|
|
47
|
+
derives the raw commit chain and changed paths, and runs focused plus authoritative broker validators
|
|
48
|
+
over filter-free materialized bytes. The resulting `SubmissionRecord` is validation evidence only:
|
|
49
|
+
this slice does not create a task, lease, receipt, batch, approval candidate, provenance statement,
|
|
50
|
+
branch, pull request, or merge authority.
|
|
51
|
+
|
|
52
|
+
### A concrete coordination problem
|
|
53
|
+
|
|
54
|
+
Four coding agents finish at once. Two touched the same file, a third started from a base that has
|
|
55
|
+
already moved, and each produced a lockfile. Testing four branches independently never proves that
|
|
56
|
+
their combined result works. Coordinate mode orders that work, rejects overlapping claims early,
|
|
57
|
+
validates compatible commits together, and retains one candidate without giving workers merge
|
|
58
|
+
authority.
|
|
16
59
|
|
|
17
60
|
## Try it in one minute
|
|
18
61
|
|
|
@@ -25,39 +68,61 @@ Two workers race on a throwaway repository, a third gets turned away for claimin
|
|
|
25
68
|
|
|
26
69
|
It is also this project's acceptance test in CI — so if the demo ever stops telling the truth, the build goes red.
|
|
27
70
|
|
|
28
|
-
## How
|
|
29
|
-
|
|
30
|
-
One integration authority; implementation stays distributed:
|
|
31
|
-
|
|
32
|
-
- Expiring, cross-worktree leases prevent predictable collisions before editing.
|
|
33
|
-
- Commit receipts separate implementation from integration authority.
|
|
34
|
-
- A deterministic conflict/dependency scheduler forms bounded batches.
|
|
35
|
-
- Every batch is tested through real cherry-picks in a disposable worktree.
|
|
36
|
-
- Focused checks run after each task; the complete gate runs either in the broker or as required CI.
|
|
37
|
-
- Successful work becomes one local branch, remote branch, or GitHub pull request.
|
|
38
|
-
- Optional exact-candidate policy separates nomination, verification, approval, and mechanical merge.
|
|
39
|
-
- Published branches can carry a committed provenance manifest for fast remote policy checks.
|
|
40
|
-
- Tasks are dependency-complete only after their batch is actually merged.
|
|
41
|
-
- An append-only audit stream records lifecycle decisions and validation results.
|
|
71
|
+
## How Coordinate mode works
|
|
42
72
|
|
|
43
|
-
|
|
73
|
+
Implementation stays distributed while one broker owns ordering, batching, validation, publication,
|
|
74
|
+
and recovery. Codex, Claude, Cursor, custom agents, CI jobs, and humans can use the same small
|
|
75
|
+
commit-receipt protocol. An append-only audit stream records lifecycle decisions and validation
|
|
76
|
+
results, while the forge keeps the final say on what merges.
|
|
44
77
|
|
|
45
78
|
## Status
|
|
46
79
|
|
|
47
80
|
`0.3.0` was the first public release: the local broker core, the GitHub CLI publishing adapter with auto-merge, and the remote provenance verifier.
|
|
48
81
|
|
|
49
|
-
`0.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
82
|
+
`0.13.0` is the current release. It adds validation-only Gate intake for trusted repository-local
|
|
83
|
+
Git refs, with an explicit protected-target authority, exact retained artifact identity,
|
|
84
|
+
filter-free validation, and crash-safe recovery. It builds on the `0.12.1` documentation and
|
|
85
|
+
machine-readable CLI consolidation around the `0.12.0` core. That core made
|
|
86
|
+
pull-request auto-merge crash-recoverable and target-bound, added unattended publication and
|
|
87
|
+
stale-base recovery, and closed approval, refresh, revision, remote-retargeting, and reopened-PR
|
|
88
|
+
races, while retaining the first-class Windows support, permission-separated MCP servers,
|
|
89
|
+
diagnostics, and bootstrap detection added in `0.11.0`.
|
|
90
|
+
|
|
91
|
+
The on-disk state, receipt, submission, candidate, and provenance formats are versioned, but
|
|
92
|
+
compatibility is not guaranteed until `1.0.0`. Expect format migrations before then.
|
|
93
|
+
|
|
94
|
+
## Product direction
|
|
95
|
+
|
|
96
|
+
Coordinate mode remains the complete repository-transaction workflow in `0.13.0`. The release also
|
|
97
|
+
ships a deliberately narrower local-ref Gate validation intake; Gate merge authority and Verify mode
|
|
98
|
+
remain planned.
|
|
99
|
+
|
|
100
|
+
### Gate mode — validation intake in 0.13.0
|
|
101
|
+
|
|
102
|
+
`merge-broker candidate adopt --ref <git-ref>` accepts a completed candidate from a producer that did
|
|
103
|
+
not use path leases while coding. Before adoption, an operator must run `candidate authority setup`
|
|
104
|
+
from a reviewed protected checkout. This first slice is trusted-source and validation-only. The ref
|
|
105
|
+
must already be available in the local repository, descend linearly from the registered base, and fit
|
|
106
|
+
both `scheduling.maxCommits` and Gate's 1,000-commit hard ceiling; the protected base must contain
|
|
107
|
+
matching committed broker policy with
|
|
108
|
+
`validation.authority: "broker"`. Approval, provenance, publication, merge reconciliation,
|
|
109
|
+
pull-request intake, bundles, and remote submission for these records are not implemented yet.
|
|
54
110
|
|
|
55
|
-
|
|
111
|
+
### Verify mode — planned
|
|
112
|
+
|
|
113
|
+
Verify mode will be a lightweight admission check for policy and attestations produced through a
|
|
114
|
+
wider set of workflows. Today's `verify-provenance` command is intentionally narrower: it verifies
|
|
115
|
+
provenance created by the current broker workflow, not arbitrary external candidates.
|
|
116
|
+
|
|
117
|
+
See [Vision](VISION.md) for the durable product boundary and
|
|
118
|
+
[Roadmap](ROADMAP.md) for the capability-based sequence. Planned work is labeled explicitly and
|
|
119
|
+
is not part of npm until a release says otherwise.
|
|
56
120
|
|
|
57
121
|
## Requirements
|
|
58
122
|
|
|
59
123
|
- Node.js 20.12 or newer
|
|
60
124
|
- Git 2.31 or newer with worktree support
|
|
125
|
+
- Git 2.46 or newer specifically for trusted local-ref Gate intake
|
|
61
126
|
- GitHub CLI only when `publish.mode` is `pull-request`
|
|
62
127
|
|
|
63
128
|
Windows, macOS, and Linux are supported and release-gating in CI. Windows validation defaults to
|
|
@@ -99,9 +164,10 @@ and owner-written `AGENTS.md` content. Use `--no-detect` or `--no-agent-contract
|
|
|
99
164
|
installer or repository template owns those concerns itself.
|
|
100
165
|
|
|
101
166
|
It also creates an Ed25519 provenance private key, mode `0600`, under Git's common runtime directory.
|
|
102
|
-
Only its public key is written to the committed configuration. Runtime state, receipt
|
|
103
|
-
|
|
104
|
-
worktree sees the same broker authority.
|
|
167
|
+
Only its public key is written to the committed configuration. Runtime state, receipt, batch, and
|
|
168
|
+
Gate submission records, keys, locks, and disposable worktrees therefore stay outside commits while
|
|
169
|
+
every linked worktree sees the same broker authority. When provenance is enabled, a separate signed
|
|
170
|
+
or unsigned provenance manifest is deliberately committed as a Coordinate-mode branch head.
|
|
105
171
|
|
|
106
172
|
## Quick start
|
|
107
173
|
|
|
@@ -116,9 +182,9 @@ git add .merge-broker AGENTS.md && git commit -m 'Configure authenticated merge
|
|
|
116
182
|
merge-broker doctor
|
|
117
183
|
```
|
|
118
184
|
|
|
119
|
-
`merge-broker status`
|
|
120
|
-
report, `merge-broker doctor --support-bundle` emits diagnostics and recent
|
|
121
|
-
URLs, and secret-bearing fields redacted; review the JSON before sharing it.
|
|
185
|
+
`merge-broker status` includes the safe next command for each active task, batch, and retained Gate
|
|
186
|
+
submission. For a bug report, `merge-broker doctor --support-bundle` emits diagnostics and recent
|
|
187
|
+
audit events with paths, URLs, and secret-bearing fields redacted; review the JSON before sharing it.
|
|
122
188
|
|
|
123
189
|
An orchestrator or worker claims a narrowly scoped task:
|
|
124
190
|
|
|
@@ -139,16 +205,17 @@ merge-broker task heartbeat CRM-142
|
|
|
139
205
|
Pass `--token`, `--token-file`, or `MERGE_BROKER_TOKEN` when the worker runs somewhere else, or
|
|
140
206
|
claim with `--no-store-token` to handle custody yourself.
|
|
141
207
|
|
|
142
|
-
Before handing anything over, the worker can
|
|
143
|
-
integration will
|
|
208
|
+
Before handing anything over, the worker can run a local preflight using the same validator
|
|
209
|
+
definitions integration will use:
|
|
144
210
|
|
|
145
211
|
```bash
|
|
146
212
|
merge-broker validate
|
|
147
213
|
```
|
|
148
214
|
|
|
149
|
-
This
|
|
150
|
-
|
|
151
|
-
|
|
215
|
+
This checks the caller's current working tree, including uncommitted and untracked files, writes no
|
|
216
|
+
state, needs no lease, and exits non-zero when a validator fails. It does not reproduce integration's
|
|
217
|
+
per-task focused sequencing or its unchanged-`HEAD` and clean-worktree postconditions, so the retained
|
|
218
|
+
integration transaction remains authoritative.
|
|
152
219
|
|
|
153
220
|
The worker commits its change and nominates a candidate receipt. It does not merge or push:
|
|
154
221
|
|
|
@@ -179,7 +246,57 @@ merge-broker integrate --publish
|
|
|
179
246
|
merge-broker batch sync <batch-id>
|
|
180
247
|
```
|
|
181
248
|
|
|
182
|
-
`batch sync` checks the GitHub PR when available. For branch-only publication it fetches the
|
|
249
|
+
`batch sync` checks the GitHub PR when available. For branch-only publication it fetches the batch's
|
|
250
|
+
fingerprint-bound recorded target and verifies exact-head ancestry. GitHub fast-forward, squash,
|
|
251
|
+
two-parent merge, and linear-rebase outcomes are reconciled automatically when their topology can be
|
|
252
|
+
proved. `batch complete` remains an explicit manual authority fallback for workflows that expose no
|
|
253
|
+
sufficient automatic proof.
|
|
254
|
+
|
|
255
|
+
## Validate a trusted local Git candidate
|
|
256
|
+
|
|
257
|
+
When another trusted local workflow has already assembled a linear candidate, retain and validate
|
|
258
|
+
its exact commit without manufacturing Coordinate-mode history:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
merge-broker candidate authority setup
|
|
262
|
+
merge-broker candidate authority show
|
|
263
|
+
merge-broker candidate adopt --ref refs/heads/external-candidate
|
|
264
|
+
merge-broker candidate list
|
|
265
|
+
merge-broker candidate show <submission-id>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Run setup from a reviewed protected checkout after committing `.merge-broker/config.json`. The
|
|
269
|
+
config-independent record binds the base locator, refresh behavior, state directory, and, when
|
|
270
|
+
available, the canonical fetch-URL fingerprint without storing the URL. A changed target requires
|
|
271
|
+
explicit `--replace`. There is intentionally no caller-supplied `--base` or path list. Adoption
|
|
272
|
+
rejects an empty, unrelated, merged-history, or over-limit candidate (the smaller of
|
|
273
|
+
`scheduling.maxCommits` and Gate's 1,000-commit ceiling) and currently requires
|
|
274
|
+
`validation.authority: "broker"`. It pins the resolved commit under
|
|
275
|
+
`refs/merge-broker/adopted/<submission-id>`, derives raw paths and history, materializes filter-free
|
|
276
|
+
blob bytes in a disposable worktree, recomputes retained commit/tree/blob IDs, and verifies the
|
|
277
|
+
retained identity after validation. It durably records successful ref establishment before any
|
|
278
|
+
validator and journals any later ref loss before create-only repair, so recovery cannot forget a
|
|
279
|
+
retention violation. If a
|
|
280
|
+
validator rejects the candidate and the final artifact identity remains provable, the durable record
|
|
281
|
+
and results are returned but the command exits nonzero. An irreproducible object identity or
|
|
282
|
+
wrong/symbolic retained ref stays `validating` for fail-closed recovery instead of producing an
|
|
283
|
+
unretained terminal claim.
|
|
284
|
+
|
|
285
|
+
When refresh is enabled and the configured ref denotes the base branch, setup requires a configured
|
|
286
|
+
fetch URL and will not fall back to a stale local ref. Set `integration.refreshBase` to false for an
|
|
287
|
+
intentionally offline/local Gate target.
|
|
288
|
+
|
|
289
|
+
Gate also rejects ambient or protected-validator Git repository/index/object/history and
|
|
290
|
+
configuration-injection or transport-command overrides, rejects configured URL/transport rewrites
|
|
291
|
+
and exact-locator remote shorthand collisions, recursively inspects the repository-owned object store, binds the
|
|
292
|
+
disposable worktree's Git administration identity, and bounds its untracked-path diagnostic. See
|
|
293
|
+
[Compatibility and current limits](docs/COMPATIBILITY.md) for the exact deny-list and ceilings.
|
|
294
|
+
|
|
295
|
+
This is not an integration shortcut. A `validated` submission is not approved, published,
|
|
296
|
+
provenanced, or authorized to merge, and cannot be passed to `batch publish`. Use Coordinate mode
|
|
297
|
+
for the current end-to-end merge workflow. If adoption is interrupted after its durable record is
|
|
298
|
+
written, `merge-broker recover` replays `received` or `validating` submissions from the retained
|
|
299
|
+
identity.
|
|
183
300
|
|
|
184
301
|
## See it work
|
|
185
302
|
|
|
@@ -234,7 +351,7 @@ installing dependencies:
|
|
|
234
351
|
with:
|
|
235
352
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
236
353
|
fetch-depth: 0
|
|
237
|
-
- uses: WeSpitfire/agent-merge-broker/verify@v0.
|
|
354
|
+
- uses: WeSpitfire/agent-merge-broker/verify@v0.13.0
|
|
238
355
|
```
|
|
239
356
|
|
|
240
357
|
The check verifies the Ed25519 signature, branch and batch identity, real base history, one-file
|
|
@@ -300,11 +417,12 @@ to be current. Approval also rechecks the open PR head, target base, task state,
|
|
|
300
417
|
and configured GitHub checks. Approval becomes merge-authorizing only after it is durable and the
|
|
301
418
|
broker observes that exact PR still open; the final `gh pr merge` uses GitHub's head-SHA guard.
|
|
302
419
|
|
|
303
|
-
Protect the target branch with
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
420
|
+
Protect the target branch with “require branches to be up to date before merging” and restrict
|
|
421
|
+
bypass permission. GitHub's merge API can guard the head SHA but cannot atomically guard a base SHA.
|
|
422
|
+
The broker rechecks the base immediately before queueing and proves the merged Git history afterward,
|
|
423
|
+
while branch protection prevents an out-of-band base update in that final remote interval. Native
|
|
424
|
+
merge-queue and `merge_group` verification are planned; the current topology proof does not treat a
|
|
425
|
+
combined merge-group artifact as the authorized candidate.
|
|
308
426
|
|
|
309
427
|
If verification finds a problem, keep the task and PR:
|
|
310
428
|
|
|
@@ -331,11 +449,13 @@ Two configuration combinations cannot work and are rejected at load time rather
|
|
|
331
449
|
|
|
332
450
|
Auto-merge requires the setting to be enabled on the GitHub repository. Configurations written before this feature existed default to `autoMerge: false`, so upgrading never starts landing work on its own.
|
|
333
451
|
|
|
334
|
-
The broker
|
|
335
|
-
assembles a batch
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
452
|
+
The broker records the selected Git remote and a SHA-256 fingerprint of its canonical push URL when
|
|
453
|
+
it assembles a publishable batch; the raw URL is not persisted because it may contain credentials.
|
|
454
|
+
Pull-request batches also record a host-qualified GitHub `HOST/OWNER/REPO`. Later changes to the
|
|
455
|
+
named remote or to `gh repo set-default` cannot redirect publication. Standard GitHub and GitHub
|
|
456
|
+
Enterprise remote URLs are derived automatically. If the Git remote is a local mirror or proxy, set
|
|
457
|
+
`publish.repository` explicitly; otherwise pull-request mode fails closed rather than guessing a
|
|
458
|
+
GitHub repository.
|
|
339
459
|
|
|
340
460
|
Running `merge-broker serve --publish` reconciles checks, finishes interrupted publication or
|
|
341
461
|
auto-merge hand-offs, re-cuts stale batches, and only then integrates the next batch. With exact
|
|
@@ -365,10 +485,12 @@ deliberately instead.
|
|
|
365
485
|
`integrate --dry-run` is a rehearsal in both directions: it retains no branch when it succeeds, and
|
|
366
486
|
returns every task to the queue when it fails, so verifying costs nothing.
|
|
367
487
|
|
|
368
|
-
Only one batch is in flight at a time.
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
488
|
+
Only one batch is in flight at a time. In the default production shape—`baseRef` identifies the
|
|
489
|
+
remote target and `integration.refreshBase` is enabled—a batch is cut from the fetched base-branch
|
|
490
|
+
tip so it is born mergeable. A deliberately different `baseRef`, or disabling refresh, uses the
|
|
491
|
+
configured construction revision instead. Cutting a second batch while the first is still open can
|
|
492
|
+
leave either one stale, so `integrate` refuses with `BATCH_OUTSTANDING` and names the batch to land
|
|
493
|
+
first; `--force` overrides it.
|
|
372
494
|
|
|
373
495
|
When a batch does end up behind — something landed on the base by another route, or `--force` was
|
|
374
496
|
used — re-cut it:
|
|
@@ -377,9 +499,10 @@ used — re-cut it:
|
|
|
377
499
|
merge-broker batch refresh <batch-id>
|
|
378
500
|
```
|
|
379
501
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
502
|
+
For PR publication, that closes the superseded pull request; branch-only publication has no PR to
|
|
503
|
+
close. It returns the tasks to the queue without spending their retry budget and integrates them
|
|
504
|
+
again from the current recorded target tip, re-validating against the base that is actually being
|
|
505
|
+
merged into. A batch already cut from that tip is left alone.
|
|
383
506
|
|
|
384
507
|
Publication is safe to retry. The pull request is recorded before auto-merge is attempted, and a
|
|
385
508
|
durable intent is recorded before the remote queue is changed. A forge that fails halfway therefore
|
|
@@ -390,12 +513,13 @@ create anything new.
|
|
|
390
513
|
|
|
391
514
|
A process that dies mid-integration can leave both a lock and durable `running` state. A holder on
|
|
392
515
|
this machine is reclaimed automatically once its process is proven gone. A holder on another machine
|
|
393
|
-
cannot be probed and is never stolen merely because it is old
|
|
394
|
-
|
|
395
|
-
`
|
|
396
|
-
|
|
397
|
-
`
|
|
398
|
-
|
|
516
|
+
cannot be probed and is never stolen merely because it is old. Inspect the locks with `doctor`; for
|
|
517
|
+
an abandoned `running` integration, confirm the old authority is gone and release
|
|
518
|
+
`unlock integration --force` (and `state` or `gate-authority` only if `doctor` shows it held). Dynamic
|
|
519
|
+
`batch:<batch-id>` locks apply to interrupted operations after integration. Once the integration lock
|
|
520
|
+
is safely acquired, `serve` and `integrate` automatically mark abandoned work failed, clean its
|
|
521
|
+
broker-owned worktree and branch, and return its tasks to `submitted` without spending their attempt
|
|
522
|
+
budget. `merge-broker recover` performs that reconciliation explicitly.
|
|
399
523
|
|
|
400
524
|
Candidate revisions also carry a durable intent before the broker moves their branch. If a process
|
|
401
525
|
stops after the branch update but before state finalization, `recover` compares the real PR/local
|
|
@@ -497,22 +621,32 @@ while broker credentials stay out of repository-defined commands.
|
|
|
497
621
|
Validators receive these environment variables:
|
|
498
622
|
|
|
499
623
|
- `MERGE_BROKER_TASK_ID`
|
|
500
|
-
- `
|
|
624
|
+
- `MERGE_BROKER_FILES_FILE`, the path to an owner-readable UTF-8 JSON array of validator-relative paths
|
|
625
|
+
- `MERGE_BROKER_FILES_FILE_FORMAT=json`
|
|
626
|
+
- `MERGE_BROKER_FILES`, the newline-separated form for the default `filesInput: "inline"`; empty in JSON mode
|
|
501
627
|
- `MERGE_BROKER_BASE_SHA`
|
|
502
628
|
- `MERGE_BROKER_HEAD_SHA`
|
|
503
629
|
- `MERGE_BROKER_BATCH_ID`
|
|
630
|
+
- `MERGE_BROKER_SUBMISSION_ID`, nonempty only for trusted local-ref adoption
|
|
504
631
|
- `MERGE_BROKER_CACHE_DIR`, an isolated cache shared by validators in one integration transaction
|
|
505
632
|
|
|
506
|
-
Commands may also use the shell-safe placeholders `{taskId}`, `{files}`, and
|
|
507
|
-
`{validatorCacheDir}` (a stable validator-specific directory inside the transaction cache).
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
633
|
+
Commands may also use the shell-safe placeholders `{taskId}`, `{filesFile}`, `{files}`, and
|
|
634
|
+
`{validatorCacheDir}` (a stable validator-specific directory inside the transaction cache).
|
|
635
|
+
`{filesFile}` expands to `MERGE_BROKER_FILES_FILE`. Validators default to `filesInput: "inline"`,
|
|
636
|
+
which supplies both the shell-quoted `{files}` arguments and newline `MERGE_BROKER_FILES` only when
|
|
637
|
+
both representations fit within 4 KiB. If either is larger, validation fails closed with
|
|
638
|
+
`VALIDATION_FAILED` before the validator starts, even when its command does not contain `{files}`.
|
|
639
|
+
For potentially large path sets, set `filesInput: "json"` and parse the UTF-8 JSON array through
|
|
640
|
+
`{filesFile}` or `MERGE_BROKER_FILES_FILE`; JSON mode leaves `MERGE_BROKER_FILES` empty and rejects a
|
|
641
|
+
command that still contains `{files}`.
|
|
642
|
+
`workingDirectory` can place a validator in a repository-relative package directory; paths in every
|
|
643
|
+
file-list form are then relative to that directory. Validator output is captured with a fixed memory
|
|
644
|
+
bound and retained in state with that cap. A timeout terminates the validator process tree.
|
|
645
|
+
|
|
646
|
+
`merge-broker validate` is a preflight that runs the same broker-side validator definitions against
|
|
647
|
+
the caller's working tree. It does not reproduce per-task focused sequencing or integration's
|
|
648
|
+
post-validator candidate-preservation checks. It reports `MERGE_BROKER_BATCH_ID=local`, which a
|
|
649
|
+
validator can branch on if it needs to behave differently outside a batch.
|
|
516
650
|
|
|
517
651
|
A validator may set `"executionArchitecture": "native"` to run under the hardware architecture on
|
|
518
652
|
macOS when Node itself is translated by Rosetta. Detected SwiftPM validators use this mode and put
|
|
@@ -520,7 +654,8 @@ their scratch build under `{validatorCacheDir}`, preventing Intel and Apple Sili
|
|
|
520
654
|
from contaminating each other without rebuilding between the focused and authoritative stages of
|
|
521
655
|
the same integration transaction.
|
|
522
656
|
|
|
523
|
-
The JSON schemas in [`schemas/`](schemas/)
|
|
657
|
+
The JSON schemas in [`schemas/`](schemas/) cover configuration, task receipts, exact approval
|
|
658
|
+
candidates, batch provenance, and Gate authority/submission records.
|
|
524
659
|
|
|
525
660
|
### One authoritative CI pass
|
|
526
661
|
|
|
@@ -564,6 +699,11 @@ merge-broker install-hooks [--force] [--uninstall] [--print]
|
|
|
564
699
|
merge-broker install-service [--uninstall] [--interval <seconds>] [--no-eager]
|
|
565
700
|
merge-broker verify-provenance --branch <ref> --head <sha> --base <sha>
|
|
566
701
|
merge-broker validate [--task <id>] [--scope focused|authoritative|all] [--base <ref>] [--cwd <path>]
|
|
702
|
+
merge-broker candidate authority setup [--replace]
|
|
703
|
+
merge-broker candidate authority show
|
|
704
|
+
merge-broker candidate list
|
|
705
|
+
merge-broker candidate adopt --ref <revision>
|
|
706
|
+
merge-broker candidate show <submission-id>
|
|
567
707
|
merge-broker task register|claim|extend|heartbeat|candidate|submit|reopen|revise|retry|release|cancel|abandon|show
|
|
568
708
|
merge-broker status
|
|
569
709
|
merge-broker plan
|
|
@@ -573,7 +713,7 @@ merge-broker audit
|
|
|
573
713
|
merge-broker metrics
|
|
574
714
|
merge-broker events
|
|
575
715
|
merge-broker prune [--older-than <days>] [--dry-run]
|
|
576
|
-
merge-broker unlock [state|integration|batch:<batch-id>] [--force]
|
|
716
|
+
merge-broker unlock [state|integration|gate-authority|batch:<batch-id>] [--force]
|
|
577
717
|
merge-broker recover
|
|
578
718
|
merge-broker serve [--publish] [--eager] [--log-file <path>]
|
|
579
719
|
merge-broker-mcp -C <directory> [--profile worker|operator]
|
|
@@ -600,6 +740,8 @@ resolve conflicts automatically. The complete supported/unsupported boundary is
|
|
|
600
740
|
|
|
601
741
|
## Documentation
|
|
602
742
|
|
|
743
|
+
- [`VISION.md`](VISION.md) — durable product boundary and design principles
|
|
744
|
+
- [`ROADMAP.md`](ROADMAP.md) — current, next, and later capability horizons
|
|
603
745
|
- [`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md) — installation and production rollout
|
|
604
746
|
- [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md) — platform matrix, Windows notes, and current limits
|
|
605
747
|
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — invariants, state model, scheduling, and transactions
|