@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/docs/configuration.md
CHANGED
|
@@ -14,6 +14,18 @@ and sessionless `ab init --validate` readiness check. Examples labelled as
|
|
|
14
14
|
fragments are intended to be added to an existing file; the [complete
|
|
15
15
|
example](#complete-example) is valid on its own.
|
|
16
16
|
|
|
17
|
+
## `[store]`
|
|
18
|
+
|
|
19
|
+
| Key | Required | Values / purpose |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `url` | When `[store]` exists | Absolute HTTPS service base URL; loopback HTTP is allowed for development. No credentials, query or fragment. Trailing slashes are normalized. |
|
|
22
|
+
|
|
23
|
+
Selection is explicit `--store` > nonblank `AB_STORE` > `[store] url` > the main
|
|
24
|
+
checkout's `.autobuild/`. A configured service without a user credential fails
|
|
25
|
+
with `ab connect` guidance. `AB_TOKEN` overrides the saved service/project
|
|
26
|
+
credential. See [connecting a project](hosted-service.md#connect-a-project).
|
|
27
|
+
Changing the store requires restarting dispatch.
|
|
28
|
+
|
|
17
29
|
## Hosted service and PostgreSQL BuildStore environment
|
|
18
30
|
|
|
19
31
|
The optional `@defrex/autobuild-hosted-store-service` and its
|
|
@@ -59,14 +71,14 @@ separate signed-user token described by the [operator API](operator-api.md).
|
|
|
59
71
|
| `AB_HOST` | Optional, ordinary Bun host | Bind hostname; defaults to `0.0.0.0`. Vercel supplies its own listener. |
|
|
60
72
|
| `PORT` | Optional, ordinary Bun host | Integer 1–65535; defaults to `3000`. Vercel supplies its own listener. |
|
|
61
73
|
| `AB_STORE` | Remote client | Hosted service base URL used by the kernel, phase commands, and dashboard. |
|
|
62
|
-
| `AB_TOKEN` | Authenticated remote client |
|
|
74
|
+
| `AB_TOKEN` | Authenticated remote client | Explicit project bearer credential override for CI; otherwise use ab connect. This is not the signing secret. |
|
|
63
75
|
| `BETTER_AUTH_SECRET` | Web dashboard | Independent server-only session secret with at least 32 high-entropy characters. |
|
|
64
76
|
| `BETTER_AUTH_URL` | Web dashboard | Exact HTTP(S) origin, without credentials or a path; HTTPS is mandatory in production. |
|
|
65
77
|
| `GITHUB_CLIENT_ID` | GitHub sign-in | OAuth application client id. |
|
|
66
78
|
| `GITHUB_CLIENT_SECRET` | GitHub sign-in | Server-only OAuth application secret. |
|
|
67
79
|
| `AB_WEB_AUTH_PROVIDERS` | Web dashboard | Comma-separated provider set; currently exactly `github`. |
|
|
68
80
|
| `AB_WEB_ALLOWED_EMAILS` | Web dashboard | Nonempty comma-separated operator email allowlist; matching is case-insensitive. |
|
|
69
|
-
| `AB_WEB_REPOSITORIES` |
|
|
81
|
+
| `AB_WEB_REPOSITORIES` | Hosted service | Deprecated once-per-database bootstrap CSV for the durable project registry. Use owner commands thereafter; see [connected projects](setup.md#connected-projects). |
|
|
70
82
|
|
|
71
83
|
GitHub's callback is `{BETTER_AUTH_URL}/api/auth/callback/github`; the app needs
|
|
72
84
|
the `user:email` scope (or GitHub App read-only email permission). Sessions are
|
|
@@ -168,7 +180,7 @@ the branch head never carried the file — the deposit records the source
|
|
|
168
180
|
provenance declines to attribute them to any commit. **Deployment-owned** sections — `[roles]`
|
|
169
181
|
(runtime, model, args, alternates, per-role `sessionBudgetSeconds`) and
|
|
170
182
|
`[policy]` — keep flowing live. **Dispatcher-owned** sections (`baseBranch`,
|
|
171
|
-
`capacity`, `forge`, `plugins`, `pr`, `tickets`, `orchestrator`) configure the
|
|
183
|
+
`capacity`, `ticketScanIntervalSeconds`, `forge`, `plugins`, `pr`, `tickets`, `orchestrator`) configure the
|
|
172
184
|
dispatcher itself and are never interpreted by the build runner.
|
|
173
185
|
|
|
174
186
|
Consequently, an accepted base-branch reload re-deposits only the
|
|
@@ -195,6 +207,7 @@ These fields hot-reload:
|
|
|
195
207
|
| Field or table | Boundary where a new value applies |
|
|
196
208
|
|---|---|
|
|
197
209
|
| `baseBranch` | Next dispatch or base fallback decision; existing `build.created` facts remain immutable. |
|
|
210
|
+
| `ticketScanIntervalSeconds` | Next tick; evaluates elapsed time against the new interval. |
|
|
198
211
|
| `capacity` | Next dispatcher tick. |
|
|
199
212
|
| `[pr]` | Next build creation. |
|
|
200
213
|
| `[commands]` | Next setup, verify check, or finalize check selected for a build whose OWN branch carries it. A base-branch reload does not retarget an in-flight build. |
|
|
@@ -211,6 +224,7 @@ remain pinned to their startup values and are reported explicitly:
|
|
|
211
224
|
|
|
212
225
|
| Restart-required field | Reason |
|
|
213
226
|
|---|---|
|
|
227
|
+
| `store` | Store selection and project authority are fixed when dispatch starts. |
|
|
214
228
|
| `plugins` | Plugin modules and registration catalogs load before wiring. |
|
|
215
229
|
| `forge` | Selects the constructed Forge adapter. |
|
|
216
230
|
| `workspace.provider`, `workspace.config` | Select and configure the constructed workspace provider. |
|
|
@@ -229,10 +243,24 @@ any table header.
|
|
|
229
243
|
| Field | Default | Constraints | Purpose |
|
|
230
244
|
|---|---:|---|---|
|
|
231
245
|
| `baseBranch` | `"main"` | nonempty string | Branch used to cut builds, target PRs, and merge during reconciliation. |
|
|
246
|
+
| `ticketScanIntervalSeconds` | `60` | positive integer seconds | Ticket-source ready scan cadence; tick spacing is the effective minimum. |
|
|
232
247
|
| `capacity` | `1` | positive integer | Maximum concurrent nonterminal builds for this repository. Paused and blocked builds still occupy capacity. |
|
|
233
248
|
| `forge` | `"github"` | nonblank string | Forge adapter name. Shipped values are `github` and `local-git`; configured plugins may register other names. |
|
|
234
249
|
| `plugins` | `[]` | array of unique nonblank module specifiers | Trusted Bun plugin modules loaded by dispatch, `ab ticket`, and scoped phase CLI processes. |
|
|
235
250
|
|
|
251
|
+
Ticket-source ready scans run immediately when no completed measurement exists,
|
|
252
|
+
then every
|
|
253
|
+
`ticketScanIntervalSeconds` (default 60 seconds, a positive integer). Actual
|
|
254
|
+
tick spacing is the floor when the configured interval is shorter. A
|
|
255
|
+
same-repository `pr.merged`, `build.completed`, or `build.aborted` fact forces
|
|
256
|
+
another scan on the next tick; changed ready criteria also force a scan.
|
|
257
|
+
Housekeeping keeps its ordinary tick cadence. Between scans, queue depth and
|
|
258
|
+
standing diagnostics repeat the last completed measurement, including across
|
|
259
|
+
process restarts. Tickets groomed directly in the tracker are picked up within
|
|
260
|
+
one scan interval plus one tick when capacity permits. Observation while intake
|
|
261
|
+
is off shares the cadence; an observation measurement cannot suppress a fresh
|
|
262
|
+
admission scan when intake is enabled.
|
|
263
|
+
|
|
236
264
|
### Plugin modules
|
|
237
265
|
|
|
238
266
|
<!-- config-fragment:plugins -->
|
|
@@ -313,7 +341,12 @@ without adding a runtime Autobuild dependency to the plugin. That entry point
|
|
|
313
341
|
exports the manifest/factory types, port types, fake adapters, and reusable
|
|
314
342
|
TicketSource, AgentRunner, WorkspaceProvider, Forge, BuildStore, and BlobStore
|
|
315
343
|
contract suites. Adapter values may use the backward-compatible bare factory or
|
|
316
|
-
carry a contract fixture descriptor.
|
|
344
|
+
carry a contract fixture descriptor.
|
|
345
|
+
TicketSource adapters must populate the required `Ticket.resolved` boolean on
|
|
346
|
+
listReady, get, and create projections, using the same native lifecycle rules as
|
|
347
|
+
`dependencyStates`. Plugin authors upgrading older adapters must add this field;
|
|
348
|
+
ready-state membership does not imply that a ticket is unresolved. Dispatch
|
|
349
|
+
reuses these facts only within the current tick. Ticket sources may also declare
|
|
317
350
|
`requiredEnv`; the host checks every declared variable for a nonempty value
|
|
318
351
|
before invoking the adapter factory. Plugins using Forge abort-cleanup and
|
|
319
352
|
AgentRunner turn-cancellation capabilities introduced in API 1.2 should require
|
|
@@ -337,7 +370,7 @@ manifest parse), and each `capabilities.requiredEnv` group must declare at
|
|
|
337
370
|
least one of `dispatchMessage` / `validationMessage` — a group with neither is
|
|
338
371
|
rejected at manifest parse, because the host would silently skip it at both
|
|
339
372
|
enforcement sites. API 1.7 extends the workspace-provider factory context with
|
|
340
|
-
the host-derived seams: `storeRef` and `
|
|
373
|
+
the host-derived seams: `storeRef` and `delegateCredential` (guaranteed present under
|
|
341
374
|
`capabilities.storeRequirements`), `runtimeReferences`, and the checkout-less
|
|
342
375
|
`origin` and `remoteBranchHead` readers, all optional and ignored by factories
|
|
343
376
|
that do not read them. A plugin reading the new seams should require `^1.7.0`.
|
|
@@ -611,7 +644,7 @@ no longer matches the identity the current system would deliver is refreshed
|
|
|
611
644
|
by reinstalling the archive before reuse, so an upgraded dispatcher retrofits
|
|
612
645
|
its persistent guests (see "Guest distribution version selection and delivery"
|
|
613
646
|
in docs/setup.md for the release-and-upgrade delivery path and the hosted
|
|
614
|
-
store's
|
|
647
|
+
store's supported client window). Immediately
|
|
615
648
|
before every build-child launch, the adapter verifies the
|
|
616
649
|
provisioned absolute Bun executable and every referenced runtime again. A
|
|
617
650
|
failure names the runtime, selecting role/alternate, stage, and provisioning
|
|
@@ -737,6 +770,28 @@ as written.
|
|
|
737
770
|
|
|
738
771
|
## `[verify]` and `[verify.<step>]`
|
|
739
772
|
|
|
773
|
+
Post-reconcile verification defaults to enabled: `[verify].afterReconcile = true`.
|
|
774
|
+
Set it to `false` to retain pre-reconcile verification and skip all steps after
|
|
775
|
+
reconciliation. An optional boolean `[verify.<step>].afterReconcile` overrides
|
|
776
|
+
the repository setting in either direction; overrides require a configured step.
|
|
777
|
+
For example, set `afterReconcile = false` in `[verify]` and
|
|
778
|
+
`afterReconcile = true` in `[verify.types]` to keep only that step re-running.
|
|
779
|
+
|
|
780
|
+
The kernel freezes the resolved ordered policy in
|
|
781
|
+
`verify.reconcile-policy-captured` at the next engine action after reconcile
|
|
782
|
+
completion. Live configuration changes apply at that boundary; a cycle already
|
|
783
|
+
started keeps its policy through recovery. Historical cycles already started
|
|
784
|
+
without a captured policy retain the rerun-all behavior. Initial verification
|
|
785
|
+
and verification after subsequent code review always use ordinary applicability.
|
|
786
|
+
Policy exclusion precedes plan selection and paths, including `always = true`.
|
|
787
|
+
Enabled steps still follow plan selection and path rules. Excluded steps record
|
|
788
|
+
`verify.completed` with outcome `skipped`, `skipCause = "post-reconcile-policy"`,
|
|
789
|
+
and a reason naming the setting. Dashboards and PR summaries call this
|
|
790
|
+
"skipped by post-reconcile policy"; it is never a pass. Forge-side required
|
|
791
|
+
checks and branch protections still gate merge. For excluded steps, merged code
|
|
792
|
+
is not re-verified, so breakage that only exists in the combination can land.
|
|
793
|
+
|
|
794
|
+
|
|
740
795
|
`[verify].steps` defines the configured universe and execution order. It is
|
|
741
796
|
optional and defaults to no verify phases. Every listed name needs one matching
|
|
742
797
|
subtable, and every named subtable must be listed; a defined-but-unlisted step
|
|
@@ -756,6 +811,7 @@ There are two strict step variants:
|
|
|
756
811
|
| `command` | — | required for check; nonempty key in `[commands]` | Deterministic shell verb to run. Forbidden for agent steps. |
|
|
757
812
|
| `skill` | — | required for agent; nonempty string | Exact installed verifier skill. Forbidden for check steps. |
|
|
758
813
|
| `paths` | omitted (unconditional) | optional nonempty array of positive repository-relative globs | Apply only when at least one changed path matches. Available to both variants. |
|
|
814
|
+
| `afterReconcile` | repository: `true`; step: inherited | boolean | Step override wins over `[verify].afterReconcile`; false skips this step after reconciliation only. |
|
|
759
815
|
| `always` | omitted (`false`) | optional boolean | `true` makes the step mandatory in plan selection and bypasses path gating. Available to both variants. |
|
|
760
816
|
|
|
761
817
|
<!-- config-fragment:verify -->
|
|
@@ -1112,6 +1168,7 @@ Optional. Every field receives its own default. All are positive integers except
|
|
|
1112
1168
|
| `sessionBudgetSeconds` | `3600` | positive integer | Wall-clock bound for each build agent session unless its logical role overrides it. |
|
|
1113
1169
|
| `stallRounds` | `3` | positive integer | Escalate when the same review finding survives this many rounds. |
|
|
1114
1170
|
| `maxVerifyAttempts` | `3` | positive integer | Bound failure-driven verify → implement retry cycles. |
|
|
1171
|
+
| `maxDispatchAttempts` | `3` | positive integer | Bound consecutive dispatch failures before human escalation. |
|
|
1115
1172
|
| `maxSetupAttempts` | `3` | positive integer | Bound consecutive workspace setup failures before human escalation. |
|
|
1116
1173
|
| `maxInfrastructureAttempts` | `3` | positive integer | Bound consecutive provision/start/wait/cleanup failures before a setup-targeted policy escalation; a human `retry` answer re-arms this budget. |
|
|
1117
1174
|
| `maxReconcileAttempts` | `3` | positive integer | Bound completed reconciles that leave the PR conflicted against an unchanged authoritative base. Moving-base races do not consume the bound. |
|
|
@@ -1119,6 +1176,15 @@ Optional. Every field receives its own default. All are positive integers except
|
|
|
1119
1176
|
| `harvestThreshold` | `5` | positive integer | New unclaimed observation occurrences needed to start one harvest run. |
|
|
1120
1177
|
| `harvestMaxDrift` | `3` | nonnegative integer | Other builds merged after the oldest unclaimed observation needed to start a run; `0` disables drift. |
|
|
1121
1178
|
|
|
1179
|
+
Dispatch failures share a `[policy].maxDispatchAttempts` budget (default 3) across
|
|
1180
|
+
create, workspace, spec, comment, and launch stages. Exhaustion raises one
|
|
1181
|
+
`dispatch-failure-limit` policy escalation naming the latest stage and error,
|
|
1182
|
+
and parks dispatch until answered. Both bare `ab answer <slug>` retries and
|
|
1183
|
+
text guidance grant a fresh budget; abort does not. Confirmed runner attachment
|
|
1184
|
+
clears the streak. Recovery-provider workspace failures belong exclusively to
|
|
1185
|
+
the infrastructure budget. Exhaustion is repaired from durable facts on restart
|
|
1186
|
+
before further dispatch work.
|
|
1187
|
+
|
|
1122
1188
|
For each repeat conflict, Autobuild compares the base merged by the most recent
|
|
1123
1189
|
completed reconcile with a fresh authoritative base snapshot. An advanced base
|
|
1124
1190
|
proves the attempt lost a race and permits another reconcile regardless of the
|
|
@@ -1169,9 +1235,10 @@ state. Within a present table, `source` and `readyState` are required.
|
|
|
1169
1235
|
| `readyState` | — | required nonblank string | The one workflow state eligible for dispatch. |
|
|
1170
1236
|
| `readyAssignee` | — | optional; `"me"` or an email address; Linear only (rejected for file, hosted, and plugin sources) | Require the ticket to be assigned to one Linear user, in addition to the state and label gates. |
|
|
1171
1237
|
| `teamKey` | — | required for Linear and hosted; forbidden for file; optional for plugins | Backend team key such as `"ENG"`, or an existing plugin config field. |
|
|
1172
|
-
| `claimedState` | `"In Progress"` for direct Linear;
|
|
1238
|
+
| `claimedState` | `"In Progress"` for direct Linear; `"Doing"` for hosted | optional nonempty string; forbidden for file; allowed for plugins | Workflow state entered when a ticket is claimed. |
|
|
1239
|
+
| `doneState` | `"Done"` | optional nonblank string; hosted | Project completion state and merged-ticket transition. |
|
|
1173
1240
|
| `createState` | provider default | optional nonempty string | Default state for newly created tickets when `ab ticket create` omits `--state`. |
|
|
1174
|
-
| `triageState` | Linear: `"Backlog"`; file/plugin: `"Triage"` | optional nonempty string | State used for spec-gate bounces, aborts, and closed-unmerged PRs. |
|
|
1241
|
+
| `triageState` | Linear/hosted: `"Backlog"`; file/plugin: `"Triage"` | optional nonempty string | State used for spec-gate bounces, aborts, and closed-unmerged PRs. |
|
|
1175
1242
|
| `proposalState` | the resolved `triageState` | optional nonempty string | State harvest files its synthesized proposals into. Setting it to `readyState` waives the human grooming gate, not dependency eligibility. |
|
|
1176
1243
|
| `dir` | file: selected local state root's `tickets/`; plugin: omitted | optional nonempty path; forbidden for Linear; allowed for plugins | Root containing file-source state directories, or an existing plugin config field. Relative file paths resolve from the repository. |
|
|
1177
1244
|
|
|
@@ -1259,6 +1326,15 @@ triageState = "Backlog"
|
|
|
1259
1326
|
Linear credentials do not belong in this table. Set `LINEAR_API_KEY` in the
|
|
1260
1327
|
environment or local `.env` file described below.
|
|
1261
1328
|
|
|
1329
|
+
[Linear's request budget](https://linear.app/developers/rate-limiting) is shared
|
|
1330
|
+
by every dispatcher and `ab ticket` command using the API key, and by other keys
|
|
1331
|
+
belonging to the same authenticated user. A rate-limited ready scan or dependency
|
|
1332
|
+
read fails the evaluation tick without new intake claims or synthetic
|
|
1333
|
+
dependency-blocked counts. That source instance suppresses requests until the
|
|
1334
|
+
reported reset time; the next call then runs normally. Missing, invalid or expired
|
|
1335
|
+
reset headers use a conservative 60-second cooldown. Cooldowns are local to the
|
|
1336
|
+
instance: processes and restarts do not coordinate their budgets.
|
|
1337
|
+
|
|
1262
1338
|
For a hosted backend, repository policy remains local while credentials remain
|
|
1263
1339
|
at the service:
|
|
1264
1340
|
|
|
@@ -1274,17 +1350,18 @@ createState = "Triage"
|
|
|
1274
1350
|
triageState = "Triage"
|
|
1275
1351
|
```
|
|
1276
1352
|
|
|
1277
|
-
Set `AB_STORE` to the service's HTTP(S) URL and `AB_TOKEN` to a
|
|
1278
|
-
|
|
1353
|
+
Set `AB_STORE` to the service's HTTP(S) URL and `AB_TOKEN` to a stored credential
|
|
1354
|
+
for that registered project (`credentials issue REPOSITORY --user IDENTITY`). The same source-agnostic wiring powers dispatch, harvest, ticket-aware
|
|
1279
1355
|
skills, and all seven command families: `ab ticket create`, `update`, `block`,
|
|
1280
1356
|
`unblock`, `list`, `show`, and `move`. See the
|
|
1281
|
-
[hosted ticket protocol](remote-ticket-protocol.md).
|
|
1282
|
-
|
|
1283
|
-
|
|
1357
|
+
[hosted ticket protocol](remote-ticket-protocol.md). Tickets are partitioned by
|
|
1358
|
+
the credential's registered project; lifecycle comes from its latest effective
|
|
1359
|
+
configuration. The service has no Linear backend and refuses ticket operations
|
|
1360
|
+
for projects using external sources. Direct Linear remains dispatcher-side.
|
|
1284
1361
|
|
|
1285
1362
|
When filing dependent tickets into the ready state, follow the
|
|
1286
|
-
[safe blocker-filing workflow](ticket-dependencies.md). Direct
|
|
1287
|
-
|
|
1363
|
+
[safe blocker-filing workflow](ticket-dependencies.md). Direct Linear
|
|
1364
|
+
creates the issue before recording its blockers, so `create --blocked-by` is not
|
|
1288
1365
|
an atomic publication guarantee. Stage outside ready, verify the relationships,
|
|
1289
1366
|
then move to the intended ready state last.
|
|
1290
1367
|
|
|
@@ -1323,7 +1400,7 @@ restart-classified as a whole.
|
|
|
1323
1400
|
| `model` | — | nonblank string, required when `enabled = true` | Provider-qualified model string for the turn runner, in the same vocabulary as `[roles]` model strings (a leading `vercel-ai-gateway/` prefix is accepted and stripped). Resolved through the deployment's gateway credential. |
|
|
1324
1401
|
| `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 (`ORCHESTRATOR_ROUTE_LIMIT_SECONDS`, the same number the operator route pins as `maxDuration`). |
|
|
1325
1402
|
| `approvals` | see below | array of `tool` or `tool:qualifier` strings | Registry tool names whose calls suspend a turn until the operator answers. Default: `["builds.control:abort", "builds.control:discard", "builds.answer:revise-spec", "sandbox.publish", "tickets.move:ready"]`. Empty (`[]`) means none — autonomous operation. An entry naming an absent or unknown tool is **inert by design**, never a config error: the list stays stable while the registry grows, and a tool's removal cannot break parsing. A `tool:qualifier` entry applies to the named discriminator value only (for example `tickets.move:ready` approves moving a ticket to `ready`); for a tool without a discriminator, only the bare form matches. |
|
|
1326
|
-
| `wake` | inherits the default | array of event-type globs | The attention events a **new** session wakes for. Kept schema-optional so absent (inherit the default attention set — the build events `ab watch` filters on by default plus the repository-journal events `ab watch
|
|
1403
|
+
| `wake` | inherits the default | array of event-type globs | The attention events a **new** session wakes for. Kept schema-optional so absent (inherit the default attention set — the build events `ab watch` filters on by default plus the repository-journal events `ab watch` follows) and `[]` (never wake; message-only) stay distinct. Each glob must match at least one build or repository-journal event type, validated with the same compiler `ab watch` uses. Existing sessions never retroactively inherit; an explicit `PUT .../wake` always wins. |
|
|
1327
1404
|
| `sandbox` | — | strict subtable; absence reads as the defaults | Sandbox behavior knobs. |
|
|
1328
1405
|
|
|
1329
1406
|
`[orchestrator.sandbox]` fields:
|
|
@@ -1465,6 +1542,7 @@ sessionBudgetSeconds = 7200
|
|
|
1465
1542
|
sessionBudgetSeconds = 3600
|
|
1466
1543
|
stallRounds = 3
|
|
1467
1544
|
maxVerifyAttempts = 3
|
|
1545
|
+
maxDispatchAttempts = 3
|
|
1468
1546
|
maxSetupAttempts = 3
|
|
1469
1547
|
maxInfrastructureAttempts = 3
|
|
1470
1548
|
maxReconcileAttempts = 3
|
|
@@ -1624,9 +1702,9 @@ Secrets and store selection accompany the file through environment variables:
|
|
|
1624
1702
|
|
|
1625
1703
|
| Variable | Used for | Notes |
|
|
1626
1704
|
|---|---|---|
|
|
1627
|
-
| `LINEAR_API_KEY` | Direct Linear ticket source | Required and nonempty when `tickets.source = "linear"`;
|
|
1628
|
-
| `AB_STORE` | BuildStore and hosted ticket selection | A local path or HTTP(S) remote-store URL. `tickets.source = "hosted"` requires a nonblank HTTP(S) URL. A command's explicit `--store` wins for BuildStore selection, then nonblank `AB_STORE`, then the main checkout's `.autobuild/`. Relative local paths resolve from the main checkout. |
|
|
1629
|
-
| `AB_TOKEN` | Protected remote BuildStore and hosted tickets | Bearer credential forwarded to the service. Hosted tickets require
|
|
1705
|
+
| `LINEAR_API_KEY` | Direct Linear ticket source | Required and nonempty when `tickets.source = "linear"`; never used by the hosted service. |
|
|
1706
|
+
| `AB_STORE` | BuildStore and hosted ticket selection | A local path or HTTP(S) remote-store URL. `tickets.source = "hosted"` requires a nonblank HTTP(S) URL. A command's explicit `--store` wins for BuildStore selection, then nonblank `AB_STORE`, then `[store] url`, then the main checkout's `.autobuild/`. Relative local paths resolve from the main checkout. |
|
|
1707
|
+
| `AB_TOKEN` | Protected remote BuildStore and hosted tickets | Bearer credential forwarded to the service. Hosted tickets require a stored credential for a registered project. Owner admin is an explicit break-glass exception. Empty means no token; nonempty token bytes are treated as opaque. |
|
|
1630
1708
|
|
|
1631
1709
|
A local store selection relocates the state database, blobs, worktrees, and the
|
|
1632
1710
|
default file-ticket directory together. With a remote store, Git worktrees and
|
|
@@ -1766,3 +1844,43 @@ progress is not shown. Harvest does not consume build capacity.
|
|
|
1766
1844
|
- **Remote BuildStore:** confirm the effective `AB_STORE` URL and `AB_TOKEN`.
|
|
1767
1845
|
A protected store reports 401 for a missing, invalid, or expired token and
|
|
1768
1846
|
403 when the token is valid but scoped to another build/session.
|
|
1847
|
+
|
|
1848
|
+
### Hosted project selection
|
|
1849
|
+
|
|
1850
|
+
The durable PostgreSQL project registry controls dashboard, MCP and operator
|
|
1851
|
+
API access. Every allowlisted user sees every active entry. Administer it with
|
|
1852
|
+
`ab-hosted-store projects list|add|remove` using deployment database credentials;
|
|
1853
|
+
mutations require `--user IDENTITY` for declared attribution. See
|
|
1854
|
+
[connected projects](setup.md#connected-projects) for migration and retention.
|
|
1855
|
+
`AB_DISPATCHER_REPOSITORIES` optionally selects an ordered subset of current
|
|
1856
|
+
registrations. When unset, each authorized tick queries all active entries.
|
|
1857
|
+
Removed credential override keys are inert in dynamic mode; explicit-list
|
|
1858
|
+
configuration still rejects unknown override keys.
|
|
1859
|
+
|
|
1860
|
+
## Hosted service client compatibility
|
|
1861
|
+
|
|
1862
|
+
A service accepts stable clients from its own `major.minor` release line and
|
|
1863
|
+
the two preceding minor lines in the same major. A major starts a new family:
|
|
1864
|
+
X.0 accepts only X.0, X.1 accepts X.0/X.1, and X.2 onward accepts three lines.
|
|
1865
|
+
Patch versions are interchangeable in both directions and must never change
|
|
1866
|
+
the protocol. Upgrade the service first, then projects independently within
|
|
1867
|
+
its window. Supported release lines retain their wire handlers and known
|
|
1868
|
+
protocol identities; an unknown protocol is refused independently of version.
|
|
1869
|
+
Malformed, missing, and prerelease identities are refused with HTTP 409.
|
|
1870
|
+
A newer client is told to upgrade the service; a client below the window is
|
|
1871
|
+
told to upgrade the project's Autobuild. Diagnostics name the service version
|
|
1872
|
+
and supported range.
|
|
1873
|
+
|
|
1874
|
+
Unauthenticated `GET /health` publishes `ok`, `autobuildVersion`,
|
|
1875
|
+
`protocolVersion`, and `supportedClientRange: { minVersion, maxVersionExclusive }`.
|
|
1876
|
+
The range is inclusive at the minimum and exclusive at the maximum; a 0.11.x
|
|
1877
|
+
service publishes `>=0.9.0 <0.12.0`. Health needs no credentials, version
|
|
1878
|
+
headers, or available backend.
|
|
1879
|
+
|
|
1880
|
+
Remote workspace factories must use `delegateCredential(storeRef, undefined,
|
|
1881
|
+
target)` to obtain per-resource grants before provisioning or launching guests.
|
|
1882
|
+
The callback keeps parent authority in host composition. `storeToken` is retired
|
|
1883
|
+
and is never supplied; factory environments also exclude `AB_TOKEN`. Launch
|
|
1884
|
+
credentials travel through the separate transient execution-auth argument, never
|
|
1885
|
+
through serialized execution identity. Existing plugins that forwarded
|
|
1886
|
+
`storeToken` must migrate to this callback and fail closed if it is unavailable.
|
|
@@ -14,6 +14,16 @@ it once a minute by default), so builds no longer depend on a maintainer's
|
|
|
14
14
|
machine. A deployment that does not install the package serves the hosted
|
|
15
15
|
store, ticket, operator, and web endpoints and never attempts a dispatch tick.
|
|
16
16
|
|
|
17
|
+
The [minimal hosted service deployment](hosted-service.md) defaults to store-only
|
|
18
|
+
mode and supplies no cron. The source-checkout deployment below retains the
|
|
19
|
+
opt-in dispatcher packing and shipping pipeline.
|
|
20
|
+
|
|
21
|
+
For a dispatcher running as a local user or service manager, first
|
|
22
|
+
[connect the project](hosted-service.md#connect-a-project). Origin-mode dispatch
|
|
23
|
+
can read the committed `[store] url` and the same user credential by origin.
|
|
24
|
+
A deployment running under another identity needs its own project credential;
|
|
25
|
+
`AB_TOKEN` remains the explicit CI override.
|
|
26
|
+
|
|
17
27
|
## Enabling the schedule
|
|
18
28
|
|
|
19
29
|
1. Deploy the hosted service with the dispatcher package installed and the
|
|
@@ -255,6 +265,11 @@ presents (`sandboxAuth=oidc-header`, `oidc-env`, `token`, or `none`); `none`
|
|
|
255
265
|
means the project has OIDC federation disabled (Settings → Security). No
|
|
256
266
|
long-lived `VERCEL_TOKEN` belongs on the service. Guests never receive a Vercel
|
|
257
267
|
token or forge credential; they authenticate to the Store with the short-TTL
|
|
258
|
-
|
|
268
|
+
stored project credential the dispatcher issues for each repository tick
|
|
259
269
|
(`AB_DISPATCHER_TOKEN_TTL_SECONDS`, default 7 days — keep it longer than your
|
|
260
|
-
largest `timeoutSeconds` guest lifetime).
|
|
270
|
+
largest `timeoutSeconds` guest lifetime). Its immutable dispatcher purpose
|
|
271
|
+
permits raw Store and hosted tickets only, never operator controls. The service
|
|
272
|
+
checks registration and revocation on each request. Tick return does not revoke
|
|
273
|
+
it; spawned builds may outlive the tick. Owner-issued project credentials and
|
|
274
|
+
the owner-only break-glass admin are documented in the
|
|
275
|
+
[remote Store protocol](remote-store-protocol.md#7-authentication-and-project-authority).
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Deploy a hosted service
|
|
2
|
+
|
|
3
|
+
A service hosts the BuildStore, tickets, dashboard, sign-in, and MCP endpoint.
|
|
4
|
+
The default deployment stores state while dispatch runs on another machine.
|
|
5
|
+
You need Bun 1.4.x, a Git repository, a Vercel project, PostgreSQL, a blob
|
|
6
|
+
backend, and a GitHub OAuth application.
|
|
7
|
+
|
|
8
|
+
Create a new directory containing these two files (also shipped in the hosted
|
|
9
|
+
package's `deployment/` directory and in `templates/hosted-service/`).
|
|
10
|
+
|
|
11
|
+
`package.json`:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"private": true,
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "ab-hosted-service-build"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@defrex/autobuild-hosted-store-service": "0.12.0",
|
|
21
|
+
"@defrex/autobuild": "0.12.0",
|
|
22
|
+
"next": "16.1.6",
|
|
23
|
+
"react": "19.2.4",
|
|
24
|
+
"react-dom": "19.2.4"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`vercel.json`:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"$schema": "https://openapi.vercel.sh/vercel.json",
|
|
34
|
+
"framework": "nextjs",
|
|
35
|
+
"installCommand": "bun install --frozen-lockfile",
|
|
36
|
+
"buildCommand": "bun run build",
|
|
37
|
+
"bunVersion": "1.4.x"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Run `bun install`, then commit both files and `bun.lock`. Add `.gitignore`
|
|
42
|
+
entries for `node_modules/`, `.next/`, `.vercel/`, `app/`, `next.config.ts`,
|
|
43
|
+
`next-env.d.ts`, `tsconfig.json`, and `.autobuild-service-assets.json`.
|
|
44
|
+
These application assets are generated during each build. Keep your own files
|
|
45
|
+
outside those names; the builder refuses to overwrite consumer-owned files.
|
|
46
|
+
Do not commit generated application sources or edit them to customize deployment.
|
|
47
|
+
|
|
48
|
+
Push the directory to your Git host. Import it in Vercel with the repository
|
|
49
|
+
root as Root Directory and Next.js as the framework. The checked-in platform
|
|
50
|
+
configuration installs the lockfile and runs `bun run build`. Each build stages
|
|
51
|
+
the installed package, runs its idempotent database migrations against the
|
|
52
|
+
configured database, then builds Next into the root `.next/`. Missing database
|
|
53
|
+
configuration, incompatible schema, or a failed migration stops the build.
|
|
54
|
+
Provide database access from the build environment as well as runtime.
|
|
55
|
+
|
|
56
|
+
## Connect a project
|
|
57
|
+
|
|
58
|
+
From a checkout with an origin remote, run `ab connect https://YOUR_ORIGIN`.
|
|
59
|
+
The CLI prints a verification URL and short code and attempts to open a browser.
|
|
60
|
+
Sign in as an allowed owner, check the full repository identity and code, and
|
|
61
|
+
approve or deny. Another device can open the printed URL, or visit `/connect`
|
|
62
|
+
and enter the code. Approval requires the web-enabled service origin; a
|
|
63
|
+
standalone machine-only listener cannot present browser consent. Requests
|
|
64
|
+
expire after ten minutes. Denial and timeout leave local configuration unchanged.
|
|
65
|
+
|
|
66
|
+
On approval the service registers the project and issues a project credential.
|
|
67
|
+
The CLI keeps it in `$XDG_CONFIG_HOME/autobuild/credentials` (or
|
|
68
|
+
`~/.config/autobuild/credentials`), keyed by normalized service and origin,
|
|
69
|
+
with directory mode 0700 and file mode 0600. Credentials never belong in the
|
|
70
|
+
repository. It adds the non-secret `[store] url` to `autobuild.toml` when
|
|
71
|
+
absent; review and commit that change yourself. An existing different URL
|
|
72
|
+
must be changed explicitly before connecting. Reconnecting replaces the saved
|
|
73
|
+
credential only after approval and revokes the previous credential.
|
|
74
|
+
|
|
75
|
+
All worktrees share the main checkout's configuration and the user's saved
|
|
76
|
+
credential. A service manager running as that user uses the same HOME and
|
|
77
|
+
XDG_CONFIG_HOME, with no AB_STORE or AB_TOKEN exports. A fresh clone with
|
|
78
|
+
committed store configuration but no saved credential fails with `ab connect`
|
|
79
|
+
guidance; it never silently creates local state. Run connect on each host/user.
|
|
80
|
+
|
|
81
|
+
`ab connect` without a URL reports service, project, and credential status:
|
|
82
|
+
accepted, rejected, missing, or unreachable. `ab disconnect` revokes the saved
|
|
83
|
+
credential remotely before removing it locally, keeping the project registered,
|
|
84
|
+
its data, and store configuration. A network/server failure retains the local
|
|
85
|
+
entry for retry; an already revoked credential can be removed. If saving a new
|
|
86
|
+
connection fails, the CLI cancels/revokes it and retains the previous entry.
|
|
87
|
+
If remote cleanup cannot be confirmed, check the printed credential id with
|
|
88
|
+
the owner's administrative tools before retrying.
|
|
89
|
+
|
|
90
|
+
Store selection is `--store` > nonblank `AB_STORE` > `[store] url` > the
|
|
91
|
+
main checkout's `.autobuild/`. `AB_TOKEN` overrides the exact service/project's
|
|
92
|
+
saved credential for CI and other non-interactive hosts. A service override
|
|
93
|
+
never borrows another service's credential. Build and harvest sessions keep
|
|
94
|
+
their explicit scoped authority.
|
|
95
|
+
|
|
96
|
+
## Environment
|
|
97
|
+
|
|
98
|
+
Set these server-side variables in every Vercel environment you deploy:
|
|
99
|
+
|
|
100
|
+
- `AB_POSTGRES_URL` or `DATABASE_URL`: PostgreSQL connection URL. The explicit
|
|
101
|
+
`AB_POSTGRES_URL` takes precedence; use the same database at build and runtime.
|
|
102
|
+
- `AB_STORE_SECRET`: a high-entropy secret for machine token signing.
|
|
103
|
+
- `AB_BLOB_BACKEND=vercel` with `BLOB_READ_WRITE_TOKEN`, or `AB_BLOB_BACKEND=s3`
|
|
104
|
+
with `AB_S3_BUCKET`, `AB_S3_REGION`, `AB_S3_ACCESS_KEY_ID`, and
|
|
105
|
+
`AB_S3_SECRET_ACCESS_KEY` (and optional endpoint for compatible storage).
|
|
106
|
+
- `BETTER_AUTH_SECRET`: an independent high-entropy secret of at least 32 characters.
|
|
107
|
+
- `BETTER_AUTH_URL`: the exact production HTTPS origin, with no path.
|
|
108
|
+
- `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`: GitHub OAuth application credentials.
|
|
109
|
+
- `AB_WEB_AUTH_PROVIDERS=github`.
|
|
110
|
+
- `AB_WEB_ALLOWED_EMAILS`: comma-separated operator email allowlist.
|
|
111
|
+
- `AB_WEB_REPOSITORIES`: comma-separated repository origins visible to operators.
|
|
112
|
+
|
|
113
|
+
Register `https://YOUR_ORIGIN/api/auth/callback/github` as the GitHub callback
|
|
114
|
+
and allow read-only email access (`user:email`). Sign-in must use the configured
|
|
115
|
+
production origin. Do not expose secrets through `NEXT_PUBLIC_` variables.
|
|
116
|
+
See the [complete environment reference](configuration.md) for storage,
|
|
117
|
+
project ticket lifecycle, credential administration, and optional MCP resource configuration.
|
|
118
|
+
|
|
119
|
+
## Check the deployment
|
|
120
|
+
|
|
121
|
+
`GET /health` returns service and protocol versions. Open `/sign-in` and sign
|
|
122
|
+
in; `/` redirects unauthenticated browsers to sign-in. Machine routes
|
|
123
|
+
require a machine token; `/mcp` challenges an unauthenticated client with OAuth
|
|
124
|
+
resource metadata. Check both discovery documents:
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
curl https://YOUR_ORIGIN/.well-known/oauth-protected-resource
|
|
128
|
+
curl https://YOUR_ORIGIN/.well-known/oauth-authorization-server
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The authorization-server document advertises a reachable `/api/auth/jwks`
|
|
132
|
+
URI and `/api/auth/mcp/register` dynamic registration endpoint. MCP clients
|
|
133
|
+
register with `redirect_uris` as an array of strings and
|
|
134
|
+
`token_endpoint_auth_method: "none"`; treat the returned `client_id` as opaque.
|
|
135
|
+
See [MCP](mcp.md) for authorization and client setup.
|
|
136
|
+
|
|
137
|
+
Without the optional hosted dispatcher installed, `GET /api/dispatch` returns
|
|
138
|
+
503 JSON: `{"error":"dispatch runs elsewhere for this deployment"}`. The
|
|
139
|
+
template has no cron and installs no dispatcher/provider package. Run dispatch
|
|
140
|
+
from a connected project or follow the separate, opt-in
|
|
141
|
+
[hosted dispatcher procedure](hosted-dispatcher.md), which retains its
|
|
142
|
+
source-checkout packaging and cron setup.
|
|
143
|
+
|
|
144
|
+
## Upgrade
|
|
145
|
+
|
|
146
|
+
Bump the exact hosted-service and core package pins in `package.json` to the
|
|
147
|
+
same new release, run `bun install` to refresh `bun.lock`, commit, and push.
|
|
148
|
+
Vercel's Git integration migrates and builds the pinned package automatically.
|
|
149
|
+
Upgrade the service **before connected projects**: that is the order expected
|
|
150
|
+
by the protocol compatibility window. No source extraction, patch application,
|
|
151
|
+
or manual production deployment is required.
|
|
152
|
+
|
|
153
|
+
## Hosted ticket projects and v1 migration
|
|
154
|
+
|
|
155
|
+
Hosted queues are partitioned by registered repository. Credentials select the
|
|
156
|
+
project, and its latest uploaded effective `[tickets]` configuration selects the
|
|
157
|
+
lifecycle; see the [ticket protocol](remote-ticket-protocol.md). If configuration
|
|
158
|
+
is unavailable, run that project's dispatcher to publish it. Projects using file,
|
|
159
|
+
Linear or another external source continue to access it directly through their
|
|
160
|
+
dispatcher. Service ticket surfaces refuse those projects with source feedback.
|
|
161
|
+
The service never connects to Linear.
|
|
162
|
+
|
|
163
|
+
The removed `AB_TICKET_BACKEND` and `LINEAR_API_KEY` settings are ignored for
|
|
164
|
+
all values, including blanks, with one startup message asking for removal.
|
|
165
|
+
The removed `AB_TICKET_TRIAGE_STATE`, `AB_TICKET_READY_STATE`,
|
|
166
|
+
`AB_TICKET_DOING_STATE` and `AB_TICKET_DONE_STATE` settings are ignored even if
|
|
167
|
+
malformed. Lifecycle now comes only from project configuration.
|
|
168
|
+
|
|
169
|
+
The environment-aware migration first imports `AB_WEB_REPOSITORIES` into the
|
|
170
|
+
registry once, including upgrades from released main schema v9 where registry
|
|
171
|
+
tables do not yet exist. This import and the main-schema promotion share the
|
|
172
|
+
ticket transaction: a stopped ticket migration rolls them back too. The owner
|
|
173
|
+
`projects add` and `tickets assign-team` commands can independently bootstrap
|
|
174
|
+
the registry while that old main marker remains, so recovery does not require
|
|
175
|
+
a successful ticket migration. If the retired environment is unavailable,
|
|
176
|
+
register the intended project with `ab-hosted-store projects add REPOSITORY
|
|
177
|
+
--user IDENTITY` before assigning its legacy team. Once the import succeeds,
|
|
178
|
+
later changes to the retired environment are ignored.
|
|
179
|
+
|
|
180
|
+
Fresh databases install ticket schema v2 directly. Existing team-keyed v1
|
|
181
|
+
queues migrate in one transaction. For each registered project, migration reads
|
|
182
|
+
the effective configuration selected by its latest dispatcher run and reloads,
|
|
183
|
+
including the actual immutable artifact bytes in blob storage. A legacy team
|
|
184
|
+
must have one claimant, or an explicit owner assignment. A registered project
|
|
185
|
+
with no dispatcher run or no selected effective-config reference makes no team
|
|
186
|
+
claim and does not block other projects. Unclaimed teams still stop unchanged.
|
|
187
|
+
When ownership must be inferred, a selected but missing, inaccessible or invalid
|
|
188
|
+
configuration fails closed with the project and remaining teams in the message.
|
|
189
|
+
Restore those bytes or explicitly assign every remaining legacy team, then
|
|
190
|
+
rerun; complete assignments to registered projects settle ownership without
|
|
191
|
+
reading unrelated configurations. Conflicting claimants and asset ownership
|
|
192
|
+
conflicts also stop without changing schema markers or tickets.
|
|
193
|
+
Historical ids, states, timestamps, blockers, comments and asset rows remain
|
|
194
|
+
unchanged. Review the named projects and resolve a shared legacy team locally:
|
|
195
|
+
|
|
196
|
+
```sh
|
|
197
|
+
ab-hosted-store tickets assign-team ENG https://github.com/acme/app --user owner@example.com
|
|
198
|
+
ab-postgres-store migrate
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
The assignment command works before the v2 migration succeeds and records the
|
|
202
|
+
actor in an append-only journal. The latest assignment moves the whole legacy
|
|
203
|
+
team once; it grants no future cross-project access. It must name a registered
|
|
204
|
+
project. Rerun migration after resolving every named team or configuration error.
|
|
205
|
+
|
|
206
|
+
For populated-v1 upgrades, both the owner migration CLI and `deploy:build` need
|
|
207
|
+
the same blob backend, access, credentials and `AB_BLOB_PREFIX` as the running
|
|
208
|
+
service: S3 bucket/region/credentials (and endpoint/path style when configured),
|
|
209
|
+
or Vercel access mode and token/OIDC store identity. The deployment build inherits
|
|
210
|
+
these variables and runs the environment-aware migration before Next build.
|
|
211
|
+
Missing blob configuration or denied reads stop deployment before Next builds;
|
|
212
|
+
diagnostics never print credentials. SQL-only fresh installs, empty-v1 upgrades
|
|
213
|
+
and already-v2 reruns do not open blob storage and keep their existing database
|
|
214
|
+
requirements. Migration reruns are idempotent.
|
package/docs/mcp.md
CHANGED
|
@@ -110,8 +110,14 @@ the standard surface the endpoint serves.
|
|
|
110
110
|
the default MCP resource's base.
|
|
111
111
|
- `AB_WEB_ALLOWED_EMAILS`: the operator allowlist. Sign-in admission and every
|
|
112
112
|
MCP tool call are checked against it.
|
|
113
|
-
- `AB_WEB_REPOSITORIES
|
|
114
|
-
|
|
113
|
+
- `AB_WEB_REPOSITORIES` (deprecated): optional once-per-database registry
|
|
114
|
+
bootstrap, never an ongoing allowlist. `repositories.list` queries current
|
|
115
|
+
active registrations on every call, and every tool checks current membership.
|
|
116
|
+
|
|
117
|
+
Every allowlisted user sees every registered project. Database-authorized
|
|
118
|
+
owners use the [project commands](setup.md#connected-projects) to add or remove
|
|
119
|
+
projects without redeploying. Removal hides retained data until re-registration;
|
|
120
|
+
registry failures never authorize a call.
|
|
115
121
|
|
|
116
122
|
The endpoint requires no additional variables beyond the hosted service's
|
|
117
123
|
existing web/auth set. Note that consent renders when the client sends
|