@defrex/autobuild 0.11.0 → 0.12.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/README.md +3 -1
- package/SPEC.md +222 -22
- package/docs/architecture.md +66 -4
- package/docs/configuration.md +105 -16
- package/docs/hosted-dispatcher.md +17 -2
- package/docs/hosted-service.md +214 -0
- package/docs/mcp.md +8 -2
- package/docs/operator-api.md +90 -7
- package/docs/remote-store-protocol.md +189 -144
- package/docs/remote-ticket-protocol.md +107 -19
- package/docs/setup.md +173 -16
- package/docs/ticket-dependencies.md +1 -1
- package/package.json +7 -6
- package/packages/core/src/cli/attention.ts +209 -0
- package/packages/core/src/cli/configured-store.ts +17 -0
- package/packages/core/src/cli/connect.ts +261 -0
- package/packages/core/src/cli/dashboard/model.ts +4 -5
- package/packages/core/src/cli/dispatch.ts +183 -41
- package/packages/core/src/cli/help.ts +39 -10
- package/packages/core/src/cli/init-validation.ts +27 -2
- package/packages/core/src/cli/main.ts +41 -15
- package/packages/core/src/cli/mcp.ts +7 -1
- package/packages/core/src/cli/pr-summary-publication.ts +220 -0
- package/packages/core/src/cli/pr-summary.ts +2 -0
- package/packages/core/src/cli/project-credentials.ts +132 -0
- package/packages/core/src/cli/repo-state.ts +15 -2
- package/packages/core/src/cli/self-update.ts +10 -0
- package/packages/core/src/cli/store-opening.ts +22 -14
- package/packages/core/src/cli/terminals.ts +0 -10
- package/packages/core/src/cli/ticket.ts +8 -1
- package/packages/core/src/cli/upgrade-compatibility.ts +80 -0
- package/packages/core/src/cli/wait.ts +84 -17
- package/packages/core/src/cli/watch.ts +197 -60
- package/packages/core/src/config/live.ts +3 -0
- package/packages/core/src/config/schema.ts +56 -9
- package/packages/core/src/connection.ts +86 -0
- package/packages/core/src/events/catalog.ts +10 -2
- package/packages/core/src/events/payloads.ts +44 -0
- package/packages/core/src/events/repository.ts +13 -0
- package/packages/core/src/kernel/__snapshots__/reducer-registry.test.ts.snap +130 -83
- package/packages/core/src/kernel/engine.ts +24 -0
- package/packages/core/src/kernel/generators/build-log.ts +10 -0
- package/packages/core/src/kernel/log-index.ts +17 -0
- package/packages/core/src/kernel/pr-summary.ts +89 -0
- package/packages/core/src/kernel/reducer-registry.ts +8 -0
- package/packages/core/src/kernel/reducer.ts +8 -0
- package/packages/core/src/ontology.ts +1 -0
- package/packages/core/src/operator/index.ts +7 -0
- package/packages/core/src/operator/query.ts +38 -16
- package/packages/core/src/operator/ticket-source-backend.ts +1 -0
- package/packages/core/src/operator/tickets.ts +6 -8
- package/packages/core/src/plugin-sdk/index.ts +1 -0
- package/packages/core/src/plugins/manifest.ts +5 -3
- package/packages/core/src/plugins/runtimes.ts +3 -1
- package/packages/core/src/ports/forge/fake.ts +13 -1
- package/packages/core/src/ports/forge/github-transport.ts +36 -1
- package/packages/core/src/ports/forge/github.ts +29 -5
- package/packages/core/src/ports/forge/local-git.ts +12 -4
- package/packages/core/src/ports/forge/summary-marker.ts +8 -0
- package/packages/core/src/ports/runner/session-env.ts +1 -0
- package/packages/core/src/ports/tickets/create.ts +11 -3
- package/packages/core/src/ports/tickets/hosted-index.ts +0 -3
- package/packages/core/src/ports/tickets/remote-protocol.ts +1 -0
- package/packages/core/src/ports/tickets/remote.ts +1 -0
- package/packages/core/src/ports/workspace/build-execution.ts +5 -1
- package/packages/core/src/ports/workspace/create.ts +11 -2
- package/packages/core/src/ports/workspace/distribution-archive.ts +3 -5
- package/packages/core/src/ports/workspace/harvest-execution.ts +3 -1
- package/packages/core/src/ports/workspace/local-build-execution.ts +8 -1
- package/packages/core/src/ports/workspace/vercel-sandbox.ts +47 -19
- package/packages/core/src/processes/build-execution-state.ts +1 -1
- package/packages/core/src/processes/build-runner.ts +87 -26
- package/packages/core/src/processes/dispatch-failure-budget.ts +83 -0
- package/packages/core/src/processes/dispatcher.ts +59 -10
- package/packages/core/src/processes/harvest-child.ts +1 -0
- package/packages/core/src/processes/harvest-execution-state.ts +19 -2
- package/packages/core/src/processes/harvest-runner.ts +142 -100
- package/packages/core/src/processes/phase-failure-budget.ts +1 -0
- package/packages/core/src/processes/publication-loss.ts +18 -1
- package/packages/core/src/store/remote/client.ts +1 -1
- package/packages/core/src/store/remote/compatibility.ts +90 -0
- package/packages/core/src/store/remote/credentials.ts +28 -0
- package/packages/core/src/store/remote/index.ts +14 -1
- package/packages/core/src/store/remote/protocol.ts +25 -0
- package/packages/core/src/store/remote/token.ts +74 -13
- package/packages/core/src/testing/index.ts +7 -0
- package/skills/guide/SKILL.md +144 -26
- package/skills/guide/references/operator-api.md +135 -13
- package/skills/guide/references/plugin-authoring.md +10 -2
- package/skills/guide/references/remote-store-protocol.md +189 -144
- package/skills/guide/references/remote-ticket-protocol.md +111 -18
- package/skills/guide/references/setup.md +173 -16
- package/skills/guide/references/ticket-dependencies.md +1 -1
- package/skills/operate/SKILL.md +126 -36
- package/templates/hosted-service/package.json +13 -0
- package/templates/hosted-service/vercel.json +7 -0
|
@@ -6,17 +6,48 @@ Every request must send `X-Autobuild-Version`,
|
|
|
6
6
|
`X-Autobuild-Protocol-Version: 3`, and `Authorization: Bearer …`. Identity is
|
|
7
7
|
checked before authentication or resource lookup.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Project credentials are opaque `abp_1_<id>_<secret>` bearer values bound to one
|
|
10
|
+
registered normalized repository. The service stores only a SHA-256 digest of
|
|
11
|
+
the random secret, plus project, creator, creation time, last use, expiry and
|
|
12
|
+
revocation metadata. It checks credential status and project registration on
|
|
13
|
+
every request. Revocation takes effect on the next request without affecting
|
|
14
|
+
other credentials. Unknown, expired or revoked credentials receive `401 auth`;
|
|
15
|
+
removed projects receive `403 auth` with `project not registered`.
|
|
16
|
+
|
|
17
|
+
The deployment owner runs these commands locally with database access:
|
|
10
18
|
|
|
11
19
|
```sh
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
ab-hosted-store credentials issue https://github.com/acme/app --user owner@example.com
|
|
21
|
+
ab-hosted-store credentials list https://github.com/acme/app
|
|
22
|
+
ab-hosted-store credentials revoke https://github.com/acme/app --id ID --user owner@example.com
|
|
14
23
|
```
|
|
15
24
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
Issue prints the secret once; list contains metadata only. Issue optionally
|
|
26
|
+
accepts `--ttl-seconds N` or `--expires-at ISO-8601`. For administrative/non-interactive issuance, set the returned token as
|
|
27
|
+
`AB_TOKEN`. Interactive project onboarding uses `ab connect <service-url>`;
|
|
28
|
+
it saves the credential outside the repository and commits no secret. Previous `AB_TOKEN` values and `mint operator` / `mint build` are
|
|
29
|
+
retired: the service responds that the credential format changed and points
|
|
30
|
+
to `credentials issue`. Supported old protocol shapes still work with a new
|
|
31
|
+
credential; protocol compatibility does not restore retired authentication.
|
|
32
|
+
|
|
33
|
+
`mint admin --ttl-seconds N` creates an explicit versioned, attributed owner
|
|
34
|
+
break-glass credential. It can cross project boundaries. Keep it owner-only:
|
|
35
|
+
never give it or `AB_STORE_SECRET` to a dispatcher or build agent.
|
|
36
|
+
|
|
37
|
+
Owner-purpose project credentials attribute every write to their recorded creator.
|
|
38
|
+
Dispatcher-purpose credentials are refused. Signed-in owners in the dashboard
|
|
39
|
+
and MCP receive short-lived internal signatures with an explicit version,
|
|
40
|
+
selected repository, signed user, expiry and MCP `via`. Only the service holds
|
|
41
|
+
the signing key. These signatures authorize operator routes only and require a
|
|
42
|
+
registered project; replay against another project is refused.
|
|
43
|
+
|
|
44
|
+
The path project is checked before registry lookup, body parsing and generic
|
|
45
|
+
tool execution. Body repositories and secondary build/session identifiers are
|
|
46
|
+
also checked inside that project. Explicit project mismatches return `403 auth:
|
|
47
|
+
wrong project`; removal returns `403 auth: project not registered`. Encode each
|
|
48
|
+
repository, build, session and artifact kind as a separate URL path segment.
|
|
49
|
+
Registration changes use the database-local `projects list|add|remove` owner
|
|
50
|
+
commands; see [owner workflow](setup.md#connected-projects).
|
|
20
51
|
|
|
21
52
|
## Operator sessions
|
|
22
53
|
|
|
@@ -66,7 +97,11 @@ supplied forms return `400 validation`.
|
|
|
66
97
|
Dashboard reads use the latest durable, run-correlated `effectiveConfig`
|
|
67
98
|
repository artifact. Missing, corrupt, or invalid configuration returns a typed
|
|
68
99
|
`409 effective-config-unavailable`; the service never guesses from a checkout.
|
|
69
|
-
Clients poll these reads
|
|
100
|
+
Clients poll these reads — the operator HTTP API exposes no push or long-poll
|
|
101
|
+
event transport. Streaming is provided as a CLI read surface: `ab watch`
|
|
102
|
+
streams build and repository events by polling the same event logs client-side
|
|
103
|
+
(the store protocol's `GET /builds/{slug}/events` and `GET /repos/{repo}/events`
|
|
104
|
+
reads), not as a transport on this API. `triageState`, `readyState`,
|
|
70
105
|
and every entry in `states` are backend state names and must be sent back verbatim
|
|
71
106
|
when used with the move control.
|
|
72
107
|
|
|
@@ -105,12 +140,25 @@ The retry object is deliberately bare: adding `text` is a `400 validation`
|
|
|
105
140
|
rather than silently changing the resolution to guidance. A revision object may
|
|
106
141
|
also carry `ceiling` only to receive the shared `incompatible-answer-options`
|
|
107
142
|
refusal; a ceiling and spec revision cannot be performed together.
|
|
108
|
-
|
|
109
143
|
The hosted service has no ticket-provider credentials. For ticket-origin
|
|
110
144
|
revision, a trusted caller fetches the current ticket body and supplies it; the
|
|
111
145
|
build must still have a recorded ticket. Revision conformance, lazy retry,
|
|
112
146
|
artifact metadata, event ordering, and refusal rules are the same as the CLI.
|
|
113
147
|
|
|
148
|
+
## The registry's protocol face: `POST …/tools/{tool}`
|
|
149
|
+
|
|
150
|
+
One generic route executes any entry of the agent tool registry (the same
|
|
151
|
+
closed table `ab mcp` serves over stdio and the hosted `/mcp` endpoint serves
|
|
152
|
+
over Streamable HTTP): the body is the tool's validated input — `repo`
|
|
153
|
+
included and required to equal the URL's repository — and the response is the
|
|
154
|
+
registry result verbatim. The verified operator token supplies the acting
|
|
155
|
+
identity and, when minted with one, the `via` attribution marker; the body
|
|
156
|
+
never does. Failures keep the shared `{kind,error,code?,progress?}` shape:
|
|
157
|
+
validation is `400`, auth `403`, not-found `404`, conflict and refusal `409`,
|
|
158
|
+
internal `500`. The route adds no authority of its own — it is the registry
|
|
159
|
+
behind the token check — so a tool available here is exactly the tool table,
|
|
160
|
+
and the table's contract suite is the single gate.
|
|
161
|
+
|
|
114
162
|
### Success results
|
|
115
163
|
|
|
116
164
|
Build control returns one of:
|
|
@@ -157,8 +205,82 @@ headers with a server-minted token that expires after 30 seconds and carries
|
|
|
157
205
|
the normalized signed-in email. Consequently every durable control event has
|
|
158
206
|
the browser user's human actor while no token or signing secret reaches client
|
|
159
207
|
code. Responses are private/no-store; a 401 sends the application back to sign
|
|
160
|
-
in. Browser clients poll the visible dashboard every two seconds;
|
|
161
|
-
streaming
|
|
208
|
+
in. Browser clients poll the visible dashboard every two seconds; the browser
|
|
209
|
+
surface offers no streaming of its own — live transcript streaming remains
|
|
210
|
+
absent here, and the streaming read surface is the CLI's `ab watch`, which
|
|
211
|
+
polls the store's event reads client-side. Delegated bearer tokens remain
|
|
212
|
+
server-side.
|
|
213
|
+
|
|
214
|
+
The API does not expose phase-session commands, runner startup, a push or
|
|
215
|
+
long-poll streaming transport, or a generic event-append operation; event
|
|
216
|
+
streaming is composed client-side by `ab watch`, which polls the store's
|
|
217
|
+
event reads.
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
Dispatcher liveness is also visible through `ab repository status --json`:
|
|
221
|
+
`dispatcher.holder` identifies the unexpired repository lease owner, independently
|
|
222
|
+
of `latestRun`. Heartbeat age measures attributable renewals; tick age measures
|
|
223
|
+
durable progress. Missing historical evidence is null. The liveness query uses
|
|
224
|
+
bounded repository facts first, with a full-history fallback when a later
|
|
225
|
+
invocation hides the holder start or the latest stop. Other state reads retain
|
|
226
|
+
their bounded semantics.
|
|
227
|
+
|
|
228
|
+
Repository-following `ab watch` additionally emits a read-only `dispatcher.lost`
|
|
229
|
+
observation when an observed lease expires without a matching stop. JSON carries
|
|
230
|
+
`observation` instead of `event`, with run, observedAt, leaseExpiresAt and available
|
|
231
|
+
identity, plus the usual repo/build/state/cursor fields. It invents no durable
|
|
232
|
+
sequence or actor. Retain the cursor to avoid repeat reports across invocations.
|
|
233
|
+
No lease alone is not evidence of death. SIGINT, SIGHUP and SIGTERM drain dispatch,
|
|
234
|
+
record the first signal in the stop fact, and release its lease before exit.
|
|
235
|
+
|
|
236
|
+
### CLI attention monitoring
|
|
237
|
+
|
|
238
|
+
The default watch reports actionable conditions only:
|
|
239
|
+
|
|
240
|
+
- Build `escalation.raised`, or `build.merge-decision`: a finalized open PR
|
|
241
|
+
with auto-merge off or a current actionable merge-gate deferral. Armed consent
|
|
242
|
+
awaiting application is silent. One merge decision is reported per build/PR.
|
|
243
|
+
- Repository `harvest.escalated`, `harvest.recovery-exhausted`,
|
|
244
|
+
`dispatcher.config-rejected`, `dispatcher.config-reloaded` with nonempty
|
|
245
|
+
`restartRequired`, abnormal `dispatcher.run-stopped`, and `dispatcher.lost`.
|
|
246
|
+
- `dispatcher.ticket-source-persistent`: degradation past its advertised
|
|
247
|
+
reset time, once a tick started at or after reset has completed or failed
|
|
248
|
+
with the episode still open; crossing reset alone is silent. Without a reset,
|
|
249
|
+
the deadline is 15 minutes after onset. Repeated evidence never postpones
|
|
250
|
+
the deadline; recovery ends the episode.
|
|
251
|
+
- `dispatcher.tick-failure-persistent`: continuously failing completed ticks
|
|
252
|
+
for five minutes in one run. A successful tick, new run, or matching stop
|
|
253
|
+
ends the episode. Source grace and cooldown-driven failures do not start
|
|
254
|
+
this clock; after grace, the first qualifying failure starts a new five-minute
|
|
255
|
+
interval. Each persistence episode is reported once.
|
|
256
|
+
|
|
257
|
+
Repository conditions are included with no slugs or with `--repository`.
|
|
258
|
+
Routine outcomes and self-healing failures are silent. Repeatable
|
|
259
|
+
`--event <glob>` replaces the default and selects exactly matching catalog
|
|
260
|
+
events (plus the existing `dispatcher.lost` observation); use explicit globs
|
|
261
|
+
to opt into failures, finalize, merge, or completion events.
|
|
262
|
+
|
|
263
|
+
Derived records use `observation` instead of `event`, without inventing a
|
|
264
|
+
durable sequence or actor. Merge observations carry `type`, `pr`, `reason`,
|
|
265
|
+
and `observedAt`, plus the build slug and normal reduced state. Persistence
|
|
266
|
+
observations carry source/cause/message/resetAt when advertised (or
|
|
267
|
+
run/firstFailure/error), `episodeSeq`, and `observedAt`; repository records
|
|
268
|
+
have `repo` and null build/state. Source observations also report
|
|
269
|
+
`dependencyLimited`.
|
|
270
|
+
|
|
271
|
+
Every record carries a cursor, including timer-only records. Resuming suppresses
|
|
272
|
+
delivered merge decisions and persistence episodes even when stream positions
|
|
273
|
+
did not advance. Old v1 cursors remain valid: historical eligible merge
|
|
274
|
+
decisions are treated as consumed; active overdue repository episodes may
|
|
275
|
+
report because old watches had no persistence notification. Fresh attachment
|
|
276
|
+
silently baselines historical direct events and merge decisions, but retains
|
|
277
|
+
active repository timers. Reconcile existing conditions through status after
|
|
278
|
+
arming the watch. Named watches still end when every named build is terminal;
|
|
279
|
+
learn their outcomes from status reconciliation at exit.
|
|
162
280
|
|
|
163
|
-
|
|
164
|
-
or a
|
|
281
|
+
`ab wait --for attention` is build-only and uses the same build conditions:
|
|
282
|
+
an open escalation or a merge decision. Existing conditions return immediately,
|
|
283
|
+
even with `--since`; live and backlog matches ignore routine outcomes and
|
|
284
|
+
self-healing failures. A merge match uses the watch observation with
|
|
285
|
+
`condition: "attention"`. Explicit `--event` globs remain event-only.
|
|
286
|
+
Watch and wait preserve each other's cursor notification metadata.
|
|
@@ -40,7 +40,7 @@ should declare an API range containing `^1.5.0`.
|
|
|
40
40
|
|
|
41
41
|
Plugin API 1.7 extends the workspace-provider factory context with the
|
|
42
42
|
host-derived seams a store-requiring remote provider needs. Workspace-provider
|
|
43
|
-
factories additionally receive `storeRef` and `
|
|
43
|
+
factories additionally receive `storeRef` and `delegateCredential` (guaranteed present
|
|
44
44
|
when the registration declares `capabilities.storeRequirements`),
|
|
45
45
|
`runtimeReferences` (the host's effective runtime routes; absent at call sites
|
|
46
46
|
that reference no runtimes), and the checkout-less `origin` and
|
|
@@ -125,7 +125,7 @@ Every module must default-export one strict `AutobuildPluginManifest`:
|
|
|
125
125
|
`[tickets]` fields, workspace providers receive `[workspace.config]`, and
|
|
126
126
|
runtime and forge factories currently receive an empty `config` object.
|
|
127
127
|
Workspace providers additionally receive the host-derived seams (API 1.7):
|
|
128
|
-
`storeRef` and `
|
|
128
|
+
`storeRef` and `delegateCredential` — guaranteed URL and exchange callback when the registration
|
|
129
129
|
declares `capabilities.storeRequirements` — plus `runtimeReferences`,
|
|
130
130
|
`origin`, and `remoteBranchHead`. Each seam is optional and absent when the
|
|
131
131
|
host call site supplies no such value; absent `origin`/`remoteBranchHead`
|
|
@@ -369,3 +369,11 @@ policy says otherwise.
|
|
|
369
369
|
Official npm references: [`package.json` fields](https://docs.npmjs.com/cli/v11/configuring-npm/package-json),
|
|
370
370
|
[`npm pack`](https://docs.npmjs.com/cli/v11/commands/npm-pack), and
|
|
371
371
|
[`npm publish`](https://docs.npmjs.com/cli/v11/commands/npm-publish).
|
|
372
|
+
|
|
373
|
+
Remote workspace factories must use `delegateCredential(storeRef, undefined,
|
|
374
|
+
target)` to obtain per-resource grants before provisioning or launching guests.
|
|
375
|
+
The callback keeps parent authority in host composition. `storeToken` is retired
|
|
376
|
+
and is never supplied; factory environments also exclude `AB_TOKEN`. Launch
|
|
377
|
+
credentials travel through the separate transient execution-auth argument, never
|
|
378
|
+
through serialized execution identity. Existing plugins that forwarded
|
|
379
|
+
`storeToken` must migrate to this callback and fail closed if it is unavailable.
|