@defrex/autobuild 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/SPEC.md +335 -31
- package/docs/architecture.md +125 -7
- package/docs/configuration.md +142 -21
- package/docs/hosted-dispatcher.md +17 -2
- package/docs/hosted-service.md +240 -0
- package/docs/mcp.md +8 -2
- package/docs/operator-api.md +97 -7
- package/docs/remote-store-protocol.md +199 -144
- package/docs/remote-ticket-protocol.md +249 -19
- package/docs/setup.md +199 -16
- package/docs/ticket-dependencies.md +1 -1
- package/docs/ticket-migration.md +64 -0
- package/package.json +7 -6
- package/packages/core/src/cli/attention.ts +209 -0
- package/packages/core/src/cli/build-control.ts +12 -1
- package/packages/core/src/cli/configured-store.ts +17 -0
- package/packages/core/src/cli/connect.ts +364 -0
- package/packages/core/src/cli/context.ts +7 -1
- package/packages/core/src/cli/dashboard/model.ts +4 -5
- package/packages/core/src/cli/dashboard/poll.ts +1 -1
- package/packages/core/src/cli/dispatch.ts +336 -41
- package/packages/core/src/cli/harvest.ts +13 -3
- package/packages/core/src/cli/help.ts +51 -16
- package/packages/core/src/cli/init-validation.ts +27 -2
- package/packages/core/src/cli/installation.ts +67 -13
- package/packages/core/src/cli/main.ts +60 -16
- package/packages/core/src/cli/mcp.ts +9 -2
- package/packages/core/src/cli/pr-summary-publication.ts +220 -0
- package/packages/core/src/cli/pr-summary.ts +2 -0
- package/packages/core/src/cli/project-credentials.ts +132 -0
- package/packages/core/src/cli/repo-state.ts +15 -2
- package/packages/core/src/cli/self-update.ts +15 -1
- 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-assets.ts +7 -2
- package/packages/core/src/cli/ticket-editor.ts +82 -0
- package/packages/core/src/cli/ticket.ts +172 -35
- package/packages/core/src/cli/upgrade-compatibility.ts +80 -0
- package/packages/core/src/cli/wait.ts +84 -17
- package/packages/core/src/cli/watch.ts +197 -60
- package/packages/core/src/config/live.ts +3 -0
- package/packages/core/src/config/schema.ts +90 -11
- package/packages/core/src/connection.ts +86 -0
- package/packages/core/src/events/catalog.ts +11 -2
- package/packages/core/src/events/payloads.ts +50 -0
- package/packages/core/src/events/repository.ts +13 -0
- package/packages/core/src/integration/harness.ts +37 -2
- package/packages/core/src/kernel/__snapshots__/reducer-registry.test.ts.snap +145 -83
- package/packages/core/src/kernel/engine.ts +24 -0
- package/packages/core/src/kernel/generators/build-log.ts +11 -1
- package/packages/core/src/kernel/incremental-fixtures.ts +13 -2
- 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 +10 -0
- package/packages/core/src/kernel/reducer.ts +8 -0
- package/packages/core/src/ontology.ts +2 -0
- package/packages/core/src/operator/annotations.ts +12 -0
- package/packages/core/src/operator/index.ts +12 -0
- package/packages/core/src/operator/protocol.ts +19 -2
- package/packages/core/src/operator/query.ts +38 -16
- package/packages/core/src/operator/registry.ts +61 -8
- package/packages/core/src/operator/ticket-source-backend.ts +17 -20
- package/packages/core/src/operator/tickets.ts +136 -28
- package/packages/core/src/plugin-sdk/index.ts +7 -0
- package/packages/core/src/plugins/manifest.ts +5 -3
- package/packages/core/src/plugins/runtimes.ts +7 -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 +3 -0
- package/packages/core/src/ports/tickets/contract.ts +66 -1
- package/packages/core/src/ports/tickets/create.ts +54 -10
- package/packages/core/src/ports/tickets/fake.ts +30 -1
- package/packages/core/src/ports/tickets/file-assets.ts +159 -0
- package/packages/core/src/ports/tickets/file-codec.ts +90 -0
- package/packages/core/src/ports/tickets/file.ts +114 -120
- package/packages/core/src/ports/tickets/grants.ts +47 -0
- package/packages/core/src/ports/tickets/hosted-index.ts +17 -3
- package/packages/core/src/ports/tickets/identity.ts +20 -0
- package/packages/core/src/ports/tickets/lifecycle.ts +18 -0
- package/packages/core/src/ports/tickets/linear.ts +74 -9
- package/packages/core/src/ports/tickets/migration.ts +336 -0
- package/packages/core/src/ports/tickets/operations.ts +38 -7
- package/packages/core/src/ports/tickets/portable-assets.ts +54 -0
- package/packages/core/src/ports/tickets/remote-protocol.ts +96 -0
- package/packages/core/src/ports/tickets/remote.ts +61 -3
- package/packages/core/src/ports/tickets/requested-id.ts +46 -0
- package/packages/core/src/ports/tickets/revision.ts +62 -0
- package/packages/core/src/ports/tickets/states.ts +61 -0
- package/packages/core/src/ports/types.ts +40 -3
- package/packages/core/src/ports/workspace/build-execution.ts +6 -1
- package/packages/core/src/ports/workspace/create.ts +15 -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/operator-sandbox.ts +2 -0
- package/packages/core/src/ports/workspace/vercel-sandbox.ts +51 -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 +168 -41
- package/packages/core/src/processes/execution-no-progress.ts +176 -0
- package/packages/core/src/processes/harvest-child.ts +31 -4
- package/packages/core/src/processes/harvest-execution-state.ts +19 -2
- package/packages/core/src/processes/harvest-runner.ts +166 -104
- package/packages/core/src/processes/harvest.ts +34 -14
- package/packages/core/src/processes/phase-failure-budget.ts +2 -0
- package/packages/core/src/processes/publication-loss.ts +18 -1
- package/packages/core/src/processes/repo-view.ts +35 -0
- package/packages/core/src/store/contract.ts +32 -1
- package/packages/core/src/store/local/store.ts +1 -1
- package/packages/core/src/store/remote/client.ts +1 -1
- package/packages/core/src/store/remote/compatibility.ts +90 -0
- package/packages/core/src/store/remote/credentials.ts +28 -0
- package/packages/core/src/store/remote/index.ts +14 -1
- package/packages/core/src/store/remote/protocol.ts +25 -0
- package/packages/core/src/store/remote/token.ts +74 -13
- package/packages/core/src/store/ticket-asset-snapshots.ts +192 -0
- package/packages/core/src/store/ticket-assets.ts +86 -8
- package/packages/core/src/store/types.ts +1 -1
- package/packages/core/src/testing/index.ts +7 -0
- package/skills/guide/SKILL.md +232 -34
- package/skills/guide/references/operator-api.md +142 -13
- package/skills/guide/references/plugin-authoring.md +10 -2
- package/skills/guide/references/remote-store-protocol.md +199 -144
- package/skills/guide/references/remote-ticket-protocol.md +253 -18
- package/skills/guide/references/setup.md +199 -16
- package/skills/guide/references/ticket-dependencies.md +1 -1
- package/skills/guide/references/ticket-migration.md +64 -0
- package/skills/operate/SKILL.md +126 -36
- package/skills/tickets/SKILL.md +71 -0
- package/templates/hosted-service/package.json +13 -0
- package/templates/hosted-service/vercel.json +7 -0
|
@@ -0,0 +1,240 @@
|
|
|
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.13.0",
|
|
21
|
+
"@defrex/autobuild": "0.13.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. Independent ticket policy selects lifecycle; `ab connect --tickets URL`
|
|
157
|
+
publishes it before dispatch. Older clients retain uploaded dispatcher configuration
|
|
158
|
+
as a fallback. See the [ticket protocol](remote-ticket-protocol.md). 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.
|
|
215
|
+
|
|
216
|
+
## Local builds with hosted tickets
|
|
217
|
+
|
|
218
|
+
Hosted tickets do not require hosted builds. Set `[tickets] source = "hosted"`
|
|
219
|
+
and `teamKey = "ENG"`, then run `ab connect --tickets https://your-service.example`.
|
|
220
|
+
Approve the project in the browser. This saves a service-scoped credential and
|
|
221
|
+
`[tickets] url` while leaving `[store]` unchanged. Ticket commands work immediately,
|
|
222
|
+
before any dispatcher runs. `ab connect` reports every service and whether it serves
|
|
223
|
+
builds, tickets, or both. Use `ab disconnect --tickets` to revoke ticket access;
|
|
224
|
+
when services differ use `--builds` to select build access. Shared uses share one
|
|
225
|
+
credential, so disconnecting either shared use affects both.
|
|
226
|
+
|
|
227
|
+
Ticket URL selection is `[tickets] url`, then the selected build service (including
|
|
228
|
+
AB_STORE or a supported --store override). With local builds, `[tickets] url` is
|
|
229
|
+
required. Builds, events, artifacts, and harvest journals remain in the local store.
|
|
230
|
+
The service stores ticket records, project ticket policy, and restricted ticket
|
|
231
|
+
grants. Normal project clients synchronize current `[tickets]` policy before use;
|
|
232
|
+
failed synchronization fails the operation. Harvest grants can read and create;
|
|
233
|
+
phase grants can only read. Neither can change policy or access BuildStore routes.
|
|
234
|
+
|
|
235
|
+
New hosted policy defaults to `triage`, `ready`, `doing`, `done`, with creation and
|
|
236
|
+
harvest proposals in `triage`. Explicit state names preserve their spelling.
|
|
237
|
+
To retain earlier names configure `triageState = "Backlog"`,
|
|
238
|
+
`claimedState = "Doing"`, `doneState = "Done"`, and the desired `readyState`.
|
|
239
|
+
Existing ticket rows are never renamed. Older combined-service clients continue
|
|
240
|
+
using the uploaded dispatcher configuration until independent policy is published.
|
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
|
package/docs/operator-api.md
CHANGED
|
@@ -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
|
|
|
@@ -56,6 +87,7 @@ turn runner (a later ticket) is the only producer of turn facts.
|
|
|
56
87
|
| `GET …/harvest/status` | Harvest gate, runs, steps, recovery, and attention projection. |
|
|
57
88
|
| `GET …/builds/{slug}/artifacts/{kind}?rev=N` | Raw bytes (`application/octet-stream`) plus content-disposition and `X-Autobuild-Artifact-*` metadata headers. Omit `rev` for latest. |
|
|
58
89
|
| `GET …/tickets?state=S&label=L` | `{states,tickets,diagnostics,criteria,triageState,readyState}`. The two lifecycle names come from effective repository configuration (including provider fallback). With no `state`, `criteria.state` is `triageState`; repeated `label` parameters narrow that state with AND filters. An explicit `state` selects that exact backend workflow state. |
|
|
90
|
+
| `GET …/tickets/states` | Full state metadata `{name,tickets,about?}[]`, including empty states (`tickets.states` in MCP). |
|
|
59
91
|
| `GET …/tickets/{id}` | `{ticket,blockers,build}`. Blockers include native `exists`/`resolved` status; `build` prefers an active matching repository build, otherwise the most recently updated one. |
|
|
60
92
|
|
|
61
93
|
For artifact reads, an absent `rev` selects the latest revision. A supplied value
|
|
@@ -88,6 +120,7 @@ JSON bodies are strict: unknown fields are rejected.
|
|
|
88
120
|
| `POST …/settings/auto-merge-default/toggle` | Empty body. |
|
|
89
121
|
| `POST …/bulk-control` | `{"action":"pause"\|"resume"}`. The hold fact, intake fact, then eligible build events are written in that order. |
|
|
90
122
|
| `POST …/harvest/control` | `{"action":"toggle-gate"}` or `{"action":"run","run":"…"}`. A run action is bound to that concrete projected run. |
|
|
123
|
+
| `POST …/tickets/states` | `{name,about?}` → `{state,created}`; requires attributed operator identity (`tickets.state.create` in MCP). Hosted duplicate names are refused case-insensitively. |
|
|
91
124
|
| `POST …/tickets` | `{"title":"…","body":"…","labels"?:[],"state"?:"…","blockedBy"?:[]}`; omitted state preserves the backend default. |
|
|
92
125
|
| `PATCH …/tickets/{id}` | Any nonempty subset of `title`, `body`, and complete-replacement `labels`. Body bytes are not normalized. |
|
|
93
126
|
| `POST …/tickets/{id}/move` | `{"state":"backend state name"}`. |
|
|
@@ -201,3 +234,60 @@ identity, plus the usual repo/build/state/cursor fields. It invents no durable
|
|
|
201
234
|
sequence or actor. Retain the cursor to avoid repeat reports across invocations.
|
|
202
235
|
No lease alone is not evidence of death. SIGINT, SIGHUP and SIGTERM drain dispatch,
|
|
203
236
|
record the first signal in the stop fact, and release its lease before exit.
|
|
237
|
+
|
|
238
|
+
### CLI attention monitoring
|
|
239
|
+
|
|
240
|
+
The default watch reports actionable conditions only:
|
|
241
|
+
|
|
242
|
+
- Build `escalation.raised`, or `build.merge-decision`: a finalized open PR
|
|
243
|
+
with auto-merge off or a current actionable merge-gate deferral. Armed consent
|
|
244
|
+
awaiting application is silent. One merge decision is reported per build/PR.
|
|
245
|
+
- Repository `harvest.escalated`, `harvest.recovery-exhausted`,
|
|
246
|
+
`dispatcher.config-rejected`, `dispatcher.config-reloaded` with nonempty
|
|
247
|
+
`restartRequired`, abnormal `dispatcher.run-stopped`, and `dispatcher.lost`.
|
|
248
|
+
- `dispatcher.ticket-source-persistent`: degradation past its advertised
|
|
249
|
+
reset time, once a tick started at or after reset has completed or failed
|
|
250
|
+
with the episode still open; crossing reset alone is silent. Without a reset,
|
|
251
|
+
the deadline is 15 minutes after onset. Repeated evidence never postpones
|
|
252
|
+
the deadline; recovery ends the episode.
|
|
253
|
+
- `dispatcher.tick-failure-persistent`: continuously failing completed ticks
|
|
254
|
+
for five minutes in one run. A successful tick, new run, or matching stop
|
|
255
|
+
ends the episode. Source grace and cooldown-driven failures do not start
|
|
256
|
+
this clock; after grace, the first qualifying failure starts a new five-minute
|
|
257
|
+
interval. Each persistence episode is reported once.
|
|
258
|
+
|
|
259
|
+
Repository conditions are included with no slugs or with `--repository`.
|
|
260
|
+
Routine outcomes and self-healing failures are silent. Repeatable
|
|
261
|
+
`--event <glob>` replaces the default and selects exactly matching catalog
|
|
262
|
+
events (plus the existing `dispatcher.lost` observation); use explicit globs
|
|
263
|
+
to opt into failures, finalize, merge, or completion events.
|
|
264
|
+
|
|
265
|
+
Derived records use `observation` instead of `event`, without inventing a
|
|
266
|
+
durable sequence or actor. Merge observations carry `type`, `pr`, `reason`,
|
|
267
|
+
and `observedAt`, plus the build slug and normal reduced state. Persistence
|
|
268
|
+
observations carry source/cause/message/resetAt when advertised (or
|
|
269
|
+
run/firstFailure/error), `episodeSeq`, and `observedAt`; repository records
|
|
270
|
+
have `repo` and null build/state. Source observations also report
|
|
271
|
+
`dependencyLimited`.
|
|
272
|
+
|
|
273
|
+
Every record carries a cursor, including timer-only records. Resuming suppresses
|
|
274
|
+
delivered merge decisions and persistence episodes even when stream positions
|
|
275
|
+
did not advance. Old v1 cursors remain valid: historical eligible merge
|
|
276
|
+
decisions are treated as consumed; active overdue repository episodes may
|
|
277
|
+
report because old watches had no persistence notification. Fresh attachment
|
|
278
|
+
silently baselines historical direct events and merge decisions, but retains
|
|
279
|
+
active repository timers. Reconcile existing conditions through status after
|
|
280
|
+
arming the watch. Named watches still end when every named build is terminal;
|
|
281
|
+
learn their outcomes from status reconciliation at exit.
|
|
282
|
+
|
|
283
|
+
`ab wait --for attention` is build-only and uses the same build conditions:
|
|
284
|
+
an open escalation or a merge decision. Existing conditions return immediately,
|
|
285
|
+
even with `--since`; live and backlog matches ignore routine outcomes and
|
|
286
|
+
self-healing failures. A merge match uses the watch observation with
|
|
287
|
+
`condition: "attention"`. Explicit `--event` globs remain event-only.
|
|
288
|
+
Watch and wait preserve each other's cursor notification metadata.
|
|
289
|
+
|
|
290
|
+
Hosted ticket tools resolve independent project ticket policy before legacy uploaded
|
|
291
|
+
configuration. Queue, detail, state discovery and mutations work before any build
|
|
292
|
+
or dispatcher run; detail reports a null matching build. Ticket policy publication
|
|
293
|
+
never creates synthetic build or repository history.
|