@telora/daemon 0.23.29 → 0.23.46
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/build-info.json +10 -3
- package/dist/backends/claude/one-shot-model.d.ts.map +1 -1
- package/dist/backends/claude/one-shot-model.js +1 -0
- package/dist/backends/claude/one-shot-model.js.map +1 -1
- package/dist/completion/completion-event/event.d.ts +12 -0
- package/dist/completion/completion-event/event.d.ts.map +1 -1
- package/dist/completion/completion-event/event.js +1 -0
- package/dist/completion/completion-event/event.js.map +1 -1
- package/dist/completion/completion-event/unfinished-work.d.ts +134 -0
- package/dist/completion/completion-event/unfinished-work.d.ts.map +1 -0
- package/dist/completion/completion-event/unfinished-work.js +140 -0
- package/dist/completion/completion-event/unfinished-work.js.map +1 -0
- package/dist/completion/team-outcome/apply-turn.d.ts.map +1 -1
- package/dist/completion/team-outcome/apply-turn.js +18 -0
- package/dist/completion/team-outcome/apply-turn.js.map +1 -1
- package/dist/completion/team-outcome/decide-turn-entry-rows.d.ts +16 -0
- package/dist/completion/team-outcome/decide-turn-entry-rows.d.ts.map +1 -1
- package/dist/completion/team-outcome/decide-turn-entry-rows.js +75 -11
- package/dist/completion/team-outcome/decide-turn-entry-rows.js.map +1 -1
- package/dist/completion/team-outcome/decide-turn-work-rows.d.ts.map +1 -1
- package/dist/completion/team-outcome/decide-turn-work-rows.js +10 -1
- package/dist/completion/team-outcome/decide-turn-work-rows.js.map +1 -1
- package/dist/completion/team-outcome/decide.d.ts.map +1 -1
- package/dist/completion/team-outcome/decide.js +1 -0
- package/dist/completion/team-outcome/decide.js.map +1 -1
- package/dist/completion/team-outcome/exit-action-roles.d.ts.map +1 -1
- package/dist/completion/team-outcome/exit-action-roles.js +2 -0
- package/dist/completion/team-outcome/exit-action-roles.js.map +1 -1
- package/dist/completion/team-outcome/exit-actions.d.ts +4 -0
- package/dist/completion/team-outcome/exit-actions.d.ts.map +1 -1
- package/dist/completion/team-outcome/exit-limits.d.ts +8 -0
- package/dist/completion/team-outcome/exit-limits.d.ts.map +1 -1
- package/dist/completion/team-outcome/exit-limits.js +9 -0
- package/dist/completion/team-outcome/exit-limits.js.map +1 -1
- package/dist/completion/team-outcome/exit-pipeline-state.d.ts +7 -0
- package/dist/completion/team-outcome/exit-pipeline-state.d.ts.map +1 -1
- package/dist/completion/team-outcome/exit-pipeline-state.js +1 -0
- package/dist/completion/team-outcome/exit-pipeline-state.js.map +1 -1
- package/dist/completion/team-outcome/team-outcome.d.ts.map +1 -1
- package/dist/completion/team-outcome/team-outcome.js +2 -1
- package/dist/completion/team-outcome/team-outcome.js.map +1 -1
- package/dist/completion/team-teardown/session-hold-bounds.d.ts +13 -1
- package/dist/completion/team-teardown/session-hold-bounds.d.ts.map +1 -1
- package/dist/completion/team-teardown/session-hold-bounds.js +15 -0
- package/dist/completion/team-teardown/session-hold-bounds.js.map +1 -1
- package/dist/completion/team-teardown/session-hold.d.ts.map +1 -1
- package/dist/completion/team-teardown/session-hold.js +4 -0
- package/dist/completion/team-teardown/session-hold.js.map +1 -1
- package/dist/composition/completion-event-context.d.ts.map +1 -1
- package/dist/composition/completion-event-context.js +8 -0
- package/dist/composition/completion-event-context.js.map +1 -1
- package/dist/composition/daemon-contexts.d.ts.map +1 -1
- package/dist/composition/daemon-contexts.js +3 -1
- package/dist/composition/daemon-contexts.js.map +1 -1
- package/dist/composition/qa-author-pass-context.d.ts +7 -0
- package/dist/composition/qa-author-pass-context.d.ts.map +1 -0
- package/dist/composition/qa-author-pass-context.js +68 -0
- package/dist/composition/qa-author-pass-context.js.map +1 -0
- package/dist/composition/runtime-poll-context.d.ts +32 -4
- package/dist/composition/runtime-poll-context.d.ts.map +1 -1
- package/dist/composition/runtime-poll-context.js +61 -5
- package/dist/composition/runtime-poll-context.js.map +1 -1
- package/dist/composition/spawn-pass-deps.d.ts +1 -1
- package/dist/composition/spawn-pass-deps.d.ts.map +1 -1
- package/dist/composition/verification-context.js +1 -1
- package/dist/composition/verify-rework-context.d.ts +12 -3
- package/dist/composition/verify-rework-context.d.ts.map +1 -1
- package/dist/composition/verify-rework-context.js +27 -10
- package/dist/composition/verify-rework-context.js.map +1 -1
- package/dist/config/live-daemon-config.js +1 -1
- package/dist/daemon-state/focus-team-state.js +1 -1
- package/dist/daemon-state/provider-window.d.ts.map +1 -1
- package/dist/daemon-state/provider-window.js +1 -0
- package/dist/daemon-state/provider-window.js.map +1 -1
- package/dist/delivery/advance-hold.d.ts +25 -0
- package/dist/delivery/advance-hold.d.ts.map +1 -1
- package/dist/delivery/advance-hold.js +52 -1
- package/dist/delivery/advance-hold.js.map +1 -1
- package/dist/delivery/delivery-reconciler.d.ts +17 -2
- package/dist/delivery/delivery-reconciler.d.ts.map +1 -1
- package/dist/delivery/delivery-reconciler.js +54 -30
- package/dist/delivery/delivery-reconciler.js.map +1 -1
- package/dist/delivery/recorded-concerns.d.ts.map +1 -1
- package/dist/delivery/recorded-concerns.js +1 -0
- package/dist/delivery/recorded-concerns.js.map +1 -1
- package/dist/directive/directive-queue.d.ts +27 -0
- package/dist/directive/directive-queue.d.ts.map +1 -1
- package/dist/directive/directive-queue.js +36 -1
- package/dist/directive/directive-queue.js.map +1 -1
- package/dist/focus/daemon-contexts.d.ts +3 -0
- package/dist/focus/daemon-contexts.d.ts.map +1 -1
- package/dist/focus/daemon-contexts.js +1 -1
- package/dist/focus/daemon-contexts.js.map +1 -1
- package/dist/focus/failed-head-wedge.d.ts +42 -13
- package/dist/focus/failed-head-wedge.d.ts.map +1 -1
- package/dist/focus/failed-head-wedge.js +45 -10
- package/dist/focus/failed-head-wedge.js.map +1 -1
- package/dist/focus/focus-loop-registry.d.ts.map +1 -1
- package/dist/focus/focus-loop-registry.js +21 -0
- package/dist/focus/focus-loop-registry.js.map +1 -1
- package/dist/focus/focus-poller-spawn.js +1 -1
- package/dist/focus/focus-poller-state.js +1 -1
- package/dist/focus/pending-spawn-review-next-step.d.ts.map +1 -1
- package/dist/focus/pending-spawn-review-next-step.js +9 -1
- package/dist/focus/pending-spawn-review-next-step.js.map +1 -1
- package/dist/focus/uncommitted-work-backstop.d.ts +115 -0
- package/dist/focus/uncommitted-work-backstop.d.ts.map +1 -0
- package/dist/focus/uncommitted-work-backstop.js +259 -0
- package/dist/focus/uncommitted-work-backstop.js.map +1 -0
- package/dist/focus/verify-routing-passes.d.ts +5 -1
- package/dist/focus/verify-routing-passes.d.ts.map +1 -1
- package/dist/focus/verify-routing-passes.js +1 -0
- package/dist/focus/verify-routing-passes.js.map +1 -1
- package/dist/git/index.d.ts.map +1 -1
- package/dist/git/index.js +2 -1
- package/dist/git/index.js.map +1 -1
- package/dist/git/review-window-commits.d.ts.map +1 -1
- package/dist/git/review-window-commits.js +1 -0
- package/dist/git/review-window-commits.js.map +1 -1
- package/dist/git/types.d.ts.map +1 -1
- package/dist/git/types.js +1 -19
- package/dist/git/types.js.map +1 -1
- package/dist/prompt-sections/qa-author-section.d.ts +58 -0
- package/dist/prompt-sections/qa-author-section.d.ts.map +1 -0
- package/dist/prompt-sections/qa-author-section.js +226 -0
- package/dist/prompt-sections/qa-author-section.js.map +1 -0
- package/dist/qa/qa-author-faithfulness.d.ts +139 -0
- package/dist/qa/qa-author-faithfulness.d.ts.map +1 -0
- package/dist/qa/qa-author-faithfulness.js +323 -0
- package/dist/qa/qa-author-faithfulness.js.map +1 -0
- package/dist/qa/qa-author-mode.d.ts +34 -0
- package/dist/qa/qa-author-mode.d.ts.map +1 -0
- package/dist/qa/qa-author-mode.js +29 -0
- package/dist/qa/qa-author-mode.js.map +1 -0
- package/dist/qa/qa-author-output.d.ts +26 -0
- package/dist/qa/qa-author-output.d.ts.map +1 -0
- package/dist/qa/qa-author-output.js +66 -0
- package/dist/qa/qa-author-output.js.map +1 -0
- package/dist/qa/qa-author-pass.d.ts +63 -0
- package/dist/qa/qa-author-pass.d.ts.map +1 -0
- package/dist/qa/qa-author-pass.js +164 -0
- package/dist/qa/qa-author-pass.js.map +1 -0
- package/dist/qa/qa-author-runner.d.ts +60 -0
- package/dist/qa/qa-author-runner.d.ts.map +1 -0
- package/dist/qa/qa-author-runner.js +180 -0
- package/dist/qa/qa-author-runner.js.map +1 -0
- package/dist/qa/qa-focus-changes.d.ts +32 -0
- package/dist/qa/qa-focus-changes.d.ts.map +1 -0
- package/dist/qa/qa-focus-changes.js +59 -0
- package/dist/qa/qa-focus-changes.js.map +1 -0
- package/dist/queries/api-client/shared.d.ts +1 -0
- package/dist/queries/api-client/shared.d.ts.map +1 -1
- package/dist/queries/api-client/shared.js +14 -1
- package/dist/queries/api-client/shared.js.map +1 -1
- package/dist/queries/deliveries/deliveries.d.ts +15 -27
- package/dist/queries/deliveries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries/deliveries.js +6 -57
- package/dist/queries/deliveries/deliveries.js.map +1 -1
- package/dist/queries/delivery-gate-state/delivery-gate-holds.d.ts +8 -3
- package/dist/queries/delivery-gate-state/delivery-gate-holds.d.ts.map +1 -1
- package/dist/queries/delivery-gate-state/delivery-gate-state.js +1 -1
- package/dist/queries/escalations/escalations.d.ts.map +1 -1
- package/dist/queries/escalations/escalations.js +1 -0
- package/dist/queries/escalations/escalations.js.map +1 -1
- package/dist/queries/index.d.ts +1 -1
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/index.js +1 -1
- package/dist/queries/index.js.map +1 -1
- package/dist/queries/qa-packets/qa-packets.d.ts +156 -0
- package/dist/queries/qa-packets/qa-packets.d.ts.map +1 -0
- package/dist/queries/qa-packets/qa-packets.js +105 -0
- package/dist/queries/qa-packets/qa-packets.js.map +1 -0
- package/dist/supervision/escalation-filing.js +1 -1
- package/dist/supervision/spawn-cooldown.js +1 -1
- package/dist/supervision/stop-registry.d.ts +5 -0
- package/dist/supervision/stop-registry.d.ts.map +1 -1
- package/dist/supervision/stop-rows-team-session.d.ts +6 -1
- package/dist/supervision/stop-rows-team-session.d.ts.map +1 -1
- package/dist/supervision/stop-rows-team-session.js +34 -1
- package/dist/supervision/stop-rows-team-session.js.map +1 -1
- package/dist/supervision/team-work.d.ts.map +1 -1
- package/dist/supervision/team-work.js +1 -0
- package/dist/supervision/team-work.js.map +1 -1
- package/dist/testing/fixtures/api-client.js +1 -1
- package/dist/testing/fixtures/approved-head-inert-deps.js +1 -1
- package/dist/testing/fixtures/approved-head-inert-deps.js.map +1 -1
- package/dist/testing/fixtures/completion-event-deps.d.ts +2 -1
- package/dist/testing/fixtures/completion-event-deps.d.ts.map +1 -1
- package/dist/testing/fixtures/completion-event-deps.js +5 -1
- package/dist/testing/fixtures/completion-event-deps.js.map +1 -1
- package/dist/testing/fixtures/index.js +1 -1
- package/dist/testing/fixtures/pending-spawn-world.d.ts.map +1 -1
- package/dist/testing/fixtures/pending-spawn-world.js +2 -1
- package/dist/testing/fixtures/pending-spawn-world.js.map +1 -1
- package/dist/testing/fixtures/review-exit-deps.js +2 -2
- package/dist/testing/fixtures/review-exit-deps.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/qa-packet.d.ts +39 -0
- package/dist/types/qa-packet.d.ts.map +1 -0
- package/dist/types/qa-packet.js +50 -0
- package/dist/types/qa-packet.js.map +1 -0
- package/dist/verify/attribution/rework-attribution.d.ts +50 -111
- package/dist/verify/attribution/rework-attribution.d.ts.map +1 -1
- package/dist/verify/attribution/rework-attribution.js +215 -71
- package/dist/verify/attribution/rework-attribution.js.map +1 -1
- package/dist/verify/gate-verdicts/commit-verdict-record.d.ts +9 -0
- package/dist/verify/gate-verdicts/commit-verdict-record.d.ts.map +1 -1
- package/dist/verify/gate-verdicts/commit-verdict-record.js +27 -1
- package/dist/verify/gate-verdicts/commit-verdict-record.js.map +1 -1
- package/dist/verify/gate-verdicts/judged-ancestor.d.ts.map +1 -1
- package/dist/verify/gate-verdicts/judged-ancestor.js +2 -1
- package/dist/verify/gate-verdicts/judged-ancestor.js.map +1 -1
- package/dist/verify/outcome-routing/gate-rework-reopen.d.ts +30 -0
- package/dist/verify/outcome-routing/gate-rework-reopen.d.ts.map +1 -0
- package/dist/verify/outcome-routing/gate-rework-reopen.js +37 -0
- package/dist/verify/outcome-routing/gate-rework-reopen.js.map +1 -0
- package/dist/verify/outcome-routing/verification-rework-issue.d.ts +114 -25
- package/dist/verify/outcome-routing/verification-rework-issue.d.ts.map +1 -1
- package/dist/verify/outcome-routing/verification-rework-issue.js +147 -88
- package/dist/verify/outcome-routing/verification-rework-issue.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/qa/qa-author-pass.test.ts,
|
|
3
|
+
// packages/daemon/src/qa/qa-author-unfaithful-answer.test.ts
|
|
4
|
+
// PINNED-BY-END
|
|
5
|
+
import { createLogger } from '../log/daemon-log.js';
|
|
6
|
+
import { QA_PACKET_STATUS } from '../types/qa-packet.js';
|
|
7
|
+
const log = createLogger({ module: 'qa-author' });
|
|
8
|
+
/** The loop's cadence. */
|
|
9
|
+
export const QA_AUTHOR_PASS_INTERVAL_MS = 60_000;
|
|
10
|
+
/**
|
|
11
|
+
* Why armed work, the provider or the daemon's mode forbids a pass now, or
|
|
12
|
+
* null. Pure: armed work keeps priority while every slot is taken or a spawn
|
|
13
|
+
* waits for one; a read-only daemon could write no packet.
|
|
14
|
+
*/
|
|
15
|
+
export function qaPassHoldReason(utilization, providerHoldUntilMs, readOnly) {
|
|
16
|
+
if (readOnly)
|
|
17
|
+
return 'the daemon is in read-only mode';
|
|
18
|
+
if (utilization && utilization.queueDepth > 0)
|
|
19
|
+
return `armed work is waiting for ${utilization.queueDepth} session slot(s)`;
|
|
20
|
+
if (utilization && utilization.total >= utilization.max)
|
|
21
|
+
return `every session slot is in use (${utilization.total}/${utilization.max})`;
|
|
22
|
+
if (providerHoldUntilMs !== null)
|
|
23
|
+
return `the claude provider rate-limit window is open until ${new Date(providerHoldUntilMs).toISOString()}`;
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
let passInFlight = false;
|
|
27
|
+
function errorMessage(err) {
|
|
28
|
+
return err instanceof Error ? err.message : String(err);
|
|
29
|
+
}
|
|
30
|
+
function tag(candidate) {
|
|
31
|
+
return `focus ${candidate.focusId.slice(0, 8)} ("${candidate.focusName}")`;
|
|
32
|
+
}
|
|
33
|
+
/** Write a packet failed; false (logged) when even that write did not land. */
|
|
34
|
+
async function writeFailed(deps, candidate, packetId, reason) {
|
|
35
|
+
try {
|
|
36
|
+
await deps.writePacket({ focusId: candidate.focusId, packetId, status: QA_PACKET_STATUS.FAILED, failureReason: reason });
|
|
37
|
+
log.warn(`[qa-author] ${tag(candidate)}: packet failed -- ${reason}`);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
log.warn(`[qa-author] ${tag(candidate)}: could not record the failed packet (${reason}): ${errorMessage(err)}`);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Open the cycle's pending packet: refresh the abandoned one, or write a new one. Null (logged) when none could be. */
|
|
46
|
+
async function openPendingPacket(deps, candidate) {
|
|
47
|
+
try {
|
|
48
|
+
if (candidate.pendingPacketId) {
|
|
49
|
+
await deps.writePacket({ focusId: candidate.focusId, packetId: candidate.pendingPacketId, status: QA_PACKET_STATUS.PENDING });
|
|
50
|
+
return candidate.pendingPacketId;
|
|
51
|
+
}
|
|
52
|
+
const opened = await deps.writePacket({ focusId: candidate.focusId, status: QA_PACKET_STATUS.PENDING });
|
|
53
|
+
if (!opened.attached) {
|
|
54
|
+
await writeFailed(deps, candidate, opened.packetId, 'the focus left its open QA cycle before the pass ran');
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return opened.packetId;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
log.warn(`[qa-author] ${tag(candidate)}: could not open a pending packet: ${errorMessage(err)}`);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** The write a finished result makes. A packet the author answered declares that it carries the previous cycle's cases. */
|
|
65
|
+
function finalWrite(candidate, packetId, result) {
|
|
66
|
+
const focusId = candidate.focusId;
|
|
67
|
+
const answered = { focusId, packetId, carriesPriorResults: true };
|
|
68
|
+
switch (result.kind) {
|
|
69
|
+
case 'cases':
|
|
70
|
+
return { ...answered, status: QA_PACKET_STATUS.READY, reviewedSha: result.reviewedSha, cases: result.cases, authorMode: result.authorMode };
|
|
71
|
+
case 'no_ui_surface':
|
|
72
|
+
return { ...answered, status: QA_PACKET_STATUS.NO_UI_SURFACE, reviewedSha: result.reviewedSha, authorMode: result.authorMode };
|
|
73
|
+
default:
|
|
74
|
+
return {
|
|
75
|
+
focusId, packetId, status: QA_PACKET_STATUS.FAILED, failureReason: result.reason,
|
|
76
|
+
...(result.reviewedSha ? { reviewedSha: result.reviewedSha } : {}),
|
|
77
|
+
...(result.authorMode ? { authorMode: result.authorMode } : {}),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function runCandidate(deps, productId, candidate) {
|
|
82
|
+
const packetId = await openPendingPacket(deps, candidate);
|
|
83
|
+
if (!packetId)
|
|
84
|
+
return 'errors';
|
|
85
|
+
let result;
|
|
86
|
+
try {
|
|
87
|
+
result = await deps.author(productId, candidate);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
result = { kind: 'failed', reason: `the QA-author pass threw: ${errorMessage(err)}`, authorMode: null, reviewedSha: null };
|
|
91
|
+
}
|
|
92
|
+
if (result.kind === 'held') {
|
|
93
|
+
log.info(`[qa-author] ${tag(candidate)}: packet left pending -- ${result.reason}`);
|
|
94
|
+
return 'held';
|
|
95
|
+
}
|
|
96
|
+
const write = finalWrite(candidate, packetId, result);
|
|
97
|
+
try {
|
|
98
|
+
await deps.writePacket(write);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
if (write.status === QA_PACKET_STATUS.FAILED) {
|
|
102
|
+
log.warn(`[qa-author] ${tag(candidate)}: could not record the failed packet: ${errorMessage(err)}`);
|
|
103
|
+
return 'errors';
|
|
104
|
+
}
|
|
105
|
+
const recorded = await writeFailed(deps, candidate, packetId, `the ${write.status} packet was refused: ${errorMessage(err)}`);
|
|
106
|
+
return recorded ? 'failed' : 'errors';
|
|
107
|
+
}
|
|
108
|
+
if (write.status === QA_PACKET_STATUS.FAILED) {
|
|
109
|
+
log.warn(`[qa-author] ${tag(candidate)}: packet failed -- ${write.failureReason ?? ''}`);
|
|
110
|
+
return 'failed';
|
|
111
|
+
}
|
|
112
|
+
log.info(`[qa-author] ${tag(candidate)}: packet ${write.status} (${write.authorMode ?? 'unknown'} pass, commit ${write.reviewedSha ?? '?'})`);
|
|
113
|
+
return 'written';
|
|
114
|
+
}
|
|
115
|
+
/** Run one pass over every product. One product's failed read never stops another's. */
|
|
116
|
+
export async function runQaAuthorPass(deps) {
|
|
117
|
+
const outcome = { skipped: null, written: 0, failed: 0, held: 0, errors: 0 };
|
|
118
|
+
if (passInFlight)
|
|
119
|
+
return { ...outcome, skipped: 'a QA-author pass is already running' };
|
|
120
|
+
passInFlight = true;
|
|
121
|
+
try {
|
|
122
|
+
for (const product of deps.products) {
|
|
123
|
+
let candidates;
|
|
124
|
+
const before = deps.holdReason();
|
|
125
|
+
if (before)
|
|
126
|
+
return { ...outcome, skipped: before };
|
|
127
|
+
try {
|
|
128
|
+
candidates = await deps.readCandidates(product.id);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
log.warn(`[qa-author] candidate read failed for product ${product.id.slice(0, 8)}: ${errorMessage(err)}`);
|
|
132
|
+
outcome.errors++;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
for (const candidate of candidates) {
|
|
136
|
+
const hold = deps.holdReason();
|
|
137
|
+
if (hold)
|
|
138
|
+
return { ...outcome, skipped: hold };
|
|
139
|
+
outcome[await runCandidate(deps, product.id, candidate)]++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return outcome;
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
passInFlight = false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** The loop tick: one pass over the live deps, never throwing into the timer. */
|
|
149
|
+
export async function runQaAuthorPassSafely(source, governor) {
|
|
150
|
+
try {
|
|
151
|
+
const deps = source(governor);
|
|
152
|
+
if (!deps)
|
|
153
|
+
return;
|
|
154
|
+
const o = await runQaAuthorPass(deps);
|
|
155
|
+
if (o.written + o.failed + o.held + o.errors > 0) {
|
|
156
|
+
log.info(`[qa-author] pass: written=${o.written} failed=${o.failed} held=${o.held} errors=${o.errors}` +
|
|
157
|
+
(o.skipped ? ` stopped=(${o.skipped})` : ''));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
log.warn(`[qa-author] pass failed: ${errorMessage(err)}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=qa-author-pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-author-pass.js","sourceRoot":"","sources":["../../src/qa/qa-author-pass.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,4DAA4D;AAC5D,+DAA+D;AAC/D,gBAAgB;AA2BhB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;AAElD,0BAA0B;AAC1B,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AA2BjD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,WAAuC,EACvC,mBAAkC,EAClC,QAAiB;IAEjB,IAAI,QAAQ;QAAE,OAAO,iCAAiC,CAAC;IACvD,IAAI,WAAW,IAAI,WAAW,CAAC,UAAU,GAAG,CAAC;QAAE,OAAO,6BAA6B,WAAW,CAAC,UAAU,kBAAkB,CAAC;IAC5H,IAAI,WAAW,IAAI,WAAW,CAAC,KAAK,IAAI,WAAW,CAAC,GAAG;QAAE,OAAO,iCAAiC,WAAW,CAAC,KAAK,IAAI,WAAW,CAAC,GAAG,GAAG,CAAC;IACzI,IAAI,mBAAmB,KAAK,IAAI;QAAE,OAAO,uDAAuD,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IAC9I,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,YAAY,GAAG,KAAK,CAAC;AAEzB,SAAS,YAAY,CAAC,GAAY;IAChC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,GAAG,CAAC,SAA4B;IACvC,OAAO,SAAS,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,SAAS,CAAC,SAAS,IAAI,CAAC;AAC7E,CAAC;AAED,+EAA+E;AAC/E,KAAK,UAAU,WAAW,CACxB,IAAsB,EACtB,SAA4B,EAC5B,QAAgB,EAChB,MAAc;IAEd,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;QACzH,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,CAAC,yCAAyC,MAAM,MAAM,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChH,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,wHAAwH;AACxH,KAAK,UAAU,iBAAiB,CAAC,IAAsB,EAAE,SAA4B;IACnF,IAAI,CAAC;QACH,IAAI,SAAS,CAAC,eAAe,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9H,OAAO,SAAS,CAAC,eAAe,CAAC;QACnC,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;QACxG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,sDAAsD,CAAC,CAAC;YAC5G,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,CAAC,sCAAsC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjG,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,2HAA2H;AAC3H,SAAS,UAAU,CAAC,SAA4B,EAAE,QAAgB,EAAE,MAAiD;IACnH,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;IAClC,MAAM,QAAQ,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC;IAClE,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,OAAO;YACV,OAAO,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9I,KAAK,eAAe;YAClB,OAAO,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,aAAa,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QACjI;YACE,OAAO;gBACL,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM;gBAChF,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClE,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChE,CAAC;IACN,CAAC;AACH,CAAC;AAID,KAAK,UAAU,YAAY,CAAC,IAAsB,EAAE,SAAiB,EAAE,SAA4B;IACjG,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC/B,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,6BAA6B,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC7H,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,CAAC,4BAA4B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACnF,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,EAAE,CAAC;YAC7C,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,CAAC,yCAAyC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpG,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,KAAK,CAAC,MAAM,wBAAwB,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9H,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACxC,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,EAAE,CAAC;QAC7C,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,CAAC,sBAAsB,KAAK,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC,CAAC;QACzF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,CAAC,YAAY,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,UAAU,IAAI,SAAS,iBAAiB,KAAK,CAAC,WAAW,IAAI,GAAG,GAAG,CAAC,CAAC;IAC9I,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAsB;IAC1D,MAAM,OAAO,GAAwB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAClG,IAAI,YAAY;QAAE,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,qCAAqC,EAAE,CAAC;IACxF,YAAY,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,UAA+B,CAAC;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,IAAI,MAAM;gBAAE,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YACnD,IAAI,CAAC;gBACH,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,iDAAiD,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC1G,OAAO,CAAC,MAAM,EAAE,CAAC;gBACjB,SAAS;YACX,CAAC;YACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC/B,IAAI,IAAI;oBAAE,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAC/C,OAAO,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;YAC7D,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;YAAS,CAAC;QACT,YAAY,GAAG,KAAK,CAAC;IACvB,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAA8B,EAAE,QAAiC;IAC3G,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,CAAC,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,IAAI,CACN,6BAA6B,CAAC,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,MAAM,EAAE;gBAC3F,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAC/C,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,4BAA4B,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { QaPacketCandidate } from '../queries/qa-packets/qa-packets.js';
|
|
2
|
+
import { type QaAuthorMode } from '../types/qa-packet.js';
|
|
3
|
+
import { type QaGit } from './qa-focus-changes.js';
|
|
4
|
+
/** Each attempt's wall-clock bound. */
|
|
5
|
+
export declare const QA_AUTHOR_TIMEOUT_MS: number;
|
|
6
|
+
/** The resumed pass's turn cap (it may read files). */
|
|
7
|
+
export declare const QA_AUTHOR_RESUMED_MAX_TURNS = 40;
|
|
8
|
+
/** The fresh pass's turn cap (it has no tools). */
|
|
9
|
+
export declare const QA_AUTHOR_FRESH_MAX_TURNS = 3;
|
|
10
|
+
/** The read-only tools a resumed pass may use. */
|
|
11
|
+
export declare const QA_AUTHOR_READ_TOOLS = "Read,Grep,Glob";
|
|
12
|
+
/** One model run, as the runner asks for it. */
|
|
13
|
+
export interface QaAuthorInvokeOptions {
|
|
14
|
+
label: string;
|
|
15
|
+
cwd?: string;
|
|
16
|
+
extraArgs: readonly string[];
|
|
17
|
+
timeoutMs: number;
|
|
18
|
+
maxTurns: number;
|
|
19
|
+
}
|
|
20
|
+
/** Run the model once; resolve with its final answer text, or reject (a ModelUnavailable names why). */
|
|
21
|
+
export type QaAuthorInvoke = (systemPrompt: string, userMessage: string, opts: QaAuthorInvokeOptions) => Promise<{
|
|
22
|
+
text: string;
|
|
23
|
+
}>;
|
|
24
|
+
export interface QaAuthorRunnerDeps {
|
|
25
|
+
invoke: QaAuthorInvoke;
|
|
26
|
+
/** The focus worktree the coding session ran in, or null when none is known. */
|
|
27
|
+
worktreePathFor: (focusId: string, branchName: string | null) => string | null;
|
|
28
|
+
pathExists: (path: string) => boolean;
|
|
29
|
+
/** The product repository and its integration branch (the fresh pass reads the change there). */
|
|
30
|
+
repoPath: string;
|
|
31
|
+
integrationBranch: string;
|
|
32
|
+
git: QaGit;
|
|
33
|
+
}
|
|
34
|
+
export type QaAuthorResult = {
|
|
35
|
+
kind: 'cases';
|
|
36
|
+
cases: unknown[];
|
|
37
|
+
authorMode: QaAuthorMode;
|
|
38
|
+
reviewedSha: string;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'no_ui_surface';
|
|
41
|
+
authorMode: QaAuthorMode;
|
|
42
|
+
reviewedSha: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'failed';
|
|
45
|
+
reason: string;
|
|
46
|
+
authorMode: QaAuthorMode | null;
|
|
47
|
+
reviewedSha: string | null;
|
|
48
|
+
} | {
|
|
49
|
+
kind: 'held';
|
|
50
|
+
reason: string;
|
|
51
|
+
};
|
|
52
|
+
/** The argv a resumed pass adds to the one-shot argv. Pure. */
|
|
53
|
+
export declare function buildResumedArgs(sessionId: string): string[];
|
|
54
|
+
/** The argv a fresh pass adds to the one-shot argv: no tools, no MCP servers. Pure. */
|
|
55
|
+
export declare function buildFreshArgs(): string[];
|
|
56
|
+
/** The commit the packet is pinned to: the reviewed commit, else the focus branch head, else null. */
|
|
57
|
+
export declare function pinPacketCommit(candidate: QaPacketCandidate, deps: Pick<QaAuthorRunnerDeps, 'repoPath' | 'git'>): string | null;
|
|
58
|
+
/** Author one candidate's packet. Never throws for a model or parse problem (those are results). */
|
|
59
|
+
export declare function authorQaPacket(candidate: QaPacketCandidate, deps: QaAuthorRunnerDeps): Promise<QaAuthorResult>;
|
|
60
|
+
//# sourceMappingURL=qa-author-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-author-runner.d.ts","sourceRoot":"","sources":["../../src/qa/qa-author-runner.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAE7E,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAI1E,OAAO,EAAmC,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAIpF,uCAAuC;AACvC,eAAO,MAAM,oBAAoB,QAAc,CAAC;AAChD,uDAAuD;AACvD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAC9C,mDAAmD;AACnD,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,kDAAkD;AAClD,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AAErD,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wGAAwG;AACxG,MAAM,MAAM,cAAc,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEnI,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,gFAAgF;IAChF,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC;IAC/E,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,iGAAiG;IACjG,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,GAAG,EAAE,KAAK,CAAC;CACZ;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAC;IAAC,UAAU,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC/F;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAYrC,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ5D;AAED,uFAAuF;AACvF,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AAID,sGAAsG;AACtG,wBAAgB,eAAe,CAAC,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI,CAK/H;AA0ED,oGAAoG;AACpG,wBAAsB,cAAc,CAAC,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0CpH"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/composition/qa-author-pass-context.test.ts,
|
|
3
|
+
// packages/daemon/src/qa/qa-author-pass.test.ts, packages/daemon/src/qa/qa-author-runner.test.ts,
|
|
4
|
+
// packages/daemon/src/qa/qa-author-unfaithful-answer.test.ts
|
|
5
|
+
// PINNED-BY-END
|
|
6
|
+
/**
|
|
7
|
+
* Author one focus's UI test packet: pin it to the reviewed commit, run the
|
|
8
|
+
* QA-author model RESUMED (a fork of the coding team's own Claude session) when
|
|
9
|
+
* qa-author-mode.ts allows it, and fall back to a FRESH pass over the delivery
|
|
10
|
+
* summaries and the diff when it does not, or when the resumed pass fails to
|
|
11
|
+
* run or answers no usable packet.
|
|
12
|
+
*
|
|
13
|
+
* The resumed pass runs `--resume <coding session> --fork-session` in the focus
|
|
14
|
+
* worktree, so the coding session itself is never extended (and the one-shot
|
|
15
|
+
* argv keeps the fork unpersisted). Both passes are `claude --print` one-shots
|
|
16
|
+
* (backends/claude/one-shot-model.ts), bounded by a timeout and a turn cap,
|
|
17
|
+
* with no MCP servers; the resumed pass may read files (Read, Grep, Glob) and
|
|
18
|
+
* the fresh pass has no tools at all -- everything it knows is in its prompt.
|
|
19
|
+
*
|
|
20
|
+
* An answer is never handed back UNFAITHFUL (qa-author-faithfulness.ts: a case
|
|
21
|
+
* whose criterion is not one the pass was shown, a case of the previous QA
|
|
22
|
+
* cycle that still applies and is not carried forward). An unfaithful resumed
|
|
23
|
+
* answer falls back to the fresh pass, as an unusable one does; an unfaithful
|
|
24
|
+
* fresh answer gets ONE corrective attempt, the fresh prompt with the
|
|
25
|
+
* violations appended (buildQaAuthorCorrection); still unfaithful, the result
|
|
26
|
+
* is `failed` with the violations as its reason -- never a ready packet.
|
|
27
|
+
*
|
|
28
|
+
* The cases a `cases` result carries are the ones that were judged: each case
|
|
29
|
+
* that carries a previous case forward is marked from the result a person
|
|
30
|
+
* RECORDED for it (retest, previously passed, needs a run), not from what the
|
|
31
|
+
* model wrote.
|
|
32
|
+
*
|
|
33
|
+
* A provider rate limit is not a failure of the pass: it returns `held`, and the
|
|
34
|
+
* caller leaves the packet pending for the edge's stale-pending rule to re-pick.
|
|
35
|
+
* Every other problem is a `failed` result with its reason. The model run is
|
|
36
|
+
* injected (QaAuthorRunnerDeps.invoke), so no test needs a claude binary.
|
|
37
|
+
*/
|
|
38
|
+
import { createLogger } from '../log/daemon-log.js';
|
|
39
|
+
import { isModelUnavailable } from '../backends/claude/one-shot-model.js';
|
|
40
|
+
import { buildQaAuthorCorrection, buildQaAuthorPrompt, QA_AUTHOR_SYSTEM_PROMPT } from '../prompt-sections/qa-author-section.js';
|
|
41
|
+
import { QA_AUTHOR_MODE } from '../types/qa-packet.js';
|
|
42
|
+
import { judgeQaAnswer } from './qa-author-faithfulness.js';
|
|
43
|
+
import { decideQaAuthorMode } from './qa-author-mode.js';
|
|
44
|
+
import { parseQaAuthorOutput } from './qa-author-output.js';
|
|
45
|
+
import { readFocusChanges, resolveCommit } from './qa-focus-changes.js';
|
|
46
|
+
const log = createLogger({ module: 'qa-author' });
|
|
47
|
+
/** Each attempt's wall-clock bound. */
|
|
48
|
+
export const QA_AUTHOR_TIMEOUT_MS = 10 * 60_000;
|
|
49
|
+
/** The resumed pass's turn cap (it may read files). */
|
|
50
|
+
export const QA_AUTHOR_RESUMED_MAX_TURNS = 40;
|
|
51
|
+
/** The fresh pass's turn cap (it has no tools). */
|
|
52
|
+
export const QA_AUTHOR_FRESH_MAX_TURNS = 3;
|
|
53
|
+
/** The read-only tools a resumed pass may use. */
|
|
54
|
+
export const QA_AUTHOR_READ_TOOLS = 'Read,Grep,Glob';
|
|
55
|
+
/** The argv a resumed pass adds to the one-shot argv. Pure. */
|
|
56
|
+
export function buildResumedArgs(sessionId) {
|
|
57
|
+
return [
|
|
58
|
+
'--resume', sessionId,
|
|
59
|
+
'--fork-session',
|
|
60
|
+
'--tools', QA_AUTHOR_READ_TOOLS,
|
|
61
|
+
'--allowed-tools', ...QA_AUTHOR_READ_TOOLS.split(','),
|
|
62
|
+
'--strict-mcp-config',
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
/** The argv a fresh pass adds to the one-shot argv: no tools, no MCP servers. Pure. */
|
|
66
|
+
export function buildFreshArgs() {
|
|
67
|
+
return ['--tools', '', '--strict-mcp-config'];
|
|
68
|
+
}
|
|
69
|
+
const HEX_SHA = /^[0-9a-f]{7,64}$/i;
|
|
70
|
+
/** The commit the packet is pinned to: the reviewed commit, else the focus branch head, else null. */
|
|
71
|
+
export function pinPacketCommit(candidate, deps) {
|
|
72
|
+
const reviewed = candidate.reviewedSha?.trim();
|
|
73
|
+
if (reviewed && HEX_SHA.test(reviewed))
|
|
74
|
+
return resolveCommit(deps.repoPath, reviewed, deps.git) ?? reviewed.toLowerCase();
|
|
75
|
+
const branch = candidate.branchName?.trim();
|
|
76
|
+
return branch ? resolveCommit(deps.repoPath, branch, deps.git) : null;
|
|
77
|
+
}
|
|
78
|
+
function errorMessage(err) {
|
|
79
|
+
return err instanceof Error ? err.message : String(err);
|
|
80
|
+
}
|
|
81
|
+
async function runAttempt(candidate, mode, prompt, opts, reviewedSha, deps) {
|
|
82
|
+
let text;
|
|
83
|
+
try {
|
|
84
|
+
text = (await deps.invoke(QA_AUTHOR_SYSTEM_PROMPT, prompt, opts)).text;
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (isModelUnavailable(err) && err.kind === 'rate_limit') {
|
|
88
|
+
return { kind: 'held', reason: `the ${mode} pass hit the provider rate limit: ${err.message}` };
|
|
89
|
+
}
|
|
90
|
+
return { kind: 'fall_back', reason: `the ${mode} pass could not run: ${errorMessage(err)}` };
|
|
91
|
+
}
|
|
92
|
+
const out = parseQaAuthorOutput(text);
|
|
93
|
+
if (out.kind === 'error')
|
|
94
|
+
return { kind: 'fall_back', reason: `the ${mode} pass answered no usable packet: ${out.error}` };
|
|
95
|
+
const { cases, violations } = judgeQaAnswer(candidate, out);
|
|
96
|
+
if (violations.length > 0) {
|
|
97
|
+
log.info(`[qa-author] focus ${candidate.focusId.slice(0, 8)}: ${opts.label} answer is not faithful (${violations.length} violation(s))`);
|
|
98
|
+
return {
|
|
99
|
+
kind: 'unfaithful',
|
|
100
|
+
violations,
|
|
101
|
+
reason: `the ${mode} pass answered a packet that is not faithful to the focus's criteria: ${violations.join('; ')}`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (out.kind === 'no_ui_surface')
|
|
105
|
+
return { kind: 'no_ui_surface', authorMode: mode, reviewedSha };
|
|
106
|
+
log.info(`[qa-author] focus ${candidate.focusId.slice(0, 8)}: ${mode} pass wrote ${cases.length} case(s)`);
|
|
107
|
+
return { kind: 'cases', cases, authorMode: mode, reviewedSha };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The one corrective attempt after an unfaithful fresh answer: the same fresh
|
|
111
|
+
* prompt with the violations appended. Still unfaithful (or unusable), the
|
|
112
|
+
* result is `failed` naming why -- never the unfaithful packet.
|
|
113
|
+
*/
|
|
114
|
+
async function runCorrectiveAttempt(candidate, freshPrompt, freshOpts, refused, reviewedSha, deps) {
|
|
115
|
+
const prompt = `${freshPrompt}\n${buildQaAuthorCorrection(refused)}`;
|
|
116
|
+
const opts = { ...freshOpts, label: `${freshOpts.label}:corrective` };
|
|
117
|
+
const corrected = await runAttempt(candidate, QA_AUTHOR_MODE.FRESH, prompt, opts, reviewedSha, deps);
|
|
118
|
+
if (corrected.kind === 'unfaithful') {
|
|
119
|
+
return {
|
|
120
|
+
kind: 'failed',
|
|
121
|
+
reason: `the packet is not faithful to the focus's criteria after one corrective attempt: ${corrected.violations.join('; ')}`,
|
|
122
|
+
authorMode: QA_AUTHOR_MODE.FRESH,
|
|
123
|
+
reviewedSha,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
if (corrected.kind === 'fall_back') {
|
|
127
|
+
return {
|
|
128
|
+
kind: 'failed',
|
|
129
|
+
reason: `${corrected.reason} (the corrective attempt after: ${refused.join('; ')})`,
|
|
130
|
+
authorMode: QA_AUTHOR_MODE.FRESH,
|
|
131
|
+
reviewedSha,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return corrected;
|
|
135
|
+
}
|
|
136
|
+
/** Author one candidate's packet. Never throws for a model or parse problem (those are results). */
|
|
137
|
+
export async function authorQaPacket(candidate, deps) {
|
|
138
|
+
const reviewedSha = pinPacketCommit(candidate, deps);
|
|
139
|
+
if (!reviewedSha) {
|
|
140
|
+
return { kind: 'failed', reason: 'no reviewed commit to pin the packet to', authorMode: null, reviewedSha: null };
|
|
141
|
+
}
|
|
142
|
+
const label = `qa-author:${candidate.focusId.slice(0, 8)}`;
|
|
143
|
+
const worktreePath = deps.worktreePathFor(candidate.focusId, candidate.branchName);
|
|
144
|
+
const decision = decideQaAuthorMode(candidate, {
|
|
145
|
+
worktreePath,
|
|
146
|
+
worktreeExists: worktreePath !== null && deps.pathExists(worktreePath),
|
|
147
|
+
});
|
|
148
|
+
let fallbackReason;
|
|
149
|
+
if (decision.mode === QA_AUTHOR_MODE.RESUMED) {
|
|
150
|
+
const resumed = await runAttempt(candidate, QA_AUTHOR_MODE.RESUMED, buildQaAuthorPrompt(candidate, QA_AUTHOR_MODE.RESUMED, reviewedSha), {
|
|
151
|
+
label: `${label}:resumed`,
|
|
152
|
+
cwd: decision.cwd,
|
|
153
|
+
extraArgs: buildResumedArgs(decision.sessionId),
|
|
154
|
+
timeoutMs: QA_AUTHOR_TIMEOUT_MS,
|
|
155
|
+
maxTurns: QA_AUTHOR_RESUMED_MAX_TURNS,
|
|
156
|
+
}, reviewedSha, deps);
|
|
157
|
+
if (resumed.kind !== 'fall_back' && resumed.kind !== 'unfaithful')
|
|
158
|
+
return resumed;
|
|
159
|
+
fallbackReason = resumed.reason;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
fallbackReason = decision.reason;
|
|
163
|
+
}
|
|
164
|
+
log.info(`[qa-author] focus ${candidate.focusId.slice(0, 8)}: fresh pass (${fallbackReason})`);
|
|
165
|
+
const changes = readFocusChanges(deps.repoPath, deps.integrationBranch, reviewedSha, candidate.deliveries.map((d) => d.deliveryId), deps.git);
|
|
166
|
+
const freshPrompt = buildQaAuthorPrompt(candidate, QA_AUTHOR_MODE.FRESH, reviewedSha, changes);
|
|
167
|
+
const freshOpts = {
|
|
168
|
+
label: `${label}:fresh`,
|
|
169
|
+
extraArgs: buildFreshArgs(),
|
|
170
|
+
timeoutMs: QA_AUTHOR_TIMEOUT_MS,
|
|
171
|
+
maxTurns: QA_AUTHOR_FRESH_MAX_TURNS,
|
|
172
|
+
};
|
|
173
|
+
const fresh = await runAttempt(candidate, QA_AUTHOR_MODE.FRESH, freshPrompt, freshOpts, reviewedSha, deps);
|
|
174
|
+
if (fresh.kind === 'unfaithful')
|
|
175
|
+
return runCorrectiveAttempt(candidate, freshPrompt, freshOpts, fresh.violations, reviewedSha, deps);
|
|
176
|
+
if (fresh.kind !== 'fall_back')
|
|
177
|
+
return fresh;
|
|
178
|
+
return { kind: 'failed', reason: `${fresh.reason} (it ran fresh because ${fallbackReason})`, authorMode: QA_AUTHOR_MODE.FRESH, reviewedSha };
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=qa-author-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-author-runner.js","sourceRoot":"","sources":["../../src/qa/qa-author-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a FRESH QA-author pass is shown of the change: the focus's commits and
|
|
3
|
+
* its diff at the reviewed commit, read from the product repository and
|
|
4
|
+
* capped, and the commit a packet is pinned to when the focus recorded none.
|
|
5
|
+
*
|
|
6
|
+
* Which commits are the focus's own depends on whether the completion merge
|
|
7
|
+
* already landed it:
|
|
8
|
+
* - not yet on integration: merge-base(integration, reviewed)..reviewed.
|
|
9
|
+
* - already on integration (the usual case -- a focus enters QA after its
|
|
10
|
+
* completion merge): the merge-base IS the reviewed commit, so the range is
|
|
11
|
+
* empty. The focus's own commits are then the ones whose Telora-Delivery
|
|
12
|
+
* trailer names one of its deliveries, listed with their patches.
|
|
13
|
+
* Every read is bounded; a read that fails says so in `note` rather than
|
|
14
|
+
* passing an empty change off as the whole one.
|
|
15
|
+
*/
|
|
16
|
+
import type { QaAuthorFreshContext } from '../prompt-sections/qa-author-section.js';
|
|
17
|
+
/** The git the reads run (production: git/types.ts runGitSync over the product repo). */
|
|
18
|
+
export interface QaGit {
|
|
19
|
+
run: (args: string[], cwd: string) => {
|
|
20
|
+
success: boolean;
|
|
21
|
+
output: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** The diff a fresh prompt carries at most, in characters. */
|
|
25
|
+
export declare const QA_DIFF_MAX_CHARS = 80000;
|
|
26
|
+
/** Commits listed (and patched) at most. */
|
|
27
|
+
export declare const QA_COMMIT_LOG_MAX = 200;
|
|
28
|
+
/** The full sha `ref` resolves to in `repoPath`, or null. */
|
|
29
|
+
export declare function resolveCommit(repoPath: string, ref: string, git: QaGit): string | null;
|
|
30
|
+
/** Read the focus's change at `reviewedSha`. */
|
|
31
|
+
export declare function readFocusChanges(repoPath: string, integrationBranch: string, reviewedSha: string, deliveryIds: readonly string[], git: QaGit, maxDiffChars?: number): QaAuthorFreshContext;
|
|
32
|
+
//# sourceMappingURL=qa-focus-changes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-focus-changes.d.ts","sourceRoot":"","sources":["../../src/qa/qa-focus-changes.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,yFAAyF;AACzF,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5E;AAED,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,QAAS,CAAC;AACxC,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAIrC,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAItF;AAYD,gDAAgD;AAChD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,GAAG,EAAE,KAAK,EACV,YAAY,GAAE,MAA0B,GACvC,oBAAoB,CAmCtB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/qa/qa-author-runner.test.ts,
|
|
3
|
+
// packages/daemon/src/qa/qa-author-unfaithful-answer.test.ts,
|
|
4
|
+
// packages/daemon/src/qa/qa-focus-changes.test.ts
|
|
5
|
+
// PINNED-BY-END
|
|
6
|
+
/** The diff a fresh prompt carries at most, in characters. */
|
|
7
|
+
export const QA_DIFF_MAX_CHARS = 80_000;
|
|
8
|
+
/** Commits listed (and patched) at most. */
|
|
9
|
+
export const QA_COMMIT_LOG_MAX = 200;
|
|
10
|
+
const SHA_RE = /^[0-9a-f]{7,64}$/i;
|
|
11
|
+
/** The full sha `ref` resolves to in `repoPath`, or null. */
|
|
12
|
+
export function resolveCommit(repoPath, ref, git) {
|
|
13
|
+
const r = git.run(['rev-parse', '--verify', '--quiet', `${ref}^{commit}`], repoPath);
|
|
14
|
+
const sha = r.output.trim();
|
|
15
|
+
return r.success && SHA_RE.test(sha) ? sha.toLowerCase() : null;
|
|
16
|
+
}
|
|
17
|
+
function cap(text, maxChars) {
|
|
18
|
+
return text.length > maxChars ? { text: text.slice(0, maxChars), truncated: true } : { text, truncated: false };
|
|
19
|
+
}
|
|
20
|
+
/** A diff read: a failed read keeps what it got (an over-long diff overflows the reader's buffer) and is marked cut. */
|
|
21
|
+
function diffRead(r, maxChars) {
|
|
22
|
+
const capped = cap(r.output, maxChars);
|
|
23
|
+
return { text: capped.text, truncated: capped.truncated || (!r.success && r.output.length > 0) };
|
|
24
|
+
}
|
|
25
|
+
/** Read the focus's change at `reviewedSha`. */
|
|
26
|
+
export function readFocusChanges(repoPath, integrationBranch, reviewedSha, deliveryIds, git, maxDiffChars = QA_DIFF_MAX_CHARS) {
|
|
27
|
+
const reviewed = resolveCommit(repoPath, reviewedSha, git);
|
|
28
|
+
if (!reviewed) {
|
|
29
|
+
return { commitLog: '', diff: '', truncated: false, note: `the reviewed commit ${reviewedSha} is not in the product repository` };
|
|
30
|
+
}
|
|
31
|
+
const base = git.run(['merge-base', integrationBranch, reviewed], repoPath);
|
|
32
|
+
const baseSha = base.success ? base.output.trim().toLowerCase() : '';
|
|
33
|
+
if (baseSha && baseSha !== reviewed) {
|
|
34
|
+
const log = git.run(['log', '--no-merges', `-n${QA_COMMIT_LOG_MAX}`, '--format=%h %s', `${baseSha}..${reviewed}`], repoPath);
|
|
35
|
+
const diff = diffRead(git.run(['diff', baseSha, reviewed], repoPath), maxDiffChars);
|
|
36
|
+
return {
|
|
37
|
+
commitLog: log.success ? log.output.trim() : '',
|
|
38
|
+
diff: diff.text,
|
|
39
|
+
truncated: diff.truncated,
|
|
40
|
+
note: diff.text ? null : 'the diff could not be read',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (deliveryIds.length === 0) {
|
|
44
|
+
return { commitLog: '', diff: '', truncated: false, note: 'the focus is already on integration and has no deliveries to find its commits by' };
|
|
45
|
+
}
|
|
46
|
+
const grep = ['-E', `--grep=^Telora-Delivery: (${deliveryIds.join('|')})`];
|
|
47
|
+
const log = git.run(['log', '--no-merges', `-n${QA_COMMIT_LOG_MAX}`, ...grep, '--format=%h %s', reviewed], repoPath);
|
|
48
|
+
const patches = diffRead(git.run(['log', '--no-merges', `-n${QA_COMMIT_LOG_MAX}`, ...grep, '-p', '--format=commit %h %s', reviewed], repoPath), maxDiffChars);
|
|
49
|
+
const commitLog = log.success ? log.output.trim() : '';
|
|
50
|
+
return {
|
|
51
|
+
commitLog,
|
|
52
|
+
diff: patches.text,
|
|
53
|
+
truncated: patches.truncated,
|
|
54
|
+
note: commitLog
|
|
55
|
+
? 'the focus is already on integration: shown are its own commits (by Telora-Delivery trailer) with their patches'
|
|
56
|
+
: 'the focus is already on integration and no commit carries a Telora-Delivery trailer naming its deliveries',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=qa-focus-changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-focus-changes.js","sourceRoot":"","sources":["../../src/qa/qa-focus-changes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/queries/api-client/shared.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAkC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAuCrG,QAAA,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/queries/api-client/shared.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAkC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAuCrG,QAAA,MAAM,eAAe;;;;;;;;;CA8DX,CAAC;AAEX,KAAK,qBAAqB,GAAG,MAAM,OAAO,eAAe,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,eAAe,CAAC;AAE7D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,qBAAqB,EAAE,YAAY,CASrE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAIpD,CAAC;AAwFH;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAEzE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAErF;AA2BD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,eAAe,CAE9D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAIvD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAE3D;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAKxC;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzD;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,CAAC,EAC7B,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED,wFAAwF;AACxF,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC;AAErC;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,OAAO,CAAC,CAAC,CAAC,CAEZ"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
-
// Pinned by:
|
|
2
|
+
// Pinned by: 91 tests -- run: npm run gen:pinned-by -- --list packages/daemon/src/queries/api-client/shared.ts
|
|
3
3
|
// PINNED-BY-END
|
|
4
4
|
import { CircuitBreaker, createApiClient, loadEnvConfig } from '@telora/daemon-core';
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
@@ -90,6 +90,15 @@ const circuitBreakers = {
|
|
|
90
90
|
maxCooldownMs: 180000,
|
|
91
91
|
label: 'tower',
|
|
92
92
|
}),
|
|
93
|
+
// qa: the QA-author pass's candidate read + packet write (qa/). Isolated so a
|
|
94
|
+
// failing QA pass can never open the 'polling' or 'delivery' breaker armed
|
|
95
|
+
// work runs through: the pass is background work that must not delay it.
|
|
96
|
+
qa: new CircuitBreaker({
|
|
97
|
+
failureThreshold: 5,
|
|
98
|
+
cooldownMs: 60000,
|
|
99
|
+
maxCooldownMs: 300000,
|
|
100
|
+
label: 'qa',
|
|
101
|
+
}),
|
|
93
102
|
};
|
|
94
103
|
export const CONCERN_CLASS = {
|
|
95
104
|
heartbeat: 'control-plane',
|
|
@@ -99,6 +108,7 @@ export const CONCERN_CLASS = {
|
|
|
99
108
|
delivery: 'control-plane',
|
|
100
109
|
drift: 'control-plane',
|
|
101
110
|
tower: 'control-plane',
|
|
111
|
+
qa: 'control-plane',
|
|
102
112
|
};
|
|
103
113
|
/**
|
|
104
114
|
* Actions that are observability/telemetry writes. They MUST resolve to an
|
|
@@ -125,6 +135,9 @@ const actionToConcern = {
|
|
|
125
135
|
daemon_get_tower_state: 'tower',
|
|
126
136
|
daemon_get_focus_branches: 'tower',
|
|
127
137
|
daemon_tower_write_verdicts: 'tower',
|
|
138
|
+
// The QA-author pass (isolated breaker; see `qa` above).
|
|
139
|
+
daemon_get_qa_packet_candidates: 'qa',
|
|
140
|
+
daemon_qa_packet_write: 'qa',
|
|
128
141
|
agent_role_list: 'polling',
|
|
129
142
|
daemon_get_done_deliveries: 'polling',
|
|
130
143
|
daemon_get_merge_conflict_deliveries: 'polling',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/queries/api-client/shared.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,+GAA+G;AAC/G,gBAAgB;AAoBhB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAkB,MAAM,qBAAqB,CAAC;AAErG,8EAA8E;AAC9E,+BAA+B;AAC/B,8EAA8E;AAC9E,oEAAoE;AACpE,iFAAiF;AAEjF,qCAAqC;AACrC,EAAE;AACF,wEAAwE;AACxE,+EAA+E;AAC/E,sEAAsE;AACtE,EAAE;AACF,0EAA0E;AAC1E,8EAA8E;AAC9E,qEAAqE;AACrE,EAAE;AACF,iFAAiF;AACjF,4EAA4E;AAC5E,4DAA4D;AAC5D,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,0EAA0E;AAC1E,+EAA+E;AAC/E,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,kFAAkF;AAClF,mFAAmF;AACnF,iFAAiF;AACjF,+EAA+E;AAC/E,sEAAsE;AACtE,EAAE;AACF,4EAA4E;AAC5E,2DAA2D;AAC3D,sEAAsE;AAEtE,MAAM,eAAe,GAAG;IACtB,SAAS,EAAE,IAAI,cAAc,CAAC;QAC5B,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,MAAM;QACrB,KAAK,EAAE,WAAW;KACnB,CAAC;IACF,OAAO,EAAE,IAAI,cAAc,CAAC;QAC1B,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,MAAM;QACrB,KAAK,EAAE,SAAS;KACjB,CAAC;IACF,QAAQ,EAAE,IAAI,cAAc,CAAC;QAC3B,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,MAAM;QACrB,KAAK,EAAE,UAAU;KAClB,CAAC;IACF,SAAS,EAAE,IAAI,cAAc,CAAC;QAC5B,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,MAAM;QACrB,KAAK,EAAE,WAAW;KACnB,CAAC;IACF,QAAQ,EAAE,IAAI,cAAc,CAAC;QAC3B,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,MAAM;QACrB,KAAK,EAAE,UAAU;KAClB,CAAC;IACF,yEAAyE;IACzE,yEAAyE;IACzE,yEAAyE;IACzE,yEAAyE;IACzE,4EAA4E;IAC5E,8EAA8E;IAC9E,KAAK,EAAE,IAAI,cAAc,CAAC;QACxB,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,MAAM;QACrB,KAAK,EAAE,OAAO;KACf,CAAC;IACF,+EAA+E;IAC/E,6EAA6E;IAC7E,4EAA4E;IAC5E,wEAAwE;IACxE,KAAK,EAAE,IAAI,cAAc,CAAC;QACxB,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,MAAM;QACrB,KAAK,EAAE,OAAO;KACf,CAAC;CACM,CAAC;AAiBX,MAAM,CAAC,MAAM,aAAa,GAAgD;IACxE,SAAS,EAAE,eAAe;IAC1B,OAAO,EAAE,eAAe;IACxB,QAAQ,EAAE,eAAe;IACzB,SAAS,EAAE,eAAe;IAC1B,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,eAAe;IACtB,KAAK,EAAE,eAAe;
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/queries/api-client/shared.ts"],"names":[],"mappings":"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"}
|