@defrex/autobuild 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/SPEC.md +335 -31
- package/docs/architecture.md +125 -7
- package/docs/configuration.md +142 -21
- package/docs/hosted-dispatcher.md +17 -2
- package/docs/hosted-service.md +240 -0
- package/docs/mcp.md +8 -2
- package/docs/operator-api.md +97 -7
- package/docs/remote-store-protocol.md +199 -144
- package/docs/remote-ticket-protocol.md +249 -19
- package/docs/setup.md +199 -16
- package/docs/ticket-dependencies.md +1 -1
- package/docs/ticket-migration.md +64 -0
- package/package.json +7 -6
- package/packages/core/src/cli/attention.ts +209 -0
- package/packages/core/src/cli/build-control.ts +12 -1
- package/packages/core/src/cli/configured-store.ts +17 -0
- package/packages/core/src/cli/connect.ts +364 -0
- package/packages/core/src/cli/context.ts +7 -1
- package/packages/core/src/cli/dashboard/model.ts +4 -5
- package/packages/core/src/cli/dashboard/poll.ts +1 -1
- package/packages/core/src/cli/dispatch.ts +336 -41
- package/packages/core/src/cli/harvest.ts +13 -3
- package/packages/core/src/cli/help.ts +51 -16
- package/packages/core/src/cli/init-validation.ts +27 -2
- package/packages/core/src/cli/installation.ts +67 -13
- package/packages/core/src/cli/main.ts +60 -16
- package/packages/core/src/cli/mcp.ts +9 -2
- package/packages/core/src/cli/pr-summary-publication.ts +220 -0
- package/packages/core/src/cli/pr-summary.ts +2 -0
- package/packages/core/src/cli/project-credentials.ts +132 -0
- package/packages/core/src/cli/repo-state.ts +15 -2
- package/packages/core/src/cli/self-update.ts +15 -1
- package/packages/core/src/cli/store-opening.ts +22 -14
- package/packages/core/src/cli/terminals.ts +0 -10
- package/packages/core/src/cli/ticket-assets.ts +7 -2
- package/packages/core/src/cli/ticket-editor.ts +82 -0
- package/packages/core/src/cli/ticket.ts +172 -35
- package/packages/core/src/cli/upgrade-compatibility.ts +80 -0
- package/packages/core/src/cli/wait.ts +84 -17
- package/packages/core/src/cli/watch.ts +197 -60
- package/packages/core/src/config/live.ts +3 -0
- package/packages/core/src/config/schema.ts +90 -11
- package/packages/core/src/connection.ts +86 -0
- package/packages/core/src/events/catalog.ts +11 -2
- package/packages/core/src/events/payloads.ts +50 -0
- package/packages/core/src/events/repository.ts +13 -0
- package/packages/core/src/integration/harness.ts +37 -2
- package/packages/core/src/kernel/__snapshots__/reducer-registry.test.ts.snap +145 -83
- package/packages/core/src/kernel/engine.ts +24 -0
- package/packages/core/src/kernel/generators/build-log.ts +11 -1
- package/packages/core/src/kernel/incremental-fixtures.ts +13 -2
- package/packages/core/src/kernel/log-index.ts +17 -0
- package/packages/core/src/kernel/pr-summary.ts +89 -0
- package/packages/core/src/kernel/reducer-registry.ts +10 -0
- package/packages/core/src/kernel/reducer.ts +8 -0
- package/packages/core/src/ontology.ts +2 -0
- package/packages/core/src/operator/annotations.ts +12 -0
- package/packages/core/src/operator/index.ts +12 -0
- package/packages/core/src/operator/protocol.ts +19 -2
- package/packages/core/src/operator/query.ts +38 -16
- package/packages/core/src/operator/registry.ts +61 -8
- package/packages/core/src/operator/ticket-source-backend.ts +17 -20
- package/packages/core/src/operator/tickets.ts +136 -28
- package/packages/core/src/plugin-sdk/index.ts +7 -0
- package/packages/core/src/plugins/manifest.ts +5 -3
- package/packages/core/src/plugins/runtimes.ts +7 -1
- package/packages/core/src/ports/forge/fake.ts +13 -1
- package/packages/core/src/ports/forge/github-transport.ts +36 -1
- package/packages/core/src/ports/forge/github.ts +29 -5
- package/packages/core/src/ports/forge/local-git.ts +12 -4
- package/packages/core/src/ports/forge/summary-marker.ts +8 -0
- package/packages/core/src/ports/runner/session-env.ts +3 -0
- package/packages/core/src/ports/tickets/contract.ts +66 -1
- package/packages/core/src/ports/tickets/create.ts +54 -10
- package/packages/core/src/ports/tickets/fake.ts +30 -1
- package/packages/core/src/ports/tickets/file-assets.ts +159 -0
- package/packages/core/src/ports/tickets/file-codec.ts +90 -0
- package/packages/core/src/ports/tickets/file.ts +114 -120
- package/packages/core/src/ports/tickets/grants.ts +47 -0
- package/packages/core/src/ports/tickets/hosted-index.ts +17 -3
- package/packages/core/src/ports/tickets/identity.ts +20 -0
- package/packages/core/src/ports/tickets/lifecycle.ts +18 -0
- package/packages/core/src/ports/tickets/linear.ts +74 -9
- package/packages/core/src/ports/tickets/migration.ts +336 -0
- package/packages/core/src/ports/tickets/operations.ts +38 -7
- package/packages/core/src/ports/tickets/portable-assets.ts +54 -0
- package/packages/core/src/ports/tickets/remote-protocol.ts +96 -0
- package/packages/core/src/ports/tickets/remote.ts +61 -3
- package/packages/core/src/ports/tickets/requested-id.ts +46 -0
- package/packages/core/src/ports/tickets/revision.ts +62 -0
- package/packages/core/src/ports/tickets/states.ts +61 -0
- package/packages/core/src/ports/types.ts +40 -3
- package/packages/core/src/ports/workspace/build-execution.ts +6 -1
- package/packages/core/src/ports/workspace/create.ts +15 -2
- package/packages/core/src/ports/workspace/distribution-archive.ts +3 -5
- package/packages/core/src/ports/workspace/harvest-execution.ts +3 -1
- package/packages/core/src/ports/workspace/local-build-execution.ts +8 -1
- package/packages/core/src/ports/workspace/operator-sandbox.ts +2 -0
- package/packages/core/src/ports/workspace/vercel-sandbox.ts +51 -19
- package/packages/core/src/processes/build-execution-state.ts +1 -1
- package/packages/core/src/processes/build-runner.ts +87 -26
- package/packages/core/src/processes/dispatch-failure-budget.ts +83 -0
- package/packages/core/src/processes/dispatcher.ts +168 -41
- package/packages/core/src/processes/execution-no-progress.ts +176 -0
- package/packages/core/src/processes/harvest-child.ts +31 -4
- package/packages/core/src/processes/harvest-execution-state.ts +19 -2
- package/packages/core/src/processes/harvest-runner.ts +166 -104
- package/packages/core/src/processes/harvest.ts +34 -14
- package/packages/core/src/processes/phase-failure-budget.ts +2 -0
- package/packages/core/src/processes/publication-loss.ts +18 -1
- package/packages/core/src/processes/repo-view.ts +35 -0
- package/packages/core/src/store/contract.ts +32 -1
- package/packages/core/src/store/local/store.ts +1 -1
- package/packages/core/src/store/remote/client.ts +1 -1
- package/packages/core/src/store/remote/compatibility.ts +90 -0
- package/packages/core/src/store/remote/credentials.ts +28 -0
- package/packages/core/src/store/remote/index.ts +14 -1
- package/packages/core/src/store/remote/protocol.ts +25 -0
- package/packages/core/src/store/remote/token.ts +74 -13
- package/packages/core/src/store/ticket-asset-snapshots.ts +192 -0
- package/packages/core/src/store/ticket-assets.ts +86 -8
- package/packages/core/src/store/types.ts +1 -1
- package/packages/core/src/testing/index.ts +7 -0
- package/skills/guide/SKILL.md +232 -34
- package/skills/guide/references/operator-api.md +142 -13
- package/skills/guide/references/plugin-authoring.md +10 -2
- package/skills/guide/references/remote-store-protocol.md +199 -144
- package/skills/guide/references/remote-ticket-protocol.md +253 -18
- package/skills/guide/references/setup.md +199 -16
- package/skills/guide/references/ticket-dependencies.md +1 -1
- package/skills/guide/references/ticket-migration.md +64 -0
- package/skills/operate/SKILL.md +126 -36
- package/skills/tickets/SKILL.md +71 -0
- package/templates/hosted-service/package.json +13 -0
- package/templates/hosted-service/vercel.json +7 -0
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ needs an authenticated [`gh` CLI](https://cli.github.com) or an exported
|
|
|
24
24
|
<!-- release-install:start -->
|
|
25
25
|
|
|
26
26
|
```sh
|
|
27
|
-
bun add -g @defrex/autobuild@0.
|
|
27
|
+
bun add -g @defrex/autobuild@0.13.0
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
<!-- release-install:end -->
|
|
@@ -174,3 +174,5 @@ routine escalations, leaving you only the real product calls.
|
|
|
174
174
|
## License
|
|
175
175
|
|
|
176
176
|
[Apache License 2.0](LICENSE).
|
|
177
|
+
|
|
178
|
+
Deploy your own store and dashboard with the [hosted service setup](docs/hosted-service.md).
|
package/SPEC.md
CHANGED
|
@@ -432,6 +432,13 @@ body file leaves the pinned assets unchanged. The one case this cannot cover is
|
|
|
432
432
|
a record an older dispatcher created with an empty stream: recovery can only
|
|
433
433
|
sample the ticket's current assets for it.
|
|
434
434
|
|
|
435
|
+
For hosted tickets, exact sampled revisions are copied into immutable repository
|
|
436
|
+
artifacts in the destination build store before pins are published. Pins carry
|
|
437
|
+
explicit manifest references; bounded binary chunks preserve files and empty
|
|
438
|
+
directories without contacting the ticket service during build reads. Original
|
|
439
|
+
ticket revision numbers are preserved. Old pins without snapshot references
|
|
440
|
+
continue reading their existing ticket rows.
|
|
441
|
+
|
|
435
442
|
## 7. The build store
|
|
436
443
|
|
|
437
444
|
The v1 repo-bloat and no-observability problems share one root cause: the
|
|
@@ -581,9 +588,8 @@ registry already exposes bounded repository reads). Each source's cursor
|
|
|
581
588
|
advances only through a recorded trigger naming that source, so a crash
|
|
582
589
|
between scan and start cannot skip or duplicate a wake, and other builds' —
|
|
583
590
|
and the journal's — matching events re-trigger on later ticks. Sessions with
|
|
584
|
-
empty wake settings are never woken. The
|
|
585
|
-
|
|
586
|
-
default plus the repository-journal events `ab watch --repository` follows.
|
|
591
|
+
empty wake settings are never woken. The legacy hosted wake settings retain their event defaults independently of
|
|
592
|
+
the actionable CLI watch projection.
|
|
587
593
|
|
|
588
594
|
**Crash recovery.** A turn invocation that dies without an outcome leaves the
|
|
589
595
|
session `running` with a silent open stream; the tick's reaper fails such a
|
|
@@ -619,15 +625,23 @@ resume or turn — no second turn, no concurrent turns, no subagents.
|
|
|
619
625
|
|
|
620
626
|
A **ticket asset** is a named, versioned bundle of files attached to a ticket —
|
|
621
627
|
a design export, a reference screenshot, a sample payload — that shapes a change
|
|
622
|
-
but belongs
|
|
623
|
-
ships) nor in the ticket tool (which build agents cannot reach). It is keyed by
|
|
628
|
+
but belongs outside the repository, where it would go stale once the change ships. It is keyed by
|
|
624
629
|
`(repo, ticketId, kind, name)` and works identically whichever ticket source is
|
|
625
630
|
configured. It is a fourth resource family beside builds, repository journals,
|
|
626
631
|
and sessions, but a deliberately thin one: no event log, because nothing here
|
|
627
632
|
needs reduction, and no retention pruning, because assets live as long as the
|
|
628
633
|
ticket's other durable data and never expire on their own.
|
|
629
634
|
|
|
630
|
-
|
|
635
|
+
Hosted ticket assets live in the ticket service's repository-keyed storage,
|
|
636
|
+
regardless of where builds run or which BuildStore is selected. File tickets use
|
|
637
|
+
native portable storage composed with legacy BuildStore attachments; Linear
|
|
638
|
+
tickets retain BuildStore storage. Existing service assets need no migration;
|
|
639
|
+
old local hosted-ticket attachments are not moved or used as a fallback.
|
|
640
|
+
|
|
641
|
+
Each put creates a new increasing **revision**; earlier revisions stay retrievable.
|
|
642
|
+
Adapters normally start at 0. Native file assets reserve revisions from
|
|
643
|
+
1,000,000,000 upward so explicit reads of old BuildStore revisions remain
|
|
644
|
+
unambiguous when native and legacy assets are composed.
|
|
631
645
|
An asset is a `file` (exactly one file) or a `tree` (a folder: its root is
|
|
632
646
|
implicit, so a tree with zero entries is a valid empty folder). The manifest is
|
|
633
647
|
a list of entries — `file` entries with size and content address, and `dir`
|
|
@@ -701,7 +715,8 @@ conformance suite):
|
|
|
701
715
|
hosted HTTP service, selected by an `http(s)://` reference. Kernels,
|
|
702
716
|
sandboxes, terminal dashboards, and later human-facing pages share this
|
|
703
717
|
service tier; it owns token authorization, protocol write validation,
|
|
704
|
-
artifact policy, and
|
|
718
|
+
artifact policy, release-line compatibility, and independent protocol
|
|
719
|
+
enforcement. The
|
|
705
720
|
later human routes share its deployment so a browser or second service never
|
|
706
721
|
receives the machine signing secret. Artifacts remain content-by-value. The
|
|
707
722
|
documented [remote store protocol](docs/remote-store-protocol.md) is the
|
|
@@ -710,6 +725,24 @@ conformance suite):
|
|
|
710
725
|
client, is the conformance bar. Autobuild does not load in-process BuildStore
|
|
711
726
|
plugins. Git worktrees and default file tickets necessarily remain local.
|
|
712
727
|
|
|
728
|
+
A service accepts stable clients from its own `major.minor` release line and
|
|
729
|
+
the two preceding minor lines in the same major. A major starts a new family:
|
|
730
|
+
X.0 accepts only X.0, X.1 accepts X.0/X.1, and X.2 onward accepts three lines.
|
|
731
|
+
Patch versions are interchangeable in both directions and must never change
|
|
732
|
+
the protocol. Upgrade the service first, then projects independently within
|
|
733
|
+
its window. Supported release lines retain their wire handlers and known
|
|
734
|
+
protocol identities; an unknown protocol is refused independently of version.
|
|
735
|
+
Malformed, missing, and prerelease identities are refused with HTTP 409.
|
|
736
|
+
A newer client is told to upgrade the service; a client below the window is
|
|
737
|
+
told to upgrade the project's Autobuild. Diagnostics name the service version
|
|
738
|
+
and supported range.
|
|
739
|
+
|
|
740
|
+
Unauthenticated `GET /health` publishes `ok`, `autobuildVersion`,
|
|
741
|
+
`protocolVersion`, and `supportedClientRange: { minVersion, maxVersionExclusive }`.
|
|
742
|
+
The range is inclusive at the minimum and exclusive at the maximum; a 0.11.x
|
|
743
|
+
service publishes `>=0.9.0 <0.12.0`. Health needs no credentials, version
|
|
744
|
+
headers, or available backend.
|
|
745
|
+
|
|
713
746
|
`subscribe` is specced in the interface; the v2.0 implementation is polling
|
|
714
747
|
`getEvents(since)`. True push comes later.
|
|
715
748
|
|
|
@@ -734,6 +767,43 @@ longer grows with the number of past dispatcher invocations. The journal
|
|
|
734
767
|
itself stays append-only: full replay remains the normative truth, and
|
|
735
768
|
`ab watch` still sees every recorded fact.
|
|
736
769
|
|
|
770
|
+
#### Hosted connected projects
|
|
771
|
+
|
|
772
|
+
The product's hosted service keeps a durable PostgreSQL project registry,
|
|
773
|
+
independent of BuildStore repository journals and ticket data. Entries record
|
|
774
|
+
normalized repository origin, addition timestamp and adding identity. An
|
|
775
|
+
append-only journal records additions/removals; latest sequence determines
|
|
776
|
+
membership. Removal never deletes build, event, artifact or ticket history;
|
|
777
|
+
re-registration restores access and records fresh addition metadata.
|
|
778
|
+
|
|
779
|
+
Database-authorized owners administer it without redeploying through
|
|
780
|
+
`ab-hosted-store projects list`, `projects add REPOSITORY --user IDENTITY`, and
|
|
781
|
+
`projects remove REPOSITORY --user IDENTITY`. Attribution is declared by the
|
|
782
|
+
administrator; ordinary store/project tokens cannot administer registration.
|
|
783
|
+
All allowlisted signed-in users own every registered project (single-owner
|
|
784
|
+
model). Per-project memberships and machine credential boundaries are deferred.
|
|
785
|
+
|
|
786
|
+
Dashboard discovery, MCP `repositories.list` and every repository tool call,
|
|
787
|
+
and all operator API routes for every operator credential consult current
|
|
788
|
+
membership. Unregistered operator paths return not-found before execution.
|
|
789
|
+
Registry failures fail closed and transient initialization can retry.
|
|
790
|
+
The dashboard selection lives at `/?repo=<URL-encoded normalized origin>`;
|
|
791
|
+
missing/invalid selections canonicalize to the first active entry, and an
|
|
792
|
+
empty registry issues no project data/control requests.
|
|
793
|
+
|
|
794
|
+
The hosted dispatcher queries the registry each authorized invocation when
|
|
795
|
+
`AB_DISPATCHER_REPOSITORIES` is unset. An explicit list is intersected with
|
|
796
|
+
current registration in its configured order. Empty registration is a
|
|
797
|
+
successful zero-project tick. Removal stops later invocations, without
|
|
798
|
+
cancelling already-started work or changing machine-route token authority.
|
|
799
|
+
|
|
800
|
+
`AB_WEB_REPOSITORIES` is deprecated: the first initialization with a nonempty
|
|
801
|
+
CSV imports absent projects once per database as `system:AB_WEB_REPOSITORIES`.
|
|
802
|
+
The import and durable marker share one transaction and mutation lock across
|
|
803
|
+
processes. Absence does not consume the marker. Restarts or later variable
|
|
804
|
+
edits cannot resurrect removals. Deployments migrate the pinned schema before
|
|
805
|
+
starting services; runtime initialization never runs DDL.
|
|
806
|
+
|
|
737
807
|
### 7.3 Persistence granularity
|
|
738
808
|
|
|
739
809
|
Required phase outputs persist at **phase/round boundaries**; a killed phase
|
|
@@ -781,8 +851,27 @@ Four base-selection invariants make this safe with Git:
|
|
|
781
851
|
|
|
782
852
|
### 7.5 What the PR gets
|
|
783
853
|
|
|
784
|
-
|
|
785
|
-
|
|
854
|
+
One marked summary comment contains verdict history, verification results,
|
|
855
|
+
and links into the store. Built-in forges discover its per-build marker on
|
|
856
|
+
every refresh and edit it, recreating it only after confirmed absence. The
|
|
857
|
+
full audit trail is queryable, not committed to the branch.
|
|
858
|
+
|
|
859
|
+
Summary publication is best effort, once per completed phase occurrence,
|
|
860
|
+
after sessions end; attaching artifacts performs no summary write. Durable
|
|
861
|
+
claim-before-write facts consume the occurrence budget even across crashes.
|
|
862
|
+
Rate limits stop that occurrence and persist a cooldown (provider headers or
|
|
863
|
+
at least one minute) before a later phase may catch up. Failures never fail
|
|
864
|
+
artifact designation or phase completion. Bodies are capped at 65,536 UTF-16
|
|
865
|
+
code units. Oversized projections are deposited as a non-attached `pr-summary`
|
|
866
|
+
artifact; a compact comment provides the exact pinned download command.
|
|
867
|
+
Current-API plugins retain `commentOnPr` and receive the same bounded calls;
|
|
868
|
+
legacy plugins may append instead of editing.
|
|
869
|
+
|
|
870
|
+
Local runners publish under their build lease. Remote guests record durable
|
|
871
|
+
summary boundary requests and yield; only the credentialed dispatcher settles
|
|
872
|
+
those requests, after guest execution ends and under exclusive ownership,
|
|
873
|
+
before replacement execution or workspace cleanup. Attempts and request
|
|
874
|
+
dispositions survive restart and do not alter pipeline routing.
|
|
786
875
|
|
|
787
876
|
Any agent session can explicitly designate an exact deposited artifact as a PR
|
|
788
877
|
attachment through `ab artifact put <kind> <file> --attach`. Designation is a
|
|
@@ -802,8 +891,8 @@ dispatcher reclaims them after the build reaches a terminal outcome, while
|
|
|
802
891
|
store artifacts remain under the store's retention policy. Upload/validation/timeout failures record follow-up
|
|
803
892
|
observations and preserve the complete text projection; they never fail
|
|
804
893
|
verification or block finalize. Agents receive no forge credentials. A
|
|
805
|
-
designation after the PR exists
|
|
806
|
-
post-steps and post-reconcile verifiers need no custom phase.
|
|
894
|
+
designation after the PR exists is included at the completed phase boundary,
|
|
895
|
+
so finalize post-steps and post-reconcile verifiers need no custom phase.
|
|
807
896
|
|
|
808
897
|
### 7.6 Streams (the third primitive)
|
|
809
898
|
|
|
@@ -925,7 +1014,7 @@ AB_STORE # store URL or local path
|
|
|
925
1014
|
AB_BUILD # build slug
|
|
926
1015
|
AB_PHASE # current phase (+ round)
|
|
927
1016
|
AB_SESSION # session id
|
|
928
|
-
AB_TOKEN #
|
|
1017
|
+
AB_TOKEN # signed credential for this exact phase session (remote store)
|
|
929
1018
|
```
|
|
930
1019
|
|
|
931
1020
|
A harvest session instead carries `AB_REPO`, `AB_HARVEST`, and an `AB_PHASE`
|
|
@@ -933,14 +1022,18 @@ of `synthesize@N` or `review@N`. The AgentRunner invocation argument is
|
|
|
933
1022
|
opaque: a build skill receives its slug; a harvest skill receives its run id.
|
|
934
1023
|
The CLI resolves identity from ambient auth. Every build process holds an
|
|
935
1024
|
interface-enforced build-scoped Store handle. At the phase CLI opening boundary,
|
|
936
|
-
|
|
937
|
-
|
|
1025
|
+
both local and remote handles are wrapped with authority over exactly
|
|
1026
|
+
`AB_BUILD` or `AB_REPO`. Before launch, the dispatcher exchanges its project credential with the service
|
|
1027
|
+
for a build or prepared harvest-execution grant. After recording a session start,
|
|
1028
|
+
the runner exchanges that grant for an exact phase-session grant. The remote
|
|
1029
|
+
handle forwards only this delegated credential; the service enforces its project,
|
|
1030
|
+
resource and session boundaries on the wire. Build and
|
|
938
1031
|
repository resources cannot cross, and naming another resource to a Store
|
|
939
1032
|
operation cannot widen either handle. Event-bearing writes attributed to an
|
|
940
1033
|
agent must name the ambient `AB_SESSION`; non-agent writes remain allowed so the
|
|
941
1034
|
CLI can perform its existing trusted kernel plumbing, including finalize.
|
|
942
|
-
Operator and kernel processes with no agent identity markers retain unscoped
|
|
943
|
-
Store access. Three read-only forms are also valid inside a phase: `ab build
|
|
1035
|
+
Operator and kernel processes with no agent identity markers retain interface-unscoped
|
|
1036
|
+
Store handles; remote authorization still limits access to the credential project. Three read-only forms are also valid inside a phase: `ab build
|
|
944
1037
|
status` and `ab artifact download` may read only `AB_BUILD`, while `ab builds`
|
|
945
1038
|
is denied because collection access cannot represent one build. A complete
|
|
946
1039
|
Harvest identity has repository scope and cannot use those build/admin reads.
|
|
@@ -949,10 +1042,60 @@ If any build or Harvest identity marker is present, the corresponding
|
|
|
949
1042
|
partial, empty, malformed, shared-only, or mixed identity fails before Store
|
|
950
1043
|
access rather than falling back to operator authority. `AB_STORE` and
|
|
951
1044
|
`AB_TOKEN` alone remain operator selection and credentials, not identity.
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
1045
|
+
Dispatcher machine authority is an opaque, revocable credential for exactly one
|
|
1046
|
+
registered project. The service keeps only a digest of its random secret and
|
|
1047
|
+
credential metadata (creator, creation, last use, expiry and revocation), and
|
|
1048
|
+
checks both credential status and project registration on each request. It
|
|
1049
|
+
checks actual build/session/stream ownership and filters collections server-side.
|
|
1050
|
+
Explicit project mismatch is 403; missing and foreign indirect IDs share 404.
|
|
1051
|
+
Remote project build creation allocates a fresh slug and branch; the returned
|
|
1052
|
+
record is authoritative. Local adapters retain exact-slug behavior.
|
|
1053
|
+
|
|
1054
|
+
Owners issue/list/revoke credentials with deployment-local `ab-hosted-store
|
|
1055
|
+
credentials` commands. Retired deployment-wide and repository-less operator
|
|
1056
|
+
tokens are rejected with migration guidance. An explicit versioned owner-only
|
|
1057
|
+
break-glass admin is the sole machine cross-project exception. Internal signed
|
|
1058
|
+
owner delegation is short-lived, repository-bound and operator-only. The hosted
|
|
1059
|
+
dispatcher issues stored credentials with immutable dispatcher purpose (raw
|
|
1060
|
+
store and tickets only) per invocation and keeps them valid through configured
|
|
1061
|
+
expiry. Already issued delegated grants do not depend on that parent expiry.
|
|
1062
|
+
Owner-issued project credentials attribute operator writes to their recorded
|
|
1063
|
+
creator. Agents never receive the dispatcher's project credential. Delegated
|
|
1064
|
+
reads retain access to same-project repository state; build mutations target only
|
|
1065
|
+
that build, and harvest mutations target only the prepared run and execution,
|
|
1066
|
+
its artifacts and streams, with heartbeat authority for its adopted lease holder.
|
|
1067
|
+
Phase grants also enforce agent session attribution. They cannot create builds or
|
|
1068
|
+
operator sessions, administer repositories, invoke operator routes, or delegate.
|
|
1069
|
+
A runner can delegate only to a recorded session within its own authority.
|
|
1070
|
+
|
|
1071
|
+
Delegated grants have no fixed wall-clock expiry. The service checks signed
|
|
1072
|
+
bindings against authoritative durable lifecycle facts on every request and
|
|
1073
|
+
fails closed if those reads fail. Active, paused and escalated builds may outlive
|
|
1074
|
+
a dispatcher restart or a week-long parent credential. Build termination,
|
|
1075
|
+
harvest execution/run termination, or the phase's own session end retires the
|
|
1076
|
+
corresponding grant after a 60-second evidence grace window. A durable ending
|
|
1077
|
+
permanently closes that grant; recovered harvest executions use fresh durable
|
|
1078
|
+
authorizations and fresh grants. Project removal denies all its grants immediately.
|
|
1079
|
+
Local-store projects require no exchange.
|
|
1080
|
+
|
|
1081
|
+
Hosted ticket operations are gated by grant kind: build-runner and build-phase
|
|
1082
|
+
grants have no access; harvest-phase grants can only list-ready, get and read
|
|
1083
|
+
dependency-states; harvest-runner grants can also create proposals. All other
|
|
1084
|
+
ticket mutations require project or admin authority. Refusals name the grant
|
|
1085
|
+
kind and operation.
|
|
1086
|
+
|
|
1087
|
+
Ticket admission uses the credential project. Hosted tickets, comments, blockers, creation-key
|
|
1088
|
+
deduplication and assets are partitioned by registered repository, never team.
|
|
1089
|
+
Lifecycle comes from independent project ticket policy (triage, ready, doing, done
|
|
1090
|
+
by default; configurable doneState). Legacy projects without independent policy
|
|
1091
|
+
use their uploaded configuration with Backlog / Doing / Done defaults. Owner admin ticket requests explicitly select a registered
|
|
1092
|
+
repository. The service has no Linear ticket backend: external tracker and
|
|
1093
|
+
file sources remain dispatcher-side, and service ticket surfaces refuse those
|
|
1094
|
+
projects with actionable source feedback. Legacy team queues migrate atomically
|
|
1095
|
+
to their sole configured claimant; conflicts stop unchanged for an owner
|
|
1096
|
+
assignment and rerun. See the hosted service migration procedure.
|
|
1097
|
+
See the remote store, remote ticket and operator protocol references for wire
|
|
1098
|
+
and revocation details. Least privilege comes from code, not prompt instructions.
|
|
956
1099
|
|
|
957
1100
|
Every phase and harvest turn also receives a runner-controlled `PATH` prefix
|
|
958
1101
|
containing a private `ab` launcher from the same Autobuild distribution that
|
|
@@ -1145,9 +1288,10 @@ implementer: ab context (findings.json now materialized) → …
|
|
|
1145
1288
|
|
|
1146
1289
|
Human/pre-build ticket grooming uses one configured-source namespace
|
|
1147
1290
|
(`ab ticket create|update|block|unblock|list|show|move`, plus the ticket-asset
|
|
1148
|
-
forms below).
|
|
1291
|
+
forms below). Migration adds `ab ticket export <dir>` and `ab ticket import <dir>`
|
|
1292
|
+
(see [Ticket source migration](#ticket-source-migration)). These commands are
|
|
1149
1293
|
sessionless, source-agnostic, and never available as a mid-build spec
|
|
1150
|
-
mutation path.
|
|
1294
|
+
mutation path. The CRUD subcommands accept `--json` and then writes exactly one
|
|
1151
1295
|
bare value: `list` emits `Ticket[]`; every other form emits the complete
|
|
1152
1296
|
created, read, or post-mutation `Ticket`. Human-readable confirmations are not
|
|
1153
1297
|
a data format and callers must not parse ids from them.
|
|
@@ -1162,8 +1306,10 @@ creates tickets directly in its ready state must therefore create a dependency
|
|
|
1162
1306
|
chain in dependency order, carrying each predecessor id into the next create,
|
|
1163
1307
|
before a later ticket can be claimed.
|
|
1164
1308
|
|
|
1165
|
-
**Ticket assets** (§7.1) attach files to a ticket
|
|
1166
|
-
|
|
1309
|
+
**Ticket assets** (§7.1) attach files to a ticket. Hosted tickets use their
|
|
1310
|
+
ticket service storage independently of the selected build store; file tickets use
|
|
1311
|
+
native storage with legacy fallback, and sources without native assets use the
|
|
1312
|
+
selected BuildStore:
|
|
1167
1313
|
|
|
1168
1314
|
- `ab ticket attach <id> <kind> <path> [--name <name>] [--store <ref>] [--json]`
|
|
1169
1315
|
stores a file or a whole folder (its relative tree preserved) as an asset.
|
|
@@ -1219,6 +1365,17 @@ be narrowed to the ambient build — and `--repo` constrains every call to one
|
|
|
1219
1365
|
repository. Mutating tools attribute their writes to the sessionless operator
|
|
1220
1366
|
identity, exactly as the other operator commands do.
|
|
1221
1367
|
|
|
1368
|
+
### 8.10 Hosted project connection
|
|
1369
|
+
|
|
1370
|
+
`ab connect <service-url>` requests owner browser approval for the normalized
|
|
1371
|
+
origin, registers the project, and saves a project credential outside the
|
|
1372
|
+
checkout. `ab connect` reports its status; `ab disconnect` revokes and removes
|
|
1373
|
+
only that credential, retaining project data. Store precedence is `--store`,
|
|
1374
|
+
nonblank `AB_STORE`, `[store] url`, then local state. `AB_TOKEN` overrides saved
|
|
1375
|
+
credentials. Configured services without credentials fail closed. Connection
|
|
1376
|
+
commands require a network origin and are unavailable in phase sessions.
|
|
1377
|
+
|
|
1378
|
+
|
|
1222
1379
|
## 9. AgentRunner
|
|
1223
1380
|
|
|
1224
1381
|
Session-based, because review loops need memory:
|
|
@@ -1619,6 +1776,19 @@ event-level mechanics live in the repository catalog and reducer tests):
|
|
|
1619
1776
|
|
|
1620
1777
|
## 13. Ticket source policy
|
|
1621
1778
|
|
|
1779
|
+
**Hosted tickets are project-scoped.** A project credential selects one registered
|
|
1780
|
+
repository; an owner selects a registered repository explicitly. Team and state
|
|
1781
|
+
fields from clients convey no authority or lifecycle policy. Tickets, comments,
|
|
1782
|
+
blockers, creation-key deduplication and assets are isolated by repository.
|
|
1783
|
+
Independent project ticket policy supplies hosted lifecycle names: triage, ready,
|
|
1784
|
+
doing, done (`doneState`), and create/proposal equal to triage by default. Hosted
|
|
1785
|
+
readyState defaults to ready; other sources require it. Legacy clients without
|
|
1786
|
+
independent policy use uploaded dispatcher config and its old defaults. Configured roles may overlap.
|
|
1787
|
+
The service has no Linear backend and never relays external ticket sources.
|
|
1788
|
+
Projects using Linear, files or plugins keep their direct dispatcher connection;
|
|
1789
|
+
service ticket surfaces refuse with project/source feedback instead of empty data.
|
|
1790
|
+
|
|
1791
|
+
|
|
1622
1792
|
The TicketSource **initiates and receives projections; it is never consulted
|
|
1623
1793
|
mid-build and never used as artifact storage.** Dispatch reads the ticket
|
|
1624
1794
|
(including the spec) as part of initiation — at claim time, or on a later tick
|
|
@@ -1629,14 +1799,16 @@ This keeps the abstraction honest: a file-based TicketSource with nowhere to
|
|
|
1629
1799
|
put blobs must be fully workable.
|
|
1630
1800
|
|
|
1631
1801
|
**Ticket assets follow the same rule.** The contents of a ticket asset (§7.1)
|
|
1632
|
-
live in the
|
|
1802
|
+
live in the ticket service for hosted tickets, independently of build storage;
|
|
1803
|
+
file sources keep portable bundles and source-local history, while sources without
|
|
1804
|
+
native assets keep them in the BuildStore. Attaching,
|
|
1633
1805
|
replacing, or removing an asset instead leaves a note on the ticket through the
|
|
1634
1806
|
existing `comment()` port — the outward projection every source, including the
|
|
1635
1807
|
plugin surface, already supports. The note names the asset, its revision, file
|
|
1636
1808
|
count, and size, and gives the `ab ticket asset get` command that fetches it, so
|
|
1637
1809
|
a person reading the ticket in Linear, the hosted service, or a local file knows
|
|
1638
1810
|
the asset exists. The note is a projection outward only; nothing reads it back,
|
|
1639
|
-
and
|
|
1811
|
+
and existing sources and plugins need no asset capability.
|
|
1640
1812
|
|
|
1641
1813
|
**Claim lifecycle.** Claim acquires nonterminal work: it returns `true` and
|
|
1642
1814
|
moves a claimable ticket to the source's claimed state. It returns `false` for
|
|
@@ -1871,7 +2043,8 @@ with illustrative members:
|
|
|
1871
2043
|
| Spec | `spec.imported`, `spec.authored`, `spec.revised` (optionally carrying `assets`, a re-pin of the ticket's assets, §6.3) |
|
|
1872
2044
|
| Sessions | `session.started`; `session.ended` with transcript ref and usage (ordinary completion — the analysis corpus), or `session.ended {outcome: reclaimed, reclaimedBy: {instance, resumedFromSeq}}` (explicit transcriptless takeover) |
|
|
1873
2045
|
| Plan/code loops | `plan.started` … `plan-review.verdict`; `implement.started` … `code-review.verdict` |
|
|
1874
|
-
| Verify/finalize | `verify.started {step, attempt, feedback?}`, `verify.completed {step, outcome}`, `finalize.completed {pr}`, `finalize.step-completed {step, ok, headSha?}` |
|
|
2046
|
+
| Verify/finalize | `verify.started {step, attempt, feedback?}`, `verify.completed {step, outcome, skipCause?}`, `verify.reconcile-policy-captured {reconcileSeq, steps}`, `finalize.completed {pr}`, `finalize.step-started {step}`, `finalize.step-completed {step, ok, headSha?}` |
|
|
2047
|
+
| PR summary | Kernel-authored `pr-summary.requested {occurrence, boundary}`, `pr-summary.attempted {occurrence, boundary, pr}`, `pr-summary.result {attempt, outcome, eligibleAfter?}`, `pr-summary.settled {request, disposition}`; sequence identities correlate durable starts, completed boundaries, attempts, and handoffs (§7.5) |
|
|
1875
2048
|
| PR attachments | `pr-attachment.designated`, `pr-attachment.hosted`, `pr-attachment.reclaimed`, `pr-attachment.reclaim-failed` |
|
|
1876
2049
|
| Post-PR [D1] | `pr.merged`, `pr.conflicted`, `reconcile.progress-checked`, `reconcile.started`, `reconcile.completed` |
|
|
1877
2050
|
| Cross-cutting | `observation.recorded`, `escalation.raised`, `phase.failed` |
|
|
@@ -1975,8 +2148,18 @@ ordinary dispatcher tick provisions the workspace, atomically imports the spec,
|
|
|
1975
2148
|
posts the ticket notice once, and launches the runner. Claim-time auto-merge
|
|
1976
2149
|
attribution retained by `build.created` is materialized as the ordinary
|
|
1977
2150
|
human-authored request before launch. A failed boundary appends `dispatch.failed
|
|
1978
|
-
{stage,attempt,error}` and stays queued for another tick
|
|
1979
|
-
|
|
2151
|
+
{stage,attempt,error}` and stays queued for another tick until its budget is
|
|
2152
|
+
exhausted. Dispatch failures share a `[policy].maxDispatchAttempts` budget
|
|
2153
|
+
(default 3) across
|
|
2154
|
+
create, workspace, spec, comment, and launch stages. Exhaustion raises one
|
|
2155
|
+
`dispatch-failure-limit` policy escalation naming the latest stage and error,
|
|
2156
|
+
and parks dispatch until answered. Both bare `ab answer <slug>` retries and
|
|
2157
|
+
text guidance grant a fresh budget; abort does not. Confirmed runner attachment
|
|
2158
|
+
clears the streak. Recovery-provider workspace failures belong exclusively to
|
|
2159
|
+
the infrastructure budget. Exhaustion is repaired from durable facts on restart
|
|
2160
|
+
before further dispatch work.
|
|
2161
|
+
|
|
2162
|
+
A discard request is honored only while the build remains queued; one that races with runner
|
|
1980
2163
|
attachment is inert and cannot tear down live work. A human discard waits out
|
|
1981
2164
|
any unexpired execution lease, then releases a partial workspace and stale
|
|
1982
2165
|
lease, returns the ticket to Ready, and appends `build.completed {outcome:
|
|
@@ -2068,6 +2251,21 @@ adapter never re-cuts it from a newer base (§7.4). `ab context` rehydrates
|
|
|
2068
2251
|
scratch from the store into a fresh session. Uncommitted round-2 work is lost by
|
|
2069
2252
|
design (§7.3 — phase boundaries are the resume points).
|
|
2070
2253
|
|
|
2254
|
+
The dispatcher also applies a fixed, non-configurable limit of three consecutive
|
|
2255
|
+
executions that complete normally with exit code zero and no durable build
|
|
2256
|
+
progress. Execution start/end, runner attachment and workspace lifecycle
|
|
2257
|
+
bookkeeping do not count as progress. Pipeline, session, spec, publication/PR,
|
|
2258
|
+
observation and acknowledged operator facts reset the streak; infrastructure,
|
|
2259
|
+
budget and provider failures do not consume the allowance and retain their own
|
|
2260
|
+
retry limits. Before a fourth actionable launch, the dispatcher raises one
|
|
2261
|
+
setup-targeted `execution-no-progress` policy escalation naming the count and
|
|
2262
|
+
the next action it expected the runner to take. Waiting, paused and terminal
|
|
2263
|
+
builds are left parked, and pending operator commands remain executable.
|
|
2264
|
+
Answering that escalation with guidance or a bare `ab answer <slug>` retry grants
|
|
2265
|
+
three fresh executions. The guard is derived from durable facts, including on
|
|
2266
|
+
supervisor restart, and uses the ordinary watch, dashboard and operator API
|
|
2267
|
+
attention paths.
|
|
2268
|
+
|
|
2071
2269
|
Two liveness rules complete the picture. Within one dispatcher process,
|
|
2072
2270
|
build-runner launches are single-flighted by slug through supervised process
|
|
2073
2271
|
liveness — execution completion means the complete environment has been reaped,
|
|
@@ -2182,7 +2380,8 @@ fresh from `origin`, and records the resolved SHA on `reconcile.started` — kno
|
|
|
2182
2380
|
used (§15.3). The agent merges that base into the branch guided by the spec,
|
|
2183
2381
|
plan, and implement-notes, with the explicit charge to regress against
|
|
2184
2382
|
neither; the resolution lands as a merge commit, and because reconciliation
|
|
2185
|
-
changed code, **`verify:*`
|
|
2383
|
+
changed code, **`verify:*` starts a fresh cycle**, subject to the captured
|
|
2384
|
+
post-reconcile policy (default: re-run all applicable steps). A resolution the agent judges
|
|
2186
2385
|
risky — semantic conflicts, spec-relevant choices — escalates rather than
|
|
2187
2386
|
guesses. Reconcile skips `code-review` by default (escalation covers the
|
|
2188
2387
|
judgment cases; policy can force it).
|
|
@@ -2314,6 +2513,7 @@ sessionBudgetSeconds = 7200 # optional role override
|
|
|
2314
2513
|
sessionBudgetSeconds = 3600 # non-infinite default for build agent sessions
|
|
2315
2514
|
stallRounds = 3
|
|
2316
2515
|
maxVerifyAttempts = 3
|
|
2516
|
+
maxDispatchAttempts = 3
|
|
2317
2517
|
maxSetupAttempts = 3
|
|
2318
2518
|
maxInfrastructureAttempts = 3
|
|
2319
2519
|
maxReconcileAttempts = 3
|
|
@@ -2386,9 +2586,12 @@ artifact deposited on reload changes only those sections. In-flight
|
|
|
2386
2586
|
environments are never re-provisioned; a fresh build from the new base is the
|
|
2387
2587
|
path for a changed provisioning definition.
|
|
2388
2588
|
|
|
2389
|
-
|
|
2589
|
+
Three configurable narrowing mechanisms govern which verify steps run, all
|
|
2390
2590
|
resolving to the ordinary `skipped` outcome so exclusions stay queryable:
|
|
2391
2591
|
|
|
2592
|
+
- **Post-reconcile policy.** The cycle snapshot resolves repository and step
|
|
2593
|
+
`afterReconcile` settings before any plan or path exclusions, including for
|
|
2594
|
+
`always` steps. It applies only after a completed reconcile.
|
|
2392
2595
|
- **Plan selection.** An approved plan may declare the complete subset of
|
|
2393
2596
|
optional verify steps warranted by the spec, in strict front matter
|
|
2394
2597
|
validated at deposit. The selection paired with the approving review
|
|
@@ -2402,6 +2605,30 @@ resolving to the ordinary `skipped` outcome so exclusions stay queryable:
|
|
|
2402
2605
|
match skips without launching anything; a Git failure is infrastructure and
|
|
2403
2606
|
fails closed, never a synthetic skip.
|
|
2404
2607
|
|
|
2608
|
+
|
|
2609
|
+
#### Post-reconcile verification policy
|
|
2610
|
+
|
|
2611
|
+
Post-reconcile verification defaults to enabled: `[verify].afterReconcile = true`.
|
|
2612
|
+
Set it to `false` to retain pre-reconcile verification and skip all steps after
|
|
2613
|
+
reconciliation. An optional boolean `[verify.<step>].afterReconcile` overrides
|
|
2614
|
+
the repository setting in either direction; overrides require a configured step.
|
|
2615
|
+
For example, set `afterReconcile = false` in `[verify]` and
|
|
2616
|
+
`afterReconcile = true` in `[verify.types]` to keep only that step re-running.
|
|
2617
|
+
|
|
2618
|
+
The kernel freezes the resolved ordered policy in
|
|
2619
|
+
`verify.reconcile-policy-captured` at the next engine action after reconcile
|
|
2620
|
+
completion. Live configuration changes apply at that boundary; a cycle already
|
|
2621
|
+
started keeps its policy through recovery. Historical cycles already started
|
|
2622
|
+
without a captured policy retain the rerun-all behavior. Initial verification
|
|
2623
|
+
and verification after subsequent code review always use ordinary applicability.
|
|
2624
|
+
Policy exclusion precedes plan selection and paths, including `always = true`.
|
|
2625
|
+
Enabled steps still follow plan selection and path rules. Excluded steps record
|
|
2626
|
+
`verify.completed` with outcome `skipped`, `skipCause = "post-reconcile-policy"`,
|
|
2627
|
+
and a reason naming the setting. Dashboards and PR summaries call this
|
|
2628
|
+
"skipped by post-reconcile policy"; it is never a pass. Forge-side required
|
|
2629
|
+
checks and branch protections still gate merge. For excluded steps, merged code
|
|
2630
|
+
is not re-verified, so breakage that only exists in the combination can land.
|
|
2631
|
+
|
|
2405
2632
|
### 16.3 Skill installation: vendored, namespaced, editable [D11]
|
|
2406
2633
|
|
|
2407
2634
|
This project ships 11 canonical default skills for the fixed phases, the
|
|
@@ -2483,6 +2710,15 @@ install failure is fatal and does not merge against the wrong defaults.
|
|
|
2483
2710
|
`--no-self-update` always selects merge-only
|
|
2484
2711
|
behavior. An exact version may be older than the installed version.
|
|
2485
2712
|
|
|
2713
|
+
Before installation or project writes, upgrades targeting a hosted store probe
|
|
2714
|
+
its public health range. An incompatible target produces a directional warning
|
|
2715
|
+
(service first for a newer target, project upgrade for a stale target) and
|
|
2716
|
+
continues. A legacy health response has an exact-version contract; different
|
|
2717
|
+
targets warn that the service needs the compatibility-window release. Failed,
|
|
2718
|
+
timed-out, or malformed probes warn that connectivity could not be verified
|
|
2719
|
+
and may fail after upgrade, then continue. Merge-only and replacement-process
|
|
2720
|
+
handoffs check the distribution actually applied before skill writes.
|
|
2721
|
+
|
|
2486
2722
|
Upgrade records its successful work in one local commit on the target's current
|
|
2487
2723
|
HEAD by default. The exact ownership boundary is the reported skills' canonical
|
|
2488
2724
|
`.agents` trees, pristine records, and `.claude` discovery paths, plus
|
|
@@ -2581,3 +2817,71 @@ or installs releases in the foreground or background.
|
|
|
2581
2817
|
enforcement and will colocate later session-authenticated human routes.
|
|
2582
2818
|
Artifacts remain content-by-value for now; direct-to-blob references are a
|
|
2583
2819
|
possible later protocol revision, not a second current deployment path.
|
|
2820
|
+
|
|
2821
|
+
## Revision-checked ticket writes
|
|
2822
|
+
|
|
2823
|
+
Every ticket read includes an opaque `revision`. Pass it as `expectedRevision`
|
|
2824
|
+
(on MCP/operator requests) or `--expected-revision <opaque>` on `ab ticket update`,
|
|
2825
|
+
`move`, `block` and `unblock`. A stale write fails without changing anything and
|
|
2826
|
+
reports the current revision. Omission preserves unguarded behavior. Blocker
|
|
2827
|
+
checks cover the entire batch. Dispatcher moves remain unguarded and change the
|
|
2828
|
+
revision. Sources without guarded writes, including Linear, refuse supplied
|
|
2829
|
+
revisions rather than ignoring them.
|
|
2830
|
+
|
|
2831
|
+
`ab ticket edit <id>` opens `$VISUAL`, falling back to `$EDITOR`, using TOML
|
|
2832
|
+
frontmatter and a Markdown body. Only title, body and labels are editable;
|
|
2833
|
+
id, blockers, creation key and reference comments are read-only. It saves only
|
|
2834
|
+
changed fields with the opening revision. Unchanged or formatting-only edits
|
|
2835
|
+
write nothing. On conflict, invalid input or editor failure, the error names an
|
|
2836
|
+
absolute file path containing the edited text. Read the current ticket and
|
|
2837
|
+
reapply the intended changes before retrying; conflicts are never merged.
|
|
2838
|
+
|
|
2839
|
+
File and Linear revisions fingerprint title, body, canonical label/blocker sets
|
|
2840
|
+
and state; reverting identical content restores its fingerprint. File checks
|
|
2841
|
+
re-read immediately before writing, with the existing no-lock race window.
|
|
2842
|
+
Direct file edits and state-directory moves change revisions. File revisions also
|
|
2843
|
+
cover structured comments and portable attachments. Legacy file comments change
|
|
2844
|
+
the body; structured comments preserve it. Separate hosted comments do not change
|
|
2845
|
+
ticket revisions. Hosted revisions
|
|
2846
|
+
are monotonic decimal bigint strings, and checks run under the same row lock
|
|
2847
|
+
and transaction as all requested changes. Hosted reads return a coherent
|
|
2848
|
+
snapshot of fields, blockers and revision.
|
|
2849
|
+
|
|
2850
|
+
### Independent hosted ticket service
|
|
2851
|
+
|
|
2852
|
+
`[tickets] url` selects hosted ticket transport independently of BuildStore selection;
|
|
2853
|
+
without it, tickets use the selected remote build store. Local builds require an
|
|
2854
|
+
explicit ticket URL. Project registration and ticket policy publication through
|
|
2855
|
+
`ab connect --tickets URL` work before dispatch. Policy is a durable per-registration
|
|
2856
|
+
record, outside BuildStore events/artifacts; legacy uploaded configuration remains
|
|
2857
|
+
a compatibility fallback. Hosted lifecycle defaults are triage/ready/doing/done.
|
|
2858
|
+
Independent harvest uses revocable, expiring, service-bound ticket grants with
|
|
2859
|
+
read/create runner authority and read-only child authority. Build state and harvest
|
|
2860
|
+
journals remain exclusively in the selected BuildStore.
|
|
2861
|
+
|
|
2862
|
+
### Ticket source migration
|
|
2863
|
+
|
|
2864
|
+
`ab ticket export <dir>` enumerates all states through TicketSource and writes a
|
|
2865
|
+
portable file tracker atomically to an absent or empty destination.
|
|
2866
|
+
`ab ticket import <dir>` preflights the entire tracker and target inventory, then
|
|
2867
|
+
creates or adopts tickets, maps blockers, deduplicates comments by exact body and
|
|
2868
|
+
restores current attachments. Both run sessionless without forge access.
|
|
2869
|
+
|
|
2870
|
+
TicketCreateOptions includes optional `requestedId`. Unsupported sources reject
|
|
2871
|
+
it. File keeps safe ids exactly; hosted preserves canonical own-team positive
|
|
2872
|
+
numbers and advances its counter above every occupied number. Creation-key
|
|
2873
|
+
adoption precedes collision checks. Known kept-number clashes stop import before
|
|
2874
|
+
any target mutation. Stable migration identities and atomic mapping files make
|
|
2875
|
+
interrupted imports resumable without content-based adoption.
|
|
2876
|
+
|
|
2877
|
+
File frontmatter additionally supports optional structured `comments` (body,
|
|
2878
|
+
createdAt, optional author) and `attachments` (kind, name, layout, entries with
|
|
2879
|
+
file base64 bytes or directory paths). Legacy absent fields retain old behavior;
|
|
2880
|
+
new creates use structured comments. Native file assets retain historical
|
|
2881
|
+
revisions in hidden source-local metadata and compose with legacy BuildStore
|
|
2882
|
+
assets. Build claims and spec re-pins freeze native assets into durable snapshots.
|
|
2883
|
+
|
|
2884
|
+
State normalization and the complete operator procedure are documented in
|
|
2885
|
+
[Ticket migration](docs/ticket-migration.md). The same reference is delivered in
|
|
2886
|
+
the installed guide. Export keeps lifecycle membership without inferring roles;
|
|
2887
|
+
import reuses unique case-insensitive states and creates normalized missing ones.
|