@defrex/autobuild 0.8.0 → 0.10.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.
Files changed (182) hide show
  1. package/README.md +1 -1
  2. package/SPEC.md +323 -26
  3. package/bin/ab-build-runner.ts +8 -2
  4. package/docs/architecture.md +166 -14
  5. package/docs/assets/headline-wide.png +0 -0
  6. package/docs/configuration.md +175 -28
  7. package/docs/hosted-dispatcher.md +69 -13
  8. package/docs/operator-api.md +2 -2
  9. package/docs/remote-store-protocol.md +204 -16
  10. package/docs/remote-ticket-protocol.md +1 -1
  11. package/docs/setup.md +12 -9
  12. package/docs/website.md +14 -0
  13. package/package.json +45 -23
  14. package/packages/core/src/cli/artifact.ts +130 -6
  15. package/packages/core/src/cli/binary.ts +9 -1
  16. package/packages/core/src/cli/build-control.ts +110 -13
  17. package/packages/core/src/cli/context.ts +46 -0
  18. package/packages/core/src/cli/dashboard/facts.ts +215 -0
  19. package/packages/core/src/cli/dashboard/frame-parse.ts +223 -0
  20. package/packages/core/src/cli/dashboard/model.ts +141 -153
  21. package/packages/core/src/cli/dashboard/poll.ts +76 -12
  22. package/packages/core/src/cli/dashboard/render.ts +34 -5
  23. package/packages/core/src/cli/dispatch-frontend.ts +54 -5
  24. package/packages/core/src/cli/dispatch-process.ts +1 -13
  25. package/packages/core/src/cli/dispatch.ts +392 -75
  26. package/packages/core/src/cli/harvest.ts +122 -8
  27. package/packages/core/src/cli/help.ts +62 -9
  28. package/packages/core/src/cli/init-readiness-remote.ts +110 -0
  29. package/packages/core/src/cli/init-readiness-shared.ts +72 -0
  30. package/packages/core/src/cli/init-validation.ts +266 -222
  31. package/packages/core/src/cli/installation.ts +50 -8
  32. package/packages/core/src/cli/main.ts +70 -11
  33. package/packages/core/src/cli/mcp.ts +23 -1
  34. package/packages/core/src/cli/plugin.ts +7 -4
  35. package/packages/core/src/cli/remote-poll.ts +277 -0
  36. package/packages/core/src/cli/repo-state.ts +22 -0
  37. package/packages/core/src/cli/repository-status.ts +39 -1
  38. package/packages/core/src/cli/self-update.ts +77 -2
  39. package/packages/core/src/cli/status.ts +150 -28
  40. package/packages/core/src/cli/terminals.ts +2 -1
  41. package/packages/core/src/cli/ticket-assets.ts +247 -0
  42. package/packages/core/src/cli/ticket.ts +453 -8
  43. package/packages/core/src/cli/wait.ts +157 -41
  44. package/packages/core/src/cli/watch.ts +138 -168
  45. package/packages/core/src/config/live.ts +23 -0
  46. package/packages/core/src/config/pipeline-source.ts +388 -0
  47. package/packages/core/src/config/schema.ts +251 -19
  48. package/packages/core/src/events/catalog.ts +1 -0
  49. package/packages/core/src/events/globs.ts +47 -0
  50. package/packages/core/src/events/payloads.ts +52 -2
  51. package/packages/core/src/events/repository.ts +52 -1
  52. package/packages/core/src/events/sessions.ts +69 -10
  53. package/packages/core/src/events/workspace-remote.ts +12 -0
  54. package/packages/core/src/integration/harness.ts +115 -2
  55. package/packages/core/src/kernel/__snapshots__/reducer-registry.test.ts.snap +1369 -0
  56. package/packages/core/src/kernel/auto-merge-default.ts +157 -0
  57. package/packages/core/src/kernel/auto-merge.ts +99 -22
  58. package/packages/core/src/kernel/dispatch-settings.ts +42 -17
  59. package/packages/core/src/kernel/dispatch-status.ts +23 -0
  60. package/packages/core/src/kernel/engine.ts +9 -438
  61. package/packages/core/src/kernel/generators/build-log.ts +259 -0
  62. package/packages/core/src/kernel/generators/repository-journals.ts +206 -0
  63. package/packages/core/src/kernel/generators/session-log.ts +72 -0
  64. package/packages/core/src/kernel/harvest.ts +62 -18
  65. package/packages/core/src/kernel/incremental-contract.ts +75 -0
  66. package/packages/core/src/kernel/incremental-fixtures.ts +211 -0
  67. package/packages/core/src/kernel/incremental.ts +53 -0
  68. package/packages/core/src/kernel/log-index.ts +620 -0
  69. package/packages/core/src/kernel/phases.ts +16 -2
  70. package/packages/core/src/kernel/pr-attachments.ts +164 -46
  71. package/packages/core/src/kernel/reducer-registry.ts +164 -0
  72. package/packages/core/src/kernel/reducer.ts +254 -73
  73. package/packages/core/src/operator/annotations.ts +6 -0
  74. package/packages/core/src/operator/control.ts +19 -5
  75. package/packages/core/src/operator/index.ts +71 -6
  76. package/packages/core/src/operator/query.ts +253 -24
  77. package/packages/core/src/operator/read-view.ts +98 -0
  78. package/packages/core/src/operator/registry.ts +55 -10
  79. package/packages/core/src/operator/requests.ts +9 -6
  80. package/packages/core/src/operator/sandbox-host.ts +140 -0
  81. package/packages/core/src/operator/sandbox.ts +247 -14
  82. package/packages/core/src/operator/ticket-source-backend.ts +47 -0
  83. package/packages/core/src/orchestrator/approvals.ts +115 -0
  84. package/packages/core/src/orchestrator/conversation.ts +167 -0
  85. package/packages/core/src/orchestrator/model.ts +86 -0
  86. package/packages/core/src/orchestrator/prompt.ts +61 -0
  87. package/packages/core/src/orchestrator/tools.ts +117 -0
  88. package/packages/core/src/orchestrator/turn-runner.ts +457 -0
  89. package/packages/core/src/plugin-sdk/index.ts +51 -1
  90. package/packages/core/src/plugins/load.ts +135 -7
  91. package/packages/core/src/plugins/manifest.ts +183 -10
  92. package/packages/core/src/plugins/registry.ts +73 -4
  93. package/packages/core/src/ports/forge/create.ts +1 -1
  94. package/packages/core/src/ports/forge/fake.ts +31 -0
  95. package/packages/core/src/ports/forge/github-transport.ts +13 -2
  96. package/packages/core/src/ports/forge/github.ts +13 -2
  97. package/packages/core/src/ports/forge/local-git.ts +31 -1
  98. package/packages/core/src/ports/runner/claude.ts +2 -2
  99. package/packages/core/src/ports/runner/codex.ts +6 -2
  100. package/packages/core/src/ports/runner/fake.ts +7 -1
  101. package/packages/core/src/ports/runner/pi.ts +8 -6
  102. package/packages/core/src/ports/runner/provider-error.ts +13 -3
  103. package/packages/core/src/ports/tickets/fake.ts +5 -1
  104. package/packages/core/src/ports/tickets/file.ts +169 -48
  105. package/packages/core/src/ports/tickets/{remote-index.ts → hosted-index.ts} +3 -2
  106. package/packages/core/src/ports/tickets/linear.ts +33 -1
  107. package/packages/core/src/ports/tickets/operations.ts +1 -1
  108. package/packages/core/src/ports/tickets/remote.ts +8 -1
  109. package/packages/core/src/ports/types.ts +49 -3
  110. package/packages/core/src/ports/workspace/builtin-capabilities.ts +114 -0
  111. package/packages/core/src/ports/workspace/create.ts +74 -39
  112. package/packages/core/src/ports/workspace/distribution-archive.ts +171 -12
  113. package/packages/core/src/ports/workspace/fake.ts +169 -4
  114. package/packages/core/src/ports/workspace/git-worktree.ts +246 -26
  115. package/packages/core/src/ports/workspace/github-origin.ts +36 -0
  116. package/packages/core/src/ports/workspace/operator-sandbox.ts +7 -1
  117. package/packages/core/src/ports/workspace/provider-capabilities.ts +171 -0
  118. package/packages/core/src/ports/workspace/vercel-capabilities.ts +110 -0
  119. package/packages/core/src/ports/workspace/vercel-sandbox.ts +142 -114
  120. package/packages/core/src/processes/build-child.ts +17 -2
  121. package/packages/core/src/processes/build-execution-state.ts +68 -15
  122. package/packages/core/src/processes/build-runner.ts +238 -93
  123. package/packages/core/src/processes/dispatcher-selectors.ts +123 -0
  124. package/packages/core/src/processes/dispatcher.ts +501 -201
  125. package/packages/core/src/processes/execution-settlement.ts +72 -39
  126. package/packages/core/src/processes/harvest-child.ts +5 -0
  127. package/packages/core/src/processes/harvest-execution-state.ts +41 -29
  128. package/packages/core/src/processes/harvest-runner.ts +66 -19
  129. package/packages/core/src/processes/harvest.ts +196 -24
  130. package/packages/core/src/processes/infrastructure-failure-budget.ts +31 -18
  131. package/packages/core/src/processes/orchestrator-tick.ts +360 -0
  132. package/packages/core/src/processes/publication-state.ts +164 -52
  133. package/packages/core/src/processes/repo-view.ts +1436 -0
  134. package/packages/core/src/processes/sandbox-state.ts +36 -2
  135. package/packages/core/src/processes/tick-state.ts +33 -0
  136. package/packages/core/src/store/adapter.ts +41 -0
  137. package/packages/core/src/store/build-scope.ts +90 -0
  138. package/packages/core/src/store/contract.ts +1205 -0
  139. package/packages/core/src/store/digest.ts +102 -0
  140. package/packages/core/src/store/local/schema.ts +46 -2
  141. package/packages/core/src/store/local/store.ts +445 -4
  142. package/packages/core/src/store/memory.ts +246 -0
  143. package/packages/core/src/store/new-build.ts +17 -0
  144. package/packages/core/src/store/phase-session.ts +94 -0
  145. package/packages/core/src/store/remote/client.ts +310 -2
  146. package/packages/core/src/store/remote/index.ts +14 -2
  147. package/packages/core/src/store/remote/protocol.ts +115 -12
  148. package/packages/core/src/store/remote/version.ts +6 -2
  149. package/packages/core/src/store/repo-state-events.ts +205 -0
  150. package/packages/core/src/store/retention.ts +7 -0
  151. package/packages/core/src/store/session-handle.ts +94 -0
  152. package/packages/core/src/{sessions/reducer.ts → store/session-reducer.ts} +79 -19
  153. package/packages/core/src/store/snapshots.ts +88 -0
  154. package/packages/core/src/store/streams/session-writer.ts +42 -2
  155. package/packages/core/src/store/streams/wait.ts +4 -5
  156. package/packages/core/src/store/ticket-assets.ts +458 -0
  157. package/packages/core/src/store/types.ts +160 -1
  158. package/packages/core/src/testing/index.ts +59 -0
  159. package/skills/code-review/SKILL.md +5 -1
  160. package/skills/guide/SKILL.md +152 -40
  161. package/skills/guide/references/operator-api.md +2 -2
  162. package/skills/guide/references/plugin-authoring.md +17 -0
  163. package/skills/guide/references/remote-store-protocol.md +204 -16
  164. package/skills/guide/references/remote-ticket-protocol.md +1 -1
  165. package/skills/guide/references/setup.md +12 -9
  166. package/skills/implement/SKILL.md +3 -0
  167. package/skills/operate/SKILL.md +126 -0
  168. package/skills/plan/SKILL.md +4 -0
  169. package/skills/plan-review/SKILL.md +5 -1
  170. package/skills/spec/SKILL.md +46 -3
  171. package/skills/tickets/SKILL.md +57 -5
  172. package/packages/core/src/cli/dashboard/frame-image.ts +0 -373
  173. package/packages/core/src/cli/store-opening.contract.ts +0 -289
  174. package/packages/core/src/cli/testkit.ts +0 -194
  175. package/packages/core/src/markdown.ts +0 -67
  176. package/packages/core/src/operator/client.ts +0 -311
  177. package/packages/core/src/operator/server.ts +0 -616
  178. package/packages/core/src/operator/sessions.ts +0 -223
  179. package/packages/core/src/ports/runner/live-contract-fixture.ts +0 -176
  180. package/packages/core/src/ports/tickets/remote-server.ts +0 -185
  181. package/packages/core/src/store/remote/server.ts +0 -923
  182. package/packages/core/src/testing/store-failures.ts +0 -32
@@ -0,0 +1,102 @@
1
+ /**
2
+ * The shared build-digest derivation (AUT-487): every BuildStore adapter
3
+ * answers `getRepoBuildDigests` by fetching only the digest-relevant event
4
+ * types from its existing event table and running this one pure function per
5
+ * build — identical results by construction, and the digest's `terminal` can
6
+ * never drift from `reduceBuild`'s terminal rule because this is the same
7
+ * in-order-overwrite of the latest terminal fact (§15.5). AUT-521 widens the
8
+ * projection with the observation timestamps and merge facts the harvest
9
+ * pressure gate needs, keeping that gate's cost flat in accumulated build
10
+ * history.
11
+ */
12
+ import type { AbEvent } from '../events/catalog'
13
+ import { defineReducer, type IncrementalReducer } from '../kernel/incremental'
14
+ import type { BuildDigest } from './types'
15
+
16
+ /** The event types a digest is derived from. Adapters filter their event
17
+ * rows to exactly these, so a per-build type-filtered index keeps the scan's
18
+ * cost growing with the actual signal, not with total history. */
19
+ export const DIGEST_EVENT_TYPES = [
20
+ 'build.completed',
21
+ 'build.aborted',
22
+ 'observation.recorded',
23
+ 'pr.merged',
24
+ 'pr-attachment.hosted',
25
+ 'pr-attachment.reclaimed',
26
+ 'execution.started',
27
+ 'execution.ended',
28
+ ] as const
29
+
30
+ /** The digest-relevant slice of one event row. Adapters ship `hostedSeq` for
31
+ * `pr-attachment.reclaimed` rows and `instance` for `execution.started` /
32
+ * `execution.ended` rows instead of whole payloads. */
33
+ export type DigestEventRow = Pick<AbEvent, 'type' | 'seq' | 'ts'> & {
34
+ hostedSeq?: number
35
+ instance?: string
36
+ }
37
+
38
+ /** The digest-relevant projection of one build's events, in log order.
39
+ * `terminal` follows `reduceBuild` exactly: `build.completed` sets `done`,
40
+ * `build.aborted` sets `aborted`, latest wins (in-order overwrite) — and
41
+ * `merged` follows the same overwrite pattern for `pr.merged` timestamps.
42
+ * The events carry no slug, so the result is slug-less; every adapter attaches
43
+ * `slug` itself when grouping its per-build event rows. */
44
+ export type DigestEvent = DigestEventRow
45
+
46
+ /** The carried accumulator for `reduceBuildDigest`. */
47
+ export interface DigestAcc {
48
+ terminal?: BuildDigest['terminal']
49
+ merged?: string
50
+ observations: { seq: number; ts: string }[]
51
+ /** `pendingPrAttachmentReclaims`: seqs of hosted events. */
52
+ hosted: number[]
53
+ /** Hosted seqs named by a reclaimed event with a later seq. */
54
+ reclaimed: number[]
55
+ /** `openExecution`: the latest start's instance, cleared only by an instance-matched end. */
56
+ openInstance: string | null
57
+ }
58
+
59
+ /** Bump when `DigestAcc`'s shape or fold semantics change. */
60
+ export const BUILD_DIGEST_REDUCER_VERSION = 2
61
+
62
+ export const buildDigestReducer: IncrementalReducer<
63
+ DigestAcc,
64
+ DigestEvent,
65
+ Omit<BuildDigest, 'slug'>
66
+ > = defineReducer({
67
+ version: BUILD_DIGEST_REDUCER_VERSION,
68
+ initial: (): DigestAcc => ({ observations: [], hosted: [], reclaimed: [], openInstance: null }),
69
+ fold(acc, events) {
70
+ for (const event of events) {
71
+ if (event.type === 'build.completed') acc.terminal = 'done'
72
+ else if (event.type === 'build.aborted') acc.terminal = 'aborted'
73
+ else if (event.type === 'pr.merged') acc.merged = event.ts
74
+ else if (event.type === 'observation.recorded')
75
+ acc.observations.push({ seq: event.seq, ts: event.ts })
76
+ else if (event.type === 'pr-attachment.hosted') acc.hosted.push(event.seq)
77
+ else if (event.type === 'pr-attachment.reclaimed') {
78
+ if (event.hostedSeq !== undefined && event.seq > event.hostedSeq)
79
+ acc.reclaimed.push(event.hostedSeq)
80
+ } else if (event.type === 'execution.started') acc.openInstance = event.instance ?? null
81
+ else if (event.type === 'execution.ended') {
82
+ if (acc.openInstance !== null && event.instance === acc.openInstance)
83
+ acc.openInstance = null
84
+ }
85
+ }
86
+ },
87
+ finish: ({ terminal, merged, observations, hosted, reclaimed, openInstance }) => {
88
+ const reclaimedSet = new Set(reclaimed)
89
+ const reclaimPending = hosted.some((seq) => !reclaimedSet.has(seq))
90
+ return {
91
+ observations: [...observations],
92
+ ...(merged !== undefined ? { merged } : {}),
93
+ ...(terminal !== undefined ? { terminal } : {}),
94
+ ...(reclaimPending ? { reclaimPending: true as const } : {}),
95
+ ...(openInstance !== null ? { executionOpen: true as const } : {}),
96
+ }
97
+ },
98
+ })
99
+
100
+ export function reduceBuildDigest(events: DigestEvent[]): Omit<BuildDigest, 'slug'> {
101
+ return buildDigestReducer.reduce(events)
102
+ }
@@ -9,9 +9,10 @@
9
9
  * be kept in lockstep with this schema (this file is the drizzle-kit source
10
10
  * of truth).
11
11
  */
12
- import { integer, primaryKey, sqliteTable, text } from 'drizzle-orm/sqlite-core'
12
+ import { index, integer, primaryKey, sqliteTable, text } from 'drizzle-orm/sqlite-core'
13
13
  import type { Actor } from '../../events/envelope'
14
14
  import type { TicketRef } from '../../ontology'
15
+ import type { TicketAssetEntry } from '../ticket-assets'
15
16
  import type { StreamPart } from '../streams/types'
16
17
 
17
18
  export const builds = sqliteTable('builds', {
@@ -39,7 +40,12 @@ export const events = sqliteTable(
39
40
  type: text('type').notNull(),
40
41
  payload: text('payload', { mode: 'json' }).notNull(),
41
42
  },
42
- (t) => [primaryKey({ columns: [t.build, t.seq] })],
43
+ // Mirrors the BOOTSTRAP_DDL digest-scan index (AUT-487), type-leading so the
44
+ // digest query's cost grows with digest-relevant events, not total history.
45
+ (t) => [
46
+ primaryKey({ columns: [t.build, t.seq] }),
47
+ index('events_type_build_seq').on(t.type, t.build, t.seq),
48
+ ],
43
49
  )
44
50
 
45
51
  export const repoStreams = sqliteTable('repo_streams', {
@@ -78,6 +84,44 @@ export const repoArtifacts = sqliteTable(
78
84
  (t) => [primaryKey({ columns: [t.repo, t.kind, t.revision] })],
79
85
  )
80
86
 
87
+ /** Ticket assets (SPEC §7.1): one row per revision, manifest as JSON, file
88
+ * bytes in the BlobStore. A removal is a tombstone row (`removed`, empty
89
+ * manifest) taking the next revision. No FK to `repo_streams`: assets can
90
+ * precede any repo-journal row. */
91
+ export const ticketAssets = sqliteTable(
92
+ 'ticket_assets',
93
+ {
94
+ repo: text('repo').notNull(),
95
+ ticketId: text('ticket_id').notNull(),
96
+ kind: text('kind').notNull(),
97
+ name: text('name').notNull(),
98
+ revision: integer('revision').notNull(),
99
+ layout: text('layout').notNull().$type<'file' | 'tree'>(),
100
+ manifest: text('manifest', { mode: 'json' }).notNull().$type<TicketAssetEntry[]>(),
101
+ size: integer('size').notNull(),
102
+ removed: integer('removed').notNull(),
103
+ createdAt: text('created_at').notNull(),
104
+ },
105
+ (t) => [primaryKey({ columns: [t.repo, t.ticketId, t.kind, t.name, t.revision] })],
106
+ )
107
+
108
+ /** Reducer snapshots (store/snapshots.ts): a cache of one reducer's state as of
109
+ * a log cursor, per scope (`scope_kind` build|repo, `scope_key` the slug or
110
+ * repo). Never an authority — the log regenerates any row. */
111
+ export const reducerSnapshots = sqliteTable(
112
+ 'reducer_snapshots',
113
+ {
114
+ scopeKind: text('scope_kind').notNull(),
115
+ scopeKey: text('scope_key').notNull(),
116
+ reducer: text('reducer').notNull(),
117
+ version: integer('version').notNull(),
118
+ cursor: integer('cursor').notNull(),
119
+ state: text('state').notNull(),
120
+ updatedAt: text('updated_at').notNull(),
121
+ },
122
+ (t) => [primaryKey({ columns: [t.scopeKind, t.scopeKey, t.reducer] })],
123
+ )
124
+
81
125
  /** Operator sessions (SPEC §7.1.1): hosted-only durable orchestrator
82
126
  * conversation state. Adapters implement the contract uniformly; nothing
83
127
  * local creates one. */