@defrex/autobuild 0.8.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/LICENSE +201 -0
- package/README.md +192 -0
- package/SPEC.md +2269 -0
- package/bin/ab-build-runner.ts +47 -0
- package/bin/ab-dev.ts +27 -0
- package/bin/ab-dispatch-kernel.ts +92 -0
- package/bin/ab-harvest-runner.ts +29 -0
- package/bin/ab-init-probe.ts +19 -0
- package/bin/ab-process-group-reaper.ts +32 -0
- package/bin/ab.ts +6 -0
- package/bin/agent/ab +3 -0
- package/docs/answering-blocked-builds.md +89 -0
- package/docs/architecture.md +726 -0
- package/docs/assets/headline-wide.png +0 -0
- package/docs/configuration.md +1623 -0
- package/docs/hosted-dispatcher-cutover-validation.md +178 -0
- package/docs/hosted-dispatcher.md +204 -0
- package/docs/mcp.md +119 -0
- package/docs/operator-api.md +186 -0
- package/docs/remote-store-protocol.md +972 -0
- package/docs/remote-ticket-protocol.md +79 -0
- package/docs/setup.md +289 -0
- package/docs/spec-standard.md +63 -0
- package/docs/ticket-dependencies.md +59 -0
- package/docs/vercel-sandbox-rollout-probe.md +7 -0
- package/package.json +135 -0
- package/packages/core/src/cli/args.ts +74 -0
- package/packages/core/src/cli/artifact.ts +182 -0
- package/packages/core/src/cli/binary.ts +198 -0
- package/packages/core/src/cli/build-control.ts +789 -0
- package/packages/core/src/cli/build-progress.ts +55 -0
- package/packages/core/src/cli/bulk-control.ts +385 -0
- package/packages/core/src/cli/context.ts +470 -0
- package/packages/core/src/cli/dashboard/actions.ts +59 -0
- package/packages/core/src/cli/dashboard/cells.ts +92 -0
- package/packages/core/src/cli/dashboard/composer.ts +230 -0
- package/packages/core/src/cli/dashboard/detail.ts +100 -0
- package/packages/core/src/cli/dashboard/frame-image.ts +373 -0
- package/packages/core/src/cli/dashboard/live.ts +152 -0
- package/packages/core/src/cli/dashboard/model.ts +1173 -0
- package/packages/core/src/cli/dashboard/poll.ts +196 -0
- package/packages/core/src/cli/dashboard/render.ts +1568 -0
- package/packages/core/src/cli/dashboard/selection.ts +66 -0
- package/packages/core/src/cli/dashboard/session-feed.ts +244 -0
- package/packages/core/src/cli/dashboard/session-view.ts +506 -0
- package/packages/core/src/cli/dashboard/transcript.ts +108 -0
- package/packages/core/src/cli/dev.ts +46 -0
- package/packages/core/src/cli/dispatch-frontend.ts +1045 -0
- package/packages/core/src/cli/dispatch-process.ts +259 -0
- package/packages/core/src/cli/dispatch.ts +3692 -0
- package/packages/core/src/cli/dotenv.ts +48 -0
- package/packages/core/src/cli/env.ts +206 -0
- package/packages/core/src/cli/harvest.ts +698 -0
- package/packages/core/src/cli/help.ts +713 -0
- package/packages/core/src/cli/init-agent.ts +106 -0
- package/packages/core/src/cli/init-validation.ts +583 -0
- package/packages/core/src/cli/init.ts +756 -0
- package/packages/core/src/cli/installation.ts +333 -0
- package/packages/core/src/cli/keyboard.ts +261 -0
- package/packages/core/src/cli/main.ts +1399 -0
- package/packages/core/src/cli/mcp.ts +279 -0
- package/packages/core/src/cli/models.ts +65 -0
- package/packages/core/src/cli/observe.ts +55 -0
- package/packages/core/src/cli/plugin.ts +227 -0
- package/packages/core/src/cli/pr-attachments.ts +138 -0
- package/packages/core/src/cli/pr-summary.ts +124 -0
- package/packages/core/src/cli/publication-settlement.ts +188 -0
- package/packages/core/src/cli/repo-state.ts +213 -0
- package/packages/core/src/cli/repository-status.ts +80 -0
- package/packages/core/src/cli/self-update.ts +443 -0
- package/packages/core/src/cli/status.ts +895 -0
- package/packages/core/src/cli/store-opening.contract.ts +289 -0
- package/packages/core/src/cli/store-opening.ts +167 -0
- package/packages/core/src/cli/store-ref.ts +33 -0
- package/packages/core/src/cli/terminal-restore.ts +174 -0
- package/packages/core/src/cli/terminal.ts +361 -0
- package/packages/core/src/cli/terminals.ts +995 -0
- package/packages/core/src/cli/testkit.ts +194 -0
- package/packages/core/src/cli/ticket.ts +484 -0
- package/packages/core/src/cli/upgrade-agent.ts +180 -0
- package/packages/core/src/cli/upgrade-commit.ts +468 -0
- package/packages/core/src/cli/upgrade-notice.ts +91 -0
- package/packages/core/src/cli/upgrade-progress.ts +110 -0
- package/packages/core/src/cli/upgrade.ts +888 -0
- package/packages/core/src/cli/wait.ts +587 -0
- package/packages/core/src/cli/watch.ts +932 -0
- package/packages/core/src/config/live.ts +255 -0
- package/packages/core/src/config/load.ts +98 -0
- package/packages/core/src/config/roles.ts +438 -0
- package/packages/core/src/config/schema.ts +774 -0
- package/packages/core/src/distribution.ts +24 -0
- package/packages/core/src/events/catalog.ts +201 -0
- package/packages/core/src/events/envelope.ts +59 -0
- package/packages/core/src/events/payloads.ts +618 -0
- package/packages/core/src/events/repository.ts +559 -0
- package/packages/core/src/events/sessions.ts +180 -0
- package/packages/core/src/harvest/schema.ts +147 -0
- package/packages/core/src/ids.ts +45 -0
- package/packages/core/src/integration/harness.ts +681 -0
- package/packages/core/src/kernel/auto-merge.ts +259 -0
- package/packages/core/src/kernel/converge.ts +117 -0
- package/packages/core/src/kernel/dispatch-settings.ts +60 -0
- package/packages/core/src/kernel/dispatch-status.ts +141 -0
- package/packages/core/src/kernel/engine.ts +1047 -0
- package/packages/core/src/kernel/harvest.ts +823 -0
- package/packages/core/src/kernel/origin.ts +69 -0
- package/packages/core/src/kernel/phases.ts +196 -0
- package/packages/core/src/kernel/plan-verify-selection.ts +105 -0
- package/packages/core/src/kernel/pr-attachments.ts +82 -0
- package/packages/core/src/kernel/reducer.ts +752 -0
- package/packages/core/src/kernel/stall.ts +155 -0
- package/packages/core/src/kernel/verify-applicability.ts +52 -0
- package/packages/core/src/markdown.ts +67 -0
- package/packages/core/src/ontology.ts +288 -0
- package/packages/core/src/open-map.ts +203 -0
- package/packages/core/src/operator/annotations.ts +187 -0
- package/packages/core/src/operator/client.ts +311 -0
- package/packages/core/src/operator/control.ts +117 -0
- package/packages/core/src/operator/index.ts +62 -0
- package/packages/core/src/operator/presentation.ts +22 -0
- package/packages/core/src/operator/protocol.ts +98 -0
- package/packages/core/src/operator/query.ts +201 -0
- package/packages/core/src/operator/registry.ts +1043 -0
- package/packages/core/src/operator/requests.ts +138 -0
- package/packages/core/src/operator/sandbox.ts +458 -0
- package/packages/core/src/operator/server.ts +616 -0
- package/packages/core/src/operator/sessions.ts +223 -0
- package/packages/core/src/operator/tickets.ts +177 -0
- package/packages/core/src/plugin-sdk/index.ts +174 -0
- package/packages/core/src/plugins/contract-entry.ts +74 -0
- package/packages/core/src/plugins/contract-env.ts +3 -0
- package/packages/core/src/plugins/load.ts +259 -0
- package/packages/core/src/plugins/manifest.ts +236 -0
- package/packages/core/src/plugins/registry.ts +274 -0
- package/packages/core/src/plugins/runtimes.ts +75 -0
- package/packages/core/src/ports/forge/contract.ts +258 -0
- package/packages/core/src/ports/forge/create.ts +74 -0
- package/packages/core/src/ports/forge/fake.ts +488 -0
- package/packages/core/src/ports/forge/github-pr-attachments.ts +351 -0
- package/packages/core/src/ports/forge/github-transport.ts +352 -0
- package/packages/core/src/ports/forge/github.ts +1162 -0
- package/packages/core/src/ports/forge/local-git.ts +568 -0
- package/packages/core/src/ports/runner/claude.ts +873 -0
- package/packages/core/src/ports/runner/cli-stream.ts +90 -0
- package/packages/core/src/ports/runner/codex.ts +873 -0
- package/packages/core/src/ports/runner/contract.ts +492 -0
- package/packages/core/src/ports/runner/fake.ts +213 -0
- package/packages/core/src/ports/runner/json-record.ts +2 -0
- package/packages/core/src/ports/runner/live-contract-fixture.ts +176 -0
- package/packages/core/src/ports/runner/one-shot.ts +29 -0
- package/packages/core/src/ports/runner/pi-bridge-core.ts +136 -0
- package/packages/core/src/ports/runner/pi-bridge.js +6 -0
- package/packages/core/src/ports/runner/pi-rpc.ts +454 -0
- package/packages/core/src/ports/runner/pi.ts +617 -0
- package/packages/core/src/ports/runner/production.ts +74 -0
- package/packages/core/src/ports/runner/provider-error.ts +121 -0
- package/packages/core/src/ports/runner/routing.ts +234 -0
- package/packages/core/src/ports/runner/runtime.ts +214 -0
- package/packages/core/src/ports/runner/session-env.ts +34 -0
- package/packages/core/src/ports/runner/stream-parts.ts +103 -0
- package/packages/core/src/ports/tickets/contract.ts +570 -0
- package/packages/core/src/ports/tickets/create.ts +135 -0
- package/packages/core/src/ports/tickets/fake.ts +215 -0
- package/packages/core/src/ports/tickets/file.ts +559 -0
- package/packages/core/src/ports/tickets/linear.ts +811 -0
- package/packages/core/src/ports/tickets/operations.ts +161 -0
- package/packages/core/src/ports/tickets/remote-index.ts +13 -0
- package/packages/core/src/ports/tickets/remote-protocol.ts +80 -0
- package/packages/core/src/ports/tickets/remote-server.ts +185 -0
- package/packages/core/src/ports/tickets/remote.ts +130 -0
- package/packages/core/src/ports/tickets/update.ts +51 -0
- package/packages/core/src/ports/types.ts +528 -0
- package/packages/core/src/ports/workspace/build-execution.ts +123 -0
- package/packages/core/src/ports/workspace/contract.ts +136 -0
- package/packages/core/src/ports/workspace/create.ts +132 -0
- package/packages/core/src/ports/workspace/distribution-archive.ts +317 -0
- package/packages/core/src/ports/workspace/fake.ts +432 -0
- package/packages/core/src/ports/workspace/git-worktree.ts +848 -0
- package/packages/core/src/ports/workspace/harvest-execution.ts +111 -0
- package/packages/core/src/ports/workspace/in-process-build-execution.ts +30 -0
- package/packages/core/src/ports/workspace/local-build-execution.ts +88 -0
- package/packages/core/src/ports/workspace/operator-sandbox.ts +142 -0
- package/packages/core/src/ports/workspace/phase-scratch.ts +156 -0
- package/packages/core/src/ports/workspace/vercel-sandbox.ts +2541 -0
- package/packages/core/src/processes/build-child-exit.ts +78 -0
- package/packages/core/src/processes/build-child.ts +119 -0
- package/packages/core/src/processes/build-execution-state.ts +95 -0
- package/packages/core/src/processes/build-parent-watch.ts +35 -0
- package/packages/core/src/processes/build-runner.ts +2614 -0
- package/packages/core/src/processes/dispatcher.ts +2825 -0
- package/packages/core/src/processes/execution-settlement.ts +171 -0
- package/packages/core/src/processes/harvest-child.ts +115 -0
- package/packages/core/src/processes/harvest-execution-state.ts +121 -0
- package/packages/core/src/processes/harvest-runner.ts +1656 -0
- package/packages/core/src/processes/harvest.ts +595 -0
- package/packages/core/src/processes/infrastructure-failure-budget.ts +146 -0
- package/packages/core/src/processes/phase-failure-budget.ts +52 -0
- package/packages/core/src/processes/process-group-reaper.ts +35 -0
- package/packages/core/src/processes/process-group.ts +65 -0
- package/packages/core/src/processes/publication-loss.ts +62 -0
- package/packages/core/src/processes/publication-state.ts +93 -0
- package/packages/core/src/processes/sandbox-state.ts +101 -0
- package/packages/core/src/registry.ts +24 -0
- package/packages/core/src/sessions/reducer.ts +185 -0
- package/packages/core/src/skills.ts +7 -0
- package/packages/core/src/spec-standard.ts +47 -0
- package/packages/core/src/store/adapter.ts +80 -0
- package/packages/core/src/store/build-scope.ts +272 -0
- package/packages/core/src/store/contract.ts +2581 -0
- package/packages/core/src/store/local/blobs.ts +38 -0
- package/packages/core/src/store/local/schema.ts +180 -0
- package/packages/core/src/store/local/store.ts +1713 -0
- package/packages/core/src/store/memory.ts +1138 -0
- package/packages/core/src/store/phase-session.ts +425 -0
- package/packages/core/src/store/remote/client.ts +780 -0
- package/packages/core/src/store/remote/index.ts +12 -0
- package/packages/core/src/store/remote/protocol.ts +348 -0
- package/packages/core/src/store/remote/server.ts +923 -0
- package/packages/core/src/store/remote/token.ts +137 -0
- package/packages/core/src/store/remote/version.ts +10 -0
- package/packages/core/src/store/retention.ts +91 -0
- package/packages/core/src/store/session-handle.ts +265 -0
- package/packages/core/src/store/streams/assemble.ts +79 -0
- package/packages/core/src/store/streams/lock.ts +42 -0
- package/packages/core/src/store/streams/session-writer.ts +306 -0
- package/packages/core/src/store/streams/types.ts +171 -0
- package/packages/core/src/store/streams/wait.ts +127 -0
- package/packages/core/src/store/subscribe.ts +105 -0
- package/packages/core/src/store/types.ts +466 -0
- package/packages/core/src/testing/fixed.ts +44 -0
- package/packages/core/src/testing/store-failures.ts +32 -0
- package/packages/core/src/zod-issues.ts +91 -0
- package/skills/code-review/SKILL.md +100 -0
- package/skills/finalize/SKILL.md +44 -0
- package/skills/guide/SKILL.md +1781 -0
- package/skills/guide/references/operator-api.md +164 -0
- package/skills/guide/references/plugin-authoring.md +354 -0
- package/skills/guide/references/remote-store-protocol.md +972 -0
- package/skills/guide/references/remote-ticket-protocol.md +79 -0
- package/skills/guide/references/setup.md +289 -0
- package/skills/guide/references/spec-standard.md +63 -0
- package/skills/guide/references/ticket-dependencies.md +59 -0
- package/skills/harvest/SKILL.md +66 -0
- package/skills/harvest-review/SKILL.md +63 -0
- package/skills/implement/SKILL.md +82 -0
- package/skills/plan/SKILL.md +123 -0
- package/skills/plan-review/SKILL.md +121 -0
- package/skills/reconcile/SKILL.md +65 -0
- package/skills/spec/SKILL.md +132 -0
- package/skills/tickets/SKILL.md +139 -0
- package/templates/autobuild.toml +36 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Hosted ticket protocol
|
|
2
|
+
|
|
3
|
+
The hosted ticket protocol exposes the complete `TicketSource` port without
|
|
4
|
+
exposing backend credentials. It shares the Autobuild and remote protocol
|
|
5
|
+
version headers with the remote BuildStore. Both must exactly match the service;
|
|
6
|
+
this release uses remote protocol version `2`.
|
|
7
|
+
|
|
8
|
+
## Authentication and context
|
|
9
|
+
|
|
10
|
+
Every request is `POST /tickets/<operation>`, has `Content-Type:
|
|
11
|
+
application/json`, and requires `Authorization: Bearer <token>`. Only a signed,
|
|
12
|
+
unexpired **deployment operator** token (`{ "operator": true, … }`) is accepted.
|
|
13
|
+
Attributed human-operator, legacy admin, build, repository, and session tokens
|
|
14
|
+
remain valid for their own routes but are denied on `/tickets`. Mint a deployment
|
|
15
|
+
operator token offline with:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
AB_STORE_SECRET='…' ab-hosted-store mint operator --ttl-seconds 3600
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The strict request envelope is:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"context": {
|
|
26
|
+
"teamKey": "ENG",
|
|
27
|
+
"claimedState": "Doing",
|
|
28
|
+
"createState": "Triage"
|
|
29
|
+
},
|
|
30
|
+
"input": {}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`teamKey` is required. The state overrides are optional. They come from the
|
|
35
|
+
requesting repository's `[tickets]` configuration and are applied only to that
|
|
36
|
+
request; the service does not cache a team-bound adapter. `list-ready` also
|
|
37
|
+
receives that repository's exact ready state and label criteria in `input`.
|
|
38
|
+
Backend credentials, including `LINEAR_API_KEY`, are service environment only
|
|
39
|
+
and never occur in this envelope or any response.
|
|
40
|
+
|
|
41
|
+
## Operations
|
|
42
|
+
|
|
43
|
+
The operation names and `input` values are:
|
|
44
|
+
|
|
45
|
+
| Operation | Input | Successful response |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `list-ready` | `{labels?: string[], state?: string}` | `TicketListing` |
|
|
48
|
+
| `get` | `{id}` | `Ticket \| null` |
|
|
49
|
+
| `claim` | `{id}` | `{claimed: boolean}` |
|
|
50
|
+
| `comment` | `{id, body}` | `{ok: true}` |
|
|
51
|
+
| `transition` | `{id, state}` | `{ok: true}` |
|
|
52
|
+
| `create` | `{draft, options?}` | `Ticket` |
|
|
53
|
+
| `update` | `{id, patch}` | `{ok: true}` |
|
|
54
|
+
| `add-blocker` | `{id, blockerId}` | `{ok: true}` |
|
|
55
|
+
| `remove-blocker` | `{id, blockerId}` | `{ok: true}` |
|
|
56
|
+
| `dependency-states` | `{ids}` | `DependencyState[]` in input order |
|
|
57
|
+
|
|
58
|
+
Requests and responses reject unknown fields. Tickets include `ref`, optional
|
|
59
|
+
`creationKey`, `title`, `body`, optional `state`, `labels`, and optional
|
|
60
|
+
`blockedBy`. The client projects every returned `ref.source` as `hosted` while
|
|
61
|
+
preserving backend ids, URLs, titles, lifecycle values, labels, creation keys,
|
|
62
|
+
and blockers.
|
|
63
|
+
|
|
64
|
+
Ticket body strings are opaque. Clients, JSON handling, the service, and the
|
|
65
|
+
database backend must not trim or normalize bytes, newlines, Unicode, blank
|
|
66
|
+
lines, or trailing whitespace.
|
|
67
|
+
|
|
68
|
+
## Errors and conformance
|
|
69
|
+
|
|
70
|
+
Errors are JSON `{ "error": string, "kind": "validation" | "not-found" |
|
|
71
|
+
"auth" | "conflict" | "internal" }`. Authentication runs before body parsing
|
|
72
|
+
or backend construction. Responses never include exception causes, stacks,
|
|
73
|
+
environment values, or credentials. Client 401/403 responses become
|
|
74
|
+
`AuthError`; other backend messages remain actionable.
|
|
75
|
+
|
|
76
|
+
The shared `TicketSource` contract is normative for the database adapter and
|
|
77
|
+
the hosted client/server pair. External pass-through is tested with a fake
|
|
78
|
+
source behind HTTP. The existing opt-in live Linear contract remains the proof
|
|
79
|
+
of Linear's GraphQL behavior; the hosted service uses that adapter unchanged.
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Repository setup
|
|
2
|
+
|
|
3
|
+
Configure Autobuild outside the build pipeline. This conversation is not a
|
|
4
|
+
build or phase. Work directly in the repository and involve the maintainer in
|
|
5
|
+
choices that cannot be derived from source. Secrets belong in the environment
|
|
6
|
+
or an ignored `.env`, never in `autobuild.toml`, commits, or validation reports.
|
|
7
|
+
|
|
8
|
+
## Choose the execution environment
|
|
9
|
+
|
|
10
|
+
Keep the default `git-worktree` provider unless the maintainer explicitly opts
|
|
11
|
+
into remote builds. It creates local disposable worktrees and uses the tools,
|
|
12
|
+
network, and credentials available to the dispatcher machine.
|
|
13
|
+
|
|
14
|
+
For remote execution, set `[workspace].provider = "vercel-sandbox"`. A Vercel
|
|
15
|
+
Sandbox is a fresh independent machine; a runtime that works on the setup
|
|
16
|
+
machine is not evidence that it works there. Confirm all of these with the
|
|
17
|
+
maintainer before selecting it:
|
|
18
|
+
|
|
19
|
+
- the intended Vercel team and project;
|
|
20
|
+
- durable dispatcher authentication with `VERCEL_TOKEN`, `VERCEL_TEAM_ID`, and
|
|
21
|
+
`VERCEL_PROJECT_ID`, or short-lived `VERCEL_OIDC_TOKEN` obtained from a linked
|
|
22
|
+
project (`vercel link` and `vercel env pull`); when validating a target other
|
|
23
|
+
than the current directory, export OIDC in the launcher environment because
|
|
24
|
+
the Vercel SDK resolves it from ambient process state. Access-token
|
|
25
|
+
credentials in the target's ignored `.env` are the durable choice for a
|
|
26
|
+
continuously running local dispatcher;
|
|
27
|
+
- an HTTPS `github.com/owner/repository` origin and `forge = "github"`;
|
|
28
|
+
- a dispatcher-side push-capable `GITHUB_TOKEN` or `GH_TOKEN`;
|
|
29
|
+
- for a private repository, a separate read-only clone identity named by
|
|
30
|
+
`gitUsernameEnv` and `gitPasswordEnv`;
|
|
31
|
+
- an HTTPS hosted `AB_STORE` reachable from Vercel and a scoped `AB_TOKEN`;
|
|
32
|
+
- each selected role and alternate's runtime/model, its pinned
|
|
33
|
+
`[workspace.config.runtimeProvisioning.<runtime>]` commands, and the API
|
|
34
|
+
credential names it needs in `[workspace.config].environmentVariables`.
|
|
35
|
+
|
|
36
|
+
Do not put `AB_STORE`, `AB_TOKEN`, Vercel credentials, Forge credentials, or
|
|
37
|
+
private-clone credentials in `environmentVariables`. Autobuild supplies Store
|
|
38
|
+
credentials separately, keeps clone credentials out of guest commands, and
|
|
39
|
+
performs publication from the trusted host.
|
|
40
|
+
|
|
41
|
+
```toml
|
|
42
|
+
[workspace]
|
|
43
|
+
provider = "vercel-sandbox"
|
|
44
|
+
|
|
45
|
+
[workspace.config]
|
|
46
|
+
image = "vercel/sandbox/universal:latest"
|
|
47
|
+
vcpus = 4
|
|
48
|
+
timeoutSeconds = 2700
|
|
49
|
+
environmentVariables = ["AI_GATEWAY_API_KEY"]
|
|
50
|
+
# Ordered system-level steps run once in every fresh/replacement sandbox as root.
|
|
51
|
+
provisioning = [
|
|
52
|
+
{ name = "system-install", command = """apt-get update
|
|
53
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y chromium""" },
|
|
54
|
+
{ name = "browser-smoke", command = "CHROMIUM_BIN=/usr/bin/chromium ./scripts/browser-smoke.sh" },
|
|
55
|
+
]
|
|
56
|
+
# Private repositories only:
|
|
57
|
+
# gitUsernameEnv = "AB_GIT_READ_USER"
|
|
58
|
+
# gitPasswordEnv = "AB_GIT_READ_TOKEN"
|
|
59
|
+
|
|
60
|
+
[workspace.config.runtimeProvisioning.pi]
|
|
61
|
+
install = "npm install --global --ignore-scripts @earendil-works/pi-coding-agent@0.84.4"
|
|
62
|
+
preflight = "test \"$(pi --version)\" = \"0.84.4\""
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use a `vercel-ai-gateway/...` Pi model with `AI_GATEWAY_API_KEY` in the
|
|
66
|
+
dispatcher environment. Do not copy `~/.pi`, OAuth refresh tokens, or any local
|
|
67
|
+
runtime auth state, and do not attempt interactive login in a sandbox. Runtime
|
|
68
|
+
names are open: a plugin runtime uses the same strict map, for example
|
|
69
|
+
`[workspace.config.runtimeProvisioning.opencode]`, with its own immutable
|
|
70
|
+
install and exact-version preflight commands.
|
|
71
|
+
|
|
72
|
+
## Make the environment reproducible
|
|
73
|
+
|
|
74
|
+
Inspect the repository's manifests, documentation, CI, test layout, and
|
|
75
|
+
conventions. Read the installed sibling `../SKILL.md` for Autobuild's complete
|
|
76
|
+
configuration and ticket surfaces.
|
|
77
|
+
|
|
78
|
+
Use the supported `vercel/sandbox/universal` image. Other managed images and
|
|
79
|
+
custom VCR images are rejected. Autobuild remains stack-neutral. For Vercel,
|
|
80
|
+
put repository-specific operating-system packages and machine-level tooling in
|
|
81
|
+
the ordered `[workspace.config].provisioning` list. Each strict `{ name,
|
|
82
|
+
command }` entry runs from the checkout through `sh -c` with provider root
|
|
83
|
+
authority after pinned Bun is verified and before dependency bootstrap,
|
|
84
|
+
`[commands].setup`, or an agent. It runs once per fresh environment and repeats
|
|
85
|
+
on every replacement. Commands are declarative TOML string data, not evaluated
|
|
86
|
+
configuration logic. Local git worktrees never run this list; ensure their host
|
|
87
|
+
already has required system tooling.
|
|
88
|
+
|
|
89
|
+
Put each selected runtime's immutable install and executable/version check in
|
|
90
|
+
its `runtimeProvisioning` entry. Autobuild runs install then preflight after
|
|
91
|
+
checkout dependencies in every fresh/replacement sandbox and before the
|
|
92
|
+
readiness probe, writes the marker only after success, and reruns every
|
|
93
|
+
preflight before each build runner. A failure names the runtime, selecting
|
|
94
|
+
role/alternate, and field and starts no agent. Runtime provisioning receives
|
|
95
|
+
only the API credentials named by `[workspace.config].environmentVariables`.
|
|
96
|
+
|
|
97
|
+
Keep package-level and checkout-level bootstrap in an idempotent
|
|
98
|
+
`[commands].setup`. It runs after system provisioning and must remain safe to
|
|
99
|
+
rerun on attachment. Do not repeatedly install OS packages there. Expose only
|
|
100
|
+
required runtime credentials through
|
|
101
|
+
`[workspace.config].environmentVariables`, keep generated caches disposable,
|
|
102
|
+
and lock dependencies in the repository. A browser-capable repository should
|
|
103
|
+
check in a dependency-free `scripts/browser-smoke.sh` that starts its dev server,
|
|
104
|
+
uses a repository-controlled path such as `CHROMIUM_BIN=/usr/bin/chromium` to
|
|
105
|
+
launch headless Chromium in the same guest, verifies the rendered page, and
|
|
106
|
+
exits nonzero on failure. Then:
|
|
107
|
+
|
|
108
|
+
1. Configure real `[commands]` and ordered `[verify]` steps from the toolchain
|
|
109
|
+
this repository actually uses. Do not invent commands or retain placeholders.
|
|
110
|
+
2. Decide the runtime and model arrangement for every pipeline role and
|
|
111
|
+
alternate. The runtime that launched setup and the temporary fresh-skeleton
|
|
112
|
+
default do not constrain the final arrangement.
|
|
113
|
+
3. Choose the ticket source and workflow states. Confirm account/team facts and
|
|
114
|
+
required environment credentials. Configure end-to-end verification with the
|
|
115
|
+
repository's real lifecycle and tools. When judgment is required, author a repository-owned
|
|
116
|
+
agent-verify skill and select it from an agent verify step.
|
|
117
|
+
4. Preserve an existing `autobuild.toml` and unrelated repository choices on a
|
|
118
|
+
rerun. Change only choices the maintainer approves.
|
|
119
|
+
5. Commit the config, setup files, lockfiles, and installed reference changes,
|
|
120
|
+
then push them to `baseBranch`. A remote sandbox clones the authoritative
|
|
121
|
+
GitHub revision; it cannot acquire local-only edits.
|
|
122
|
+
6. Run `ab init --validate`. Fix every named failure and rerun until every check
|
|
123
|
+
passes. Only then use the installed grooming/ticket skills to create the
|
|
124
|
+
first groomed Ready ticket and start `ab dispatch`.
|
|
125
|
+
|
|
126
|
+
Validation is explicit and noninteractive. It does not dispatch, claim a
|
|
127
|
+
ticket, or create build, phase, session, event, transcript, or artifact history.
|
|
128
|
+
For local execution it identifies and removes a disposable detached worktree.
|
|
129
|
+
For Vercel it identifies and permanently deletes a fresh unnamed sandbox, even
|
|
130
|
+
when system or runtime provisioning, setup, or a probe fails; cleanup failures
|
|
131
|
+
name the environment for manual deletion. Its `system provisioning` check lists
|
|
132
|
+
completed step names (or says none were declared) before guest setup checks. A
|
|
133
|
+
failed step reports its name, command, status, labeled stdout/stderr, and
|
|
134
|
+
remediation without marking the environment ready. It provisions/preflights
|
|
135
|
+
every effective primary and alternate runtime, then runs `commands.setup`, loads
|
|
136
|
+
repository plugins, and checks every
|
|
137
|
+
selected primary/alternate runtime and model, and performs a read-only Store
|
|
138
|
+
request in the candidate execution context. If the local database is absent,
|
|
139
|
+
validation reports that no repository history is available without creating
|
|
140
|
+
`.autobuild` or any SQLite files. If it exists, validation copies the database
|
|
141
|
+
and any WAL/SHM sidecars to a disposable filesystem snapshot and inspects that
|
|
142
|
+
copy without SQLite-opening or modifying the repository Store files. It never
|
|
143
|
+
silently falls back from Vercel to local execution. Local launcher probes
|
|
144
|
+
printed by ordinary `ab init` are only setup-agent discovery and are not remote
|
|
145
|
+
readiness evidence.
|
|
146
|
+
|
|
147
|
+
Typical remediation is intentionally specific: add a missing system executable
|
|
148
|
+
to `workspace.config.provisioning` (or a package dependency to setup) while
|
|
149
|
+
retaining the universal image; add a runtime credential name to
|
|
150
|
+
`environmentVariables` and its value to the dispatcher environment; correct the
|
|
151
|
+
Vercel team/project credential set; provide separate private-clone credentials;
|
|
152
|
+
use an HTTPS GitHub origin and hosted Store; authorize the Store token; or commit
|
|
153
|
+
and push the selected base branch.
|
|
154
|
+
|
|
155
|
+
## Repository identity is the origin, not a checkout path
|
|
156
|
+
|
|
157
|
+
Repository identity in the Store, dispatcher, `ab builds`, `ab build status`,
|
|
158
|
+
`ab repository status`, and the web app is the repository's **normalized origin
|
|
159
|
+
URL** (`https://github.com/owner/repository`), not a checkout's absolute path.
|
|
160
|
+
Two checkouts of the same repository — on different hosts, or a dispatcher and
|
|
161
|
+
its sandboxes — agree on one identity.
|
|
162
|
+
|
|
163
|
+
Records written before this change are keyed by checkout path and are **not
|
|
164
|
+
migrated**. They remain visible only where their recorded `repoOrigin` matches
|
|
165
|
+
the querying checkout's origin; dropping the old identity's history is an
|
|
166
|
+
accepted trade for path-free operation.
|
|
167
|
+
|
|
168
|
+
## Running the dispatcher without a checkout (origin mode)
|
|
169
|
+
|
|
170
|
+
A dispatcher can operate a repository with no local checkout at all — from a
|
|
171
|
+
serverless function or any host with only network access:
|
|
172
|
+
|
|
173
|
+
```sh
|
|
174
|
+
ab dispatch --repository https://github.com/owner/repository \\
|
|
175
|
+
--plain --store https://hosted-store.example \\
|
|
176
|
+
# environment: AB_TOKEN (store), GITHUB_TOKEN or GH_TOKEN (GitHub API)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`--repository` (or `AB_REPOSITORY`) is the normalized origin. Origin mode
|
|
180
|
+
requires an HTTPS `AB_STORE` plus `AB_TOKEN`, an exported `GITHUB_TOKEN` or
|
|
181
|
+
`GH_TOKEN`, and `forge = "github"`; the interactive dashboard is unavailable
|
|
182
|
+
(`--plain` or no TTY). Origin mode never consults the gh CLI: a checkout-less
|
|
183
|
+
host has no gh and no keyring, and the only workspace provider it can run,
|
|
184
|
+
`vercel-sandbox`, injects that same exported token for publication. The gh CLI
|
|
185
|
+
fallback (`GITHUB_TOKEN`, then `GH_TOKEN`, then the login stored by `gh auth
|
|
186
|
+
login`) is a checkout-mode convenience for a local dispatcher whose workspace
|
|
187
|
+
provider is not `vercel-sandbox`; that provider requires the exported token in
|
|
188
|
+
every mode. The
|
|
189
|
+
startup configuration — and every per-tick reload — is `autobuild.toml` read
|
|
190
|
+
from the forge at the current `baseBranch` (the first read resolves against the
|
|
191
|
+
repository's default branch), so a push to the base branch is honored by a
|
|
192
|
+
later tick without restarting anything. Configs declaring local `plugins` are
|
|
193
|
+
rejected: plugin code is checkout-relative. The guest installs the Autobuild
|
|
194
|
+
distribution published for its version — the npm registry tarball, else the
|
|
195
|
+
GitHub release asset `autobuild-<version>.tgz` — so origin-mode dispatch
|
|
196
|
+
requires a published release.
|
|
197
|
+
|
|
198
|
+
### Guest distribution version selection and delivery
|
|
199
|
+
|
|
200
|
+
The guest's distribution version is selected by the archive source, and both
|
|
201
|
+
sources agree with the running system by construction:
|
|
202
|
+
|
|
203
|
+
- **Source checkout** (dispatcher running from a repository checkout): the
|
|
204
|
+
guest archive is packed from the host tree with `bun pm pack`, so the guest
|
|
205
|
+
runs the dispatcher's own code.
|
|
206
|
+
- **Origin mode** (checkout-less dispatcher): the guest archive is the release
|
|
207
|
+
asset `autobuild-<version>.tgz` fetched from the canonical repository at the
|
|
208
|
+
**running dispatcher's version** (read from the deployed distribution's
|
|
209
|
+
`package.json`), so the guest runs the dispatcher's own release.
|
|
210
|
+
|
|
211
|
+
The hosted remote store enforces exact **version lockstep**: every client
|
|
212
|
+
request must carry an `x-autobuild-version` equal to the server's, and any
|
|
213
|
+
mismatch — a guest older *or* newer than the store — is rejected with a 409
|
|
214
|
+
`remote store version mismatch`. Guest, store, and dispatcher versions
|
|
215
|
+
therefore cannot be mixed: a distribution fix reaches guests only after
|
|
216
|
+
`tools/release.ts` cuts a release (credential-gated; requires GitHub
|
|
217
|
+
credentials — a documented delivery dependency, not an automatic propagation)
|
|
218
|
+
**and** the hosted store and dispatcher are upgraded to that release in the
|
|
219
|
+
same lockstep window. If the release is cut but the store upgrade lags, guests
|
|
220
|
+
carrying the new distribution fail loudly against the old store (409) rather
|
|
221
|
+
than running silently stale.
|
|
222
|
+
|
|
223
|
+
Provisioning records the installed distribution's version in the guest's
|
|
224
|
+
`/opt/autobuild/.distribution-version` marker. A reused persistent sandbox
|
|
225
|
+
whose marker disagrees with the version the current system would deliver —
|
|
226
|
+
which includes every guest provisioned before the marker existed — is
|
|
227
|
+
refreshed in place (archive re-fetched, extracted, and production-installed)
|
|
228
|
+
before being reused, so an upgraded dispatcher retrofits its existing guests
|
|
229
|
+
instead of resuming a stale distribution. A refresh failure deletes the
|
|
230
|
+
sandbox so the next provisioning pass rematerializes it from scratch.
|
|
231
|
+
|
|
232
|
+
After a lockstep upgrade, confirm a fix-bearing guest from the guest
|
|
233
|
+
perspective:
|
|
234
|
+
|
|
235
|
+
1. `ab build status <slug> --json` with the ambient build identity for a
|
|
236
|
+
build whose record carries `repoOrigin` succeeds and exposes `.pr.number`
|
|
237
|
+
and `.pr.url` even though the guest's checkout path differs from the path
|
|
238
|
+
recorded at build creation (post-#297 origin-equality behavior).
|
|
239
|
+
2. The same command for a genuinely foreign repository's slug still fails
|
|
240
|
+
with the `belongs to repository … not …` rejection.
|
|
241
|
+
|
|
242
|
+
Local `git-worktree` dispatch keeps working from a checkout exactly as before;
|
|
243
|
+
apart from the identity change, `ab dispatch` behaves as it did.
|
|
244
|
+
|
|
245
|
+
## Hosted deployment variables
|
|
246
|
+
|
|
247
|
+
A hosted-store deployment configures its web/auth variables once — see the
|
|
248
|
+
hosted service README and the complete environment reference in the pinned
|
|
249
|
+
distribution checkout: `BETTER_AUTH_URL`, `AB_WEB_ALLOWED_EMAILS`,
|
|
250
|
+
`AB_WEB_REPOSITORIES`, and the optional `AB_WEB_MCP_RESOURCE` — the protected
|
|
251
|
+
resource the hosted MCP server (docs/mcp.md) binds its OAuth tokens to,
|
|
252
|
+
defaulting to `<BETTER_AUTH_URL>/mcp`. Set it only when a proxy or custom
|
|
253
|
+
domain fronts the deployment under a different public URL than
|
|
254
|
+
`BETTER_AUTH_URL`; the value must be an absolute http(s) URL (https in
|
|
255
|
+
production) or every MCP client's discovery binds tokens to the wrong
|
|
256
|
+
resource.
|
|
257
|
+
|
|
258
|
+
## Authoring an agent verifier
|
|
259
|
+
|
|
260
|
+
A repository-owned agent-verify skill is a verifier, not a reviewer: it drives
|
|
261
|
+
the running application and observes whether the spec's acceptance criteria
|
|
262
|
+
hold. It does not inspect the diff for style or edit product code.
|
|
263
|
+
|
|
264
|
+
Its session instructions must preserve this contract:
|
|
265
|
+
|
|
266
|
+
1. Run `ab context`. The verifier receives `.ab/spec.md`, the configured step,
|
|
267
|
+
the commit range, and, after escalation is answered, `.ab/guidance.json`.
|
|
268
|
+
2. Exercise each applicable acceptance criterion through the repository's real
|
|
269
|
+
application lifecycle. Prefer the narrowest honest flow that catches a
|
|
270
|
+
regression.
|
|
271
|
+
3. Write criterion-oriented evidence: criterion, action, observation, and
|
|
272
|
+
pass/fail. Failures include reproduction inputs, expected/observed behavior,
|
|
273
|
+
and relevant repository-native logs.
|
|
274
|
+
4. Deposit passing review evidence explicitly with
|
|
275
|
+
`ab artifact put <kind> <file> --attach`. Never attach failed or partial
|
|
276
|
+
output; use stable kinds so retries replace the designation.
|
|
277
|
+
5. Finish with exactly one terminal:
|
|
278
|
+
|
|
279
|
+
```text
|
|
280
|
+
ab verdict pass --notes <report-file>
|
|
281
|
+
ab verdict fail --report <report-file>
|
|
282
|
+
ab verdict skip --reason "Why this entire step does not apply"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
An applicable behavior that cannot be exercised is a failure with an
|
|
286
|
+
explanation, never a skip or silent pass. Use `skip` only when the complete step
|
|
287
|
+
does not apply. If guidance still cannot make a verdict possible, escalate and
|
|
288
|
+
explain what remains unresolved. Record out-of-scope work with `ab observe`;
|
|
289
|
+
the verifier does not fix it.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# The spec standard
|
|
2
|
+
|
|
3
|
+
This document is the complete reference definition of **buildable**. Every
|
|
4
|
+
ticket-producing surface uses the same standard: interactive specification,
|
|
5
|
+
harvest, ingesters, and dispatch. An ingester's proposal is a spec written to
|
|
6
|
+
this standard with weaker evidence. Dispatch's quality gate returns any Ready
|
|
7
|
+
ticket that cannot be expanded into a conforming spec to Triage, citing this
|
|
8
|
+
standard.
|
|
9
|
+
|
|
10
|
+
A conforming spec has four parts:
|
|
11
|
+
|
|
12
|
+
## 1. What and why — never how
|
|
13
|
+
|
|
14
|
+
State the change in terms of observable behavior and the reason it matters.
|
|
15
|
+
Implementation strategy belongs to the `plan` phase; a spec that prescribes
|
|
16
|
+
file names, function signatures, or libraries is over-specified and will
|
|
17
|
+
mislead the planner. One or two paragraphs.
|
|
18
|
+
|
|
19
|
+
- Bad: "Add a `RateLimiter` class in `src/middleware/` using a token bucket."
|
|
20
|
+
- Good: "Login attempts are currently unlimited; an attacker can brute-force
|
|
21
|
+
credentials. After this change, repeated failed logins from one source are
|
|
22
|
+
throttled, and legitimate users see a clear retry-after message."
|
|
23
|
+
|
|
24
|
+
## 2. Acceptance criteria
|
|
25
|
+
|
|
26
|
+
A checklist of verifiable statements that define done. Each criterion must be
|
|
27
|
+
something a reviewer or a verify step can actually check — behavior, not
|
|
28
|
+
intention. These become the contract that `plan-review`, `code-review`, and
|
|
29
|
+
`verify:*` all measure against.
|
|
30
|
+
|
|
31
|
+
- Each criterion is a single observable fact ("a sixth failed login within
|
|
32
|
+
five minutes returns 429 with a Retry-After header").
|
|
33
|
+
- Avoid criteria that cannot fail ("code is clean").
|
|
34
|
+
- Do not predict which repository paths implementation will touch. Tickets
|
|
35
|
+
describe observable behavior; any repository-configured path applicability
|
|
36
|
+
is evaluated later by the kernel from the build's actual diff in each verify
|
|
37
|
+
cycle.
|
|
38
|
+
|
|
39
|
+
## 3. Out of scope — explicit
|
|
40
|
+
|
|
41
|
+
Name the adjacent work this spec deliberately excludes. This is what keeps
|
|
42
|
+
builds from thrashing: the implementer files an `ab observe` observation for
|
|
43
|
+
out-of-scope discoveries instead of expanding the diff, and the reviewer
|
|
44
|
+
cannot demand out-of-scope work in findings.
|
|
45
|
+
|
|
46
|
+
## 4. Evidence
|
|
47
|
+
|
|
48
|
+
Links and data supporting the why: the Sentry issue and its frequency, the
|
|
49
|
+
observation events that were clustered into this proposal, the conversation
|
|
50
|
+
where the human decided this matters. Evidence strength varies by origin —
|
|
51
|
+
a human-authored `/spec` may cite a decision; an `ingest:sentry` proposal
|
|
52
|
+
cites error counts and affected users. Weak evidence is acceptable; absent
|
|
53
|
+
evidence is not.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Immutability during a build
|
|
58
|
+
|
|
59
|
+
The spec is the build's contract artifact (kind `spec`, revision 0). It
|
|
60
|
+
cannot change during a build because every downstream reviewer approves
|
|
61
|
+
conformance *to it*. A phase that discovers the spec itself is wrong raises
|
|
62
|
+
an escalation (`ab escalate`); a human answers, the spec gets revision N+1,
|
|
63
|
+
and the build restarts from `plan`.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Filing tickets with blockers safely
|
|
2
|
+
|
|
3
|
+
`ab ticket create --blocked-by` validates prerequisite ids and records blocking
|
|
4
|
+
relationships, but a single CLI command is **not an atomic publication guarantee**.
|
|
5
|
+
In particular, direct Linear and hosted Linear create the issue first and add
|
|
6
|
+
its blocker relationships in separate requests. If the issue is already in the
|
|
7
|
+
ready state, a dispatcher can see it before those relationships exist. A
|
|
8
|
+
successful create response containing every blocker does not prove that no build
|
|
9
|
+
was claimed during the request. Harvest's durable creation reservations protect
|
|
10
|
+
its own filing workflow; ordinary interactive ticket creation has no such hold.
|
|
11
|
+
|
|
12
|
+
## Safe interactive workflow
|
|
13
|
+
|
|
14
|
+
For tickets with prerequisites, determine the intended final state from the
|
|
15
|
+
human's instruction, then the configured create state or source default. Do not
|
|
16
|
+
invent a different final destination. If that destination is ready, or the source
|
|
17
|
+
default's eligibility is unknown, stage the ticket in a known non-ready state
|
|
18
|
+
before publishing it. Use the repository's triage state when it differs from its
|
|
19
|
+
ready state. This temporary staging does not require another placement approval.
|
|
20
|
+
If no non-ready state can be established, resolve that before creating the
|
|
21
|
+
dependent; never guess that a name such as "Backlog" is safe in every repository.
|
|
22
|
+
|
|
23
|
+
1. Create prerequisites in dependency order and extract each new `.ref.id` from
|
|
24
|
+
the complete `--json` response, never the human confirmation line.
|
|
25
|
+
2. Create the dependent in the non-ready staging state with **all** known
|
|
26
|
+
`--blocked-by` ids in the create command.
|
|
27
|
+
3. Read it back with `ab ticket show <id> --json`. Verify its state is still
|
|
28
|
+
non-ready and every expected blocker is present. Repair missing relationships
|
|
29
|
+
through `ab ticket block`, then read back again.
|
|
30
|
+
4. Only after verification, move it to the intended final state with
|
|
31
|
+
`ab ticket move <id> <state> --json`. Verify the final state and blockers.
|
|
32
|
+
|
|
33
|
+
For a repository whose configured triage and ready states are `Triage` and
|
|
34
|
+
`Ready`, respectively, and whose human requested ready placement:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
ab ticket create "Dependent" --body dependent.md --state Triage --blocked-by ENG-8,ENG-9 --json > dependent-ticket.json
|
|
38
|
+
dependent_id="$(jq -r '.ref.id' dependent-ticket.json)"
|
|
39
|
+
ab ticket show "$dependent_id" --json
|
|
40
|
+
# Verify state and the full blocker set before the following command.
|
|
41
|
+
ab ticket move "$dependent_id" Ready --json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If creation fails after an issue may have been written, find and repair that
|
|
45
|
+
issue rather than blindly creating a duplicate. Leave partial work non-ready
|
|
46
|
+
until the blockers are verified. If the intended destination was already
|
|
47
|
+
non-ready, create there, verify, and leave it there. For a source default that
|
|
48
|
+
cannot be determined, clarify the final destination rather than silently making
|
|
49
|
+
the ticket ready.
|
|
50
|
+
|
|
51
|
+
## Already-claimed work
|
|
52
|
+
|
|
53
|
+
Adding blockers does not stop a build already claimed from an earlier listing.
|
|
54
|
+
When the human authorizes restarting premature work: request `ab abort <slug>`,
|
|
55
|
+
wait for dispatcher cleanup to finish and return the ticket to triage, verify
|
|
56
|
+
or repair the blocker set, and only then move the ticket back to ready. Moving
|
|
57
|
+
the ticket before cleanup finishes can be overwritten by cleanup. Ready with
|
|
58
|
+
unresolved blockers is the normal waiting state: dispatch rechecks dependencies
|
|
59
|
+
and claims the ticket only after they resolve and other readiness gates pass.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harvest
|
|
3
|
+
description: Synthesize a claimed observation snapshot into structured, spec-standard ticket proposals. Invoked only by the harvest runner.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ab-harvest <run>
|
|
7
|
+
|
|
8
|
+
You are the harvest producer. The repository runner has already scanned and
|
|
9
|
+
claimed a fixed set of structured `observation.recorded` occurrences. You
|
|
10
|
+
cluster and author; you never create or move tickets.
|
|
11
|
+
|
|
12
|
+
1. Run `ab harvest context`. Read `.ab/observations.json`,
|
|
13
|
+
`.ab/originating-tickets.json`, and `.ab/ledger.json`. The originating-ticket
|
|
14
|
+
context shows scan-time source match, existence, and resolution state; filing
|
|
15
|
+
refreshes matching refs before create. On a revise round, address every item
|
|
16
|
+
in `.ab/findings.json` and revise the prior `.ab/proposals.json`.
|
|
17
|
+
2. Write `.ab/proposals.json` with this exact top-level shape:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"proposals": [
|
|
22
|
+
{
|
|
23
|
+
"action": "create",
|
|
24
|
+
"title": "...",
|
|
25
|
+
"whatWhy": "...",
|
|
26
|
+
"acceptanceCriteria": ["..."],
|
|
27
|
+
"outOfScope": ["..."],
|
|
28
|
+
"blockedBy": ["SOURCE-123"],
|
|
29
|
+
"observations": [{"build": "slug", "seq": 12}]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Every claimed `{build, seq}` must appear exactly once. Cluster occurrences
|
|
36
|
+
only when they describe the same underlying problem. A `create` must be a
|
|
37
|
+
useful spec: what/why rather than implementation, verifiable criteria, and
|
|
38
|
+
explicit scope exclusions. `blockedBy` is optional. Filing automatically
|
|
39
|
+
blocks a create on every unresolved, same-source originating ticket of its
|
|
40
|
+
clustered observations, using fresh lifecycle state; do not restate that
|
|
41
|
+
automatic dependency in `blockedBy` to make it take effect. When evidence
|
|
42
|
+
establishes some other ticket as a hard prerequisite, include that ticket's
|
|
43
|
+
source-local id in `blockedBy` as well as explaining it in the spec.
|
|
44
|
+
Contextual citations, related work, and nonbinding sequencing preferences
|
|
45
|
+
such as “do this later” are not blockers. Never invent an id or turn every
|
|
46
|
+
ticket mention into a dependency.
|
|
47
|
+
|
|
48
|
+
You may instead use a known prior proposal from `.ab/ledger.json`:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{"action":"join","ticket":{"source":"...","id":"..."},"reason":"...","observations":[...]}
|
|
52
|
+
{"action":"suppress","reason":"...","observations":[...]}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Join only an existing unresolved ticket supplied by the ledger. Suppress a
|
|
56
|
+
duplicate whose ledger ticket is resolved/missing, or a record that cannot
|
|
57
|
+
support actionable work. Never invent a ticket reference.
|
|
58
|
+
3. Finish exactly once:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
ab harvest submit .ab/proposals.json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Do not call the TicketSource, edit tracker files, dispatch a build, push, or
|
|
65
|
+
infer state from your own stdout. If evidence is weak, preserve that limitation
|
|
66
|
+
in acceptance criteria rather than inventing facts.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harvest-review
|
|
3
|
+
description: Fresh adversarial review of one harvest proposal set. Invoked only by the harvest runner.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ab-harvest-review <run>
|
|
7
|
+
|
|
8
|
+
You are the fresh skeptic in the observation-harvest convergence loop. You do
|
|
9
|
+
not author proposals or touch tickets.
|
|
10
|
+
|
|
11
|
+
1. Run `ab harvest context`.
|
|
12
|
+
2. Review `.ab/proposals.json` against `.ab/observations.json`,
|
|
13
|
+
`.ab/originating-tickets.json`, `.ab/ledger.json`, and every prior
|
|
14
|
+
`history/findings-r*.json` file. Origin lifecycle is scan-time context;
|
|
15
|
+
deterministic filing refreshes matching refs before create.
|
|
16
|
+
3. Check all of the following:
|
|
17
|
+
- every claimed `{build, seq}` occurs exactly once;
|
|
18
|
+
- clusters describe one underlying problem rather than superficial keyword
|
|
19
|
+
overlap;
|
|
20
|
+
- create proposals meet the spec standard (what/why, verifiable acceptance
|
|
21
|
+
criteria, explicit out-of-scope, evidence-supported claims);
|
|
22
|
+
- filing automatically blocks a create on unresolved, same-source
|
|
23
|
+
originating tickets for its clustered observations; neither producer nor
|
|
24
|
+
reviewer must restate that originating dependency in `blockedBy` for it to
|
|
25
|
+
take effect;
|
|
26
|
+
- evidence-supported prose saying some other ticket must complete before work
|
|
27
|
+
can start has the same source-local id in `blockedBy`; a prose-only hard
|
|
28
|
+
prerequisite is not approvable;
|
|
29
|
+
- every `blockedBy` id is justified by evidence as a hard start gate;
|
|
30
|
+
contextual citations, related work, and nonbinding preferences such as
|
|
31
|
+
“do this later” must not become blockers, and ticket ids are never invented;
|
|
32
|
+
- joins name only an unresolved ledger proposal and resolved/missing ledger
|
|
33
|
+
tickets are tombstones, not recreated work;
|
|
34
|
+
- suppression has a concrete evidence-backed reason;
|
|
35
|
+
- no proposal asks harvest to groom, ready, claim, or dispatch anything.
|
|
36
|
+
4. Write review notes to `.ab/harvest-review.md`, then finish exactly once:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
ab harvest verdict approve --notes .ab/harvest-review.md
|
|
40
|
+
ab harvest verdict revise --notes .ab/harvest-review.md --findings .ab/findings.json
|
|
41
|
+
ab harvest verdict escalate --notes .ab/harvest-review.md --reason "the human question"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Use `escalate` only when evidence or product intent requires human judgment,
|
|
45
|
+
not as a substitute for a precise revision finding.
|
|
46
|
+
|
|
47
|
+
## Writing findings
|
|
48
|
+
|
|
49
|
+
For `revise`, `.ab/findings.json` is an array of the normal finding drafts:
|
|
50
|
+
`severity`, `summary`, optional `detail`, and `persists` containing ids from
|
|
51
|
+
prior harvest review rounds. The work under review is this round's proposal
|
|
52
|
+
set.
|
|
53
|
+
|
|
54
|
+
`persists` means the defect a prior finding named is still present in the
|
|
55
|
+
work under review — not that a new problem falls in the same category as
|
|
56
|
+
one already fixed. Test it that way: if the exact defect the prior finding
|
|
57
|
+
named is gone, the chain ends there, however closely your new finding
|
|
58
|
+
resembles it. A new instance of a defect class whose reported instance was
|
|
59
|
+
fixed is fresh work and starts its own chain — raise it with no `persists`
|
|
60
|
+
link. Mark honestly in both directions: neither re-litigate a resolved
|
|
61
|
+
finding nor let a dodged one look fresh, because the kernel mechanically
|
|
62
|
+
escalates a chain that persists too long, and a stalemate is the only
|
|
63
|
+
thing that counter can usefully measure.
|