@alecsibilia/luca 14.0.0-alpha.2 → 14.0.0-alpha.21

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 (321) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +7 -2
  3. package/board/client/board-look.ts +31 -1
  4. package/board/client/board-panel-parts.tsx +150 -0
  5. package/board/client/board-panel-stages.ts +99 -0
  6. package/board/client/board-panel-styles.ts +223 -0
  7. package/board/client/board-panel.tsx +77 -1275
  8. package/board/client/engine-life.ts +48 -0
  9. package/board/client/final-review-stack.tsx +144 -0
  10. package/board/client/heartbeat.tsx +61 -0
  11. package/board/client/helper-lines.tsx +69 -0
  12. package/board/client/live-feed.tsx +86 -0
  13. package/board/client/live-line.ts +73 -0
  14. package/board/client/model-line.tsx +178 -0
  15. package/board/client/needs-you-section.tsx +133 -0
  16. package/board/client/one-line.tsx +193 -0
  17. package/board/client/repo-wait-banner.tsx +69 -0
  18. package/board/client/run-footer.tsx +68 -0
  19. package/board/client/run-header.tsx +189 -0
  20. package/board/client/run-picker.tsx +98 -0
  21. package/board/client/status-bar.tsx +131 -0
  22. package/board/client/step-dots.tsx +127 -0
  23. package/board/client/stuck-actions.tsx +269 -0
  24. package/board/client/ticket-card-view.tsx +238 -0
  25. package/board/client/ticket-detail.tsx +87 -0
  26. package/board/client/ticket-stack.tsx +119 -0
  27. package/board/client/ticket-wait.ts +188 -0
  28. package/board/client/timeline-rows.tsx +41 -14
  29. package/board/client/usage-line.tsx +51 -0
  30. package/board/client/wait-line.tsx +39 -0
  31. package/board/index.client.tsx +1 -1
  32. package/board/index.server.ts +7 -1
  33. package/board/package.json +1 -1
  34. package/board/server/board-panel-state-helpers.ts +67 -0
  35. package/board/server/board-server-check.ts +294 -0
  36. package/board/server/board-server-engine.ts +129 -0
  37. package/board/server/board-server-events.ts +134 -0
  38. package/board/server/board-server-read.ts +190 -0
  39. package/board/server/board-server-resume.ts +164 -0
  40. package/board/server/board-server-start.ts +174 -0
  41. package/board/server/board-server-store.ts +281 -0
  42. package/board/server/board-server-types.ts +114 -0
  43. package/board/server/board-server-util.ts +4 -0
  44. package/board/server/board-server.ts +52 -943
  45. package/board/server/board-vocabulary-engine.ts +144 -0
  46. package/board/server/board-vocabulary-review.ts +115 -0
  47. package/board/server/board-vocabulary-run.ts +145 -0
  48. package/board/server/board-vocabulary-shapes.ts +153 -0
  49. package/board/server/board-vocabulary.ts +20 -375
  50. package/board/server/current-step-panel-helpers.ts +108 -0
  51. package/board/server/describe-record.ts +403 -0
  52. package/board/server/engine-launch.ts +20 -3
  53. package/board/server/engine-restart-helpers.ts +105 -0
  54. package/board/server/engine-watch.ts +45 -5
  55. package/board/server/journal-rebuild-helpers.ts +169 -0
  56. package/board/server/live-file.ts +130 -0
  57. package/board/server/luca-version.ts +1 -1
  58. package/board/server/make-rows.ts +14 -629
  59. package/board/server/record-texts.ts +350 -0
  60. package/board/server/reduce-board-agent-start.ts +224 -0
  61. package/board/server/reduce-board-agents.ts +160 -0
  62. package/board/server/reduce-board-counters.ts +138 -0
  63. package/board/server/reduce-board-create.ts +148 -0
  64. package/board/server/reduce-board-final-review.ts +174 -0
  65. package/board/server/reduce-board-needs-you.ts +283 -0
  66. package/board/server/reduce-board-reasons.ts +59 -0
  67. package/board/server/reduce-board-run.ts +255 -0
  68. package/board/server/reduce-board-settle.ts +88 -0
  69. package/board/server/reduce-board-steps.ts +226 -0
  70. package/board/server/reduce-board-text.ts +139 -0
  71. package/board/server/reduce-board-ticket-checks.ts +168 -0
  72. package/board/server/reduce-board-ticket-join.ts +144 -0
  73. package/board/server/reduce-board-ticket-start.ts +132 -0
  74. package/board/server/reduce-board-update.ts +117 -0
  75. package/board/server/reduce-board-usage.ts +247 -0
  76. package/board/server/reduce-board.ts +100 -1917
  77. package/board/server/reply-post.ts +407 -0
  78. package/board/server/run-registry.ts +8 -4
  79. package/board/server/ticket-stages-panel-helpers.ts +296 -0
  80. package/board/shared/board-rows.ts +9 -0
  81. package/board/shared/board-rpc.ts +42 -0
  82. package/board/shared/board-state-counts.ts +77 -0
  83. package/board/shared/board-state-live.ts +99 -0
  84. package/board/shared/board-state-review.ts +59 -0
  85. package/board/shared/board-state-run.ts +236 -0
  86. package/board/shared/board-state-ticket.ts +257 -0
  87. package/board/shared/board-state-usage.ts +107 -0
  88. package/board/shared/board-state.ts +97 -567
  89. package/board/shared/reply-actions.ts +207 -0
  90. package/engine/agents/agent-launcher.ts +27 -4
  91. package/engine/agents/claude-launcher-helpers.ts +233 -0
  92. package/engine/agents/claude-launcher.ts +28 -669
  93. package/engine/agents/claude-messages.ts +212 -0
  94. package/engine/agents/claude-options.ts +43 -8
  95. package/engine/agents/common-instructions.ts +138 -0
  96. package/engine/agents/input-channel.ts +36 -0
  97. package/engine/agents/launch-paths.ts +29 -0
  98. package/engine/agents/launch-session.ts +227 -0
  99. package/engine/agents/learner-instructions.ts +31 -0
  100. package/engine/agents/open-session.ts +210 -0
  101. package/engine/agents/prompt-sections.ts +95 -0
  102. package/engine/agents/rejoin-prompts.ts +135 -0
  103. package/engine/agents/reviewer-instructions.ts +99 -0
  104. package/engine/agents/role-instructions.ts +31 -244
  105. package/engine/agents/role-prompts.ts +39 -109
  106. package/engine/agents/role-results.ts +106 -7
  107. package/engine/agents/scripted-launcher.ts +21 -6
  108. package/engine/agents/session-pool.ts +124 -0
  109. package/engine/agents/turn-progress.ts +283 -0
  110. package/engine/agents/writer-instructions.ts +151 -0
  111. package/engine/cli/computer-adapters-real.ts +15 -3
  112. package/engine/cli/computer-adapters.ts +2 -0
  113. package/engine/cli/computer-checks.ts +87 -4
  114. package/engine/cli/config-reload-text.ts +39 -0
  115. package/engine/cli/decision-model-setup.ts +70 -0
  116. package/engine/cli/doctor-command.ts +1 -0
  117. package/engine/cli/doctor.ts +21 -3
  118. package/engine/cli/going-runs.ts +192 -36
  119. package/engine/cli/init-command.ts +1 -0
  120. package/engine/cli/init.ts +23 -1
  121. package/engine/cli/live-runs.ts +73 -0
  122. package/engine/cli/luca-run.ts +42 -7
  123. package/engine/cli/luca-skills.ts +183 -0
  124. package/engine/cli/luca.ts +8 -1
  125. package/engine/cli/models-command.ts +119 -0
  126. package/engine/cli/read-run.ts +81 -0
  127. package/engine/cli/run-args.ts +33 -6
  128. package/engine/cli/run-demo.ts +143 -0
  129. package/engine/cli/run-end.ts +184 -0
  130. package/engine/cli/run-modes-helpers.ts +81 -0
  131. package/engine/cli/run-modes.ts +62 -439
  132. package/engine/cli/setup.ts +5 -48
  133. package/engine/cli/unfinished-runs.ts +122 -0
  134. package/engine/cli/upgrade-command.ts +212 -30
  135. package/engine/cli/upgrade-finish.ts +149 -0
  136. package/engine/cli/upgrade.ts +112 -71
  137. package/engine/config/config-fields.ts +127 -0
  138. package/engine/config/config-reload.ts +250 -0
  139. package/engine/config/engine-config-schema.ts +235 -0
  140. package/engine/config/engine-config.ts +72 -142
  141. package/engine/config/test-commands.ts +102 -0
  142. package/engine/core/agent-guards-helpers.ts +84 -0
  143. package/engine/core/agent-turn.ts +395 -0
  144. package/engine/core/already-done.ts +44 -1
  145. package/engine/core/build-action.ts +214 -0
  146. package/engine/core/build-context.ts +135 -0
  147. package/engine/core/build-launch.ts +259 -0
  148. package/engine/core/commit-in.ts +282 -0
  149. package/engine/core/decide-build-early.ts +108 -0
  150. package/engine/core/decide-build-ending.ts +145 -0
  151. package/engine/core/decide-build-helpers.ts +87 -0
  152. package/engine/core/decide-build-tickets.ts +207 -0
  153. package/engine/core/decide-build-view.ts +103 -0
  154. package/engine/core/decide-build.ts +101 -1368
  155. package/engine/core/decide-final-fix.ts +203 -0
  156. package/engine/core/decide-final-review.ts +55 -310
  157. package/engine/core/decide-red-green.ts +398 -0
  158. package/engine/core/decide-rejoin.ts +259 -0
  159. package/engine/core/decide-repo-wait.ts +129 -0
  160. package/engine/core/decide-run-budget.ts +86 -12
  161. package/engine/core/decide-stuck-helpers.ts +127 -0
  162. package/engine/core/decide-stuck.ts +60 -8
  163. package/engine/core/decide-ticket-review.ts +95 -0
  164. package/engine/core/decide-ticket.ts +267 -0
  165. package/engine/core/decide-waits.ts +47 -0
  166. package/engine/core/decide.ts +74 -23
  167. package/engine/core/engine-chores.ts +163 -0
  168. package/engine/core/environment-rerun.ts +83 -0
  169. package/engine/core/evidence-text.ts +84 -0
  170. package/engine/core/execute-action.ts +303 -0
  171. package/engine/core/execute-already-done-check.ts +133 -0
  172. package/engine/core/execute-build.ts +68 -944
  173. package/engine/core/execute-changeset.ts +5 -7
  174. package/engine/core/execute-final-review.ts +125 -13
  175. package/engine/core/execute-gates.ts +182 -0
  176. package/engine/core/execute-intake.ts +130 -0
  177. package/engine/core/execute-join.ts +276 -0
  178. package/engine/core/execute-memory.ts +12 -0
  179. package/engine/core/execute-pull-request.ts +84 -0
  180. package/engine/core/execute-red-check.ts +219 -0
  181. package/engine/core/execute-repo-wait.ts +129 -0
  182. package/engine/core/execute-stuck.ts +25 -10
  183. package/engine/core/execute-waits.ts +158 -0
  184. package/engine/core/execute-with-jev.ts +118 -0
  185. package/engine/core/execute.ts +124 -831
  186. package/engine/core/final-failure-cap.ts +38 -0
  187. package/engine/core/final-review-action.ts +125 -0
  188. package/engine/core/final-review-text.ts +63 -17
  189. package/engine/core/final-stuck-text.ts +86 -0
  190. package/engine/core/fix-loop-text.ts +49 -2
  191. package/engine/core/left-out.ts +120 -0
  192. package/engine/core/live-file.ts +372 -0
  193. package/engine/core/loop-caps.ts +25 -2
  194. package/engine/core/not-in-run.ts +7 -3
  195. package/engine/core/pull-request-text.ts +255 -6
  196. package/engine/core/repo-wait-text.ts +81 -0
  197. package/engine/core/review-text.ts +55 -1
  198. package/engine/core/run-crash-recovery-helpers.ts +16 -0
  199. package/engine/core/run-session-close-helpers.ts +96 -0
  200. package/engine/core/run-start.ts +148 -0
  201. package/engine/core/run-stuck-text.ts +86 -0
  202. package/engine/core/schedule-rules.ts +193 -0
  203. package/engine/core/stuck-detail-text.ts +89 -0
  204. package/engine/core/stuck-format.ts +22 -0
  205. package/engine/core/stuck-text.ts +29 -332
  206. package/engine/core/ticket-stuck-text.ts +192 -0
  207. package/engine/core/worktree-changes.ts +106 -0
  208. package/engine/gates/already-done-check.ts +120 -0
  209. package/engine/gates/feature-map.ts +96 -0
  210. package/engine/gates/gate-runner.ts +108 -108
  211. package/engine/gates/gate-schemas.ts +61 -2
  212. package/engine/gates/leftover-scan.ts +154 -31
  213. package/engine/gates/new-tests.ts +45 -0
  214. package/engine/gates/own-files-check.ts +98 -0
  215. package/engine/gates/prepare-check.ts +60 -0
  216. package/engine/gates/prepare-slots.ts +99 -0
  217. package/engine/gates/red-check.ts +184 -16
  218. package/engine/gates/shell-check.ts +64 -0
  219. package/engine/gates/slot-waits.ts +55 -0
  220. package/engine/gates/slow-test-runner.ts +59 -0
  221. package/engine/gates/test-checks.ts +161 -0
  222. package/engine/gates/test-runner.ts +164 -5
  223. package/engine/gates/test-slots.ts +48 -0
  224. package/engine/git/git-adapter.ts +55 -396
  225. package/engine/git/git-commits.ts +132 -0
  226. package/engine/git/git-join.ts +139 -0
  227. package/engine/git/git-read.ts +123 -0
  228. package/engine/git/git-run.ts +32 -0
  229. package/engine/git/git-worktrees.ts +143 -0
  230. package/engine/git/outside-links.ts +55 -0
  231. package/engine/guards/after-turn-check.ts +31 -5
  232. package/engine/guards/guard-hook.ts +60 -12
  233. package/engine/guards/guard-roles.ts +68 -0
  234. package/engine/guards/helper-rules.ts +92 -0
  235. package/engine/guards/permission-rules.ts +161 -0
  236. package/engine/guards/role-rules-helpers.ts +48 -0
  237. package/engine/guards/role-rules.ts +34 -606
  238. package/engine/guards/shell-rules.ts +344 -0
  239. package/engine/guards/worktree-git.ts +208 -0
  240. package/engine/guards/worktree-snapshot.ts +412 -0
  241. package/engine/guards/worktree-state.ts +28 -825
  242. package/engine/guards/worktree-undo.ts +260 -0
  243. package/engine/guards/write-rules.ts +149 -0
  244. package/engine/index.ts +30 -9
  245. package/engine/intake/criteria-checks.ts +114 -0
  246. package/engine/intake/intake-checks.ts +164 -30
  247. package/engine/intake/intake-schemas.ts +37 -2
  248. package/engine/jev/clef-client.ts +259 -0
  249. package/engine/jev/decision-model-credentials.ts +212 -0
  250. package/engine/jev/jev-jobs.ts +144 -60
  251. package/engine/jev/jev-schemas.ts +86 -5
  252. package/engine/jev/jev-shadow-helpers.ts +218 -0
  253. package/engine/jev/jev-shadow.ts +109 -64
  254. package/engine/jev/model-pick.ts +275 -0
  255. package/engine/journal/agent-entries.ts +167 -0
  256. package/engine/journal/agent-message-entries.ts +72 -0
  257. package/engine/journal/agent-turn-replay.ts +203 -0
  258. package/engine/journal/already-done-entries.ts +55 -0
  259. package/engine/journal/commit-entries.ts +56 -0
  260. package/engine/journal/cross-ticket-replay.ts +222 -0
  261. package/engine/journal/decision-model-entries.ts +86 -0
  262. package/engine/journal/entry-fields.ts +10 -0
  263. package/engine/journal/final-review-entries.ts +128 -0
  264. package/engine/journal/final-review-replay.ts +324 -0
  265. package/engine/journal/final-review-round.ts +320 -0
  266. package/engine/journal/final-review-state.ts +180 -0
  267. package/engine/journal/gate-entries.ts +81 -0
  268. package/engine/journal/intake-entries.ts +87 -0
  269. package/engine/journal/join-entries.ts +126 -0
  270. package/engine/journal/journal-entry-schema.ts +218 -0
  271. package/engine/journal/journal-kinds.ts +97 -0
  272. package/engine/journal/journal-record-schema.ts +218 -0
  273. package/engine/journal/journal-record.ts +43 -1400
  274. package/engine/journal/journal.ts +6 -1
  275. package/engine/journal/limit-entries.ts +90 -0
  276. package/engine/journal/memory-entries.ts +124 -0
  277. package/engine/journal/memory-replay.ts +157 -0
  278. package/engine/journal/plan-replay.ts +139 -0
  279. package/engine/journal/pull-request-entries.ts +41 -0
  280. package/engine/journal/replay.ts +157 -2144
  281. package/engine/journal/reply-replay.ts +144 -0
  282. package/engine/journal/repo-wait-entries.ts +53 -0
  283. package/engine/journal/run-entries.ts +172 -0
  284. package/engine/journal/run-state.ts +264 -0
  285. package/engine/journal/shared-failure-replay.ts +133 -0
  286. package/engine/journal/stuck-entries.ts +193 -0
  287. package/engine/journal/ticket-progress.ts +392 -0
  288. package/engine/journal/ticket-replay.ts +411 -0
  289. package/engine/journal/ticket-result-replay.ts +364 -0
  290. package/engine/journal/ticket-retry-replay.ts +142 -0
  291. package/engine/journal/worktree-entries.ts +122 -0
  292. package/engine/models/model-score.ts +512 -0
  293. package/engine/shell/run-command.ts +187 -18
  294. package/engine/testing/agent-turn-fixtures.ts +287 -0
  295. package/engine/testing/already-done-fixtures.ts +97 -0
  296. package/engine/testing/build-fixtures.ts +68 -973
  297. package/engine/testing/checkouts-fixtures.ts +48 -0
  298. package/engine/testing/final-review-fixtures.ts +62 -1
  299. package/engine/testing/final-review-steps.ts +143 -0
  300. package/engine/testing/limit-fixtures.ts +85 -0
  301. package/engine/testing/live-file-fixtures.ts +57 -0
  302. package/engine/testing/practice-repo.ts +10 -4
  303. package/engine/testing/practice-run.ts +1 -1
  304. package/engine/testing/reply-fixtures.ts +88 -0
  305. package/engine/testing/run-budget-fixtures.ts +165 -0
  306. package/engine/testing/run-fixtures.ts +219 -0
  307. package/engine/testing/sdk-play.ts +177 -0
  308. package/engine/testing/setup-repo.ts +194 -0
  309. package/engine/testing/step-record-fixtures.ts +55 -0
  310. package/engine/testing/ticket-step-fixtures.ts +272 -0
  311. package/engine/testing/wait-scenarios.ts +186 -0
  312. package/engine/tracker/gh-retry.ts +217 -0
  313. package/engine/tracker/github-tracker.ts +310 -90
  314. package/engine/tracker/in-memory-tracker.ts +8 -4
  315. package/engine/tracker/tracker.ts +131 -6
  316. package/package.json +2 -1
  317. package/skills/luca-retro/SKILL.md +74 -0
  318. package/skills/luca-retro/scripts/retro-summary.ts +1356 -0
  319. package/skills/luca-unstick/SKILL.md +153 -0
  320. package/skills/luca-unstick/scripts/stuck-summary.ts +1063 -0
  321. package/engine/jev/jev-client.ts +0 -173
@@ -1,978 +1,73 @@
1
- import { SPEC_OWNER } from './intake-fixtures'
2
-
3
- import type {
4
- AgentRole,
5
- Finding,
6
- FindingResponse,
7
- FindingRuling,
8
- } from '../agents/role-results'
9
- import type { EngineConfig } from '../config/engine-config'
10
- import type { TestRun } from '../gates/gate-schemas'
11
- import type { TicketSnapshot } from '../intake/intake-schemas'
12
- import type {
13
- CommitStage,
14
- JournalEntry,
15
- StuckReason,
16
- } from '../journal/journal-record'
17
-
18
1
  /**
19
2
  * Journal entry builders for the build steps, so decision-step tests can
20
3
  * write a journal that stops anywhere along a ticket's spine.
4
+ *
5
+ * The builders live in modules by job, and this module re-exports all of
6
+ * them, so a test imports every one from here.
21
7
  */
22
8
 
23
- export const BUILD_CONFIG: EngineConfig = {
24
- checks: { test: 'bun test', types: 'bun run types', lint: 'bun run lint' },
25
- test_file_patterns: ['**/*.test.ts'],
26
- test_setup_files: [],
27
- rule_files: [],
28
- }
29
-
30
- /** A ticket as intake snapshots it. */
31
- export const practiceTicket = ({
32
- number,
33
- title,
34
- criteria,
35
- labels,
36
- blockers,
37
- }: {
38
- number: number
39
- title?: string
40
- criteria?: string[]
41
- /** Defaults to `ready-for-agent` only; add `refactor` for a refactor ticket. */
42
- labels?: string[]
43
- /** The tickets it waits on. Defaults to none. */
44
- blockers?: number[]
45
- }): TicketSnapshot => ({
46
- number,
47
- title: title ?? 'Add sum',
48
- body: '## What to build\n\nA sum function.',
49
- labels: labels ?? ['ready-for-agent'],
50
- url: `https://github.com/acme/app/issues/${number}`,
51
- criteria: (criteria ?? ['sum adds two numbers']).map((text, index) => ({
52
- id: `AC${index + 1}`,
53
- text,
54
- })),
55
- blockers: blockers ?? [],
56
- })
57
-
58
- /** A run whose intake passed with these tickets, in this order. */
59
- export const intakePassed = ({
60
- tickets,
61
- }: {
62
- tickets: TicketSnapshot[]
63
- }): JournalEntry[] => [
64
- {
65
- kind: 'run_started',
66
- ticket: null,
67
- role: null,
68
- content: { spec_number: 10, config: BUILD_CONFIG, base_branch: 'main' },
69
- },
70
- {
71
- kind: 'spec_snapshot',
72
- ticket: 10,
73
- role: null,
74
- content: {
75
- spec: {
76
- number: 10,
77
- title: 'Practice spec',
78
- body: '## Testing Decisions\n\n- Test the sum.',
79
- labels: ['ready-for-agent'],
80
- url: 'https://github.com/acme/app/issues/10',
81
- author: SPEC_OWNER,
82
- },
83
- ticket_order: tickets.map((ticket) => ticket.number),
84
- closed_tickets: [],
85
- },
86
- },
87
- ...tickets.map(
88
- (ticket): JournalEntry => ({
89
- kind: 'ticket_snapshot',
90
- ticket: ticket.number,
91
- role: null,
92
- content: ticket,
93
- })
94
- ),
95
- ]
96
-
97
- export const RUN_BRANCH = 'luca/spec-10-run'
98
-
99
- /** Where fixtures put each ticket's worktree, and the run branch's. */
100
- export const ticketPath = (ticket: number): string =>
101
- `/runs/run/tickets/${ticket}`
102
-
103
- export const RUN_BRANCH_PATH = '/runs/run/run-branch'
104
-
105
- export const runBranchCreated = (): JournalEntry => ({
106
- kind: 'run_branch_created',
107
- ticket: null,
108
- role: null,
109
- content: {
110
- branch: RUN_BRANCH,
111
- path: RUN_BRANCH_PATH,
112
- base_sha: 'b0',
113
- },
114
- })
115
-
116
- export const ticketWorktreeCreated = ({
117
- ticket,
118
- }: {
119
- ticket: number
120
- }): JournalEntry => ({
121
- kind: 'ticket_worktree_created',
122
- ticket,
123
- role: null,
124
- content: {
125
- branch: `${RUN_BRANCH}--ticket-${ticket}`,
126
- path: ticketPath(ticket),
127
- base_sha: 'b0',
128
- },
129
- })
130
-
131
- /**
132
- * The engine's install in a new worktree: the run branch's checkout
133
- * (`ticket` unset) or a ticket's worktree. Passing unless `ok` is false.
134
- */
135
- export const dependenciesInstalled = ({
136
- ticket,
137
- ok,
138
- }: {
139
- ticket?: number
140
- ok?: boolean
141
- }): JournalEntry => ({
142
- kind: 'dependencies_installed',
143
- ticket: ticket ?? null,
144
- role: null,
145
- content: {
146
- target: ticket === undefined ? 'run_branch' : 'ticket',
147
- check: {
148
- name: 'install',
149
- command: 'bun install --frozen-lockfile',
150
- ok: ok ?? true,
151
- exit_code: ok === false ? 1 : 0,
152
- output:
153
- ok === false
154
- ? 'error: lockfile had changes, but lockfile is frozen'
155
- : '',
156
- },
157
- },
158
- })
159
-
160
- /**
161
- * The entries with a passing install after each new worktree that has none,
162
- * so tests about later steps need not list the installs.
163
- */
164
- export const withInstalls = ({
165
- entries,
166
- }: {
167
- entries: JournalEntry[]
168
- }): JournalEntry[] =>
169
- entries.flatMap((entry, index) => {
170
- const made =
171
- entry.kind === 'run_branch_created' ||
172
- entry.kind === 'ticket_worktree_created'
173
- if (!made || entries[index + 1]?.kind === 'dependencies_installed') {
174
- return [entry]
175
- }
176
- return [
177
- entry,
178
- dependenciesInstalled({ ticket: entry.ticket ?? undefined }),
179
- ]
180
- })
181
-
182
- /** A test run with no test files, as a fresh repo has. */
183
- export const emptyTestRun = (): TestRun => ({
184
- command: 'bun test',
185
- ok: true,
186
- exit_code: 1,
187
- no_test_files: true,
188
- cases: [],
189
- files_without_results: [],
190
- output: '0 test files matching',
191
- })
192
-
193
- export const baselineTests = ({
194
- ticket,
195
- }: {
196
- ticket: number
197
- }): JournalEntry => ({
198
- kind: 'baseline_tests',
199
- ticket,
200
- role: null,
201
- content: emptyTestRun(),
202
- })
203
-
204
- /** The session id fixtures give each role's turns unless told otherwise. */
205
- export const SESSIONS = {
206
- 'test-writer': 'tw-1',
207
- implementer: 'impl-1',
208
- 'ticket-reviewer': 'rev-1',
209
- 'architecture-lens': 'architecture-1',
210
- 'simplification-lens': 'simplification-1',
211
- 'security-lens': 'security-1',
212
- 'integration-lens': 'integration-1',
213
- 'rules-lens': 'rules-1',
214
- learner: 'learner-1',
215
- } as const satisfies Record<AgentRole, string>
216
-
217
- /** An agent turn started: a fresh launch, or a follow-up to `follow_up_of`. */
218
- export const agentStarted = ({
219
- ticket,
220
- role,
221
- prompt,
222
- follow_up_of,
223
- }: {
224
- /** `null` for the final review. */
225
- ticket: number | null
226
- role: AgentRole
227
- prompt?: string
228
- follow_up_of?: string
229
- }): JournalEntry => ({
230
- kind: 'agent_started',
231
- ticket,
232
- role,
233
- content: {
234
- role,
235
- prompt: prompt ?? 'p',
236
- follow_up_of: follow_up_of ?? null,
237
- },
238
- })
239
-
240
- export const testsWritten = ({
241
- ticket,
242
- session_id,
243
- assumptions,
244
- finding_responses,
245
- run_notes,
246
- }: {
247
- /** `null` for the final review. */
248
- ticket: number | null
249
- /** Defaults to `SESSIONS['test-writer']`. */
250
- session_id?: string
251
- /** Defaults to one assumption. */
252
- assumptions?: string[]
253
- /** A review fixer's answer to each finding it got. */
254
- finding_responses?: FindingResponse[]
255
- /** Defaults to none. */
256
- run_notes?: string[]
257
- }): JournalEntry => ({
258
- kind: 'agent_finished',
259
- ticket,
260
- role: 'test-writer',
261
- content: {
262
- role: 'test-writer',
263
- session_id: session_id ?? SESSIONS['test-writer'],
264
- result: {
265
- outcome: 'tests_written',
266
- criteria: [
267
- {
268
- criterion_id: 'AC1',
269
- tests: [
270
- {
271
- file: 'src/sum.test.ts',
272
- name: 'sum adds two numbers',
273
- },
274
- ],
275
- },
276
- ],
277
- summary: 'One test for AC1.',
278
- assumptions: assumptions ?? ['Numbers are integers.'],
279
- run_notes: run_notes ?? [],
280
- finding_responses: finding_responses ?? [],
281
- },
282
- },
283
- })
284
-
285
- /** A test-writer that found nothing new to test. */
286
- export const nothingNewToTest = ({
287
- ticket,
288
- }: {
289
- ticket: number
290
- }): JournalEntry => ({
291
- kind: 'agent_finished',
292
- ticket,
293
- role: 'test-writer',
294
- content: {
295
- role: 'test-writer',
296
- session_id: SESSIONS['test-writer'],
297
- result: { outcome: 'nothing_new_to_test' },
298
- },
299
- })
300
-
301
- /** The commit fixtures say did an already-done ticket's work. */
302
- export const DONE_SHA = '3559c25f5a1b2c3d4e5f60718293a4b5c6d7e8f9'
303
-
304
- /**
305
- * A test-writer that found the ticket's work already on the base branch:
306
- * done by `DONE_SHA` unless told otherwise, with one existing test for AC1.
307
- */
308
- export const alreadyDone = ({
309
- ticket,
310
- shas,
311
- }: {
312
- ticket: number
313
- /** Defaults to `[DONE_SHA]`. */
314
- shas?: string[]
315
- }): JournalEntry => ({
316
- kind: 'agent_finished',
317
- ticket,
318
- role: 'test-writer',
319
- content: {
320
- role: 'test-writer',
321
- session_id: SESSIONS['test-writer'],
322
- result: {
323
- outcome: 'already_done',
324
- done_by: (shas ?? [DONE_SHA]).map((sha) => ({
325
- sha,
326
- title: 'feat: add sum',
327
- })),
328
- criteria: [
329
- {
330
- criterion_id: 'AC1',
331
- tests: [
332
- {
333
- file: 'src/sum.test.ts',
334
- name: 'sum adds two numbers',
335
- },
336
- ],
337
- },
338
- ],
339
- summary: 'The sum is already on main, with its test.',
340
- },
341
- },
342
- })
343
-
344
- /** The engine noted that a ticket's work is already done, on the spec issue. */
345
- export const ticketAlreadyDone = ({
346
- ticket,
347
- shas,
348
- }: {
349
- ticket: number
350
- /** Defaults to `[DONE_SHA]`. */
351
- shas?: string[]
352
- }): JournalEntry => ({
353
- kind: 'ticket_already_done',
354
- ticket,
355
- role: null,
356
- content: { shas: shas ?? [DONE_SHA], comment_id: 300 + ticket },
357
- })
358
-
359
- /** The engine closed an already-done ticket, with a comment on it. */
360
- export const ticketClosed = ({ ticket }: { ticket: number }): JournalEntry => ({
361
- kind: 'ticket_closed',
362
- ticket,
363
- role: null,
364
- content: { comment_id: 400 + ticket },
365
- })
366
-
367
- export const redCheck = ({
368
- ticket,
369
- ok,
370
- }: {
371
- ticket: number
372
- ok: boolean
373
- }): JournalEntry => ({
374
- kind: 'red_check',
375
- ticket,
376
- role: null,
377
- content: {
378
- ok,
379
- problems: ok ? [] : ['"sum adds two numbers" passes already'],
380
- notes: [],
381
- tests: {
382
- ...emptyTestRun(),
383
- output: ok ? '1 fail' : '(pass) sum adds two numbers',
384
- },
385
- },
386
- })
387
-
388
- export const leftoverScan = ({
389
- ticket,
390
- stage,
391
- hits,
392
- }: {
393
- /** `null` for the final review. */
394
- ticket: number | null
395
- stage: CommitStage
396
- hits?: { path: string; reason: string }[]
397
- }): JournalEntry => ({
398
- kind: 'leftover_scan',
399
- ticket,
400
- role: null,
401
- content: { stage, hits: hits ?? [] },
402
- })
403
-
404
- export const commitMade = ({
405
- ticket,
406
- stage,
407
- sha,
408
- files,
409
- }: {
410
- /** `null` for the final review. */
411
- ticket: number | null
412
- stage: CommitStage
413
- /** Defaults to `<stage>-sha`. */
414
- sha?: string
415
- files?: string[]
416
- }): JournalEntry => ({
417
- kind: 'commit_made',
418
- ticket,
419
- role: null,
420
- content: {
421
- stage,
422
- sha: sha ?? `${stage}-sha`,
423
- message: stage,
424
- files: files ?? [],
425
- },
426
- })
427
-
428
- export const implemented = ({
429
- ticket,
430
- outcome,
431
- session_id,
432
- reason,
433
- assumptions,
434
- finding_responses,
435
- run_notes,
436
- }: {
437
- /** `null` for the final review. */
438
- ticket: number | null
439
- outcome?: 'done' | 'bad_test'
440
- /** Defaults to `SESSIONS.implementer`. */
441
- session_id?: string
442
- /** The bad test's reason. Defaults to "Wrong sum." */
443
- reason?: string
444
- assumptions?: string[]
445
- finding_responses?: FindingResponse[]
446
- /** Defaults to none. */
447
- run_notes?: string[]
448
- }): JournalEntry => ({
449
- kind: 'agent_finished',
450
- ticket,
451
- role: 'implementer',
452
- content: {
453
- role: 'implementer',
454
- session_id: session_id ?? SESSIONS.implementer,
455
- result: {
456
- outcome: outcome ?? 'done',
457
- bad_test:
458
- outcome === 'bad_test'
459
- ? {
460
- file: 'src/sum.test.ts',
461
- name: 'sum adds two numbers',
462
- reason: reason ?? 'Wrong sum.',
463
- }
464
- : null,
465
- summary: 'Added sum.',
466
- assumptions: assumptions ?? [],
467
- run_notes: run_notes ?? [],
468
- finding_responses: finding_responses ?? [],
469
- },
470
- },
471
- })
472
-
473
- export const gatesRun = ({
474
- ticket,
475
- target,
476
- ok,
477
- }: {
478
- /** `null` for the final review. */
479
- ticket: number | null
480
- target: 'ticket' | 'run_branch'
481
- ok: boolean
482
- }): JournalEntry => ({
483
- kind: 'gates_run',
484
- ticket,
485
- role: null,
486
- content: {
487
- target,
488
- ok,
489
- checks: [
490
- {
491
- name: 'test',
492
- command: 'bun test',
493
- ok,
494
- exit_code: ok ? 0 : 1,
495
- output: ok ? '' : '1 fail',
496
- },
497
- ],
498
- },
499
- })
500
-
501
- /** One reviewer finding; a code should-fix in `src/sum.ts` unless told otherwise. */
502
- export const finding = ({
503
- id,
504
- severity,
505
- kind,
506
- title,
507
- file,
508
- }: {
509
- id: string
510
- severity?: 'blocker' | 'should_fix' | 'nit'
511
- kind?: 'code' | 'test'
512
- title?: string
513
- file?: string | null
514
- }): Finding => ({
515
- id,
516
- severity: severity ?? 'should_fix',
517
- kind: kind ?? 'code',
518
- file: file === undefined ? 'src/sum.ts' : file,
519
- title: title ?? `Finding ${id}`,
520
- detail: `Detail of ${id}.`,
521
- })
522
-
523
- /**
524
- * A ticket reviewer's result. The verdict follows the findings: changes are
525
- * requested when any is a blocker or should-fix.
526
- */
527
- export const reviewed = ({
528
- ticket,
529
- findings,
530
- rulings,
531
- session_id,
532
- }: {
533
- ticket: number
534
- findings?: Finding[]
535
- rulings?: FindingRuling[]
536
- /** Defaults to `SESSIONS['ticket-reviewer']`. */
537
- session_id?: string
538
- }): JournalEntry => {
539
- const list = findings ?? []
540
- const blocking = list.some(({ severity }) => severity !== 'nit')
541
- return {
542
- kind: 'agent_finished',
543
- ticket,
544
- role: 'ticket-reviewer',
545
- content: {
546
- role: 'ticket-reviewer',
547
- session_id: session_id ?? SESSIONS['ticket-reviewer'],
548
- result: {
549
- verdict: blocking ? 'changes_requested' : 'approve',
550
- findings: list,
551
- rulings: rulings ?? [],
552
- summary: 'Looks right.',
553
- assumptions: [],
554
- },
555
- },
556
- }
557
- }
558
-
559
- /** An agent turn failed, in the session its role's fixtures use unless told otherwise. */
560
- export const agentFailed = ({
561
- ticket,
562
- role,
563
- failure,
564
- error,
565
- session_id,
566
- }: {
567
- /** `null` for the final review. */
568
- ticket: number | null
569
- role: AgentRole
570
- failure: 'agent' | 'result' | 'guard' | 'engine'
571
- /** Defaults to "It broke." */
572
- error?: string
573
- /** Defaults to `SESSIONS[role]`; `null` for a turn with no session. */
574
- session_id?: string | null
575
- }): JournalEntry => ({
576
- kind: 'agent_failed',
577
- ticket,
578
- role,
579
- content: {
580
- role,
581
- failure,
582
- error: error ?? 'It broke.',
583
- session_id: session_id === undefined ? SESSIONS[role] : session_id,
584
- },
585
- })
586
-
587
- /** The engine threw away a ticket worktree's uncommitted changes. */
588
- export const worktreeReset = ({
589
- ticket,
590
- }: {
591
- ticket: number
592
- }): JournalEntry => ({
593
- kind: 'worktree_reset',
594
- ticket,
595
- role: null,
596
- content: { sha: 'red-sha' },
597
- })
598
-
599
- export const joined = ({ ticket }: { ticket: number }): JournalEntry => ({
600
- kind: 'ticket_joined',
601
- ticket,
602
- role: null,
603
- content: { ok: true, shas: ['r1', 'g1'] },
604
- })
605
-
606
- /** A join whose cherry-pick clashed with the run branch (git aborted it). */
607
- export const joinClashed = ({
608
- ticket,
609
- error,
610
- }: {
611
- ticket: number
612
- /** Defaults to a conflict in `src/index.ts`. */
613
- error?: string
614
- }): JournalEntry => ({
615
- kind: 'ticket_joined',
616
- ticket,
617
- role: null,
618
- content: { ok: false, error: error ?? 'CONFLICT (content): src/index.ts' },
619
- })
620
-
621
- /** The engine put a ticket's change back on top of the run branch. */
622
- export const ticketRebased = ({
623
- ticket,
624
- cause,
625
- tests,
626
- code,
627
- undone,
628
- }: {
629
- ticket: number
630
- cause: 'clash' | 'join_gates'
631
- /** The test files that clashed. Defaults to none. */
632
- tests?: string[]
633
- /** The code files that clashed. Defaults to none. */
634
- code?: string[]
635
- /** The run branch commits undone first. Defaults to none. */
636
- undone?: string[]
637
- }): JournalEntry => ({
638
- kind: 'ticket_rebased',
639
- ticket,
640
- role: null,
641
- content: {
642
- cause,
643
- base_sha: 'onto-sha',
644
- tests: tests ?? [],
645
- code: code ?? [],
646
- undone: undone ?? [],
647
- },
648
- })
649
-
650
- /** The engine removed these worktrees at the end of the run. */
651
- export const worktreesRemoved = ({
652
- paths,
653
- }: {
654
- paths: string[]
655
- }): JournalEntry => ({
656
- kind: 'worktrees_removed',
657
- ticket: null,
658
- role: null,
659
- content: { paths },
660
- })
661
-
662
- /** The run's one PR, #99, opened from the run branch. */
663
- export const pullRequestOpened = (): JournalEntry => ({
664
- kind: 'pull_request_opened',
665
- ticket: null,
666
- role: null,
667
- content: {
668
- number: 99,
669
- url: 'https://github.com/acme/app/pull/99',
670
- head: RUN_BRANCH,
671
- base: 'main',
672
- title: 'Practice spec (#10)',
673
- body: '',
674
- },
675
- })
676
-
677
- export const ticketStuck = ({
678
- ticket,
679
- reason,
680
- detail,
681
- }: {
682
- ticket: number
683
- reason: StuckReason
684
- /** Defaults to "why". */
685
- detail?: string
686
- }): JournalEntry => ({
687
- kind: 'ticket_stuck',
688
- ticket,
689
- role: null,
690
- content: { reason, detail: detail ?? 'why' },
691
- })
692
-
693
- export const pushed = ({
694
- ticket,
695
- sha,
696
- }: {
697
- /** `null` for the final review's push. */
698
- ticket: number | null
699
- /** Defaults to `g1`. */
700
- sha?: string
701
- }): JournalEntry => ({
702
- kind: 'run_branch_pushed',
703
- ticket,
704
- role: null,
705
- content: { branch: RUN_BRANCH, sha: sha ?? 'g1' },
706
- })
707
-
708
- /** Every step of one ticket, from its worktree to the push, all passing. */
709
- export const ticketBuilt = ({ ticket }: { ticket: number }): JournalEntry[] => [
710
- ticketWorktreeCreated({ ticket }),
711
- baselineTests({ ticket }),
712
- testsWritten({ ticket }),
713
- redCheck({ ticket, ok: true }),
714
- leftoverScan({ ticket, stage: 'red' }),
715
- commitMade({ ticket, stage: 'red' }),
716
- implemented({ ticket }),
717
- gatesRun({ ticket, target: 'ticket', ok: true }),
718
- leftoverScan({ ticket, stage: 'green' }),
719
- commitMade({ ticket, stage: 'green' }),
720
- reviewed({ ticket }),
721
- joined({ ticket }),
722
- gatesRun({ ticket, target: 'run_branch', ok: true }),
723
- pushed({ ticket }),
724
- ]
725
-
726
- /** Seconds since the epoch for an ISO time, as `resetsAt` gives it. */
727
- export const epochSeconds = (iso: string): number =>
728
- Math.floor(Date.parse(iso) / 1000)
729
-
730
- /**
731
- * One `rate_limit_event`'s info as the SDK sends it, with the windows'
732
- * utilization under `unifiedWindows` as real readings have it.
733
- */
734
- export const rateLimitReading = ({
735
- status,
736
- rate_limit_type,
737
- resets_at,
738
- is_using_overage,
739
- windows,
740
- }: {
741
- status: 'allowed' | 'allowed_warning' | 'rejected'
742
- /** Defaults to `five_hour`. */
743
- rate_limit_type?: string
744
- /** An ISO time; leave it out for a reading with no `resetsAt`. */
745
- resets_at?: string
746
- is_using_overage?: boolean
747
- /** Utilization (0 to 1) per window, such as `{ five_hour: 0.2 }`. */
748
- windows?: Record<string, number>
749
- }): Record<string, unknown> => ({
750
- status,
751
- rateLimitType: rate_limit_type ?? 'five_hour',
752
- ...(resets_at === undefined ? {} : { resetsAt: epochSeconds(resets_at) }),
753
- overageStatus: 'rejected',
754
- overageDisabledReason: 'org_level_disabled',
755
- isUsingOverage: is_using_overage ?? false,
756
- unifiedWindows: Object.fromEntries(
757
- Object.entries(windows ?? {}).map(([name, utilization]) => [
758
- name,
759
- { utilization },
760
- ])
761
- ),
762
- })
763
-
764
- /** The launcher's summary of one agent turn, with these readings and tokens. */
765
- export const agentSession = ({
766
- ticket,
767
- role,
768
- rate_limit_events,
769
- billing_error,
770
- output_tokens,
771
- }: {
772
- /** `null` for the final review. */
773
- ticket: number | null
774
- role: AgentRole
775
- rate_limit_events?: Record<string, unknown>[]
776
- billing_error?: boolean
777
- /** Defaults to 100; input tokens are always 10. */
778
- output_tokens?: number
779
- }): JournalEntry => ({
780
- kind: 'agent_session',
781
- ticket,
782
- role,
783
- content: {
784
- role,
785
- session: {
786
- session_id: SESSIONS[role],
787
- usage: {
788
- input_tokens: 10,
789
- output_tokens: output_tokens ?? 100,
790
- cache_read_input_tokens: 0,
791
- cache_creation_input_tokens: 0,
792
- },
793
- rate_limit_events: rate_limit_events ?? [],
794
- billing_error: billing_error ?? false,
795
- },
796
- },
797
- })
798
-
799
- /** A limit wait started, hit by #11's test-writer unless told otherwise. */
800
- export const limitWaitStarted = ({
801
- until,
802
- resets_at,
803
- rate_limit_type,
804
- }: {
805
- until: string
806
- resets_at: string | null
807
- /** Defaults to `five_hour`. */
808
- rate_limit_type?: string
809
- }): JournalEntry => ({
810
- kind: 'limit_wait_started',
811
- ticket: null,
812
- role: null,
813
- content: {
814
- until,
815
- resets_at,
816
- rate_limit_type: rate_limit_type ?? 'five_hour',
817
- hit_ticket: 11,
818
- hit_role: 'test-writer',
819
- },
820
- })
821
-
822
- export const limitWaitEnded = ({ until }: { until: string }): JournalEntry => ({
823
- kind: 'limit_wait_ended',
824
- ticket: null,
825
- role: null,
826
- content: { until },
827
- })
828
-
829
- /** The run stopped for good on a sign of per-token billing. */
830
- export const billingStopped = ({
831
- reason,
832
- }: {
833
- reason: string
834
- }): JournalEntry => ({
835
- kind: 'run_stopped',
836
- ticket: null,
837
- role: null,
838
- content: { reason, role: null, billing: true },
839
- })
840
-
841
- /** One ticket's steps up to and including its approving review. */
842
- export const ticketApproved = ({
843
- ticket,
844
- }: {
845
- ticket: number
846
- }): JournalEntry[] => ticketBuilt({ ticket }).slice(0, 11)
847
-
848
- /** The engine told the spec issue that a ticket is stuck, in comment `comment_id`. */
849
- export const stuckReported = ({
850
- ticket,
851
- comment_id,
852
- }: {
853
- ticket: number
854
- /** Defaults to 100 + the ticket number. */
855
- comment_id?: number
856
- }): JournalEntry => ({
857
- kind: 'stuck_reported',
858
- ticket,
859
- role: null,
860
- content: { comment_id: comment_id ?? 100 + ticket, body: 'stuck' },
861
- })
862
-
863
- /** A comment the engine read on the spec issue. */
864
- export const commentRead = ({
865
- comment_id,
866
- body,
867
- author,
868
- }: {
869
- comment_id: number
870
- body: string
871
- /** Defaults to the spec's owner. */
872
- author?: string
873
- }): JournalEntry => ({
874
- kind: 'comment_read',
875
- ticket: null,
876
- role: null,
877
- content: { comment_id, author: author ?? SPEC_OWNER, body },
878
- })
879
-
880
- /** The engine took a reply word from the spec's owner. */
881
- export const replyReceived = ({
882
- word,
883
- ticket,
884
- comment_id,
885
- }: {
886
- word: 'retry' | 'skip' | 'stop' | 'ship'
887
- ticket: number | null
888
- comment_id: number
889
- }): JournalEntry => ({
890
- kind: 'reply_received',
891
- ticket,
892
- role: null,
893
- content: { word, ticket, comment_id, author: SPEC_OWNER },
894
- })
895
-
896
- /** A retried ticket: resumed, started over, or refused. */
897
- export const ticketRetried = ({
898
- ticket,
899
- mode,
900
- }: {
901
- ticket: number
902
- mode: 'resume' | 'restart' | 'refused'
903
- }): JournalEntry => ({
904
- kind: 'ticket_retried',
905
- ticket,
906
- role: null,
907
- content: {
908
- mode,
909
- base_sha: mode === 'restart' ? 'tip-sha' : null,
910
- problems: mode === 'refused' ? ['no criteria'] : [],
911
- answer_id: null,
912
- },
913
- })
914
-
915
- /** A ticket left out of the run. */
916
- export const ticketSkipped = ({
917
- ticket,
918
- because,
919
- }: {
920
- ticket: number
921
- because?: number
922
- }): JournalEntry => ({
923
- kind: 'ticket_skipped',
924
- ticket,
925
- role: null,
926
- content: { because: because ?? null },
927
- })
928
-
929
- export { SPEC_OWNER }
930
-
931
- /**
932
- * The scheduler started a step: `step` is its action type, plus `:<role>`
933
- * for an agent's turn. `key` defaults to the ticket's number, or `run`.
934
- */
935
- export const stepStarted = ({
936
- ticket,
937
- step,
938
- key,
939
- role,
940
- first_seq,
941
- }: {
942
- ticket: number | null
943
- step: string
944
- key?: string
945
- role?: AgentRole
946
- /** The step's first try, on a redo. Defaults to `null`. */
947
- first_seq?: number
948
- }): JournalEntry => ({
949
- kind: 'step_started',
950
- ticket,
951
- role: role ?? null,
952
- content: {
953
- key: key ?? (ticket === null ? 'run' : String(ticket)),
954
- step,
955
- first_seq: first_seq ?? null,
956
- },
957
- })
958
-
959
- /** The scheduler saw a step settle. `key` as in `stepStarted`. */
960
- export const stepEnded = ({
961
- ticket,
962
- step,
963
- key,
964
- role,
965
- }: {
966
- ticket: number | null
967
- step: string
968
- key?: string
969
- role?: AgentRole
970
- }): JournalEntry => ({
971
- kind: 'step_ended',
972
- ticket,
973
- role: role ?? null,
974
- content: {
975
- key: key ?? (ticket === null ? 'run' : String(ticket)),
976
- step,
977
- },
978
- })
9
+ export {
10
+ agentFailed,
11
+ agentSession,
12
+ agentStarted,
13
+ finding,
14
+ implemented,
15
+ nothingNewToTest,
16
+ reviewed,
17
+ SESSIONS,
18
+ testsWritten,
19
+ } from './agent-turn-fixtures'
20
+ export {
21
+ alreadyDone,
22
+ alreadyDoneChecked,
23
+ DONE_SHA,
24
+ ticketAlreadyDone,
25
+ ticketClosed,
26
+ } from './already-done-fixtures'
27
+ export { SPEC_OWNER } from './intake-fixtures'
28
+ export {
29
+ billingStopped,
30
+ epochSeconds,
31
+ limitWaitEnded,
32
+ limitWaitStarted,
33
+ rateLimitReading,
34
+ } from './limit-fixtures'
35
+ export {
36
+ commentRead,
37
+ replyReceived,
38
+ stuckReported,
39
+ ticketRetried,
40
+ ticketSkipped,
41
+ } from './reply-fixtures'
42
+ export {
43
+ baselineTests,
44
+ BUILD_CONFIG,
45
+ dependenciesInstalled,
46
+ emptyTestRun,
47
+ intakePassed,
48
+ practiceTicket,
49
+ pullRequestOpened,
50
+ RUN_BRANCH,
51
+ RUN_BRANCH_PATH,
52
+ runBranchCreated,
53
+ ticketPath,
54
+ ticketWorktreeCreated,
55
+ withInstalls,
56
+ worktreesRemoved,
57
+ } from './run-fixtures'
58
+ export { stepEnded, stepStarted } from './step-record-fixtures'
59
+ export {
60
+ commitMade,
61
+ gatesRun,
62
+ joinClashed,
63
+ joined,
64
+ leftoverScan,
65
+ pushed,
66
+ redCheck,
67
+ testsSentBack,
68
+ ticketApproved,
69
+ ticketBuilt,
70
+ ticketRebased,
71
+ ticketStuck,
72
+ worktreeReset,
73
+ } from './ticket-step-fixtures'