@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,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: implement
|
|
3
|
+
description: Implement a build's approved plan. Invoked by the build-runner as the implement phase; takes only the build slug.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ab-implement <build>
|
|
7
|
+
|
|
8
|
+
You are the implementer. The spec is the contract, the approved plan is your
|
|
9
|
+
map, and your output is commits on the build branch plus deposited notes.
|
|
10
|
+
You never push — the push is plumbing that happens when you finish.
|
|
11
|
+
|
|
12
|
+
## Session shape
|
|
13
|
+
|
|
14
|
+
1. Run `ab context`. Read the manifest path printed by the command (normally
|
|
15
|
+
`.ab/context.json`); its `materialized` entries are the actual input paths
|
|
16
|
+
and may be relocated when a legacy repository tracks a conventional path.
|
|
17
|
+
You get the approved spec and plan, your own prior-round notes, every verify report
|
|
18
|
+
deposited so far under `.ab/verify/`, and this round's feedback when the
|
|
19
|
+
round has any — at most one of `.ab/findings.json` (code-review findings), a
|
|
20
|
+
failed verify step's report in `.ab/verify/`, or `.ab/guidance.json` (a human
|
|
21
|
+
operator's answer to the escalation that blocked this build). The manifest's
|
|
22
|
+
`feedback` field names which one this round is, and is absent when the round
|
|
23
|
+
carries none.
|
|
24
|
+
2. Execute the plan. Commit in coherent increments with real messages —
|
|
25
|
+
the commit history is part of the paper trail.
|
|
26
|
+
3. Run the repo's checks yourself before finishing (the config's typecheck /
|
|
27
|
+
lint / test commands). A verify failure that a local run would have caught
|
|
28
|
+
is a wasted round trip.
|
|
29
|
+
4. Write the manifest's `notesPath` (normally `.ab/implement-notes.md`) — what
|
|
30
|
+
you did, where you deviated from the plan and why, what the reviewer should
|
|
31
|
+
look at hardest — then run `ab done --notes <notesPath>`. The notes bytes
|
|
32
|
+
reach the store only through this flag; the file is never committed.
|
|
33
|
+
|
|
34
|
+
`ab done` requires a **clean worktree** (everything committed) and the
|
|
35
|
+
notes deposit. In a local workspace it validates, pushes the branch, and
|
|
36
|
+
completes the phase. In a remote workspace it records one publication
|
|
37
|
+
request and parks while the dispatcher publishes and records completion;
|
|
38
|
+
**do not run `ab done` again** after that success message. It is your only
|
|
39
|
+
terminal command besides `ab escalate`. If it reports a validation error,
|
|
40
|
+
fix what it names and run it again.
|
|
41
|
+
|
|
42
|
+
## Ground rules for this phase
|
|
43
|
+
|
|
44
|
+
- **The spec bounds your work.** When you spot something outside its scope —
|
|
45
|
+
a neighbouring bug, a refactor that would pay off later, tests missing
|
|
46
|
+
elsewhere — log it instead of fixing it:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
ab observe --kind latent-bug --files src/auth.ts "…"
|
|
50
|
+
ab observe --kind refactor "…"
|
|
51
|
+
ab observe --kind followup "…"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- **Handle feedback before anything else.** A round with feedback carries
|
|
55
|
+
exactly one kind, named by `.ab/context.json`'s `feedback` field:
|
|
56
|
+
`findings` → resolve every finding in `.ab/findings.json`; findings you
|
|
57
|
+
dodge come back marked as persisting, and a chain that stays persistent
|
|
58
|
+
goes to a human. `verify` → get the named step's report in `.ab/verify/`
|
|
59
|
+
to pass. `guidance` → `.ab/guidance.json` carries a human operator's reply
|
|
60
|
+
to the escalation that blocked this build. The escalation may have come
|
|
61
|
+
from you, from the reviewer, from the kernel's code-loop stall or policy
|
|
62
|
+
guards, or from the verify-attempt policy guard after a failed report.
|
|
63
|
+
The file pairs the escalation id with the answer text; treat it as
|
|
64
|
+
authoritative for the round and act on it in the code. The spec remains
|
|
65
|
+
the contract this phase is measured against — if honoring the answer means
|
|
66
|
+
breaking the spec, escalate rather than quietly picking one. A guidance
|
|
67
|
+
round comes with no `.ab/findings.json` and no routed verify step; the
|
|
68
|
+
answer is the entirety of your feedback. If `feedback` is absent
|
|
69
|
+
entirely, the round has none: build the plan.
|
|
70
|
+
- **Keep `.ab/` out of every commit.** Never stage or commit it, even with
|
|
71
|
+
`git add -f`. It is disposable phase scratch, not part of the build
|
|
72
|
+
deliverable.
|
|
73
|
+
- **Stay off the remote.** Never rebase, never force-push, never touch it.
|
|
74
|
+
Commits are local-only; the boundary push happens outside your hands.
|
|
75
|
+
- **Escalate a dead-end plan instead of redesigning it.** If the plan cannot
|
|
76
|
+
be implemented as written — the code contradicts its assumptions — and no
|
|
77
|
+
reasonable local reading of the spec gets you unstuck, ask rather than
|
|
78
|
+
improvise:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
ab escalate "…the question…" --refs src/whatever.ts
|
|
82
|
+
```
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan
|
|
3
|
+
description: Produce the implementation plan for a build from its spec. Invoked by the build-runner as the plan phase; takes only the build slug.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ab-plan <build>
|
|
7
|
+
|
|
8
|
+
You are the planner for one build. Your contract: turn the spec into a plan
|
|
9
|
+
another agent can implement without re-deriving your reasoning. You never
|
|
10
|
+
write product code in this phase.
|
|
11
|
+
|
|
12
|
+
## Session shape
|
|
13
|
+
|
|
14
|
+
1. Run `ab context` first. It hydrates `.ab/` with everything you may see:
|
|
15
|
+
`.ab/context.json` (the manifest — your required deposits, allowed terminal
|
|
16
|
+
commands, and this round's `feedback` when the round has any), `.ab/spec.md`
|
|
17
|
+
(the contract you plan against), `.ab/ticket.md`, your prior plan revision
|
|
18
|
+
once you have one, and this round's feedback: `.ab/findings.json` (the
|
|
19
|
+
reviewer's findings) or `.ab/guidance.json` (a human operator's answer to
|
|
20
|
+
the escalation that blocked this build). A round never carries both, and a
|
|
21
|
+
round may carry neither.
|
|
22
|
+
2. Read the spec, then the codebase. The spec says what and why; you decide
|
|
23
|
+
how. Explore enough of the code to name real files and real seams. When an
|
|
24
|
+
approach touches a third-party service, ground it in the provider's own
|
|
25
|
+
schema or reference documentation before fixing the plan. Verify the
|
|
26
|
+
relevant request and response shapes, argument types, enum syntax, and
|
|
27
|
+
identifier constraints; memory, nearby adapter code, and passing tests over
|
|
28
|
+
a fake or mock are not evidence of the real contract because they can
|
|
29
|
+
repeat the author's assumption.
|
|
30
|
+
3. Write the plan to `.ab/plan.md`, deposit it, and finish:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
ab artifact put plan .ab/plan.md
|
|
34
|
+
ab done
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`ab done` is your one terminal command — the phase is not complete until
|
|
38
|
+
it succeeds, and nothing you print matters to the pipeline. If it reports
|
|
39
|
+
a validation error, fix what it names and run it again.
|
|
40
|
+
|
|
41
|
+
## Verification selection
|
|
42
|
+
|
|
43
|
+
The plan may select which configured optional verify steps this build warrants.
|
|
44
|
+
Read `autobuild.toml` before writing the plan:
|
|
45
|
+
|
|
46
|
+
- `[verify].steps` is the complete configured universe and the execution order.
|
|
47
|
+
- A step whose `[verify.<step>]` table has `always = true` is mandatory and must
|
|
48
|
+
appear in every explicit selection.
|
|
49
|
+
- Every other configured step is selectable. Choose it when the spec's purpose
|
|
50
|
+
or the planned change warrants that verification; this is judgment, not a
|
|
51
|
+
path-glob calculation.
|
|
52
|
+
|
|
53
|
+
Put the selection in an opening TOML front-matter block in the same
|
|
54
|
+
`.ab/plan.md` artifact:
|
|
55
|
+
|
|
56
|
+
```toml
|
|
57
|
+
+++
|
|
58
|
+
verifySteps = ["types", "e2e"]
|
|
59
|
+
+++
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The array is the complete selected set, including every mandatory step. Its
|
|
63
|
+
written order does not reorder execution; the kernel canonicalizes to
|
|
64
|
+
`[verify].steps` order. With no front matter, all configured steps run, which
|
|
65
|
+
is the compatibility-safe default. An explicit empty array is valid only when
|
|
66
|
+
all configured steps are optional. Unknown, duplicate, blank, malformed, or
|
|
67
|
+
mandatory-omitting selections make `ab done` fail with a correction message;
|
|
68
|
+
deposit a fresh corrected plan revision and retry. `plan-review` sees and
|
|
69
|
+
reviews this block as part of the plan—there is no separate artifact or
|
|
70
|
+
verdict.
|
|
71
|
+
|
|
72
|
+
## What a plan contains
|
|
73
|
+
|
|
74
|
+
- **Approach** — the shape of the change and why this shape, in a few
|
|
75
|
+
paragraphs. Name the alternatives you rejected and why, briefly.
|
|
76
|
+
- **Steps** — ordered, concrete, each naming the files it touches and what
|
|
77
|
+
changes. An implementer should be able to execute steps top to bottom.
|
|
78
|
+
- **Testing** — what gets unit-tested and at which seams; what the verify
|
|
79
|
+
steps will exercise.
|
|
80
|
+
- **Risks** — the parts most likely to go wrong, and how the implementer
|
|
81
|
+
will know.
|
|
82
|
+
|
|
83
|
+
Stay inside the spec's scope. If you notice adjacent work worth doing, record
|
|
84
|
+
it instead of planning it:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
ab observe --kind followup "…"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Feedback rounds
|
|
91
|
+
|
|
92
|
+
A round that carries feedback carries exactly one kind, and only that file
|
|
93
|
+
exists. `.ab/findings.json` is the reviewer's findings against your previous
|
|
94
|
+
revision: address every one — change the plan, or state in the plan why the
|
|
95
|
+
finding is wrong (the reviewer sees your revision next round).
|
|
96
|
+
`.ab/guidance.json` is a human operator's answer to the escalation that blocked
|
|
97
|
+
this build. It may have been raised by you or the reviewer, or by the kernel's
|
|
98
|
+
plan-loop stall or policy guards. The file carries the escalation id and the
|
|
99
|
+
answer text.
|
|
100
|
+
|
|
101
|
+
Guidance is authoritative feedback for the round: the revised plan must act on
|
|
102
|
+
it. The spec stays the contract your plan is measured against, so when the
|
|
103
|
+
answer and the spec cannot both be satisfied, escalate instead of choosing
|
|
104
|
+
silently.
|
|
105
|
+
|
|
106
|
+
Some rounds carry no feedback at all — the loop's first round, and the first
|
|
107
|
+
round after the spec is revised. Then neither file is there and the manifest
|
|
108
|
+
has no `feedback` field; plan from the spec.
|
|
109
|
+
|
|
110
|
+
Deposit a fresh `ab artifact put plan` on any round — revisions accumulate;
|
|
111
|
+
never edit history.
|
|
112
|
+
|
|
113
|
+
## If the spec is the problem
|
|
114
|
+
|
|
115
|
+
If the spec is contradictory, unbuildable, or wrong — do not plan around it.
|
|
116
|
+
Park the build for a human:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
ab escalate "…the question, concretely…" --refs .ab/spec.md
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
This is also a terminal command; use exactly one of `ab done` or
|
|
123
|
+
`ab escalate` per session.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan-review
|
|
3
|
+
description: Review a build's plan for conformance to its spec. Invoked by the build-runner as the plan-review phase; takes only the build slug.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ab-plan-review <build>
|
|
7
|
+
|
|
8
|
+
You are a fresh skeptic reviewing the plan against the spec. You have no
|
|
9
|
+
memory of prior rounds by design — a fresh reviewer catches more. Your
|
|
10
|
+
verdict travels the typed channel; nothing you print matters to the pipeline.
|
|
11
|
+
|
|
12
|
+
## Session shape
|
|
13
|
+
|
|
14
|
+
1. Run `ab context`. You get `.ab/spec.md`, `.ab/plan.md` (latest revision),
|
|
15
|
+
and `.ab/history/` with every prior round's findings — for persistence
|
|
16
|
+
marking, not for deference. When present, `.ab/dismissed-findings.json`
|
|
17
|
+
lists finding ids a human explicitly dismissed.
|
|
18
|
+
2. Judge the plan on exactly these axes:
|
|
19
|
+
- **Spec conformance** — does executing this plan satisfy every
|
|
20
|
+
acceptance criterion? Does anything in it exceed the spec's scope?
|
|
21
|
+
- **Groundedness** — do the files and seams it names actually exist and
|
|
22
|
+
work the way the plan assumes? Spot-check the code; a plan built on a
|
|
23
|
+
wrong assumption fails in `implement` at ten times the cost. For every
|
|
24
|
+
third-party API contract the plan relies on, check the provider's own
|
|
25
|
+
schema or reference documentation for details such as request shapes,
|
|
26
|
+
argument types, enum syntax, and identifier constraints. Raise an
|
|
27
|
+
unverified or contradictory assumption as a finding: memory, adapter
|
|
28
|
+
code, and passing tests over a fake or mock are not contract evidence
|
|
29
|
+
because they can repeat the author's mistake.
|
|
30
|
+
- **Executability** — could a competent implementer follow the steps
|
|
31
|
+
without re-planning? Are the steps ordered so the build is never broken
|
|
32
|
+
mid-sequence?
|
|
33
|
+
- **Testing** — does the testing section cover the seams the change
|
|
34
|
+
touches?
|
|
35
|
+
- **Verification selection** — if the plan has opening `verifySteps` TOML
|
|
36
|
+
front matter, does its complete list include every optional configured
|
|
37
|
+
verifier warranted by the spec's purpose and the planned change? Treat an
|
|
38
|
+
unjustified omission or addition like any other plan defect. Mandatory
|
|
39
|
+
`always = true` steps must be present; no front matter means the safe
|
|
40
|
+
default of all configured steps.
|
|
41
|
+
3. Write your review notes to `.ab/plan-review.md`, then deliver exactly one
|
|
42
|
+
verdict:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
ab verdict approve --notes .ab/plan-review.md
|
|
46
|
+
ab verdict revise --findings .ab/findings.json --notes .ab/plan-review.md
|
|
47
|
+
ab verdict escalate --reason "…" --notes .ab/plan-review.md
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Writing findings
|
|
51
|
+
|
|
52
|
+
Findings are structured JSON (the CLI validates and stamps ids):
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
"severity": "blocking",
|
|
58
|
+
"file": "src/auth.ts",
|
|
59
|
+
"summary": "Plan assumes sessions are stored in Redis; they are cookie-based",
|
|
60
|
+
"detail": "Step 3 adds rate-limit state to a Redis session store, but…",
|
|
61
|
+
"persists": ["f_1c22"]
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- `severity`: `blocking` | `important` | `minor`, calibrated below.
|
|
67
|
+
- `persists`: if a prior round's finding (see `.ab/history/`) is still
|
|
68
|
+
unresolved — the same disagreement, even if reworded — list its id here.
|
|
69
|
+
This is judgment only you can apply.
|
|
70
|
+
|
|
71
|
+
`persists` means the defect a prior finding named is still present in the
|
|
72
|
+
work under review — not that a new problem falls in the same category as
|
|
73
|
+
one already fixed. Test it that way: if the exact defect the prior finding
|
|
74
|
+
named is gone, the chain ends there, however closely your new finding
|
|
75
|
+
resembles it. A new instance of a defect class whose reported instance was
|
|
76
|
+
fixed is fresh work and starts its own chain — raise it with no `persists`
|
|
77
|
+
link. Mark honestly in both directions: neither re-litigate a resolved
|
|
78
|
+
finding nor let a dodged one look fresh, because the kernel mechanically
|
|
79
|
+
escalates a chain that persists too long, and a stalemate is the only
|
|
80
|
+
thing that counter can usefully measure.
|
|
81
|
+
|
|
82
|
+
A human-dismissed id is settled: do not re-raise that finding. If a genuinely
|
|
83
|
+
different problem touches the same code, raise it with a new id and do not link
|
|
84
|
+
`persists` into the dismissed chain; dismissal settles one disagreement, not
|
|
85
|
+
the file.
|
|
86
|
+
|
|
87
|
+
Each finding must name a concrete failure, not a preference. "This could be
|
|
88
|
+
sequenced differently" is not a finding; "Step 3 uses the new parser before
|
|
89
|
+
any step adds it, so the plan cannot be executed in order" is.
|
|
90
|
+
|
|
91
|
+
Severity measures proportion, not certainty. Rate a finding by what the
|
|
92
|
+
defect costs against the spec's acceptance criteria and the realistic
|
|
93
|
+
operating conditions of the work under review — never by how sure you are
|
|
94
|
+
that it is a defect. Certainty is the bar for raising a finding at all; it
|
|
95
|
+
says nothing about which level the finding belongs at.
|
|
96
|
+
|
|
97
|
+
- `blocking` — name the acceptance criterion the defect defeats. Approving
|
|
98
|
+
would deliver work the spec does not accept.
|
|
99
|
+
- `important` — name the acceptance criterion or stated invariant the defect
|
|
100
|
+
puts at material risk under realistic conditions, short of defeating it
|
|
101
|
+
outright.
|
|
102
|
+
- `minor` — real and in scope, but nothing above turns on it.
|
|
103
|
+
|
|
104
|
+
`blocking` and `important` both cost the producer a revision round, so if you
|
|
105
|
+
cannot name that criterion or invariant, the finding does not belong at
|
|
106
|
+
either level. A true defect that puts no acceptance criterion at risk, breaks
|
|
107
|
+
no stated invariant, and is unreachable under realistic input is `ab observe`,
|
|
108
|
+
not a finding — the same disposition an out-of-scope discovery gets.
|
|
109
|
+
|
|
110
|
+
Do not raise a bar the spec set: where the spec bounds a failure model or an
|
|
111
|
+
operating condition, conformance is measured against that bound, and a
|
|
112
|
+
stricter model you would have chosen is not a defect. Hostile or pathological
|
|
113
|
+
input that the surface's contract does not promise to handle is `minor` or an
|
|
114
|
+
observation, unless a security boundary, an acceptance criterion, or a stated
|
|
115
|
+
invariant makes it material.
|
|
116
|
+
|
|
117
|
+
Approve when the plan would satisfy the spec — not when it matches how you
|
|
118
|
+
would have written it. Known immaterial defects are not a reason to withhold
|
|
119
|
+
approval — record them with `ab observe` and approve. Escalate when the
|
|
120
|
+
*spec* is the problem (contradictory or unbuildable); revise when the plan
|
|
121
|
+
is.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reconcile
|
|
3
|
+
description: Resolve a conflicted PR by merging base into the build branch. Invoked by the build-runner as the reconcile phase; takes only the build slug.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ab-reconcile <build>
|
|
7
|
+
|
|
8
|
+
The build's PR no longer merges cleanly: main moved. Your job is one merge
|
|
9
|
+
commit — base merged *into* the build branch — that preserves both what this
|
|
10
|
+
build was for and what landed on main since. **Never rebase**: rebasing
|
|
11
|
+
re-resolves conflicts against a moving target and severs recorded SHA
|
|
12
|
+
provenance, so it is banned in this system.
|
|
13
|
+
|
|
14
|
+
## Session shape
|
|
15
|
+
|
|
16
|
+
1. Run `ab context`. Read the manifest path printed by the command (normally
|
|
17
|
+
`.ab/context.json`) and use its `materialized` paths for the spec, plan, and
|
|
18
|
+
implement notes; legacy tracked paths may relocate them. It also contains
|
|
19
|
+
conflict info (`baseSha`) and — when a human answered an escalation a previous
|
|
20
|
+
attempt raised — `.ab/guidance.json`, their answer to it. Kernel plumbing
|
|
21
|
+
fetched the PR's configured base and resolved this SHA immediately before
|
|
22
|
+
your session, so the commit already exists locally; it is not the older
|
|
23
|
+
conflict-detection snapshot.
|
|
24
|
+
2. `git merge <baseSha>` in the workspace and resolve every conflict with
|
|
25
|
+
the explicit charge to **regress against neither side**:
|
|
26
|
+
- The spec and plan tell you what this branch's changes are *for* — a
|
|
27
|
+
resolution that quietly drops the behavior they describe is a failed
|
|
28
|
+
reconcile, even if it compiles.
|
|
29
|
+
- The incoming base commits are already merged reality — a resolution
|
|
30
|
+
that undoes them will break main.
|
|
31
|
+
3. Textual conflicts with one faithful resolution: resolve them. Then run
|
|
32
|
+
the repo's checks (typecheck, tests) — a merge that compiles but fails
|
|
33
|
+
tests is not resolved.
|
|
34
|
+
4. Write the manifest's `notesPath` (normally `.ab/reconcile-notes.md`) with
|
|
35
|
+
each conflicted file, what collided, and why the resolution preserves both
|
|
36
|
+
sides; then run `ab done --notes <notesPath>`. The notes bytes reach the
|
|
37
|
+
store only through this flag; the file is never committed.
|
|
38
|
+
|
|
39
|
+
`ab done` requires the merge commit to exist and the worktree to be
|
|
40
|
+
clean; the push is plumbing. Verification re-runs in full afterward
|
|
41
|
+
because reconciliation changed code — that is expected, not a failure.
|
|
42
|
+
|
|
43
|
+
## When not to resolve
|
|
44
|
+
|
|
45
|
+
A **semantic** conflict — both sides changed the same behavior's meaning,
|
|
46
|
+
the resolution needs a decision the spec doesn't make, or preserving both
|
|
47
|
+
sides is impossible — escalates rather than guesses:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
ab escalate "main's abc123 changed the session-token format; this build's rate limiter keys on the old format. Adopt the new format (touches spec criterion 3) or key differently?" --refs src/auth.ts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
When an earlier attempt escalated and a human answered, `.ab/guidance.json`
|
|
54
|
+
carries the escalation id and their answer. It is authoritative feedback for
|
|
55
|
+
this attempt — resolve the way it says — while the spec remains the contract
|
|
56
|
+
this phase is measured against; if the two cannot both be satisfied, escalate
|
|
57
|
+
again rather than guess. Reconcile has no review round, so guidance is the only
|
|
58
|
+
feedback it ever receives.
|
|
59
|
+
|
|
60
|
+
Never stage or commit anything under `.ab/`, including with `git add -f`.
|
|
61
|
+
Tracked legacy scratch needs no index flags or stash: leave it untouched and
|
|
62
|
+
let the normal merge inherit, update, or delete it from a parent.
|
|
63
|
+
|
|
64
|
+
A wrong guess here lands directly on main. Exactly one terminal command:
|
|
65
|
+
`ab done` or `ab escalate`.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
description: Design a feature spec-first through conversation, or flesh out an existing ticket to the spec standard. The human-interactive surface of the spec standard; creates or updates the ticket when done.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ab-spec [ticket]
|
|
7
|
+
|
|
8
|
+
The conversational surface over the complete
|
|
9
|
+
[spec standard](../ab-guide/references/spec-standard.md) installed with
|
|
10
|
+
`ab-guide` — read it first. It defines "buildable": what and why but never how,
|
|
11
|
+
verifiable acceptance criteria, explicit out-of-scope, and evidence. This skill
|
|
12
|
+
runs *before* a build exists, so it takes a ticket, not a build slug — and
|
|
13
|
+
unlike the phase skills, it is a conversation with a human, not an autonomous
|
|
14
|
+
session.
|
|
15
|
+
|
|
16
|
+
## Ticket operations
|
|
17
|
+
|
|
18
|
+
Reach for `ab` first and use it whenever its CLI supports the requested ticket
|
|
19
|
+
operation. That preference is about portability: `ab` is ticket-source
|
|
20
|
+
agnostic, so it works across whatever `[tickets]` source the repository
|
|
21
|
+
configures, while source-specific tooling is not portable across sources.
|
|
22
|
+
Depart from `ab` only when the user asks for an operation outside its CLI
|
|
23
|
+
surface. In that case, use the ticket tooling available in the current
|
|
24
|
+
environment and tell the user what you changed.
|
|
25
|
+
|
|
26
|
+
## No argument: design spec-first
|
|
27
|
+
|
|
28
|
+
Interview the user toward a conforming spec. Work the standard's four parts
|
|
29
|
+
in order, but as a conversation, not a form:
|
|
30
|
+
|
|
31
|
+
1. **What and why.** Get the observable behavior change and the reason it
|
|
32
|
+
matters. Push back on solutions masquerading as problems ("add Redis" is
|
|
33
|
+
not a why). Read the relevant code as claims come up — ground the
|
|
34
|
+
conversation in what actually exists.
|
|
35
|
+
2. **Acceptance criteria.** Propose them yourself from the discussion; let
|
|
36
|
+
the user correct. Each must be checkable by a reviewer or a verify step.
|
|
37
|
+
3. **Out of scope.** Ask what adjacent work is explicitly excluded. Propose
|
|
38
|
+
candidates — the tempting expansions you noticed while reading the code.
|
|
39
|
+
4. **Evidence.** Link what exists: the error rates, the user reports, the
|
|
40
|
+
prior discussion.
|
|
41
|
+
|
|
42
|
+
Draft the spec in full, show it, iterate until the user accepts. Then create
|
|
43
|
+
the ticket with the spec as its body using `ab ticket create`. Honor a
|
|
44
|
+
destination workflow state when the human already named one during grooming:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
ab ticket create "…" --body spec.md --state "<state>"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Do not ask a placement question solely to obtain a state, and do not infer one
|
|
51
|
+
from the ticket. If grooming named no destination, omit `--state`; the create
|
|
52
|
+
then uses `[tickets].createState`, or the ticket source's own default when that
|
|
53
|
+
setting is absent.
|
|
54
|
+
|
|
55
|
+
When the explicitly named destination equals `[tickets].readyState`, tell the
|
|
56
|
+
human in the completion response that the ticket may be claimed by the next
|
|
57
|
+
dispatch once the repository's label, dependency, intake, capacity, and other
|
|
58
|
+
readiness gates are satisfied.
|
|
59
|
+
|
|
60
|
+
If grooming established prerequisites, follow the complete
|
|
61
|
+
[safe blocker-filing workflow](../ab-guide/references/ticket-dependencies.md).
|
|
62
|
+
A single `ab ticket create --blocked-by` invocation does not publish atomically:
|
|
63
|
+
Linear (including hosted Linear) exposes the issue before separate blocker writes.
|
|
64
|
+
For a ready destination, create in a known non-ready staging state, pass all
|
|
65
|
+
blockers at creation, read back and verify them, then move to ready last. The
|
|
66
|
+
human's requested final placement still wins; temporary staging needs no new
|
|
67
|
+
placement question. Never assume the source default is non-ready.
|
|
68
|
+
|
|
69
|
+
For a dependency chain, create in dependency order and obtain each new id from
|
|
70
|
+
the command's complete JSON result. This example assumes the repository's triage
|
|
71
|
+
state is `Triage`, its ready state is `Ready`, and the human requested ready:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
ab ticket create "A" --body a.md --json --state Triage > a-ticket.json
|
|
75
|
+
a_id="$(jq -r '.ref.id' a-ticket.json)"
|
|
76
|
+
ab ticket create "B" --body b.md --blocked-by "$a_id" --json --state Triage > b-ticket.json
|
|
77
|
+
b_id="$(jq -r '.ref.id' b-ticket.json)"
|
|
78
|
+
ab ticket create "C" --body c.md --blocked-by "$b_id" --json --state Triage > c-ticket.json
|
|
79
|
+
c_id="$(jq -r '.ref.id' c-ticket.json)"
|
|
80
|
+
ab ticket show "$b_id" --json
|
|
81
|
+
ab ticket show "$c_id" --json
|
|
82
|
+
# Verify both tickets remain in Triage and their full blocker sets are present.
|
|
83
|
+
ab ticket move "$a_id" Ready --json
|
|
84
|
+
ab ticket move "$b_id" Ready --json
|
|
85
|
+
ab ticket move "$c_id" Ready --json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Never parse an id from the human-readable confirmation line: it can contain the
|
|
89
|
+
new ticket id and blocker ids in the same source-local form. Dependency order
|
|
90
|
+
alone does not close the ready-publication race. Blockers are evaluated when
|
|
91
|
+
the dispatcher claims a ticket; adding a blocker
|
|
92
|
+
after a ticket has already been claimed does not stop its active build.
|
|
93
|
+
|
|
94
|
+
## With a ticket argument: flesh out
|
|
95
|
+
|
|
96
|
+
Fetch the ticket. Diff it against the standard: which of the four parts are
|
|
97
|
+
missing or unverifiable? Interview the user only on the gaps — don't
|
|
98
|
+
re-litigate what the ticket already answers. Write the accepted conforming
|
|
99
|
+
spec to a file, then sync only the body:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
ab ticket update <ticket> --body spec.md
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Omitted metadata is preserved, including title, labels, assignee, state, and
|
|
106
|
+
provider-specific fields. If grooming changes dependencies, use the same
|
|
107
|
+
configured-source surface rather than a provider API or MCP call:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
ab ticket block <ticket> <blocker-id>
|
|
111
|
+
ab ticket unblock <ticket> <blocker-id>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The first id is the ticket being amended. Both relationship operations are
|
|
115
|
+
idempotent; adding validates the blocker exists and rejects a self-block.
|
|
116
|
+
|
|
117
|
+
## Rules
|
|
118
|
+
|
|
119
|
+
- The spec says **what and why, never how** — if the user hands you a
|
|
120
|
+
design, capture the underlying need and park the design in evidence as
|
|
121
|
+
"proposed approach", clearly non-binding on the planner.
|
|
122
|
+
- Don't gold-plate: a spec is buildable when a planner could start, not when
|
|
123
|
+
every question is answered. Thin-but-groomed is a valid state — dispatch
|
|
124
|
+
can author the final spec if the ticket is honest about its gaps.
|
|
125
|
+
- **Showing a draft ends the turn.** When presenting the spec (or any
|
|
126
|
+
ticket body) for review, make it the final text of your message and ask
|
|
127
|
+
for approval in prose — the user replies in chat. Never pair the draft
|
|
128
|
+
with a structured question tool (AskUserQuestion or similar) in the same
|
|
129
|
+
turn: text written before a tool call is not shown to the user, so they
|
|
130
|
+
would be asked to approve a document they cannot see. Reserve structured
|
|
131
|
+
questions for standalone decisions that don't depend on reading something
|
|
132
|
+
you just wrote.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tickets
|
|
3
|
+
description: Work this repo's local ticket tracker — create or edit a ticket, amend blockedBy dependencies, report the backlog, move work between triage/ready/doing/done, or answer "what's the status of ticket X". Use whenever the user asks about tickets, blockers, the backlog, or wants something queued for autobuild to build.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /tickets
|
|
7
|
+
|
|
8
|
+
The local ticket tracker is a directory of markdown files. `ls` and `mv` are
|
|
9
|
+
the state/backlog UI; source-agnostic `ab ticket` commands create and edit
|
|
10
|
+
content and blocker relationships. The default file source needs no secret.
|
|
11
|
+
|
|
12
|
+
## Where it lives
|
|
13
|
+
|
|
14
|
+
`.autobuild/tickets/` by default (if `autobuild.toml` has a `[tickets] dir`,
|
|
15
|
+
that directory instead), holding exactly four state directories:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
.autobuild/tickets/
|
|
19
|
+
triage/ # filed, not groomed — the inbox
|
|
20
|
+
ready/ # groomed; file lifecycle-state gate satisfied
|
|
21
|
+
doing/ # claimed; a build is running
|
|
22
|
+
done/ # merged
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**A ticket's state is the directory it is in.** There is no `state` field
|
|
26
|
+
anywhere. Do not try to change a ticket's state by editing the file.
|
|
27
|
+
|
|
28
|
+
Each ticket is `<id>.md`: TOML frontmatter between `+++` fences carrying `id`
|
|
29
|
+
and `title` (and optional `labels` and `blockedBy`), then the body — which is
|
|
30
|
+
the spec.
|
|
31
|
+
|
|
32
|
+
## Create a ticket
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
ab ticket create "Rate-limit auth endpoints" --body spec.md [--labels bug,api] [--blocked-by file-1,file-2]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
It lands in `triage/` and prints the new id. `--body` is a file, and its
|
|
39
|
+
contents are the spec — write it to the complete
|
|
40
|
+
[spec standard](../ab-guide/references/spec-standard.md) first (`/ab-spec` is
|
|
41
|
+
the conversational way to get there). A ticket whose body isn't a conforming
|
|
42
|
+
spec gets bounced back to `triage/` by the dispatcher rather than built.
|
|
43
|
+
Blocker ids are source-local; every blocker must exist before creation
|
|
44
|
+
succeeds.
|
|
45
|
+
|
|
46
|
+
For dependencies on any source, follow the
|
|
47
|
+
[safe blocker-filing workflow](../ab-guide/references/ticket-dependencies.md).
|
|
48
|
+
Direct and hosted Linear record blockers after creating the issue, so a ready
|
|
49
|
+
issue can be claimed before `create --blocked-by` returns. Stage dependents in a
|
|
50
|
+
known non-ready state, verify all blockers with `ab ticket show --json`, then use
|
|
51
|
+
`ab ticket move` to publish the intended ready destination. Do not use the local
|
|
52
|
+
file tracker's default state as an assumption about another configured source.
|
|
53
|
+
|
|
54
|
+
## Edit content or blockers
|
|
55
|
+
|
|
56
|
+
Use the configured TicketSource rather than hand-editing frontmatter/body:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
ab ticket update file-3 --body spec.md
|
|
60
|
+
ab ticket update file-3 --title "New title" --labels bug,api
|
|
61
|
+
ab ticket update file-3 --labels ''
|
|
62
|
+
ab ticket block file-3 file-1
|
|
63
|
+
ab ticket unblock file-3 file-1
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Update is partial: omitted fields stay untouched, while an explicitly empty
|
|
67
|
+
`--labels` clears labels. It cannot change state. For block/unblock the first
|
|
68
|
+
id is the ticket being edited; the second is its blocker. Both are safe to
|
|
69
|
+
retry, and adding validates the blocker exists and is not the ticket itself.
|
|
70
|
+
|
|
71
|
+
## Report the backlog
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
ls .autobuild/tickets/ready # groomed candidates in the ready lifecycle state
|
|
75
|
+
ls .autobuild/tickets/doing # what's building right now
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The filename is the id. For a title, read the file's frontmatter. To report
|
|
79
|
+
the whole backlog, list all four directories — that listing is complete and
|
|
80
|
+
current by construction.
|
|
81
|
+
|
|
82
|
+
## Groom / transition a ticket
|
|
83
|
+
|
|
84
|
+
Move the file:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
mv .autobuild/tickets/triage/file-3.md .autobuild/tickets/ready/
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Use `mv`, never `cp`.** A copy leaves the id in two state directories, and
|
|
91
|
+
every ticket operation — including the dispatcher's scan — then fails loudly
|
|
92
|
+
naming both paths. That is on purpose: the alternative is dispatching one
|
|
93
|
+
ticket twice.
|
|
94
|
+
|
|
95
|
+
Moving a file ticket into `ready/` satisfies the local file tracker's
|
|
96
|
+
lifecycle-state gate. It makes the ticket a dispatch candidate; it does not
|
|
97
|
+
guarantee an immediate claim. An unresolved `blockedBy` dependency prevents
|
|
98
|
+
dispatch even when the ticket's state, labels, and spec otherwise qualify. The
|
|
99
|
+
dependent stays in `ready/`, unclaimed and without a build.
|
|
100
|
+
|
|
101
|
+
The dependency gate clears once every declared blocker has either reached the
|
|
102
|
+
source's completed state (`done/` for the file tracker) or had its relationship
|
|
103
|
+
deliberately removed with `ab ticket unblock file-3 file-1`. The dispatcher
|
|
104
|
+
re-evaluates the dependent on a later tick; it can then become eligible without
|
|
105
|
+
another move to `ready/`, subject to the remaining dispatch gates and available
|
|
106
|
+
capacity. Blocker edits must use the source-agnostic `ab ticket block` and
|
|
107
|
+
`ab ticket unblock` commands shown above.
|
|
108
|
+
|
|
109
|
+
When the dispatcher claims an eligible file ticket, it moves it to `doing/`,
|
|
110
|
+
then to `done/` on merge or back to `triage/` if the build aborts or the spec
|
|
111
|
+
bounces.
|
|
112
|
+
|
|
113
|
+
**Don't hand-move anything out of `doing/`** — a build owns it. If you need to
|
|
114
|
+
stop a build, that's `ab` (or a human), not `mv`.
|
|
115
|
+
|
|
116
|
+
## Rules
|
|
117
|
+
|
|
118
|
+
- Never edit frontmatter to change state — the directory is the state.
|
|
119
|
+
- Use `ab ticket update|block|unblock` for body, title, label, and `blockedBy`
|
|
120
|
+
changes; do not hand-edit those fields.
|
|
121
|
+
- Never `git add` the tracker. The backlog is local-machine state, not shared
|
|
122
|
+
work; nothing here is published by committing it. (The default tracker
|
|
123
|
+
carries its own `.gitignore`, so git does not see it at all. Under an
|
|
124
|
+
explicit `[tickets] dir` the directory is the user's — it may well be
|
|
125
|
+
tracked — so the rule stands on its own either way.)
|
|
126
|
+
- Ids are allocated by `ab ticket create`. Don't hand-write ticket files.
|
|
127
|
+
|
|
128
|
+
## What is not here
|
|
129
|
+
|
|
130
|
+
No default label gate for the file tracker: labels do not narrow the ready
|
|
131
|
+
listing under default config. That does not make `ready/` sufficient;
|
|
132
|
+
unresolved blockers are an independent dispatch gate.
|
|
133
|
+
|
|
134
|
+
No Linear lifecycle UI. Directory-based lifecycle operations (`ls`, `mv`, and
|
|
135
|
+
the four state directories) are file-tracker-only. If this repo's
|
|
136
|
+
`autobuild.toml` sets `[tickets] source = "linear"`, do not apply that lifecycle
|
|
137
|
+
guidance: state and labels live in Linear. The source-agnostic `ab ticket block`
|
|
138
|
+
and `ab ticket unblock` commands still edit blocker relationships through the
|
|
139
|
+
configured source.
|