@straiffi/archon 1.10.9 → 1.10.12
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/dist/client/assets/ActivityView-BFn_Nhj4.js +1 -0
- package/dist/client/assets/GitHubActionsDialog-iZD86Yju.js +1 -0
- package/dist/client/assets/VerificationDialog-CqKE8t1d.js +4 -0
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BAIGV9Mj.js → architectureDiagram-3BPJPVTR-C8KefY67.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-B-5v5jSZ.js → blockDiagram-GPEHLZMM-BO2Q_Osr.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-C6wU415o.js → c4Diagram-AAUBKEIU-DGPkhbrK.js} +1 -1
- package/dist/client/assets/channel-DXKn3TOv.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-COmvX2tP.js → chunk-2J33WTMH-Dtb7Xu8C.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-BlANptdY.js → chunk-3OPIFGDE-Bnf4GbOF.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-ETyA2_GU.js → chunk-5ZQYHXKU-BWGid3g7.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-D5-DudwF.js → chunk-727SXJPM-ScA8IRGP.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-k1AJ4sA3.js → chunk-AQP2D5EJ-Bygg04Ip.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-jfksXwY9.js → chunk-CSCIHK7Q-CxdDDtfN.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-CHj0FDj9.js → chunk-KSCS5N6A-BgpZFsB5.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-1ODGxXhG.js → chunk-L5ZTLDWV-CKSew0OL.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-Bgh9X2W0.js → chunk-LZXEDZCA-DVG9Rx0K.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-DDkb3sp4.js → chunk-ND2GUHAM-CHBqNmuF.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-B6B8PZ_-.js → chunk-NZK2D7GU-DvZYWn7V.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-DhiUIFgj.js → chunk-O5CBEL6O-BL7lRTSe.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-Dzd0fbP3.js → chunk-WU5MYG2G-C-il2wHZ.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-U0fU20hT.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-C6bQNSxL.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-DoNDMCXI.js → dagre-BM42HDAG-B00l5tLi.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-ETDXSa5q.js → diagram-2AECGRRQ-Tum6g1_5.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-CgTUep7e.js → diagram-5GNKFQAL-BK1GX5jc.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-BKTx2iRe.js → diagram-KO2AKTUF-BrzmD5NB.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-9iEiScHT.js → diagram-LMA3HP47-BhrlgXiJ.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-UIZRh7Qa.js → diagram-OG6HWLK6-K-fWsJ3a.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-BpNJmJva.js → erDiagram-TEJ5UH35-Der6PjHE.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-C-rK0XZ1.js → flowDiagram-I6XJVG4X-BVWgGhXe.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DWyfPvv_.js → ganttDiagram-6RSMTGT7-DcoZ5ggj.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-x71bzdc_.js → gitGraphDiagram-PVQCEYII-BhhbMTBu.js} +1 -1
- package/dist/client/assets/index-B6BltHSr.css +2 -0
- package/dist/client/assets/index-CFOYm3j9.js +276 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-CbRus0Xu.js → infoDiagram-5YYISTIA-Lwc-agyc.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-DvaMHrgN.js → ishikawaDiagram-YF4QCWOH-B95U1Xcl.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-BQBu4YGn.js → journeyDiagram-JHISSGLW-xFpigy5D.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-8rU-U7L1.js → kanban-definition-UN3LZRKU-D3mudQnR.js} +1 -1
- package/dist/client/assets/{line-CSZnwjLA.js → line-DtTL3ZI2.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-CTOl2slE.js → mermaid-parser.core-Dau7K6zV.js} +1 -1
- package/dist/client/assets/{mermaid.core-B9gr0Vqf.js → mermaid.core-B8qtvATu.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-But1_PWQ.js → mindmap-definition-RKZ34NQL-Cus04Yq3.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-CnlVmfSG.js → pieDiagram-4H26LBE5-BCMGpBnn.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Dww1ZGuR.js → quadrantDiagram-W4KKPZXB-CAmOr-PJ.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CNf_loe8.js → requirementDiagram-4Y6WPE33-kisD3jc4.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DBhi37Jj.js → sankeyDiagram-5OEKKPKP-CsCedmM0.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-B64hb4E4.js → sequenceDiagram-3UESZ5HK-B-dAi954.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-DcS6oB-S.js → stateDiagram-AJRCARHV-X0BnedIW.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-6B8YH8Y2.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-Dq-4tXfh.js → timeline-definition-PNZ67QCA-DfFoSjhr.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-CeDklSE_.js → vennDiagram-CIIHVFJN-CKSCBwhG.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-D2cJISMm.js → wardleyDiagram-YWT4CUSO-DNIBQmHO.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-CBF-tTpF.js → xychartDiagram-2RQKCTM6-FvB55TQN.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +368 -5
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +194 -250
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/agentRuns.js +14 -1
- package/dist/server/lib/agentRuns.js.map +1 -1
- package/dist/server/lib/automationLoopProjection.js +55 -12
- package/dist/server/lib/automationLoopProjection.js.map +1 -1
- package/dist/server/lib/automationProgression.js +2 -5
- package/dist/server/lib/automationProgression.js.map +1 -1
- package/dist/server/lib/automationResumeDecision.js +19 -1
- package/dist/server/lib/automationResumeDecision.js.map +1 -1
- package/dist/server/lib/buildControlEligibility.js +4 -0
- package/dist/server/lib/buildControlEligibility.js.map +1 -0
- package/dist/server/lib/buildExecutionAdmission.js +76 -0
- package/dist/server/lib/buildExecutionAdmission.js.map +1 -0
- package/dist/server/lib/buildSequenceResume.js +79 -0
- package/dist/server/lib/buildSequenceResume.js.map +1 -0
- package/dist/server/lib/buildWorkload.js +11 -0
- package/dist/server/lib/buildWorkload.js.map +1 -0
- package/dist/server/lib/checkAutoFixDetails.js +36 -1
- package/dist/server/lib/checkAutoFixDetails.js.map +1 -1
- package/dist/server/lib/executionEnvironmentReconciliation.js +15 -2
- package/dist/server/lib/executionEnvironmentReconciliation.js.map +1 -1
- package/dist/server/lib/executionEnvironments.js +15 -0
- package/dist/server/lib/executionEnvironments.js.map +1 -1
- package/dist/server/lib/executionRetry.js +13 -1
- package/dist/server/lib/executionRetry.js.map +1 -1
- package/dist/server/lib/executionRunAuthority.js +2 -2
- package/dist/server/lib/executionRunAuthority.js.map +1 -1
- package/dist/server/lib/executionTargets.js +7 -4
- package/dist/server/lib/executionTargets.js.map +1 -1
- package/dist/server/lib/executionTimeline.js +8 -13
- package/dist/server/lib/executionTimeline.js.map +1 -1
- package/dist/server/lib/executionTimelineHierarchy.js +83 -0
- package/dist/server/lib/executionTimelineHierarchy.js.map +1 -0
- package/dist/server/lib/failedBuildSequenceRecovery.js +133 -0
- package/dist/server/lib/failedBuildSequenceRecovery.js.map +1 -0
- package/dist/server/lib/hostRunSession.js +62 -0
- package/dist/server/lib/hostRunSession.js.map +1 -0
- package/dist/server/lib/hostServiceRecovery.js +159 -0
- package/dist/server/lib/hostServiceRecovery.js.map +1 -0
- package/dist/server/lib/hostServiceRunProvider.js +32 -0
- package/dist/server/lib/hostServiceRunProvider.js.map +1 -0
- package/dist/server/lib/mobileAccess.js +6 -2
- package/dist/server/lib/mobileAccess.js.map +1 -1
- package/dist/server/lib/projectAutoConfig.js +5 -2
- package/dist/server/lib/projectAutoConfig.js.map +1 -1
- package/dist/server/lib/projectTargets.js +16 -2
- package/dist/server/lib/projectTargets.js.map +1 -1
- package/dist/server/lib/projects.js +25 -1
- package/dist/server/lib/projects.js.map +1 -1
- package/dist/server/lib/reviewFindingReconciliation.js +9 -2
- package/dist/server/lib/reviewFindingReconciliation.js.map +1 -1
- package/dist/server/lib/reviewFindings.js +82 -21
- package/dist/server/lib/reviewFindings.js.map +1 -1
- package/dist/server/lib/reviewRepairAssessmentRecords.js +41 -0
- package/dist/server/lib/reviewRepairAssessmentRecords.js.map +1 -0
- package/dist/server/lib/reviewRepairCompletion.js +78 -18
- package/dist/server/lib/reviewRepairCompletion.js.map +1 -1
- package/dist/server/lib/reviewRepairIterationRecords.js +4 -2
- package/dist/server/lib/reviewRepairIterationRecords.js.map +1 -1
- package/dist/server/lib/reviewRepairIterations.js +8 -2
- package/dist/server/lib/reviewRepairIterations.js.map +1 -1
- package/dist/server/lib/reviewRepairProgress.js +177 -0
- package/dist/server/lib/reviewRepairProgress.js.map +1 -0
- package/dist/server/lib/reviewRepairReconciliation.js +119 -140
- package/dist/server/lib/reviewRepairReconciliation.js.map +1 -1
- package/dist/server/lib/reviewRepairResumeOverride.js +55 -0
- package/dist/server/lib/reviewRepairResumeOverride.js.map +1 -0
- package/dist/server/lib/run.js +541 -504
- package/dist/server/lib/run.js.map +1 -1
- package/dist/server/lib/runProcessIdentity.js +71 -0
- package/dist/server/lib/runProcessIdentity.js.map +1 -0
- package/dist/server/lib/runProcesses.js +273 -0
- package/dist/server/lib/runProcesses.js.map +1 -0
- package/dist/server/lib/runServices.js +223 -0
- package/dist/server/lib/runServices.js.map +1 -0
- package/dist/server/lib/runSessionLifecycle.js +77 -0
- package/dist/server/lib/runSessionLifecycle.js.map +1 -0
- package/dist/server/lib/runStatus.js +8 -0
- package/dist/server/lib/runStatus.js.map +1 -0
- package/dist/server/lib/serviceRunCleanup.js +70 -0
- package/dist/server/lib/serviceRunCleanup.js.map +1 -0
- package/dist/server/lib/serviceRuns.js +458 -19
- package/dist/server/lib/serviceRuns.js.map +1 -1
- package/dist/server/lib/ticketAutomation.js +4 -27
- package/dist/server/lib/ticketAutomation.js.map +1 -1
- package/dist/server/lib/ticketRunOperations.js +103 -34
- package/dist/server/lib/ticketRunOperations.js.map +1 -1
- package/dist/server/lib/tickets.js +0 -13
- package/dist/server/lib/tickets.js.map +1 -1
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/workers/build.js +44 -69
- package/dist/server/workers/build.js.map +1 -1
- package/dist/server/workers/plan.js +0 -7
- package/dist/server/workers/plan.js.map +1 -1
- package/dist/server/workers/review.js +95 -146
- package/dist/server/workers/review.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/ActivityView-CKvbDXeA.js +0 -1
- package/dist/client/assets/GitHubActionsDialog-Dzo0vtak.js +0 -1
- package/dist/client/assets/VerificationDialog-BJnOitrJ.js +0 -4
- package/dist/client/assets/channel-5mIy7nm1.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BiQ-X2Sg.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CF-wCYW-.js +0 -1
- package/dist/client/assets/index-CIAO5aE_.css +0 -2
- package/dist/client/assets/index-nCGyalrn.js +0 -276
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-PWeeL0tR.js +0 -1
- package/dist/server/lib/automationDeliveryDecision.js +0 -34
- package/dist/server/lib/automationDeliveryDecision.js.map +0 -1
|
@@ -12,7 +12,7 @@ import { resolveReviewerConfig } from '../lib/reviewerConfig.js';
|
|
|
12
12
|
import { enqueue, isRunning } from '../lib/queue.js';
|
|
13
13
|
import { appendLifecycleEvent, getExecutionRun, transitionExecutionRun, withExecutionRunTransaction } from '../lib/executionRuns.js';
|
|
14
14
|
import { buildReviewContext } from '../lib/reviewContext.js';
|
|
15
|
-
import { computeDiffSignature, constrainReviewOutputToDiff, createReviewRun, finalizeReviewRun, formatExistingReviewFindingsForPrompt, formatReviewFindingsMarkdown, getLatestCompletedReviewRunForContext, hasPriorReviewRunForBundle, insertReviewFindings, listReviewFindings, mergeReviewFindings, parseStructuredReviewOutput, reconcileReviewFindingsToDiff, updateReviewRunPreparation, } from '../lib/reviewFindings.js';
|
|
15
|
+
import { computeDiffSignature, computeReviewEvaluatorFingerprint, constrainReviewOutputToDiff, createReviewRun, finalizeReviewRun, formatExistingReviewFindingsForPrompt, formatReviewFindingsMarkdown, getLatestCompletedReviewRunForContext, hasPriorReviewRunForBundle, insertReviewFindings, listReviewFindings, mergeReviewFindings, parseStructuredReviewOutput, reconcileReviewFindingsToDiff, updateReviewRunPreparation, } from '../lib/reviewFindings.js';
|
|
16
16
|
import { buildSpecCoverageContext } from '../lib/specCoverageContext.js';
|
|
17
17
|
import { listTickets } from '../lib/tickets.js';
|
|
18
18
|
import { registerBundleActivity, unregisterBundleActivity } from '../lib/bundleActivity.js';
|
|
@@ -23,12 +23,12 @@ import { captureStageBaseline, captureStageSuccess } from '../lib/ticketUndo.js'
|
|
|
23
23
|
import { beginTicketThinkingRun, bindTicketThinkingMessage } from '../lib/thinkingState.js';
|
|
24
24
|
import { autoParkTicketIfStale, getTicket, resolveTicketBranch, resolveTicketTool, resolveTicketWorkerKey } from '../lib/tickets.js';
|
|
25
25
|
import { createAgentRun, emitAgentRunsUpdated, emitExecutionAgentRunsUpdated, getAgentRun, listAgentRunsForExecutionRun, terminalizeAgentRunsForExecutionRun, } from '../lib/agentRuns.js';
|
|
26
|
-
import { buildAutomationFixInstruction, buildAutomationFixStatusMessage,
|
|
26
|
+
import { buildAutomationFixInstruction, buildAutomationFixStatusMessage, depthAtLeast, resetBundleAutomationLoop, resolveAutomationConfig, } from '../lib/ticketAutomation.js';
|
|
27
27
|
import { runAutomationCommitChain } from '../lib/ticketAutomationCommit.js';
|
|
28
28
|
import { submitTicketFollowUp } from '../lib/ticketFollowUpOperations.js';
|
|
29
|
-
import { completeAutomationProgressionInTransaction, completeAutomationProgression, completeAutomationReviewFixActionInTransaction,
|
|
29
|
+
import { completeAutomationProgressionInTransaction, completeAutomationProgression, completeAutomationReviewFixActionInTransaction, ensureAutomationProgression, finishAutomationReviewFix, pauseAutomationProgression, resolveProgressionForChild, waitAutomationProgression, } from '../lib/automationProgression.js';
|
|
30
30
|
import { assertAutomationAuthorizationCurrent, assertAutomationBoundaryNotRequired, AutomationCheckGateError, } from '../lib/automationCheckGate.js';
|
|
31
|
-
import {
|
|
31
|
+
import { attachReviewRepairActionInTransaction, attachReviewRepairResultInTransaction, getReviewRepairIteration, getReviewRepairIterationByVerification, pauseReviewRepairIteration, terminalizeReviewRepairIterationInTransaction, } from '../lib/reviewRepairIterations.js';
|
|
32
32
|
import { formatBuildOpenQuestionAnswersPrompt, listAnsweredBuildOpenQuestionsForBundle } from '../lib/buildOpenQuestions.js';
|
|
33
33
|
import { validateWorkflowContext } from '../lib/types.js';
|
|
34
34
|
import { isModelResolutionError } from '../lib/modelResolutionErrors.js';
|
|
@@ -97,6 +97,11 @@ const stripSystemReminderBlocks = (output) => {
|
|
|
97
97
|
const normalizeReviewOutput = (output) => {
|
|
98
98
|
return extractProjectMemorySuggestionsFromOutput(stripSystemReminderBlocks(output));
|
|
99
99
|
};
|
|
100
|
+
const getEffectiveReviewOutputProvenance = (outputs) => {
|
|
101
|
+
const provenances = outputs.map(output => output.outputProvenance ?? 'parse_failed');
|
|
102
|
+
return ['parse_failed', 'markdown_fallback', 'subagent_aggregation', 'structured_transcript', 'structured_primary']
|
|
103
|
+
.find(provenance => provenances.includes(provenance)) ?? 'parse_failed';
|
|
104
|
+
};
|
|
100
105
|
const resolveStructuredReviewOutput = (parentResponse, transcriptRuns, mainRole = 'code-review') => {
|
|
101
106
|
const normalizedParent = typeof parentResponse === 'string'
|
|
102
107
|
? normalizeReviewOutput(parentResponse)
|
|
@@ -114,7 +119,7 @@ const resolveStructuredReviewOutput = (parentResponse, transcriptRuns, mainRole
|
|
|
114
119
|
if (!normalized.cleanedOutput) {
|
|
115
120
|
return [];
|
|
116
121
|
}
|
|
117
|
-
const parsed = parseStructuredReviewOutput(normalized.cleanedOutput);
|
|
122
|
+
const parsed = parseStructuredReviewOutput(normalized.cleanedOutput, 'structured_transcript');
|
|
118
123
|
return parsed.status === 'completed' ? [parsed] : [];
|
|
119
124
|
})
|
|
120
125
|
.at(0);
|
|
@@ -129,7 +134,7 @@ const resolveStructuredReviewOutput = (parentResponse, transcriptRuns, mainRole
|
|
|
129
134
|
if (!normalized.cleanedOutput) {
|
|
130
135
|
return [];
|
|
131
136
|
}
|
|
132
|
-
const parsed = parseStructuredReviewOutput(normalized.cleanedOutput);
|
|
137
|
+
const parsed = parseStructuredReviewOutput(normalized.cleanedOutput, 'subagent_aggregation');
|
|
133
138
|
return parsed.status === 'completed' ? [parsed] : [];
|
|
134
139
|
});
|
|
135
140
|
if (parsedSubagentOutputs.length === 0) {
|
|
@@ -148,12 +153,18 @@ const resolveStructuredReviewOutput = (parentResponse, transcriptRuns, mainRole
|
|
|
148
153
|
findings,
|
|
149
154
|
resolvedExistingFindingIds: [],
|
|
150
155
|
status: 'completed',
|
|
156
|
+
outputProvenance: parsedSubagentOutputs.some(output => output.outputProvenance === 'markdown_fallback')
|
|
157
|
+
? 'markdown_fallback'
|
|
158
|
+
: 'subagent_aggregation',
|
|
151
159
|
},
|
|
152
160
|
};
|
|
153
161
|
};
|
|
154
162
|
const MAX_INLINE_DIFF_LINES = 400;
|
|
155
163
|
const MAX_INLINE_DIFF_CHARS = 20_000;
|
|
156
164
|
const SUBAGENT_REVIEW_GUIDANCE = 'If you delegate any part of the review to subagents, you remain responsible for evaluating their results and consolidating every accepted finding into your final response using the exact format below.';
|
|
165
|
+
const REVIEW_PROMPT_VERSION = 'ticket-review-v2';
|
|
166
|
+
const REVIEW_ROLE_POLICY_VERSION = 'ticket-review-role-policy-v1';
|
|
167
|
+
const REVIEW_OUTPUT_CONTRACT_VERSION = 'archon-review-findings-v1';
|
|
157
168
|
const countLines = (value) => {
|
|
158
169
|
if (!value) {
|
|
159
170
|
return 0;
|
|
@@ -372,89 +383,23 @@ Every finding must set \`file_path\` to a path in \`<review_scope>\` and set at
|
|
|
372
383
|
|
|
373
384
|
Do not include planning text, implementation steps, or commentary about changing modes.`, ticket.skills);
|
|
374
385
|
};
|
|
375
|
-
const runReviewCompletionAutomation = async (ticket, project, reviewRunId,
|
|
376
|
-
if (!ticket.worktree_bundle_id || !ticket.project_id) {
|
|
386
|
+
const runReviewCompletionAutomation = async (ticket, project, reviewRunId, io, executionContext, initiation, persistedAutomation) => {
|
|
387
|
+
if (!ticket.worktree_bundle_id || !ticket.project_id || !persistedAutomation) {
|
|
377
388
|
return false;
|
|
378
389
|
}
|
|
379
390
|
const projectId = ticket.project_id;
|
|
380
391
|
const bundleId = ticket.worktree_bundle_id;
|
|
381
|
-
const
|
|
382
|
-
const liveProject = getEffectiveProject(liveTicket) ?? project;
|
|
383
|
-
const config = persistedAutomation?.config ?? resolveAutomationConfig(liveTicket.bundle ?? null, liveProject);
|
|
384
|
-
const bundleState = getBundleAutomationState(projectId, bundleId);
|
|
385
|
-
const decision = persistedAutomation?.decision
|
|
386
|
-
?? decideReviewAutomation(config, bundleState, reviewRunId, parsedStatus, findings);
|
|
387
|
-
const progressionRunId = persistedAutomation?.progressionRunId
|
|
388
|
-
?? (initiation.initiator === 'automation'
|
|
389
|
-
? resolveProgressionForChild({ projectId, bundleId, childRunId: executionContext.runId }).id
|
|
390
|
-
: null);
|
|
392
|
+
const { config, decision, progressionRunId, disposition } = persistedAutomation;
|
|
391
393
|
const progression = progressionRunId ? { id: progressionRunId } : null;
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
: null;
|
|
399
|
-
withExecutionRunTransaction(transaction => {
|
|
400
|
-
if (parsedStatus === 'completed' && reviewRunId) {
|
|
401
|
-
attachReviewRepairResultInTransaction(transaction, {
|
|
402
|
-
projectId,
|
|
403
|
-
iterationId: iteration.id,
|
|
404
|
-
expectedPhase: 'verification_active',
|
|
405
|
-
expectedVerificationRunId: executionContext.runId,
|
|
406
|
-
resultingReviewRunId: reviewRunId,
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
appendReviewRepairIterationDecisionInTransaction(transaction, {
|
|
410
|
-
projectId,
|
|
411
|
-
iterationId: iteration.id,
|
|
412
|
-
decisionPoint: 'verification_completion',
|
|
413
|
-
effectiveAutomationConfig: config,
|
|
414
|
-
decisionCode: parsedStatus === 'completed' ? 'verification_completed' : 'verification_failed',
|
|
415
|
-
operationRunId: executionContext.runId,
|
|
416
|
-
});
|
|
417
|
-
const terminal = decision.kind === 'fix_iteration'
|
|
418
|
-
? { outcome: 'continuing', stopReason: null }
|
|
419
|
-
: decision.kind === 'clean'
|
|
420
|
-
? { outcome: 'repaired', stopReason: 'no_blocking_findings' }
|
|
421
|
-
: decision.kind === 'exhausted'
|
|
422
|
-
? { outcome: 'exhausted', stopReason: 'max_iterations' }
|
|
423
|
-
: decision.kind === 'pause_blocking'
|
|
424
|
-
? { outcome: 'interrupted', stopReason: 'automation_disabled' }
|
|
425
|
-
: parsedStatus !== 'completed'
|
|
426
|
-
? { outcome: 'failed', stopReason: 'verification_failed' }
|
|
427
|
-
: { outcome: 'interrupted', stopReason: 'configuration_changed' };
|
|
428
|
-
if (parsedStatus !== 'completed') {
|
|
429
|
-
pauseReviewRepairIterationInTransaction(transaction, {
|
|
430
|
-
projectId,
|
|
431
|
-
iterationId: iteration.id,
|
|
432
|
-
expectedPhase: 'verification_active',
|
|
433
|
-
expectedCurrentRunId: executionContext.runId,
|
|
434
|
-
stopReason: 'verification_failed',
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
terminalizeReviewRepairIterationInTransaction(transaction, {
|
|
439
|
-
projectId,
|
|
440
|
-
iterationId: iteration.id,
|
|
441
|
-
expectedPhase: 'verification_active',
|
|
442
|
-
expectedCurrentRunId: executionContext.runId,
|
|
443
|
-
outcome: terminal.outcome,
|
|
444
|
-
stopReason: terminal.stopReason,
|
|
445
|
-
resultingBlockingCount,
|
|
446
|
-
});
|
|
447
|
-
if (decision.kind === 'exhausted' && progression) {
|
|
448
|
-
completeAutomationProgressionInTransaction(transaction, {
|
|
449
|
-
projectId,
|
|
450
|
-
bundleId,
|
|
451
|
-
progressionRunId: progression.id,
|
|
452
|
-
deliveryReadyStageRunId: executionContext.runId,
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
}, asGenericEmitter(io), 'immediate');
|
|
394
|
+
if (disposition === 'handled' || decision.kind === 'no_progress') {
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
if (disposition === 'commit') {
|
|
398
|
+
if (!progressionRunId) {
|
|
399
|
+
throw new Error('Persisted Review commit has no owning progression');
|
|
457
400
|
}
|
|
401
|
+
await runAutomationCommitChain(ticket, project, ticket.bundle ?? null, config, io, progressionRunId, undefined, executionContext.runId);
|
|
402
|
+
return true;
|
|
458
403
|
}
|
|
459
404
|
switch (decision.kind) {
|
|
460
405
|
case 'manual':
|
|
@@ -511,61 +456,14 @@ const runReviewCompletionAutomation = async (ticket, project, reviewRunId, parse
|
|
|
511
456
|
review_finding_run_id: reviewRunId,
|
|
512
457
|
review_severity: config.reviewSeverity,
|
|
513
458
|
});
|
|
514
|
-
|
|
515
|
-
projectId,
|
|
516
|
-
bundleId,
|
|
517
|
-
ticketId: ticket.id,
|
|
518
|
-
ticketTitle: ticket.title,
|
|
519
|
-
parentRunId: executionContext.runId,
|
|
520
|
-
workflowContext: initiation.workflowContext,
|
|
521
|
-
broadcaster: asGenericEmitter(io),
|
|
522
|
-
}).runId;
|
|
523
|
-
let reviewFix = persistedAutomation?.repair?.reviewFix ?? null;
|
|
524
|
-
let iterationId = persistedAutomation?.repair?.iterationId ?? null;
|
|
525
|
-
if (persistedAutomation && !persistedAutomation.repair) {
|
|
459
|
+
if (disposition !== 'dispatch_repair' || !persistedAutomation.repair) {
|
|
526
460
|
return true;
|
|
527
461
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
projectId,
|
|
532
|
-
worktreeBundleId: bundleId,
|
|
533
|
-
ownerTicketId: ticket.id,
|
|
534
|
-
automationProgressionRunId: repairProgressionRunId,
|
|
535
|
-
triggeringReviewExecutionRunId: executionContext.runId,
|
|
536
|
-
triggeringReviewRunId: reviewRunId,
|
|
537
|
-
triggeringBlockingCount: countBlockingFindings(findings, config),
|
|
538
|
-
effectiveAutomationConfig: config,
|
|
539
|
-
decisionCode: 'repair_admitted',
|
|
540
|
-
});
|
|
541
|
-
if (iteration.phase !== 'observed') {
|
|
542
|
-
return { iteration, reviewFix: null };
|
|
543
|
-
}
|
|
544
|
-
const createdReviewFix = createAutomationReviewFixInTransaction(transaction, {
|
|
545
|
-
projectId,
|
|
546
|
-
bundleId,
|
|
547
|
-
ticketId: ticket.id,
|
|
548
|
-
ticketTitle: ticket.title,
|
|
549
|
-
progressionRunId: repairProgressionRunId,
|
|
550
|
-
workflowContext: reviewFixWorkflowContext,
|
|
551
|
-
triggeringReviewRunId: executionContext.runId,
|
|
552
|
-
reviewFindingRunId: reviewRunId,
|
|
553
|
-
reviewSeverity: config.reviewSeverity,
|
|
554
|
-
});
|
|
555
|
-
attachReviewRepairActionEnvelopeInTransaction(transaction, {
|
|
556
|
-
projectId,
|
|
557
|
-
iterationId: iteration.id,
|
|
558
|
-
expectedPhase: 'observed',
|
|
559
|
-
runId: createdReviewFix.runId,
|
|
560
|
-
});
|
|
561
|
-
return { iteration, reviewFix: createdReviewFix };
|
|
562
|
-
}, asGenericEmitter(io), 'immediate');
|
|
563
|
-
iterationId = claimed.iteration.id;
|
|
564
|
-
reviewFix = claimed.reviewFix;
|
|
565
|
-
}
|
|
566
|
-
if (!reviewFix) {
|
|
567
|
-
return true;
|
|
462
|
+
const { reviewFix, iterationId } = persistedAutomation.repair;
|
|
463
|
+
if (!progressionRunId) {
|
|
464
|
+
throw new Error('Persisted Review repair has no owning progression');
|
|
568
465
|
}
|
|
466
|
+
const repairProgressionRunId = progressionRunId;
|
|
569
467
|
const started = submitTicketFollowUp({
|
|
570
468
|
ticketId: ticket.id,
|
|
571
469
|
requestedProjectId: projectId,
|
|
@@ -580,7 +478,7 @@ const runReviewCompletionAutomation = async (ticket, project, reviewRunId, parse
|
|
|
580
478
|
onExecutionCreated: (createdContext, transaction) => {
|
|
581
479
|
attachReviewRepairActionInTransaction(transaction, {
|
|
582
480
|
projectId,
|
|
583
|
-
iterationId
|
|
481
|
+
iterationId,
|
|
584
482
|
expectedPhase: 'action_claimed',
|
|
585
483
|
runId: createdContext.runId,
|
|
586
484
|
});
|
|
@@ -674,8 +572,28 @@ const runReviewCompletionAutomation = async (ticket, project, reviewRunId, parse
|
|
|
674
572
|
return true;
|
|
675
573
|
}
|
|
676
574
|
case 'exhausted': {
|
|
677
|
-
if (
|
|
678
|
-
|
|
575
|
+
if (progression) {
|
|
576
|
+
waitAutomationProgression({
|
|
577
|
+
projectId,
|
|
578
|
+
bundleId,
|
|
579
|
+
progressionRunId: progression.id,
|
|
580
|
+
pauseCode: 'review',
|
|
581
|
+
pauseReason: 'Blocking Review findings remain after repair verification.',
|
|
582
|
+
reasonCode: 'precondition_failed',
|
|
583
|
+
pausedStageRunId: executionContext.runId,
|
|
584
|
+
broadcaster: asGenericEmitter(io),
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
pauseAutomationProgression({
|
|
589
|
+
projectId,
|
|
590
|
+
bundleId,
|
|
591
|
+
pauseCode: 'review',
|
|
592
|
+
pauseReason: 'Blocking Review findings remain after repair verification.',
|
|
593
|
+
reasonCode: 'precondition_failed',
|
|
594
|
+
pausedStageRunId: null,
|
|
595
|
+
broadcaster: asGenericEmitter(io),
|
|
596
|
+
});
|
|
679
597
|
}
|
|
680
598
|
const pausedTicket = getTicket(ticket.id);
|
|
681
599
|
if (pausedTicket) {
|
|
@@ -938,6 +856,16 @@ export function startReview(ticket, io, options) {
|
|
|
938
856
|
model: acceptedReviewExecution.model,
|
|
939
857
|
variant: acceptedReviewExecution.variant,
|
|
940
858
|
};
|
|
859
|
+
const evaluatorInput = {
|
|
860
|
+
tool,
|
|
861
|
+
...reviewerConfig,
|
|
862
|
+
skills,
|
|
863
|
+
promptVersion: REVIEW_PROMPT_VERSION,
|
|
864
|
+
rolePolicyVersion: REVIEW_ROLE_POLICY_VERSION,
|
|
865
|
+
outputContractVersion: REVIEW_OUTPUT_CONTRACT_VERSION,
|
|
866
|
+
rolePolicy: 'preparing',
|
|
867
|
+
changeScope: null,
|
|
868
|
+
};
|
|
941
869
|
reviewExecutionProvenance = { tool, model: reviewerConfig.model, variant: reviewerConfig.variant };
|
|
942
870
|
const reviewProcessState = registerReviewProcess(acceptedTicket.id);
|
|
943
871
|
registeredReviewProcess = reviewProcessState;
|
|
@@ -1112,6 +1040,7 @@ export function startReview(ticket, io, options) {
|
|
|
1112
1040
|
messageId: null,
|
|
1113
1041
|
model: reviewerConfig.model,
|
|
1114
1042
|
variant: reviewerConfig.variant,
|
|
1043
|
+
evaluatorFingerprint: computeReviewEvaluatorFingerprint(evaluatorInput),
|
|
1115
1044
|
status: 'running',
|
|
1116
1045
|
});
|
|
1117
1046
|
transaction.addExecutionRunLink({
|
|
@@ -1181,13 +1110,15 @@ export function startReview(ticket, io, options) {
|
|
|
1181
1110
|
const supplementalRequirements = ticket.project_id && ticket.worktree_bundle_id
|
|
1182
1111
|
? formatBuildOpenQuestionAnswersPrompt(listAnsweredBuildOpenQuestionsForBundle(ticket.project_id, ticket.worktree_bundle_id))
|
|
1183
1112
|
: '';
|
|
1184
|
-
const
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1113
|
+
const previousReviewRunId = verificationIteration
|
|
1114
|
+
? verificationIteration.triggering_review_run_id
|
|
1115
|
+
: getLatestCompletedReviewRunForContext({
|
|
1116
|
+
ticketId: ticket.id,
|
|
1117
|
+
projectId: ticket.project_id,
|
|
1118
|
+
worktreeBundleId: ticket.worktree_bundle_id,
|
|
1119
|
+
})?.id;
|
|
1120
|
+
const existingReviewFindings = previousReviewRunId
|
|
1121
|
+
? reconcileReviewFindingsToDiff(listReviewFindings(previousReviewRunId), diffText)
|
|
1191
1122
|
: [];
|
|
1192
1123
|
const specCoverageEligible = Boolean(project.spec_aware_code_review_enabled)
|
|
1193
1124
|
&& Boolean(ticket.origin_spec_snapshot_id)
|
|
@@ -1204,6 +1135,14 @@ export function startReview(ticket, io, options) {
|
|
|
1204
1135
|
}
|
|
1205
1136
|
const runSpecCoverage = Boolean(specContext) && !hasPriorReview;
|
|
1206
1137
|
const specGuardContext = hasPriorReview ? specContext : null;
|
|
1138
|
+
const preparedEvaluatorInput = {
|
|
1139
|
+
...evaluatorInput,
|
|
1140
|
+
rolePolicy: runSpecCoverage ? 'code-review+spec-coverage' : specGuardContext ? 'code-review+spec-guard' : 'code-review',
|
|
1141
|
+
changeScope,
|
|
1142
|
+
};
|
|
1143
|
+
const evaluatorFingerprint = computeReviewEvaluatorFingerprint(preparedEvaluatorInput);
|
|
1144
|
+
db.prepare('UPDATE review_runs SET evaluator_fingerprint = ? WHERE id = ? AND status = ?')
|
|
1145
|
+
.run(evaluatorFingerprint, activeReviewRunId, 'running');
|
|
1207
1146
|
let specCoverageRunStreamTarget = null;
|
|
1208
1147
|
if (runSpecCoverage) {
|
|
1209
1148
|
const runId = createAgentRun({
|
|
@@ -1338,11 +1277,16 @@ export function startReview(ticket, io, options) {
|
|
|
1338
1277
|
let persistedMessageId = null;
|
|
1339
1278
|
let reviewContent = null;
|
|
1340
1279
|
let findingsToPersist = [];
|
|
1280
|
+
let outputProvenance = constrainedBlindParsed?.outputProvenance ?? 'parse_failed';
|
|
1341
1281
|
if (constrainedBlindParsed?.status === 'completed') {
|
|
1342
1282
|
const specOutput = resolveStructuredReviewOutput(specCoverageResult?.response ?? null, specCoverageResult?.transcriptRuns ?? [], 'spec-coverage').parsed;
|
|
1343
1283
|
const specParsed = specOutput
|
|
1344
1284
|
? constrainReviewOutputToDiff(specOutput, diffText)
|
|
1345
1285
|
: null;
|
|
1286
|
+
outputProvenance = getEffectiveReviewOutputProvenance([
|
|
1287
|
+
constrainedBlindParsed,
|
|
1288
|
+
...(specParsed?.status === 'completed' ? [specParsed] : []),
|
|
1289
|
+
]);
|
|
1346
1290
|
const newlyReportedFindings = specParsed && specParsed.status === 'completed'
|
|
1347
1291
|
? [...constrainedBlindParsed.findings, ...specParsed.findings.map(finding => ({
|
|
1348
1292
|
...finding,
|
|
@@ -1353,11 +1297,15 @@ export function startReview(ticket, io, options) {
|
|
|
1353
1297
|
existingFindings: existingReviewFindings,
|
|
1354
1298
|
newFindings: newlyReportedFindings,
|
|
1355
1299
|
resolvedExistingFindingIds: constrainedBlindParsed.resolvedExistingFindingIds,
|
|
1300
|
+
outputProvenance,
|
|
1301
|
+
evaluatorFingerprint,
|
|
1356
1302
|
});
|
|
1357
1303
|
const blindFindings = mergeReviewFindings({
|
|
1358
1304
|
existingFindings: existingReviewFindings,
|
|
1359
1305
|
newFindings: constrainedBlindParsed.findings,
|
|
1360
1306
|
resolvedExistingFindingIds: constrainedBlindParsed.resolvedExistingFindingIds,
|
|
1307
|
+
outputProvenance: constrainedBlindParsed.outputProvenance ?? 'parse_failed',
|
|
1308
|
+
evaluatorFingerprint,
|
|
1361
1309
|
});
|
|
1362
1310
|
parsedFindings = mergedFindings;
|
|
1363
1311
|
parsedStatus = constrainedBlindParsed.status;
|
|
@@ -1393,6 +1341,7 @@ export function startReview(ticket, io, options) {
|
|
|
1393
1341
|
status: parsedStatus ?? 'parse_failed',
|
|
1394
1342
|
messageId,
|
|
1395
1343
|
failureMessage: parseFailed ? 'Review output could not be parsed' : null,
|
|
1344
|
+
outputProvenance,
|
|
1396
1345
|
});
|
|
1397
1346
|
if (findingsToPersist.length > 0) {
|
|
1398
1347
|
insertReviewFindings(activeReviewRunId, findingsToPersist);
|
|
@@ -1460,7 +1409,7 @@ export function startReview(ticket, io, options) {
|
|
|
1460
1409
|
let handled = false;
|
|
1461
1410
|
try {
|
|
1462
1411
|
await releaseWorkloadEnvironment();
|
|
1463
|
-
handled = await runReviewCompletionAutomation(updated, project, reviewRunId,
|
|
1412
|
+
handled = await runReviewCompletionAutomation(updated, project, reviewRunId, io, executionContext, initiation, persisted.persistedAutomation);
|
|
1464
1413
|
}
|
|
1465
1414
|
catch (automationError) {
|
|
1466
1415
|
if (ticket.project_id && ticket.worktree_bundle_id) {
|