@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.
- package/CHANGELOG.md +76 -0
- package/README.md +7 -2
- package/board/client/board-look.ts +31 -1
- package/board/client/board-panel-parts.tsx +150 -0
- package/board/client/board-panel-stages.ts +99 -0
- package/board/client/board-panel-styles.ts +223 -0
- package/board/client/board-panel.tsx +77 -1275
- package/board/client/engine-life.ts +48 -0
- package/board/client/final-review-stack.tsx +144 -0
- package/board/client/heartbeat.tsx +61 -0
- package/board/client/helper-lines.tsx +69 -0
- package/board/client/live-feed.tsx +86 -0
- package/board/client/live-line.ts +73 -0
- package/board/client/model-line.tsx +178 -0
- package/board/client/needs-you-section.tsx +133 -0
- package/board/client/one-line.tsx +193 -0
- package/board/client/repo-wait-banner.tsx +69 -0
- package/board/client/run-footer.tsx +68 -0
- package/board/client/run-header.tsx +189 -0
- package/board/client/run-picker.tsx +98 -0
- package/board/client/status-bar.tsx +131 -0
- package/board/client/step-dots.tsx +127 -0
- package/board/client/stuck-actions.tsx +269 -0
- package/board/client/ticket-card-view.tsx +238 -0
- package/board/client/ticket-detail.tsx +87 -0
- package/board/client/ticket-stack.tsx +119 -0
- package/board/client/ticket-wait.ts +188 -0
- package/board/client/timeline-rows.tsx +41 -14
- package/board/client/usage-line.tsx +51 -0
- package/board/client/wait-line.tsx +39 -0
- package/board/index.client.tsx +1 -1
- package/board/index.server.ts +7 -1
- package/board/package.json +1 -1
- package/board/server/board-panel-state-helpers.ts +67 -0
- package/board/server/board-server-check.ts +294 -0
- package/board/server/board-server-engine.ts +129 -0
- package/board/server/board-server-events.ts +134 -0
- package/board/server/board-server-read.ts +190 -0
- package/board/server/board-server-resume.ts +164 -0
- package/board/server/board-server-start.ts +174 -0
- package/board/server/board-server-store.ts +281 -0
- package/board/server/board-server-types.ts +114 -0
- package/board/server/board-server-util.ts +4 -0
- package/board/server/board-server.ts +52 -943
- package/board/server/board-vocabulary-engine.ts +144 -0
- package/board/server/board-vocabulary-review.ts +115 -0
- package/board/server/board-vocabulary-run.ts +145 -0
- package/board/server/board-vocabulary-shapes.ts +153 -0
- package/board/server/board-vocabulary.ts +20 -375
- package/board/server/current-step-panel-helpers.ts +108 -0
- package/board/server/describe-record.ts +403 -0
- package/board/server/engine-launch.ts +20 -3
- package/board/server/engine-restart-helpers.ts +105 -0
- package/board/server/engine-watch.ts +45 -5
- package/board/server/journal-rebuild-helpers.ts +169 -0
- package/board/server/live-file.ts +130 -0
- package/board/server/luca-version.ts +1 -1
- package/board/server/make-rows.ts +14 -629
- package/board/server/record-texts.ts +350 -0
- package/board/server/reduce-board-agent-start.ts +224 -0
- package/board/server/reduce-board-agents.ts +160 -0
- package/board/server/reduce-board-counters.ts +138 -0
- package/board/server/reduce-board-create.ts +148 -0
- package/board/server/reduce-board-final-review.ts +174 -0
- package/board/server/reduce-board-needs-you.ts +283 -0
- package/board/server/reduce-board-reasons.ts +59 -0
- package/board/server/reduce-board-run.ts +255 -0
- package/board/server/reduce-board-settle.ts +88 -0
- package/board/server/reduce-board-steps.ts +226 -0
- package/board/server/reduce-board-text.ts +139 -0
- package/board/server/reduce-board-ticket-checks.ts +168 -0
- package/board/server/reduce-board-ticket-join.ts +144 -0
- package/board/server/reduce-board-ticket-start.ts +132 -0
- package/board/server/reduce-board-update.ts +117 -0
- package/board/server/reduce-board-usage.ts +247 -0
- package/board/server/reduce-board.ts +100 -1917
- package/board/server/reply-post.ts +407 -0
- package/board/server/run-registry.ts +8 -4
- package/board/server/ticket-stages-panel-helpers.ts +296 -0
- package/board/shared/board-rows.ts +9 -0
- package/board/shared/board-rpc.ts +42 -0
- package/board/shared/board-state-counts.ts +77 -0
- package/board/shared/board-state-live.ts +99 -0
- package/board/shared/board-state-review.ts +59 -0
- package/board/shared/board-state-run.ts +236 -0
- package/board/shared/board-state-ticket.ts +257 -0
- package/board/shared/board-state-usage.ts +107 -0
- package/board/shared/board-state.ts +97 -567
- package/board/shared/reply-actions.ts +207 -0
- package/engine/agents/agent-launcher.ts +27 -4
- package/engine/agents/claude-launcher-helpers.ts +233 -0
- package/engine/agents/claude-launcher.ts +28 -669
- package/engine/agents/claude-messages.ts +212 -0
- package/engine/agents/claude-options.ts +43 -8
- package/engine/agents/common-instructions.ts +138 -0
- package/engine/agents/input-channel.ts +36 -0
- package/engine/agents/launch-paths.ts +29 -0
- package/engine/agents/launch-session.ts +227 -0
- package/engine/agents/learner-instructions.ts +31 -0
- package/engine/agents/open-session.ts +210 -0
- package/engine/agents/prompt-sections.ts +95 -0
- package/engine/agents/rejoin-prompts.ts +135 -0
- package/engine/agents/reviewer-instructions.ts +99 -0
- package/engine/agents/role-instructions.ts +31 -244
- package/engine/agents/role-prompts.ts +39 -109
- package/engine/agents/role-results.ts +106 -7
- package/engine/agents/scripted-launcher.ts +21 -6
- package/engine/agents/session-pool.ts +124 -0
- package/engine/agents/turn-progress.ts +283 -0
- package/engine/agents/writer-instructions.ts +151 -0
- package/engine/cli/computer-adapters-real.ts +15 -3
- package/engine/cli/computer-adapters.ts +2 -0
- package/engine/cli/computer-checks.ts +87 -4
- package/engine/cli/config-reload-text.ts +39 -0
- package/engine/cli/decision-model-setup.ts +70 -0
- package/engine/cli/doctor-command.ts +1 -0
- package/engine/cli/doctor.ts +21 -3
- package/engine/cli/going-runs.ts +192 -36
- package/engine/cli/init-command.ts +1 -0
- package/engine/cli/init.ts +23 -1
- package/engine/cli/live-runs.ts +73 -0
- package/engine/cli/luca-run.ts +42 -7
- package/engine/cli/luca-skills.ts +183 -0
- package/engine/cli/luca.ts +8 -1
- package/engine/cli/models-command.ts +119 -0
- package/engine/cli/read-run.ts +81 -0
- package/engine/cli/run-args.ts +33 -6
- package/engine/cli/run-demo.ts +143 -0
- package/engine/cli/run-end.ts +184 -0
- package/engine/cli/run-modes-helpers.ts +81 -0
- package/engine/cli/run-modes.ts +62 -439
- package/engine/cli/setup.ts +5 -48
- package/engine/cli/unfinished-runs.ts +122 -0
- package/engine/cli/upgrade-command.ts +212 -30
- package/engine/cli/upgrade-finish.ts +149 -0
- package/engine/cli/upgrade.ts +112 -71
- package/engine/config/config-fields.ts +127 -0
- package/engine/config/config-reload.ts +250 -0
- package/engine/config/engine-config-schema.ts +235 -0
- package/engine/config/engine-config.ts +72 -142
- package/engine/config/test-commands.ts +102 -0
- package/engine/core/agent-guards-helpers.ts +84 -0
- package/engine/core/agent-turn.ts +395 -0
- package/engine/core/already-done.ts +44 -1
- package/engine/core/build-action.ts +214 -0
- package/engine/core/build-context.ts +135 -0
- package/engine/core/build-launch.ts +259 -0
- package/engine/core/commit-in.ts +282 -0
- package/engine/core/decide-build-early.ts +108 -0
- package/engine/core/decide-build-ending.ts +145 -0
- package/engine/core/decide-build-helpers.ts +87 -0
- package/engine/core/decide-build-tickets.ts +207 -0
- package/engine/core/decide-build-view.ts +103 -0
- package/engine/core/decide-build.ts +101 -1368
- package/engine/core/decide-final-fix.ts +203 -0
- package/engine/core/decide-final-review.ts +55 -310
- package/engine/core/decide-red-green.ts +398 -0
- package/engine/core/decide-rejoin.ts +259 -0
- package/engine/core/decide-repo-wait.ts +129 -0
- package/engine/core/decide-run-budget.ts +86 -12
- package/engine/core/decide-stuck-helpers.ts +127 -0
- package/engine/core/decide-stuck.ts +60 -8
- package/engine/core/decide-ticket-review.ts +95 -0
- package/engine/core/decide-ticket.ts +267 -0
- package/engine/core/decide-waits.ts +47 -0
- package/engine/core/decide.ts +74 -23
- package/engine/core/engine-chores.ts +163 -0
- package/engine/core/environment-rerun.ts +83 -0
- package/engine/core/evidence-text.ts +84 -0
- package/engine/core/execute-action.ts +303 -0
- package/engine/core/execute-already-done-check.ts +133 -0
- package/engine/core/execute-build.ts +68 -944
- package/engine/core/execute-changeset.ts +5 -7
- package/engine/core/execute-final-review.ts +125 -13
- package/engine/core/execute-gates.ts +182 -0
- package/engine/core/execute-intake.ts +130 -0
- package/engine/core/execute-join.ts +276 -0
- package/engine/core/execute-memory.ts +12 -0
- package/engine/core/execute-pull-request.ts +84 -0
- package/engine/core/execute-red-check.ts +219 -0
- package/engine/core/execute-repo-wait.ts +129 -0
- package/engine/core/execute-stuck.ts +25 -10
- package/engine/core/execute-waits.ts +158 -0
- package/engine/core/execute-with-jev.ts +118 -0
- package/engine/core/execute.ts +124 -831
- package/engine/core/final-failure-cap.ts +38 -0
- package/engine/core/final-review-action.ts +125 -0
- package/engine/core/final-review-text.ts +63 -17
- package/engine/core/final-stuck-text.ts +86 -0
- package/engine/core/fix-loop-text.ts +49 -2
- package/engine/core/left-out.ts +120 -0
- package/engine/core/live-file.ts +372 -0
- package/engine/core/loop-caps.ts +25 -2
- package/engine/core/not-in-run.ts +7 -3
- package/engine/core/pull-request-text.ts +255 -6
- package/engine/core/repo-wait-text.ts +81 -0
- package/engine/core/review-text.ts +55 -1
- package/engine/core/run-crash-recovery-helpers.ts +16 -0
- package/engine/core/run-session-close-helpers.ts +96 -0
- package/engine/core/run-start.ts +148 -0
- package/engine/core/run-stuck-text.ts +86 -0
- package/engine/core/schedule-rules.ts +193 -0
- package/engine/core/stuck-detail-text.ts +89 -0
- package/engine/core/stuck-format.ts +22 -0
- package/engine/core/stuck-text.ts +29 -332
- package/engine/core/ticket-stuck-text.ts +192 -0
- package/engine/core/worktree-changes.ts +106 -0
- package/engine/gates/already-done-check.ts +120 -0
- package/engine/gates/feature-map.ts +96 -0
- package/engine/gates/gate-runner.ts +108 -108
- package/engine/gates/gate-schemas.ts +61 -2
- package/engine/gates/leftover-scan.ts +154 -31
- package/engine/gates/new-tests.ts +45 -0
- package/engine/gates/own-files-check.ts +98 -0
- package/engine/gates/prepare-check.ts +60 -0
- package/engine/gates/prepare-slots.ts +99 -0
- package/engine/gates/red-check.ts +184 -16
- package/engine/gates/shell-check.ts +64 -0
- package/engine/gates/slot-waits.ts +55 -0
- package/engine/gates/slow-test-runner.ts +59 -0
- package/engine/gates/test-checks.ts +161 -0
- package/engine/gates/test-runner.ts +164 -5
- package/engine/gates/test-slots.ts +48 -0
- package/engine/git/git-adapter.ts +55 -396
- package/engine/git/git-commits.ts +132 -0
- package/engine/git/git-join.ts +139 -0
- package/engine/git/git-read.ts +123 -0
- package/engine/git/git-run.ts +32 -0
- package/engine/git/git-worktrees.ts +143 -0
- package/engine/git/outside-links.ts +55 -0
- package/engine/guards/after-turn-check.ts +31 -5
- package/engine/guards/guard-hook.ts +60 -12
- package/engine/guards/guard-roles.ts +68 -0
- package/engine/guards/helper-rules.ts +92 -0
- package/engine/guards/permission-rules.ts +161 -0
- package/engine/guards/role-rules-helpers.ts +48 -0
- package/engine/guards/role-rules.ts +34 -606
- package/engine/guards/shell-rules.ts +344 -0
- package/engine/guards/worktree-git.ts +208 -0
- package/engine/guards/worktree-snapshot.ts +412 -0
- package/engine/guards/worktree-state.ts +28 -825
- package/engine/guards/worktree-undo.ts +260 -0
- package/engine/guards/write-rules.ts +149 -0
- package/engine/index.ts +30 -9
- package/engine/intake/criteria-checks.ts +114 -0
- package/engine/intake/intake-checks.ts +164 -30
- package/engine/intake/intake-schemas.ts +37 -2
- package/engine/jev/clef-client.ts +259 -0
- package/engine/jev/decision-model-credentials.ts +212 -0
- package/engine/jev/jev-jobs.ts +144 -60
- package/engine/jev/jev-schemas.ts +86 -5
- package/engine/jev/jev-shadow-helpers.ts +218 -0
- package/engine/jev/jev-shadow.ts +109 -64
- package/engine/jev/model-pick.ts +275 -0
- package/engine/journal/agent-entries.ts +167 -0
- package/engine/journal/agent-message-entries.ts +72 -0
- package/engine/journal/agent-turn-replay.ts +203 -0
- package/engine/journal/already-done-entries.ts +55 -0
- package/engine/journal/commit-entries.ts +56 -0
- package/engine/journal/cross-ticket-replay.ts +222 -0
- package/engine/journal/decision-model-entries.ts +86 -0
- package/engine/journal/entry-fields.ts +10 -0
- package/engine/journal/final-review-entries.ts +128 -0
- package/engine/journal/final-review-replay.ts +324 -0
- package/engine/journal/final-review-round.ts +320 -0
- package/engine/journal/final-review-state.ts +180 -0
- package/engine/journal/gate-entries.ts +81 -0
- package/engine/journal/intake-entries.ts +87 -0
- package/engine/journal/join-entries.ts +126 -0
- package/engine/journal/journal-entry-schema.ts +218 -0
- package/engine/journal/journal-kinds.ts +97 -0
- package/engine/journal/journal-record-schema.ts +218 -0
- package/engine/journal/journal-record.ts +43 -1400
- package/engine/journal/journal.ts +6 -1
- package/engine/journal/limit-entries.ts +90 -0
- package/engine/journal/memory-entries.ts +124 -0
- package/engine/journal/memory-replay.ts +157 -0
- package/engine/journal/plan-replay.ts +139 -0
- package/engine/journal/pull-request-entries.ts +41 -0
- package/engine/journal/replay.ts +157 -2144
- package/engine/journal/reply-replay.ts +144 -0
- package/engine/journal/repo-wait-entries.ts +53 -0
- package/engine/journal/run-entries.ts +172 -0
- package/engine/journal/run-state.ts +264 -0
- package/engine/journal/shared-failure-replay.ts +133 -0
- package/engine/journal/stuck-entries.ts +193 -0
- package/engine/journal/ticket-progress.ts +392 -0
- package/engine/journal/ticket-replay.ts +411 -0
- package/engine/journal/ticket-result-replay.ts +364 -0
- package/engine/journal/ticket-retry-replay.ts +142 -0
- package/engine/journal/worktree-entries.ts +122 -0
- package/engine/models/model-score.ts +512 -0
- package/engine/shell/run-command.ts +187 -18
- package/engine/testing/agent-turn-fixtures.ts +287 -0
- package/engine/testing/already-done-fixtures.ts +97 -0
- package/engine/testing/build-fixtures.ts +68 -973
- package/engine/testing/checkouts-fixtures.ts +48 -0
- package/engine/testing/final-review-fixtures.ts +62 -1
- package/engine/testing/final-review-steps.ts +143 -0
- package/engine/testing/limit-fixtures.ts +85 -0
- package/engine/testing/live-file-fixtures.ts +57 -0
- package/engine/testing/practice-repo.ts +10 -4
- package/engine/testing/practice-run.ts +1 -1
- package/engine/testing/reply-fixtures.ts +88 -0
- package/engine/testing/run-budget-fixtures.ts +165 -0
- package/engine/testing/run-fixtures.ts +219 -0
- package/engine/testing/sdk-play.ts +177 -0
- package/engine/testing/setup-repo.ts +194 -0
- package/engine/testing/step-record-fixtures.ts +55 -0
- package/engine/testing/ticket-step-fixtures.ts +272 -0
- package/engine/testing/wait-scenarios.ts +186 -0
- package/engine/tracker/gh-retry.ts +217 -0
- package/engine/tracker/github-tracker.ts +310 -90
- package/engine/tracker/in-memory-tracker.ts +8 -4
- package/engine/tracker/tracker.ts +131 -6
- package/package.json +2 -1
- package/skills/luca-retro/SKILL.md +74 -0
- package/skills/luca-retro/scripts/retro-summary.ts +1356 -0
- package/skills/luca-unstick/SKILL.md +153 -0
- package/skills/luca-unstick/scripts/stuck-summary.ts +1063 -0
- package/engine/jev/jev-client.ts +0 -173
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared failures in replay (#544): the run-wide list of old tests that
|
|
3
|
+
* failed, and whether a ticket's failed red check or gates failed only on
|
|
4
|
+
* old tests another ticket failed shortly before, so a lone rerun is due.
|
|
5
|
+
*/
|
|
6
|
+
import type { JournalRecord } from './journal-record'
|
|
7
|
+
import type { OldTestFailure, RunState } from './run-state'
|
|
8
|
+
import type { TicketProgress } from './ticket-progress'
|
|
9
|
+
|
|
10
|
+
import type { TestCaseRef } from '../gates/gate-schemas'
|
|
11
|
+
|
|
12
|
+
/** How close in time two tickets' failures of one old test must be. */
|
|
13
|
+
export const SHARED_FAILURE_WINDOW_MS = 10 * 60_000
|
|
14
|
+
|
|
15
|
+
type CheckRecord = Extract<JournalRecord, { kind: 'red_check' | 'gates_run' }>
|
|
16
|
+
|
|
17
|
+
/** The test cases a check's record says failed: none in old gates records. */
|
|
18
|
+
const failedCasesOf = (record: CheckRecord): TestCaseRef[] =>
|
|
19
|
+
record.kind === 'red_check'
|
|
20
|
+
? record.content.tests.cases
|
|
21
|
+
.filter(({ status }) => status === 'failed')
|
|
22
|
+
.map(({ file, full_name }) => ({ file, full_name }))
|
|
23
|
+
: (record.content.failed_cases ?? [])
|
|
24
|
+
|
|
25
|
+
const sameTest = (a: TestCaseRef, b: TestCaseRef): boolean =>
|
|
26
|
+
a.file === b.file && a.full_name === b.full_name
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether every one of `old` (non-empty) failed in another ticket, as
|
|
30
|
+
* journaled before `time`'s record, within `SHARED_FAILURE_WINDOW_MS` of it.
|
|
31
|
+
*/
|
|
32
|
+
const sharedWithOthers = ({
|
|
33
|
+
old,
|
|
34
|
+
ticket,
|
|
35
|
+
time,
|
|
36
|
+
failures,
|
|
37
|
+
}: {
|
|
38
|
+
old: TestCaseRef[]
|
|
39
|
+
ticket: number
|
|
40
|
+
time: string
|
|
41
|
+
failures: OldTestFailure[]
|
|
42
|
+
}): boolean =>
|
|
43
|
+
old.length > 0 &&
|
|
44
|
+
old.every((test) =>
|
|
45
|
+
failures.some(
|
|
46
|
+
(failure) =>
|
|
47
|
+
failure.ticket !== ticket &&
|
|
48
|
+
sameTest(failure, test) &&
|
|
49
|
+
Math.abs(Date.parse(failure.time) - Date.parse(time)) <=
|
|
50
|
+
SHARED_FAILURE_WINDOW_MS
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A ticket's progress with the check `record` journaled marked `shared`:
|
|
56
|
+
* its red check, or its own gates. A join's gates get no lone rerun.
|
|
57
|
+
*/
|
|
58
|
+
const markedShared = ({
|
|
59
|
+
progress,
|
|
60
|
+
record,
|
|
61
|
+
}: {
|
|
62
|
+
progress: TicketProgress
|
|
63
|
+
record: CheckRecord
|
|
64
|
+
}): TicketProgress => {
|
|
65
|
+
if (record.kind === 'red_check' && progress.red_check !== null) {
|
|
66
|
+
return {
|
|
67
|
+
...progress,
|
|
68
|
+
red_check: { ...progress.red_check, shared: true },
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (
|
|
72
|
+
record.kind === 'gates_run' &&
|
|
73
|
+
record.content.target === 'ticket' &&
|
|
74
|
+
progress.gates !== null
|
|
75
|
+
) {
|
|
76
|
+
return { ...progress, gates: { ...progress.gates, shared: true } }
|
|
77
|
+
}
|
|
78
|
+
return progress
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The state after a ticket's red check or gates record, once its own
|
|
83
|
+
* progress took it in: the old tests it failed (ones that passed at the
|
|
84
|
+
* ticket's baseline) join `old_test_failures`, and a failed red check or
|
|
85
|
+
* ticket gates is marked `shared` when every old test it failed also failed
|
|
86
|
+
* in another ticket within 10 minutes, by record time. Only failures
|
|
87
|
+
* journaled earlier count, so of two tickets failing at once the later one
|
|
88
|
+
* gets the lone rerun. A check that failed no old test (only new ones) is
|
|
89
|
+
* never shared.
|
|
90
|
+
*/
|
|
91
|
+
export const sharedFailuresAfter = ({
|
|
92
|
+
state,
|
|
93
|
+
record,
|
|
94
|
+
}: {
|
|
95
|
+
state: RunState
|
|
96
|
+
record: CheckRecord
|
|
97
|
+
}): RunState => {
|
|
98
|
+
const { ticket } = record
|
|
99
|
+
if (ticket === null || record.content.ok) return state
|
|
100
|
+
const progress = state.tickets[ticket]
|
|
101
|
+
const baseline = progress?.baseline
|
|
102
|
+
if (progress === undefined || baseline === undefined || baseline === null) {
|
|
103
|
+
return state
|
|
104
|
+
}
|
|
105
|
+
const old = failedCasesOf(record).filter((test) =>
|
|
106
|
+
baseline.cases.some(
|
|
107
|
+
(base) => base.status === 'passed' && sameTest(base, test)
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
if (old.length === 0) return state
|
|
111
|
+
const shared = sharedWithOthers({
|
|
112
|
+
old,
|
|
113
|
+
ticket,
|
|
114
|
+
time: record.time,
|
|
115
|
+
failures: state.old_test_failures,
|
|
116
|
+
})
|
|
117
|
+
return {
|
|
118
|
+
...state,
|
|
119
|
+
tickets: {
|
|
120
|
+
...state.tickets,
|
|
121
|
+
[ticket]: shared ? markedShared({ progress, record }) : progress,
|
|
122
|
+
},
|
|
123
|
+
old_test_failures: [
|
|
124
|
+
...state.old_test_failures,
|
|
125
|
+
...old.map(({ file, full_name }) => ({
|
|
126
|
+
ticket,
|
|
127
|
+
file,
|
|
128
|
+
full_name,
|
|
129
|
+
time: record.time,
|
|
130
|
+
})),
|
|
131
|
+
],
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import { ENTRY_FIELDS } from './entry-fields'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The journal entries of stuck work and the spec owner's replies: stuck
|
|
7
|
+
* tickets and runs, the report, comments read, replies taken or ignored,
|
|
8
|
+
* and tickets retried or skipped.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Why a ticket (or the final review) is stuck. A failed red check or gate is only stuck once its
|
|
13
|
+
* fix loop reaches its cap, and a bad test only on its second bounce.
|
|
14
|
+
* `undo_refused`: undoing its join would have rewound the run branch over
|
|
15
|
+
* other work, so the engine left the run branch alone (#519).
|
|
16
|
+
* `environment_failed`: a writer said a failure was not its ticket's fault,
|
|
17
|
+
* and the rerun failed the same way, or its reruns ran out (#613).
|
|
18
|
+
*/
|
|
19
|
+
export const StuckReasonSchema = z.enum([
|
|
20
|
+
'agent_failed',
|
|
21
|
+
'red_check_failed',
|
|
22
|
+
'nothing_new_to_test',
|
|
23
|
+
'leftovers_found',
|
|
24
|
+
'gates_failed',
|
|
25
|
+
'bad_test',
|
|
26
|
+
'changes_requested',
|
|
27
|
+
'join_failed',
|
|
28
|
+
'join_gates_failed',
|
|
29
|
+
'install_failed',
|
|
30
|
+
'prepare_failed',
|
|
31
|
+
'setup_change_needed',
|
|
32
|
+
'crashed',
|
|
33
|
+
'undo_refused',
|
|
34
|
+
'environment_failed',
|
|
35
|
+
])
|
|
36
|
+
|
|
37
|
+
export type StuckReason = z.infer<typeof StuckReasonSchema>
|
|
38
|
+
|
|
39
|
+
export const TicketStuckEntrySchema = z.object({
|
|
40
|
+
...ENTRY_FIELDS,
|
|
41
|
+
kind: z.literal('ticket_stuck'),
|
|
42
|
+
content: z.object({ reason: StuckReasonSchema, detail: z.string() }),
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Why the whole run is stuck: it used up its run budget of tokens, its
|
|
47
|
+
* pull request didn't open (`gh pr create` failed, #508), or its repo wait
|
|
48
|
+
* lasted 24 hours (`repo_busy`, #615).
|
|
49
|
+
*/
|
|
50
|
+
export const RunStuckReasonSchema = z.enum([
|
|
51
|
+
'run_budget',
|
|
52
|
+
'pull_request_failed',
|
|
53
|
+
'repo_busy',
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
export type RunStuckReason = z.infer<typeof RunStuckReasonSchema>
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The whole run is stuck (`ticket: null`): nothing new starts until the
|
|
60
|
+
* spec owner replies `retry` (a top-up of the run budget, another try at
|
|
61
|
+
* the PR, or another repo wait) or `stop`.
|
|
62
|
+
*/
|
|
63
|
+
export const RunStuckEntrySchema = z.object({
|
|
64
|
+
...ENTRY_FIELDS,
|
|
65
|
+
kind: z.literal('run_stuck'),
|
|
66
|
+
content: z.object({ reason: RunStuckReasonSchema, detail: z.string() }),
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The engine told the spec issue that a ticket (or, with `ticket: null`,
|
|
71
|
+
* the stuck run, else the final review) is stuck, in its comment
|
|
72
|
+
* `comment_id`, and now waits for the spec owner's reply.
|
|
73
|
+
*/
|
|
74
|
+
export const StuckReportedEntrySchema = z.object({
|
|
75
|
+
...ENTRY_FIELDS,
|
|
76
|
+
kind: z.literal('stuck_reported'),
|
|
77
|
+
content: z.object({
|
|
78
|
+
comment_id: z.number().int(),
|
|
79
|
+
body: z.string(),
|
|
80
|
+
}),
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A comment the engine read on the spec issue while it waited for a reply,
|
|
85
|
+
* word for word, whoever wrote it. Only the spec owner's count as replies.
|
|
86
|
+
*/
|
|
87
|
+
export const CommentReadEntrySchema = z.object({
|
|
88
|
+
...ENTRY_FIELDS,
|
|
89
|
+
kind: z.literal('comment_read'),
|
|
90
|
+
content: z.object({
|
|
91
|
+
comment_id: z.number().int(),
|
|
92
|
+
author: z.string(),
|
|
93
|
+
body: z.string(),
|
|
94
|
+
}),
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The one-word replies the spec owner can give to stuck work: `retry`,
|
|
99
|
+
* `skip`, and `stop` for a ticket; `retry`, `stop`, and `ship` for the
|
|
100
|
+
* final review.
|
|
101
|
+
*/
|
|
102
|
+
export const ReplyWordSchema = z.enum(['retry', 'skip', 'stop', 'ship'])
|
|
103
|
+
|
|
104
|
+
export type ReplyWord = z.infer<typeof ReplyWordSchema>
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The engine took the spec owner's reply: `retry` or `skip` for `ticket`,
|
|
108
|
+
* `stop` for the whole run, `retry` for the run stuck on its budget, or
|
|
109
|
+
* `retry` or `ship` for the stuck final review (`ticket` is `null` for
|
|
110
|
+
* these). A `retry` of the run stuck on its budget carries the tokens it
|
|
111
|
+
* added (`top_up`, #543); one journaled before top-ups has none, and counts
|
|
112
|
+
* as one whole budget.
|
|
113
|
+
*/
|
|
114
|
+
export const ReplyReceivedEntrySchema = z.object({
|
|
115
|
+
...ENTRY_FIELDS,
|
|
116
|
+
kind: z.literal('reply_received'),
|
|
117
|
+
content: z.object({
|
|
118
|
+
word: ReplyWordSchema,
|
|
119
|
+
ticket: z.number().int().positive().nullable(),
|
|
120
|
+
comment_id: z.number().int(),
|
|
121
|
+
author: z.string(),
|
|
122
|
+
top_up: z.number().int().positive().optional(),
|
|
123
|
+
}),
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Why the spec owner's reply could not be used: it named no ticket while
|
|
128
|
+
* more than one is stuck, named a ticket that isn't stuck, or was `ship`
|
|
129
|
+
* (the final review's word) while no final review is stuck, or was `skip`
|
|
130
|
+
* for the final review, which can't be skipped. A `retry +<amount>` is only
|
|
131
|
+
* for the run stuck on its budget (`amount_only_for_run_budget`), and its
|
|
132
|
+
* amount must be a whole number above zero (`bad_amount`).
|
|
133
|
+
*/
|
|
134
|
+
export const ReplyProblemSchema = z.enum([
|
|
135
|
+
'no_ticket_named',
|
|
136
|
+
'not_stuck',
|
|
137
|
+
'nothing_stuck',
|
|
138
|
+
'ship_needs_final_review',
|
|
139
|
+
'skip_not_for_final_review',
|
|
140
|
+
'amount_only_for_run_budget',
|
|
141
|
+
'bad_amount',
|
|
142
|
+
])
|
|
143
|
+
|
|
144
|
+
export type ReplyProblem = z.infer<typeof ReplyProblemSchema>
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The spec owner's reply could not be used; the engine said why on the spec
|
|
148
|
+
* issue, in its comment `answer_id`.
|
|
149
|
+
*/
|
|
150
|
+
export const ReplyIgnoredEntrySchema = z.object({
|
|
151
|
+
...ENTRY_FIELDS,
|
|
152
|
+
kind: z.literal('reply_ignored'),
|
|
153
|
+
content: z.object({
|
|
154
|
+
comment_id: z.number().int(),
|
|
155
|
+
reason: ReplyProblemSchema,
|
|
156
|
+
answer_id: z.number().int().nullable(),
|
|
157
|
+
}),
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* How a `retry` went:
|
|
162
|
+
* - `resume`: the ticket's text and labels are unchanged, so it picks up
|
|
163
|
+
* where it stopped, with a fresh agent and fresh counts, keeping any
|
|
164
|
+
* code the user changed in its worktree.
|
|
165
|
+
* - `restart`: the ticket's text or labels changed, so its new copy (a
|
|
166
|
+
* `ticket_snapshot` just before) is built from scratch, in its worktree
|
|
167
|
+
* reset to the run branch's tip `base_sha`.
|
|
168
|
+
* - `refused`: the changed ticket is not ready to build (`problems`); the
|
|
169
|
+
* engine said so on the spec issue (`answer_id`), and it stays stuck.
|
|
170
|
+
*/
|
|
171
|
+
export const TicketRetriedEntrySchema = z.object({
|
|
172
|
+
...ENTRY_FIELDS,
|
|
173
|
+
kind: z.literal('ticket_retried'),
|
|
174
|
+
content: z.object({
|
|
175
|
+
mode: z.enum(['resume', 'restart', 'refused']),
|
|
176
|
+
base_sha: z.string().nullable(),
|
|
177
|
+
problems: z.array(z.string()),
|
|
178
|
+
answer_id: z.number().int().nullable(),
|
|
179
|
+
}),
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* A ticket left out of the run: the stuck ticket the owner skipped
|
|
184
|
+
* (`because` is `null`), or one that waits on a skipped ticket. It stays
|
|
185
|
+
* open, with a comment saying why.
|
|
186
|
+
*/
|
|
187
|
+
export const TicketSkippedEntrySchema = z.object({
|
|
188
|
+
...ENTRY_FIELDS,
|
|
189
|
+
kind: z.literal('ticket_skipped'),
|
|
190
|
+
content: z.object({
|
|
191
|
+
because: z.number().int().positive().nullable(),
|
|
192
|
+
}),
|
|
193
|
+
})
|