@defrex/autobuild 0.10.1 → 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 +237 -23
- package/bin/ab-dispatch-kernel.ts +1 -1
- package/docs/architecture.md +66 -4
- package/docs/configuration.md +137 -19
- 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 +107 -7
- package/docs/remote-store-protocol.md +189 -144
- package/docs/remote-ticket-protocol.md +111 -18
- 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/binary.ts +3 -3
- 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 +8 -5
- package/packages/core/src/cli/dashboard/render.ts +37 -7
- package/packages/core/src/cli/dispatch-frontend.ts +16 -1
- package/packages/core/src/cli/dispatch-process.ts +25 -7
- package/packages/core/src/cli/dispatch.ts +247 -47
- package/packages/core/src/cli/dispatcher-liveness.ts +91 -0
- package/packages/core/src/cli/help.ts +45 -13
- 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/repository-status.ts +45 -5
- 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 +350 -68
- package/packages/core/src/config/live.ts +4 -0
- package/packages/core/src/config/schema.ts +65 -11
- package/packages/core/src/connection.ts +86 -0
- package/packages/core/src/events/catalog.ts +10 -2
- package/packages/core/src/events/globs.ts +8 -3
- package/packages/core/src/events/payloads.ts +44 -0
- package/packages/core/src/events/repository.ts +64 -2
- package/packages/core/src/integration/harness.ts +2 -1
- package/packages/core/src/kernel/__snapshots__/reducer-registry.test.ts.snap +148 -83
- package/packages/core/src/kernel/dispatch-status.ts +9 -1
- package/packages/core/src/kernel/dispatcher-liveness.ts +70 -0
- 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 +12 -0
- package/packages/core/src/kernel/reducer.ts +8 -0
- package/packages/core/src/kernel/ticket-source-health.ts +30 -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 +44 -19
- 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/contract.ts +25 -0
- package/packages/core/src/ports/tickets/create.ts +11 -3
- package/packages/core/src/ports/tickets/fake.ts +10 -8
- package/packages/core/src/ports/tickets/file.ts +1 -0
- package/packages/core/src/ports/tickets/hosted-index.ts +0 -3
- package/packages/core/src/ports/tickets/linear.ts +241 -49
- package/packages/core/src/ports/tickets/remote-protocol.ts +3 -0
- package/packages/core/src/ports/tickets/remote.ts +1 -0
- package/packages/core/src/ports/types.ts +17 -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 +336 -83
- 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/processes/repo-view.ts +2 -1
- package/packages/core/src/store/adapter.ts +1 -0
- package/packages/core/src/store/contract.ts +109 -0
- package/packages/core/src/store/digest.ts +14 -2
- package/packages/core/src/store/local/store.ts +18 -5
- 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 +26 -0
- package/packages/core/src/store/remote/token.ts +74 -13
- package/packages/core/src/store/repo-state-events.ts +49 -59
- package/packages/core/src/store/types.ts +5 -1
- package/packages/core/src/testing/index.ts +7 -0
- package/skills/guide/SKILL.md +175 -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 +159 -34
- package/templates/hosted-service/package.json +13 -0
- package/templates/hosted-service/vercel.json +7 -0
package/skills/guide/SKILL.md
CHANGED
|
@@ -234,6 +234,19 @@ Every other known table is closed to unknown keys. The removed `[dashboardFrames
|
|
|
234
234
|
`[dispatcher]`, `[harvest]`, and `[outer]` tables have no aliases or migration
|
|
235
235
|
shims; they fail as ordinary unknown top-level keys.
|
|
236
236
|
|
|
237
|
+
Ticket-source ready scans run immediately when no completed measurement exists,
|
|
238
|
+
then every
|
|
239
|
+
`ticketScanIntervalSeconds` (default 60 seconds, a positive integer). Actual
|
|
240
|
+
tick spacing is the floor when the configured interval is shorter. A
|
|
241
|
+
same-repository `pr.merged`, `build.completed`, or `build.aborted` fact forces
|
|
242
|
+
another scan on the next tick; changed ready criteria also force a scan.
|
|
243
|
+
Housekeeping keeps its ordinary tick cadence. Between scans, queue depth and
|
|
244
|
+
standing diagnostics repeat the last completed measurement, including across
|
|
245
|
+
process restarts. Tickets groomed directly in the tracker are picked up within
|
|
246
|
+
one scan interval plus one tick when capacity permits. Observation while intake
|
|
247
|
+
is off shares the cadence; an observation measurement cannot suppress a fresh
|
|
248
|
+
admission scan when intake is enabled.
|
|
249
|
+
|
|
237
250
|
### Root scalars
|
|
238
251
|
|
|
239
252
|
Root scalars must appear before the first TOML table; TOML otherwise nests them
|
|
@@ -242,6 +255,7 @@ under the preceding table.
|
|
|
242
255
|
| Field | Default | Allowed / constraints | Effect |
|
|
243
256
|
|---|---|---|---|
|
|
244
257
|
| `baseBranch` | `"main"` | nonempty string | The branch builds branch from and target with their PR; what `reconcile` merges into the build branch. |
|
|
258
|
+
| `ticketScanIntervalSeconds` | `60` | positive integer seconds | Hot-reloaded ready scan cadence; tick spacing is the floor, and same-repository merge/completion/abort forces an early scan. |
|
|
245
259
|
| `capacity` | `1` | positive integer | Maximum concurrent builds for this repository. |
|
|
246
260
|
| `forge` | `"github"` | nonblank string | Selects shipped `github` or `local-git`, or a plugin-registered Forge adapter. `github` authenticates with `GITHUB_TOKEN`, then `GH_TOKEN`, then the gh CLI's stored login. |
|
|
247
261
|
| `plugins` | `[]` | array of unique nonblank module specifiers | Trusted Bun plugin modules loaded before dispatch, `ab ticket`, and scoped phase wiring. |
|
|
@@ -269,6 +283,19 @@ through the strict versioned manifest and environment-only secrets, to the
|
|
|
269
283
|
unchanged shared contract suite and optional npm publication—read
|
|
270
284
|
[`references/plugin-authoring.md`](references/plugin-authoring.md).
|
|
271
285
|
|
|
286
|
+
### `[store]`
|
|
287
|
+
|
|
288
|
+
| Key | Required | Values / purpose |
|
|
289
|
+
|---|---|---|
|
|
290
|
+
| `url` | When `[store]` exists | Absolute HTTPS service base URL; loopback HTTP is allowed for development. No credentials, query or fragment. Trailing slashes are normalized. |
|
|
291
|
+
|
|
292
|
+
Selection is explicit `--store` > nonblank `AB_STORE` > `[store] url` > the main
|
|
293
|
+
checkout's `.autobuild/`. A configured service without a user credential fails
|
|
294
|
+
with `ab connect` guidance. `AB_TOKEN` overrides the saved service/project
|
|
295
|
+
credential. See [repository setup](references/setup.md#connect-a-project).
|
|
296
|
+
Changing the store requires restarting dispatch.
|
|
297
|
+
|
|
298
|
+
|
|
272
299
|
### `[pr]`
|
|
273
300
|
|
|
274
301
|
Optional PR-projection settings. Omission leaves artifact attachments text-only.
|
|
@@ -394,6 +421,28 @@ manager.
|
|
|
394
421
|
|
|
395
422
|
### `[verify]`
|
|
396
423
|
|
|
424
|
+
Post-reconcile verification defaults to enabled: `[verify].afterReconcile = true`.
|
|
425
|
+
Set it to `false` to retain pre-reconcile verification and skip all steps after
|
|
426
|
+
reconciliation. An optional boolean `[verify.<step>].afterReconcile` overrides
|
|
427
|
+
the repository setting in either direction; overrides require a configured step.
|
|
428
|
+
For example, set `afterReconcile = false` in `[verify]` and
|
|
429
|
+
`afterReconcile = true` in `[verify.types]` to keep only that step re-running.
|
|
430
|
+
|
|
431
|
+
The kernel freezes the resolved ordered policy in
|
|
432
|
+
`verify.reconcile-policy-captured` at the next engine action after reconcile
|
|
433
|
+
completion. Live configuration changes apply at that boundary; a cycle already
|
|
434
|
+
started keeps its policy through recovery. Historical cycles already started
|
|
435
|
+
without a captured policy retain the rerun-all behavior. Initial verification
|
|
436
|
+
and verification after subsequent code review always use ordinary applicability.
|
|
437
|
+
Policy exclusion precedes plan selection and paths, including `always = true`.
|
|
438
|
+
Enabled steps still follow plan selection and path rules. Excluded steps record
|
|
439
|
+
`verify.completed` with outcome `skipped`, `skipCause = "post-reconcile-policy"`,
|
|
440
|
+
and a reason naming the setting. Dashboards and PR summaries call this
|
|
441
|
+
"skipped by post-reconcile policy"; it is never a pass. Forge-side required
|
|
442
|
+
checks and branch protections still gate merge. For excluded steps, merged code
|
|
443
|
+
is not re-verified, so breakage that only exists in the combination can land.
|
|
444
|
+
|
|
445
|
+
|
|
397
446
|
`steps` orders the verify phases; each entry `"<step>"` becomes a
|
|
398
447
|
`verify:<step>` phase and needs its own `[verify.<step>]` subtable. Those
|
|
399
448
|
subtables are part of this section — their fields are listed here.
|
|
@@ -405,6 +454,7 @@ subtables are part of this section — their fields are listed here.
|
|
|
405
454
|
| `command` | — | **required when `kind = "check"`**, nonempty string | Ref into `[commands]` — the key, not a shell string. Pass/fail is the command's exit status. |
|
|
406
455
|
| `skill` | — | **required when `kind = "agent"`**, nonempty string | Installed skill name to run (e.g. a repository-authored `"verify-app-e2e"`). |
|
|
407
456
|
| `paths` | — | optional nonempty array of positive repository-relative globs | Makes either step kind apply when any changed path matches any selector. Omitted means unconditional. |
|
|
457
|
+
| `afterReconcile` | repository: `true`; step: inherited | boolean | Step override wins over `[verify].afterReconcile`; false skips this step after reconciliation only. |
|
|
408
458
|
| `always` | — | optional boolean | `true` makes the step unconditional and mandatory (a plan cannot deselect it); `false` is equivalent to omission. |
|
|
409
459
|
|
|
410
460
|
A plan may begin with strict TOML front matter selecting the complete set of
|
|
@@ -474,7 +524,7 @@ A selected step's `paths` are evaluated immediately before the step against
|
|
|
474
524
|
current `HEAD`, relative to the initial branch-cut SHA or the refreshed base
|
|
475
525
|
from the latest completed reconcile. It uses a NUL-delimited, no-rename Git diff, so
|
|
476
526
|
adds/modifications/deletions and both rename sides participate. A reconcile
|
|
477
|
-
starts a fresh cycle and evaluation repeats; upstream-only merged paths are
|
|
527
|
+
starts a fresh cycle and evaluation repeats for policy-enabled steps; upstream-only merged paths are
|
|
478
528
|
excluded while build-owned resolutions remain visible. A miss starts no
|
|
479
529
|
command, agent, or session and records `skipped` with
|
|
480
530
|
`excluded by [verify.<step>].paths: no changed path matched <JSON paths>`.
|
|
@@ -674,6 +724,7 @@ nonnegative integer so zero can disable that trigger.
|
|
|
674
724
|
| `sessionBudgetSeconds` | `3600` | positive integer | Wall-clock bound for each build agent session unless its logical role overrides it. |
|
|
675
725
|
| `stallRounds` | `3` | positive integer | The same finding surviving this many review rounds auto-escalates to a human — the anti-loop guard. |
|
|
676
726
|
| `maxVerifyAttempts` | `3` | positive integer | Caps the `verify → implement → verify` cycle before escalation. |
|
|
727
|
+
| `maxDispatchAttempts` | `3` | positive integer | Caps consecutive dispatch failures before a setup-targeted `dispatch-failure-limit` escalation. |
|
|
677
728
|
| `maxSetupAttempts` | `3` | positive integer | Caps consecutive `[commands].setup` failures before a setup-targeted human escalation. |
|
|
678
729
|
| `maxInfrastructureAttempts` | `3` | positive integer | Caps consecutive remote provider lifecycle failures before a setup-targeted human escalation; a `retry` answer re-arms the budget. |
|
|
679
730
|
| `maxReconcileAttempts` | `3` | positive integer | Caps completed reconciles that leave the PR conflicted against an unchanged authoritative base. Moving-base races do not consume the budget. |
|
|
@@ -681,6 +732,11 @@ nonnegative integer so zero can disable that trigger.
|
|
|
681
732
|
| `harvestThreshold` | `5` | positive integer | Newly unclaimed `observation.recorded` occurrences required to start one repository harvest run. |
|
|
682
733
|
| `harvestMaxDrift` | `3` | nonnegative integer | Other builds merged after the oldest unclaimed observation required to start a run; `0` disables drift. |
|
|
683
734
|
|
|
735
|
+
Dispatch failures share one budget across stages until runner attachment. At
|
|
736
|
+
exhaustion dispatch parks durably; bare `ab answer <slug>` and text guidance
|
|
737
|
+
both grant a fresh budget, while abort terminates without retrying. Workspace
|
|
738
|
+
failures owned by provider infrastructure recovery use only its existing budget.
|
|
739
|
+
|
|
684
740
|
For each repeat conflict, Autobuild compares the base merged by the latest
|
|
685
741
|
completed reconcile with a fresh authoritative base snapshot. An advanced base
|
|
686
742
|
proves the attempt lost a race and permits another reconcile regardless of the
|
|
@@ -698,7 +754,7 @@ roundless no-progress answer. An already exhausted no-progress budget raises its
|
|
|
698
754
|
matching cause separately before another reconcile. Cause-less historical
|
|
699
755
|
raises retain their former round-shaped reset behavior, and roundless
|
|
700
756
|
policy/reconcile raises retain their former no-progress meaning, on replay
|
|
701
|
-
without migration. Post-reconcile verification
|
|
757
|
+
without migration. Post-reconcile verification follows the captured policy and remains
|
|
702
758
|
independently bounded by `maxVerifyAttempts`.
|
|
703
759
|
|
|
704
760
|
`stallRounds` counts *persistence chains*, which reviewers mark and the kernel
|
|
@@ -734,10 +790,11 @@ state eligible.
|
|
|
734
790
|
| `readyLabels` | — (source-aware) | optional; array of nonempty strings | A ticket must carry **every** listed label to be dispatchable. `[]` = **no label gate**. Absent uses the source default below. |
|
|
735
791
|
| `readyState` | — | **required**, non-blank string | The one workflow state a ticket must sit in to be dispatchable. Linear matches exactly and case-sensitively; file matches it case-insensitively to a state directory (`ready` → `ready/`). There is no any-state mode. |
|
|
736
792
|
| `readyAssignee` | — | optional; `"me"` or an email; `linear` only | Also require the ticket to be assigned to that Linear user (`me` = owner of `LINEAR_API_KEY`); unassigned tickets are never ready. |
|
|
737
|
-
| `teamKey` | — | required by `linear`, forbidden by `file`, allowed for plugins | The Linear team key (e.g. `"ENG"`) or an existing plugin configuration field. |
|
|
793
|
+
| `teamKey` | — | required by `linear` and `hosted`, forbidden by `file`, allowed for plugins | The Linear team key (e.g. `"ENG"`) or an existing plugin configuration field. |
|
|
738
794
|
| `claimedState` | — | optional nonempty string; forbidden by `file`, allowed for plugins | Workflow state `claim()` moves a ticket to when a build starts. |
|
|
795
|
+
| `doneState` | hosted: `"Done"` | optional nonblank string | Project completion state and merged-ticket transition; hosted tickets only. |
|
|
739
796
|
| `createState` | — | optional, nonempty string | Default state for new tickets when a create does not name one. Absent = the provider's default (Linear: the team's default, e.g. Backlog; file: Triage). |
|
|
740
|
-
| `triageState` | — | optional, nonempty string | State the dispatcher hands tickets back to for human triage — spec-gate bounces, aborted builds, closed-unmerged PRs. Absent = Linear: Backlog; file/plugin: Triage. Must name a state the tracker actually has — a Linear team only has "Triage" when its triage feature is enabled. |
|
|
797
|
+
| `triageState` | — | optional, nonempty string | State the dispatcher hands tickets back to for human triage — spec-gate bounces, aborted builds, closed-unmerged PRs. Absent = Linear/hosted: Backlog; file/plugin: Triage. Must name a state the tracker actually has — a Linear team only has "Triage" when its triage feature is enabled. |
|
|
741
798
|
| `proposalState` | — | optional, nonempty string | State observation harvest files approved proposals into. Absent = the resolved `triageState`, which keeps the human grooming gate. Setting it to `readyState` waives that gate: harvested proposals dispatch without being read. Keep it distinct from `triageState` — see below. |
|
|
742
799
|
| `dir` | file: `.autobuild/tickets`; plugin: — | optional nonempty string; forbidden by `linear`, allowed for plugins | Root holding file state directories, or an existing plugin configuration field. |
|
|
743
800
|
|
|
@@ -815,7 +872,7 @@ changing it requires a dispatcher restart.
|
|
|
815
872
|
| `model` | — (required when `enabled = true`) | nonblank provider-qualified string, same vocabulary as `[roles]` | The turn runner's model, resolved through the deployment's gateway credential; a leading `vercel-ai-gateway/` prefix is accepted and stripped. |
|
|
816
873
|
| `invocationBudgetSeconds` | `240` | positive integer, clamped to 300 | Wall-clock budget for one turn invocation. A larger value is clamped — not rejected — to the 300-second hosted function limit the runner executes under. |
|
|
817
874
|
| `approvals` | `["builds.control:abort", "builds.control:discard", "builds.answer:revise-spec", "sandbox.publish", "tickets.move:ready"]` | array of `tool` or `tool:qualifier` strings | Registry tool calls that suspend a turn until the operator answers. Empty (`[]`) means none — autonomous operation. An entry naming an absent or unknown tool is **inert by design**, never an error. A qualified entry applies to one discriminator value only (`tickets.move:ready` approves moving a ticket to `ready`); for a tool without a discriminator, only the bare form matches. |
|
|
818
|
-
| `wake` | inherits the default | array of event-type globs | The attention events a **new** session wakes for. Absent inherits the
|
|
875
|
+
| `wake` | inherits the default | array of event-type globs | The attention events a **new** session wakes for. Absent inherits the legacy hosted wake event set, independent of CLI watch defaults; an explicit `[]` means never wake — message-only. Each glob must match at least one build event type. Existing sessions never retroactively inherit; an explicit wake update always wins. |
|
|
819
876
|
| `sandbox` | — | strict subtable | The sandbox behavior knobs; absence reads as the defaults below. |
|
|
820
877
|
|
|
821
878
|
`[orchestrator.sandbox]` fields:
|
|
@@ -1035,7 +1092,7 @@ There is no home-directory fallback: a repository with no state tree starts
|
|
|
1035
1092
|
empty.
|
|
1036
1093
|
|
|
1037
1094
|
Every command uses the same precedence: explicit `--store <ref>` > nonempty
|
|
1038
|
-
`AB_STORE` > `<main-repo>/.autobuild`. Relative local overrides are normalized
|
|
1095
|
+
`AB_STORE` > `[store] url` > `<main-repo>/.autobuild`. Relative local overrides are normalized
|
|
1039
1096
|
against the main checkout. A local override relocates the whole state tree,
|
|
1040
1097
|
including `worktrees/` and default file tickets; an explicit `[tickets].dir`
|
|
1041
1098
|
remains repo-relative. An HTTP(S) URL still selects the remote store unchanged,
|
|
@@ -1043,6 +1100,46 @@ while worktrees and default file tickets remain under the repository-default
|
|
|
1043
1100
|
`.autobuild/` directory. The dispatcher passes its normalized selection to
|
|
1044
1101
|
every agent session as `AB_STORE`.
|
|
1045
1102
|
|
|
1103
|
+
## Connect a project
|
|
1104
|
+
|
|
1105
|
+
From a checkout with an origin remote, run `ab connect https://YOUR_ORIGIN`.
|
|
1106
|
+
The CLI prints a verification URL and short code and attempts to open a browser.
|
|
1107
|
+
Sign in as an allowed owner, check the full repository identity and code, and
|
|
1108
|
+
approve or deny. Another device can open the printed URL, or visit `/connect`
|
|
1109
|
+
and enter the code. Approval requires the web-enabled service origin; a
|
|
1110
|
+
standalone machine-only listener cannot present browser consent. Requests
|
|
1111
|
+
expire after ten minutes. Denial and timeout leave local configuration unchanged.
|
|
1112
|
+
|
|
1113
|
+
On approval the service registers the project and issues a project credential.
|
|
1114
|
+
The CLI keeps it in `$XDG_CONFIG_HOME/autobuild/credentials` (or
|
|
1115
|
+
`~/.config/autobuild/credentials`), keyed by normalized service and origin,
|
|
1116
|
+
with directory mode 0700 and file mode 0600. Credentials never belong in the
|
|
1117
|
+
repository. It adds the non-secret `[store] url` to `autobuild.toml` when
|
|
1118
|
+
absent; review and commit that change yourself. An existing different URL
|
|
1119
|
+
must be changed explicitly before connecting. Reconnecting replaces the saved
|
|
1120
|
+
credential only after approval and revokes the previous credential.
|
|
1121
|
+
|
|
1122
|
+
All worktrees share the main checkout's configuration and the user's saved
|
|
1123
|
+
credential. A service manager running as that user uses the same HOME and
|
|
1124
|
+
XDG_CONFIG_HOME, with no AB_STORE or AB_TOKEN exports. A fresh clone with
|
|
1125
|
+
committed store configuration but no saved credential fails with `ab connect`
|
|
1126
|
+
guidance; it never silently creates local state. Run connect on each host/user.
|
|
1127
|
+
|
|
1128
|
+
`ab connect` without a URL reports service, project, and credential status:
|
|
1129
|
+
accepted, rejected, missing, or unreachable. `ab disconnect` revokes the saved
|
|
1130
|
+
credential remotely before removing it locally, keeping the project registered,
|
|
1131
|
+
its data, and store configuration. A network/server failure retains the local
|
|
1132
|
+
entry for retry; an already revoked credential can be removed. If saving a new
|
|
1133
|
+
connection fails, the CLI cancels/revokes it and retains the previous entry.
|
|
1134
|
+
If remote cleanup cannot be confirmed, check the printed credential id with
|
|
1135
|
+
the owner's administrative tools before retrying.
|
|
1136
|
+
|
|
1137
|
+
Store selection is `--store` > nonblank `AB_STORE` > `[store] url` > the
|
|
1138
|
+
main checkout's `.autobuild/`. `AB_TOKEN` overrides the exact service/project's
|
|
1139
|
+
saved credential for CI and other non-interactive hosts. A service override
|
|
1140
|
+
never borrows another service's credential. Build and harvest sessions keep
|
|
1141
|
+
their explicit scoped authority.
|
|
1142
|
+
|
|
1046
1143
|
## Source-agnostic ticket operations
|
|
1047
1144
|
|
|
1048
1145
|
The sessionless `ab ticket` namespace constructs whichever TicketSource the
|
|
@@ -1097,7 +1194,7 @@ to a ticket that has already been claimed into a build does not stop that build.
|
|
|
1097
1194
|
For dependent tickets, follow the
|
|
1098
1195
|
[safe blocker-filing workflow](references/ticket-dependencies.md): determine the
|
|
1099
1196
|
intended final destination, stage outside ready, verify all blocker relationships,
|
|
1100
|
-
and move to ready last. Direct
|
|
1197
|
+
and move to ready last. Direct Linear creates the issue and its blockers
|
|
1101
1198
|
in separate requests; one `create --blocked-by` call is not atomic publication.
|
|
1102
1199
|
Harvest's creation reservations cover Harvest only, not interactive CLI creates.
|
|
1103
1200
|
Dependency order and JSON id extraction are still required, but do not alone
|
|
@@ -1159,7 +1256,7 @@ judge against it.
|
|
|
1159
1256
|
is the read-only binary retrieval form. Operators need no session identity: it
|
|
1160
1257
|
works after a build is terminal, writes exact bytes (creating parent
|
|
1161
1258
|
directories), verifies that the build belongs to this repository, and uses the
|
|
1162
|
-
standard explicit `--store` > nonblank `AB_STORE` > repository-local selection.
|
|
1259
|
+
standard explicit `--store` > nonblank `AB_STORE` > `[store] url` > repository-local selection.
|
|
1163
1260
|
Inside a phase, a complete ambient tuple permits only the ambient build; a
|
|
1164
1261
|
foreign build or malformed/partial identity is rejected. Use the exact pinned
|
|
1165
1262
|
`@rev` from a PR attachment command.
|
|
@@ -1493,7 +1590,7 @@ Every command requires the target to exist in this repository and be active
|
|
|
1493
1590
|
`ab answer` additionally requires an open escalation. A stale, missing, done,
|
|
1494
1591
|
aborted, or otherwise inapplicable target is an error and gets no new event. Attribution uses `USER`, then `USERNAME`, then the
|
|
1495
1592
|
same stable fallback on both surfaces. All five commands run sessionless and
|
|
1496
|
-
accept `--store <ref>` with the usual explicit flag > `AB_STORE` > repository
|
|
1593
|
+
accept `--store <ref>` with the usual explicit flag > `AB_STORE` > `[store] url` > repository
|
|
1497
1594
|
local precedence. If nonblank `AB_SESSION` and matching `AB_BUILD` identify the
|
|
1498
1595
|
caller's own phase build, the command refuses it; a phase cannot pause, resume,
|
|
1499
1596
|
auto-merge, answer, or abort itself. `ab pause --all` and `ab resume --all`
|
|
@@ -1539,7 +1636,7 @@ repository-wide pause (`paused`, default `false`), and the claim-time auto-merge
|
|
|
1539
1636
|
default (`defaultAutoMerge`, default `false`). Those defaults also describe a
|
|
1540
1637
|
repository with no journal row; the read does not create one. Human output is
|
|
1541
1638
|
the default. `--json` emits one bare object with those exact fields plus the
|
|
1542
|
-
canonical `repo`, and `--store` follows the usual explicit flag > `AB_STORE` >
|
|
1639
|
+
canonical `repo`, and `--store` follows the usual explicit flag > `AB_STORE` > `[store] url` >
|
|
1543
1640
|
repository-local precedence. The command uses the same reducer as the
|
|
1544
1641
|
dispatcher and dashboard, writes no state, claims no ticket, attaches no runner,
|
|
1545
1642
|
and starts no dispatcher work.
|
|
@@ -1622,19 +1719,51 @@ streams matching events as they land instead of answering once. With no slug it
|
|
|
1622
1719
|
follows every nonterminal build in the repository — a build created while the
|
|
1623
1720
|
watch runs joins it without a restart — and naming one or more slugs watches
|
|
1624
1721
|
exactly those builds, ending the watch when all of them reach a terminal status.
|
|
1625
|
-
|
|
1626
|
-
repository
|
|
1627
|
-
|
|
1628
|
-
The default
|
|
1629
|
-
|
|
1630
|
-
`
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
`harvest.escalated`, `harvest.
|
|
1634
|
-
`dispatcher.config-rejected`, `dispatcher.
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1722
|
+
With no slugs the repository journal is included; named watches add it with
|
|
1723
|
+
`--repository`.
|
|
1724
|
+
|
|
1725
|
+
The default watch reports actionable conditions only:
|
|
1726
|
+
|
|
1727
|
+
- Build `escalation.raised`, or `build.merge-decision`: a finalized open PR
|
|
1728
|
+
with auto-merge off or a current actionable merge-gate deferral. Armed consent
|
|
1729
|
+
awaiting application is silent. One merge decision is reported per build/PR.
|
|
1730
|
+
- Repository `harvest.escalated`, `harvest.recovery-exhausted`,
|
|
1731
|
+
`dispatcher.config-rejected`, `dispatcher.config-reloaded` with nonempty
|
|
1732
|
+
`restartRequired`, abnormal `dispatcher.run-stopped`, and `dispatcher.lost`.
|
|
1733
|
+
- `dispatcher.ticket-source-persistent`: degradation past its advertised
|
|
1734
|
+
reset time, once a tick started at or after reset has completed or failed
|
|
1735
|
+
with the episode still open; crossing reset alone is silent. Without a reset,
|
|
1736
|
+
the deadline is 15 minutes after onset. Repeated evidence never postpones
|
|
1737
|
+
the deadline; recovery ends the episode.
|
|
1738
|
+
- `dispatcher.tick-failure-persistent`: continuously failing completed ticks
|
|
1739
|
+
for five minutes in one run. A successful tick, new run, or matching stop
|
|
1740
|
+
ends the episode. Source grace and cooldown-driven failures do not start
|
|
1741
|
+
this clock; after grace, the first qualifying failure starts a new five-minute
|
|
1742
|
+
interval. Each persistence episode is reported once.
|
|
1743
|
+
|
|
1744
|
+
Repository conditions are included with no slugs or with `--repository`.
|
|
1745
|
+
Routine outcomes and self-healing failures are silent. Repeatable
|
|
1746
|
+
`--event <glob>` replaces the default and selects exactly matching catalog
|
|
1747
|
+
events (plus the existing `dispatcher.lost` observation); use explicit globs
|
|
1748
|
+
to opt into failures, finalize, merge, or completion events.
|
|
1749
|
+
|
|
1750
|
+
Derived records use `observation` instead of `event`, without inventing a
|
|
1751
|
+
durable sequence or actor. Merge observations carry `type`, `pr`, `reason`,
|
|
1752
|
+
and `observedAt`, plus the build slug and normal reduced state. Persistence
|
|
1753
|
+
observations carry source/cause/message/resetAt when advertised (or
|
|
1754
|
+
run/firstFailure/error), `episodeSeq`, and `observedAt`; repository records
|
|
1755
|
+
have `repo` and null build/state. Source observations also report
|
|
1756
|
+
`dependencyLimited`.
|
|
1757
|
+
|
|
1758
|
+
Every record carries a cursor, including timer-only records. Resuming suppresses
|
|
1759
|
+
delivered merge decisions and persistence episodes even when stream positions
|
|
1760
|
+
did not advance. Old v1 cursors remain valid: historical eligible merge
|
|
1761
|
+
decisions are treated as consumed; active overdue repository episodes may
|
|
1762
|
+
report because old watches had no persistence notification. Fresh attachment
|
|
1763
|
+
silently baselines historical direct events and merge decisions, but retains
|
|
1764
|
+
active repository timers. Reconcile existing conditions through status after
|
|
1765
|
+
arming the watch. Named watches still end when every named build is terminal;
|
|
1766
|
+
learn their outcomes from status reconciliation at exit.
|
|
1638
1767
|
|
|
1639
1768
|
With `--json`, stdout is newline-delimited JSON — exactly one object per
|
|
1640
1769
|
matching event, flushed as soon as it is written — with fields `build` (slug,
|
|
@@ -1650,6 +1779,23 @@ matching event after that cursor is delivered exactly once, in per-stream
|
|
|
1650
1779
|
sequence order — including events that landed while no watch was running. A
|
|
1651
1780
|
cursor from a different repository or store is rejected.
|
|
1652
1781
|
|
|
1782
|
+
|
|
1783
|
+
Dispatcher liveness is also visible through `ab repository status --json`:
|
|
1784
|
+
`dispatcher.holder` identifies the unexpired repository lease owner, independently
|
|
1785
|
+
of `latestRun`. Heartbeat age measures attributable renewals; tick age measures
|
|
1786
|
+
durable progress. Missing historical evidence is null. The liveness query uses
|
|
1787
|
+
bounded repository facts first, with a full-history fallback when a later
|
|
1788
|
+
invocation hides the holder start or the latest stop. Other state reads retain
|
|
1789
|
+
their bounded semantics.
|
|
1790
|
+
|
|
1791
|
+
Repository-following `ab watch` additionally emits a read-only `dispatcher.lost`
|
|
1792
|
+
observation when an observed lease expires without a matching stop. JSON carries
|
|
1793
|
+
`observation` instead of `event`, with run, observedAt, leaseExpiresAt and available
|
|
1794
|
+
identity, plus the usual repo/build/state/cursor fields. It invents no durable
|
|
1795
|
+
sequence or actor. Retain the cursor to avoid repeat reports across invocations.
|
|
1796
|
+
No lease alone is not evidence of death. SIGINT, SIGHUP and SIGTERM drain dispatch,
|
|
1797
|
+
record the first signal in the stop fact, and release its lease before exit.
|
|
1798
|
+
|
|
1653
1799
|
The watch ends with exit 0 when `--timeout` elapses (30 minutes by default;
|
|
1654
1800
|
`0` unbounded), after `--count <n>` records, or when named builds have all
|
|
1655
1801
|
gone terminal; with no slugs named, an empty set of active builds does not end
|
|
@@ -1714,7 +1860,7 @@ vocabulary is closed: `blocked`, `paused`, `running`, `done`, `aborted`,
|
|
|
1714
1860
|
`terminal` (done or aborted), `pr=open`, `pr=merged`, `pr=closed`,
|
|
1715
1861
|
`pr=conflicted`, `phase=<phase>` (a core phase — `plan`, `plan-review`,
|
|
1716
1862
|
`implement`, `code-review`, `finalize`, `reconcile` — or `verify:<step>`), and
|
|
1717
|
-
`attention` (
|
|
1863
|
+
`attention` (an open escalation or a build waiting for a merge decision). Repeatable `--event`
|
|
1718
1864
|
globs follow the `ab watch` rules. Multiple values are alternatives: the first
|
|
1719
1865
|
one satisfied ends the wait — all `--for` values in supply order, then all
|
|
1720
1866
|
globs in supply order — and the record names what matched.
|
|
@@ -1725,8 +1871,11 @@ means an open escalation exactly as everywhere else. In the manner of `kubectl
|
|
|
1725
1871
|
wait`, a condition that already holds when the command starts returns
|
|
1726
1872
|
immediately with that build's latest event (`--since` does not suppress this);
|
|
1727
1873
|
otherwise the first later event whose reduction produces it ends the wait.
|
|
1728
|
-
`attention`
|
|
1729
|
-
|
|
1874
|
+
`attention` is also a current-state condition: an already open escalation or
|
|
1875
|
+
merge decision returns immediately, including with `--since`. Merge matches
|
|
1876
|
+
use the same observation as watch. During replay, only new escalation events
|
|
1877
|
+
or undelivered eligible merge decisions satisfy attention. `--event` conditions
|
|
1878
|
+
fire only on new events or a cursor-resumed backlog.
|
|
1730
1879
|
|
|
1731
1880
|
The record is the `ab watch` record plus a `condition` field naming the
|
|
1732
1881
|
satisfied `--for` value or `--event` glob. Unlike `ab watch`, there is no
|
|
@@ -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.
|