@zq-silk/yui 0.14.0 → 0.14.2
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/ARCHITECTURE.md +64 -35
- package/README.md +258 -125
- package/dist/agent/argumentPolicy.js +2 -1
- package/dist/agent/managedRuntimeEnvironment.js +5 -8
- package/dist/cli/commandCatalog.js +74 -109
- package/dist/cli/helpRenderer.js +1 -2
- package/dist/cli/interactionCandidates.js +10 -0
- package/dist/cli/interactionPolicy.js +76 -37
- package/dist/cli/roleWizard.js +5 -6
- package/dist/cli/updateOrchestrator.js +10 -8
- package/dist/cli/updatePorts.js +17 -13
- package/dist/cli/upgradeCommand.js +2 -5
- package/dist/cli.js +268 -231
- package/dist/commands/agentCommands.js +13 -0
- package/dist/commands/configCommands.js +7 -19
- package/dist/commands/configOverview.js +3 -2
- package/dist/commands/durableJobCommands.js +1 -1
- package/dist/commands/executionAuditCommands.js +4 -9
- package/dist/commands/globalRoleCommands.js +17 -0
- package/dist/commands/profileCommands.js +200 -30
- package/dist/commands/sessionCommands.js +1 -1
- package/dist/commands/taskActor.js +29 -127
- package/dist/commands/taskChangeSetCommands.js +1 -3
- package/dist/commands/taskCommands.js +1771 -2107
- package/dist/commands/taskCompletionGate.js +27 -103
- package/dist/commands/taskContextCommand.js +47 -80
- package/dist/commands/taskExecutionCommands.js +9 -27
- package/dist/commands/taskInputCommands.js +10 -10
- package/dist/commands/taskIntegrationCommands.js +69 -61
- package/dist/commands/taskIntegrationQueueCommands.js +1 -1
- package/dist/commands/taskNextActionCommand.js +8 -29
- package/dist/commands/taskOverviewCommand.js +25 -3
- package/dist/commands/taskPublicationCommands.js +151 -85
- package/dist/commands/taskPublicationVerifyCommand.js +181 -0
- package/dist/commands/taskRemoteDeliveryCommand.js +134 -0
- package/dist/commands/taskRoleRuntimeStatus.js +5 -6
- package/dist/commands/taskUpstreamCommands.js +79 -95
- package/dist/config/configCatalog.js +1 -1
- package/dist/context/contextSnapshot.js +17 -2
- package/dist/context/sessionBootstrapManifest.js +18 -1
- package/dist/context/sourceTurnContext.js +30 -0
- package/dist/context/turnContextPack.js +107 -48
- package/dist/context/turnInputContract.js +11 -4
- package/dist/context/wakeNotification.js +84 -22
- package/dist/controller/agentRuntimeObserver.js +9 -12
- package/dist/controller/clientRuntime.js +13 -13
- package/dist/controller/controller.js +11 -11
- package/dist/controller/fileSchedulerStoreAdapter.js +262 -219
- package/dist/controller/jobControl.js +11 -10
- package/dist/controller/resourceInventory.js +6 -6
- package/dist/controller/resourceInventoryLinux.js +2 -2
- package/dist/controller/runtime.js +18 -61
- package/dist/controller/runtimeEventInbox.js +57 -34
- package/dist/controller/runtimeEventProcessor.js +36 -96
- package/dist/controller/runtimeHookTurnFence.js +33 -57
- package/dist/controller/runtimeLaunchCoordinator.js +44 -40
- package/dist/controller/runtimeObservationHook.js +18 -12
- package/dist/controller/sessionNotify.js +43 -28
- package/dist/controller/sessionOwnerReconciliation.js +21 -21
- package/dist/controller/structuredProviderObservation.js +13 -16
- package/dist/coordination/workMailboxQueue.js +132 -0
- package/dist/core/controllerServer.js +1 -0
- package/dist/domain/agentResultTransport.js +60 -0
- package/dist/execution/executionHealth.js +111 -118
- package/dist/execution/reviewMainTurn.js +161 -0
- package/dist/execution/workItemExecution.js +454 -0
- package/dist/execution/workItemExecutionProjection.js +309 -0
- package/dist/execution/workItemMainTurn.js +164 -0
- package/dist/executor/agentExecutor.js +19 -19
- package/dist/executor/executorRegistry.js +7 -28
- package/dist/executor/fileRoleLaunchPlanner.js +51 -83
- package/dist/external/githubPublicationVerifier.js +114 -0
- package/dist/external/gitlabPublicationVerifier.js +158 -0
- package/dist/external/pinnedCommandRunner.js +73 -0
- package/dist/integration/changeSetManifest.js +0 -3
- package/dist/integration/deliveryObligation.js +43 -6
- package/dist/integration/gitIntegrationService.js +284 -101
- package/dist/integration/integrationAttempt.js +64 -14
- package/dist/integration/integrationQueueEntry.js +5 -35
- package/dist/integration/integrationQueueService.js +65 -194
- package/dist/lifecycle/canonicalLifecycleEvent.js +16 -15
- package/dist/lifecycle/exactTurnTerminalization.js +100 -97
- package/dist/message/message.js +16 -0
- package/dist/observability/executionAudit.js +4 -25
- package/dist/observability/faultClassification.js +58 -70
- package/dist/observability/orchestrationMetrics.js +8 -50
- package/dist/profile/agentProfile.js +60 -15
- package/dist/profile/agentProfileRuntime.js +100 -0
- package/dist/release/releaseWorkflowPorts.js +5 -68
- package/dist/repository/executionLaneGitSnapshot.js +80 -0
- package/dist/repository/gitWorkspace.js +9 -67
- package/dist/repository/taskBaseFreshness.js +3 -1
- package/dist/repository/taskWorkspaceCoordinator.js +32 -4
- package/dist/repository/taskWorkspacePreparer.js +252 -411
- package/dist/resources/liveReferences.js +6 -55
- package/dist/resources/resourceDiscovery.js +1 -30
- package/dist/resources/resourceRegistrar.js +0 -23
- package/dist/review/deltaRecheck.js +8 -65
- package/dist/review/reviewAcceptance.js +22 -19
- package/dist/review/reviewConfig.js +0 -10
- package/dist/review/reviewDecision.js +2 -2
- package/dist/review/reviewRound.js +147 -273
- package/dist/review/reviewerAvailability.js +13 -23
- package/dist/role/role.js +3 -0
- package/dist/runtime/agentDriverObservation.js +1 -1
- package/dist/runtime/agentHost.js +51 -51
- package/dist/runtime/builtinAgentDrivers.js +9 -2
- package/dist/runtime/codexAppServerRuntime.js +23 -5
- package/dist/runtime/exactControlPlane.js +2 -267
- package/dist/runtime/firstProgressAdvisory.js +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/launchBroker.js +11 -11
- package/dist/runtime/lifecycleReservation.js +2 -2
- package/dist/runtime/managedCaller.js +111 -0
- package/dist/runtime/ports.js +16 -3
- package/dist/runtime/preallocatedNativeSession.js +2 -2
- package/dist/runtime/processExitObservation.js +3 -2
- package/dist/runtime/providerContinuationReconciliationService.js +1 -1
- package/dist/runtime/runtimeBinding.js +1 -1
- package/dist/runtime/runtimeObservation.js +33 -16
- package/dist/runtime/runtimeSessionCandidate.js +2 -2
- package/dist/runtime/runtimeStopReceipt.js +11 -11
- package/dist/runtime/sessionLaunchRequest.js +2 -2
- package/dist/runtime/sessionOwnerIdentity.js +9 -9
- package/dist/runtime/sessionOwnerRegistry.js +13 -13
- package/dist/runtime/sessionReconciliation.js +4 -4
- package/dist/runtime/sessionTerminationGuard.js +9 -9
- package/dist/runtime/sessionTokenMetrics.js +5 -7
- package/dist/runtime/structuredProviderHost.js +5 -5
- package/dist/runtime/taskRuntimeIsolation.js +24 -24
- package/dist/runtime/tmuxAdapters.js +32 -30
- package/dist/scheduler/activeRoleTurnDelivery.js +37 -15
- package/dist/scheduler/leaderWakeupProcessor.js +78 -55
- package/dist/scheduler/roleTurnLiveness.js +6 -6
- package/dist/scheduler/roleTurnStall.js +8 -9
- package/dist/scheduler/taskExecutionProjection.js +19 -41
- package/dist/scheduler/taskObservabilityProjection.js +75 -122
- package/dist/storage/sqliteSchema.js +1 -21
- package/dist/storage/sqliteStore.js +62 -47
- package/dist/storage/storageSchema.js +1 -8
- package/dist/storage/storageVersions.js +7 -4
- package/dist/storage/taskStore.js +8 -8
- package/dist/storage/upgrade/upgradeOrchestrator.js +112 -83
- package/dist/task/completionReadiness.js +17 -98
- package/dist/task/deliveryGuard.js +9 -11
- package/dist/task/draftPlan.js +142 -0
- package/dist/task/nextAction.js +179 -477
- package/dist/task/publicationVerification.js +1 -0
- package/dist/task/remoteDelivery.js +233 -0
- package/dist/task/task.js +108 -4
- package/dist/task/taskRecordReference.js +0 -1
- package/dist/turn/turn.js +109 -16
- package/dist/verification/verificationGateService.js +0 -26
- package/dist/web/assets/client/components.js +99 -121
- package/dist/web/assets/client/i18n.js +136 -58
- package/dist/web/assets/client/view.js +44 -0
- package/dist/web/assets/styles/cards.js +3 -15
- package/dist/web/assets/styles/widgets.js +4 -0
- package/dist/web/webSnapshot.js +29 -14
- package/dist/workItem/dependencyGate.js +34 -0
- package/dist/workItem/workItem.js +99 -266
- package/dist/workspace/workItemChangeSetManager.js +15 -59
- package/docs/task-local-identity.md +1 -1
- package/i18n/README.zh-CN.md +165 -59
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +272 -782
- package/skills/yui-operator/SKILL.md +190 -365
- package/skills/yui-reviewer/SKILL.md +40 -33
- package/skills/yui-runtime/SKILL.md +27 -6
- package/skills/yui-worker/SKILL.md +19 -6
- package/dist/execution/candidateConvergence.js +0 -623
- package/dist/execution/executionGroup.js +0 -854
- package/dist/execution/resourceBroker.js +0 -426
- package/dist/executor/launchPlan.js +0 -16
- package/dist/review/reviewFinding.js +0 -240
- package/dist/review/reviewFindingLedger.js +0 -550
- package/dist/review/reviewOutcomeClassifier.js +0 -255
- package/dist/scheduler/resourceQueueProjection.js +0 -71
- package/dist/task/repairWave.js +0 -150
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
import { isTaskRecordRetired, operationalTaskRecords } from "../task/taskRecordRetirement.js";
|
|
2
|
-
const INFRA_SIGNATURES = [
|
|
3
|
-
{ kind: "session-not-stopped", pattern: /session must be stopped before workspace migration/iu },
|
|
4
|
-
{ kind: "turn-start", pattern: /role turn could not start|could not start (?:the )?(?:reviewer|role) turn/iu },
|
|
5
|
-
{ kind: "storage-lock", pattern: /\.state\.lock|state lock|lock timeout|storage lock/iu },
|
|
6
|
-
{ kind: "tmux-exit", pattern: /tmux[^\n]{0,80}(?:exited|exit|died|vanished)|pane (?:exited|died)/iu },
|
|
7
|
-
{ kind: "turn-identity", pattern: /wrong turn id|unknown turn id|turn id (?:is )?(?:invalid|unknown|mismatch)/iu },
|
|
8
|
-
{ kind: "policy", pattern: /cyber_?policy|policy denial|permission denied by policy/iu },
|
|
9
|
-
{ kind: "baseline-contamination", pattern: /cross[-\s]?baseline|baseline pollution|contaminated baseline|wrong base sha/iu },
|
|
10
|
-
{ kind: "context-load", pattern: /(?:turn )?(?:context|context pack) load (?:failed|unavailable|unauthorized|stale|mismatched|malformed)/iu },
|
|
11
|
-
{ kind: "workspace-binding", pattern: /workspace is not the durable owner|workspace-binding failure/iu }
|
|
12
|
-
];
|
|
13
|
-
/** Classify one terminal Round without rewriting it. */
|
|
14
|
-
export function classifyReviewRoundOutcome(round, evidence) {
|
|
15
|
-
if (round.status !== "completed" && round.status !== "failed")
|
|
16
|
-
return null;
|
|
17
|
-
if (evidence !== undefined && round.reviewerTurnId !== undefined
|
|
18
|
-
&& isTaskRecordRetired(evidence.listEvents(round.taskId), "turn", round.reviewerTurnId)) {
|
|
19
|
-
return {
|
|
20
|
-
kind: "non-semantic",
|
|
21
|
-
infraKind: "turn-identity",
|
|
22
|
-
reason: `Reviewer Turn ${round.reviewerTurnId} was retired from operational evidence.`
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
const infraKind = classifyInfraKind(`${round.summary ?? ""}\n${round.report ?? ""}`);
|
|
26
|
-
if (round.status === "failed") {
|
|
27
|
-
const semanticEvidence = failedRoundSemanticEvidence(round, evidence);
|
|
28
|
-
return semanticEvidence === null
|
|
29
|
-
? {
|
|
30
|
-
kind: "non-semantic",
|
|
31
|
-
infraKind,
|
|
32
|
-
reason: "Failed Review execution carries no semantic report evidence."
|
|
33
|
-
}
|
|
34
|
-
: {
|
|
35
|
-
kind: "ambiguous",
|
|
36
|
-
infraKind,
|
|
37
|
-
reason: semanticEvidence
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
if (!explicitCompletedReviewInfrastructureFailure(round.summary ?? "", round)) {
|
|
41
|
-
return { kind: "semantic", reason: "Reviewer delivered a terminal report." };
|
|
42
|
-
}
|
|
43
|
-
if (evidence === undefined) {
|
|
44
|
-
return {
|
|
45
|
-
kind: "ambiguous",
|
|
46
|
-
infraKind,
|
|
47
|
-
reason: "Completed Round claims an infrastructure failure but corroborating Turn/Event evidence was not supplied."
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
const corroborationFailure = completedInfrastructureCorroborationFailure(round, evidence);
|
|
51
|
-
return corroborationFailure === null
|
|
52
|
-
? {
|
|
53
|
-
kind: "non-semantic",
|
|
54
|
-
infraKind,
|
|
55
|
-
reason: "Completed Round and Turn agree on an explicit pre-review infrastructure failure."
|
|
56
|
-
}
|
|
57
|
-
: {
|
|
58
|
-
kind: "ambiguous",
|
|
59
|
-
infraKind,
|
|
60
|
-
reason: corroborationFailure
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
/** True only when a Round contains semantic Reviewer evidence. */
|
|
64
|
-
export function isSemanticReviewRound(round, evidence) {
|
|
65
|
-
return classifyReviewRoundOutcome(round, evidence)?.kind === "semantic";
|
|
66
|
-
}
|
|
67
|
-
function classifyInfraKind(text) {
|
|
68
|
-
return INFRA_SIGNATURES.find(({ pattern }) => pattern.test(text))?.kind ?? "other-infra";
|
|
69
|
-
}
|
|
70
|
-
function failedRoundSemanticEvidence(round, evidence) {
|
|
71
|
-
if ((round.checks ?? []).length > 0)
|
|
72
|
-
return "Failed Round records review checks.";
|
|
73
|
-
if (round.evidenceCommit !== undefined)
|
|
74
|
-
return "Failed Round records a review evidence commit.";
|
|
75
|
-
if (round.deltaRecheck?.disposition !== undefined || round.deltaRecheck?.reasoning !== undefined) {
|
|
76
|
-
return "Failed Round records a semantic delta-recheck disposition.";
|
|
77
|
-
}
|
|
78
|
-
if (round.report !== round.summary)
|
|
79
|
-
return "Failed Round stores a report distinct from its terminal summary.";
|
|
80
|
-
if (runtimeFailureSummaryHasReviewerOutput(round.report ?? "")) {
|
|
81
|
-
return "Failed Round stores non-empty Reviewer output in its runtime failure summary.";
|
|
82
|
-
}
|
|
83
|
-
if (looksLikeStructuredReviewReport(round.report ?? "")) {
|
|
84
|
-
return "Failed Round stores a structured Reviewer report.";
|
|
85
|
-
}
|
|
86
|
-
const semanticLane = (round.executionGroup?.lanes ?? []).find((lane) => ((lane.result?.checks ?? []).length > 0
|
|
87
|
-
|| (lane.result?.findings ?? []).length > 0
|
|
88
|
-
|| (lane.result?.evidence ?? []).length > 0
|
|
89
|
-
|| lane.result?.evidenceCommit !== undefined
|
|
90
|
-
|| lane.result?.gitSnapshot !== undefined
|
|
91
|
-
|| lane.status === "completed"));
|
|
92
|
-
if (semanticLane !== undefined)
|
|
93
|
-
return `Reviewer Lane ${semanticLane.id} delivered semantic evidence.`;
|
|
94
|
-
if (evidence !== undefined) {
|
|
95
|
-
const events = evidence.listEvents(round.taskId);
|
|
96
|
-
const reviewRun = operationalTaskRecords(evidence.listTurns(round.taskId), events, "turn").find((run) => (run.purpose === "review"
|
|
97
|
-
&& run.reviewRoundId === round.id
|
|
98
|
-
&& (run.status === "completed"
|
|
99
|
-
|| runtimeFailureSummaryHasReviewerOutput(run.result?.output ?? ""))));
|
|
100
|
-
if (reviewRun !== undefined)
|
|
101
|
-
return `Reviewer Turn ${reviewRun.id} records Reviewer output.`;
|
|
102
|
-
const finding = evidence.listReviewFindings(round.taskId).find((entry) => (entry.firstReviewRoundId === round.id || entry.lastReviewRoundId === round.id));
|
|
103
|
-
if (finding !== undefined)
|
|
104
|
-
return `Review finding ${finding.id} references the Round.`;
|
|
105
|
-
const completion = events.find((event) => (event.type === "review.completed" && event.payload.reviewRoundId === round.id));
|
|
106
|
-
if (completion !== undefined)
|
|
107
|
-
return `Review completion Event ${completion.id} exists.`;
|
|
108
|
-
}
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
function completedInfrastructureCorroborationFailure(round, store) {
|
|
112
|
-
if ((round.checks ?? []).length > 0)
|
|
113
|
-
return "Completed Round records review checks.";
|
|
114
|
-
if (round.evidenceCommit !== round.reviewBaseCommit) {
|
|
115
|
-
return "Completed Round lacks an exact frozen-head evidence commit.";
|
|
116
|
-
}
|
|
117
|
-
if (round.report !== round.summary) {
|
|
118
|
-
return "Completed Round stores a report distinct from its terminal summary.";
|
|
119
|
-
}
|
|
120
|
-
if (runtimeFailureSummaryHasReviewerOutput(round.report ?? "")) {
|
|
121
|
-
return "Completed Round stores non-empty Reviewer output in its runtime failure summary.";
|
|
122
|
-
}
|
|
123
|
-
if (round.deltaRecheck?.disposition !== undefined || round.deltaRecheck?.reasoning !== undefined) {
|
|
124
|
-
return "Completed Round records a semantic delta-recheck disposition.";
|
|
125
|
-
}
|
|
126
|
-
if (looksLikeStructuredReviewReport(round.report ?? "")) {
|
|
127
|
-
return "Completed Round stores a structured Reviewer report.";
|
|
128
|
-
}
|
|
129
|
-
for (const lane of round.executionGroup?.lanes ?? []) {
|
|
130
|
-
if (lane.status === "pending" || lane.status === "running") {
|
|
131
|
-
return `Reviewer Lane ${lane.id} is still active.`;
|
|
132
|
-
}
|
|
133
|
-
if ((lane.result?.checks ?? []).length > 0
|
|
134
|
-
|| (lane.result?.findings ?? []).length > 0
|
|
135
|
-
|| (lane.result?.evidence ?? []).length > 0
|
|
136
|
-
|| (lane.result?.evidenceCommit !== undefined
|
|
137
|
-
&& lane.result.evidenceCommit !== round.reviewBaseCommit)
|
|
138
|
-
|| lane.result?.gitSnapshot !== undefined) {
|
|
139
|
-
return `Reviewer Lane ${lane.id} delivered semantic evidence.`;
|
|
140
|
-
}
|
|
141
|
-
if (lane.status === "completed") {
|
|
142
|
-
if (lane.result === undefined
|
|
143
|
-
|| lane.result.summary !== round.summary
|
|
144
|
-
|| lane.result.report !== round.report
|
|
145
|
-
|| lane.result.evidenceCommit !== round.reviewBaseCommit) {
|
|
146
|
-
return `Reviewer Lane ${lane.id} output is absent or differs from the Round.`;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
return `Completed Round has non-completed Reviewer Lane ${lane.id}/${lane.status}.`;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
const allEvents = store.listEvents(round.taskId);
|
|
154
|
-
const runs = operationalTaskRecords(store.listTurns(round.taskId), allEvents, "turn").filter((run) => (run.purpose === "review" && run.reviewRoundId === round.id));
|
|
155
|
-
const active = runs.find(({ status }) => status === "active");
|
|
156
|
-
if (active !== undefined)
|
|
157
|
-
return `Reviewer Turn ${active.id} is still active.`;
|
|
158
|
-
const output = runs.find((run) => (run.status === "failed" && runtimeFailureSummaryHasReviewerOutput(run.result?.output ?? "")));
|
|
159
|
-
if (output !== undefined)
|
|
160
|
-
return `Reviewer Turn ${output.id} records Reviewer output.`;
|
|
161
|
-
const completed = runs.filter(({ status }) => status === "completed");
|
|
162
|
-
if (round.reviewerTurnId === undefined
|
|
163
|
-
|| completed.length !== 1
|
|
164
|
-
|| completed[0].id !== round.reviewerTurnId) {
|
|
165
|
-
return "Completed Round lacks one exact completed Reviewer Turn.";
|
|
166
|
-
}
|
|
167
|
-
const run = completed[0];
|
|
168
|
-
if (run.roleName !== round.reviewerRoleName
|
|
169
|
-
|| run.result?.output !== round.summary) {
|
|
170
|
-
return `Reviewer Turn ${run.id} does not match the non-semantic Round result.`;
|
|
171
|
-
}
|
|
172
|
-
const finding = store.listReviewFindings(round.taskId).find((entry) => (entry.firstReviewRoundId === round.id || entry.lastReviewRoundId === round.id));
|
|
173
|
-
if (finding !== undefined)
|
|
174
|
-
return `Review finding ${finding.id} references the Round.`;
|
|
175
|
-
const events = allEvents.filter((event) => (event.type === "review.completed" && event.payload.reviewRoundId === round.id));
|
|
176
|
-
if (events.length !== 1)
|
|
177
|
-
return "Completed Round lacks one exact completion Event.";
|
|
178
|
-
const event = events[0];
|
|
179
|
-
if (event.payload.workItemId !== round.workItemId
|
|
180
|
-
|| event.payload.candidateId !== round.candidateId
|
|
181
|
-
|| event.payload.reviewBaseCommit !== round.reviewBaseCommit
|
|
182
|
-
|| event.payload.evidenceCommit !== round.reviewBaseCommit
|
|
183
|
-
|| event.payload.checks !== "none") {
|
|
184
|
-
return `Review completion Event ${event.id} carries mismatched or semantic evidence.`;
|
|
185
|
-
}
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
function explicitCompletedReviewInfrastructureFailure(summary, round) {
|
|
189
|
-
if (exactCompletedReviewInfrastructureFailureReport(summary))
|
|
190
|
-
return true;
|
|
191
|
-
const report = summary.trim();
|
|
192
|
-
if (report === `Role Turn workspace is not the durable owner: ${round.taskId}/${round.reviewerRoleName}.`
|
|
193
|
-
|| (round.reviewerTurnId !== undefined
|
|
194
|
-
&& report === `Review Turn workspace is not the durable owner: ${round.reviewerTurnId}.`)) {
|
|
195
|
-
return true;
|
|
196
|
-
}
|
|
197
|
-
return /^(?:Turn )?(?:Context|Context Pack) load (?:failed|unavailable|unauthorized|stale|mismatched|malformed)(?:: (?:failure|mismatch|unavailable|unauthorized|stale|mismatched|malformed))?\.?$/iu
|
|
198
|
-
.test(report);
|
|
199
|
-
}
|
|
200
|
-
function exactCompletedReviewInfrastructureFailureReport(summary) {
|
|
201
|
-
const lines = summary.trim().split(/\r?\n/u);
|
|
202
|
-
const envelope = [
|
|
203
|
-
/^# Review result: (?:context-load|workspace-binding) failure$/u,
|
|
204
|
-
/^$/u,
|
|
205
|
-
/^The assigned Turn context could not be safely matched to this native session, so no candidate review was performed\.$/u,
|
|
206
|
-
/^$/u,
|
|
207
|
-
/^- Turn: `[^`\r\n]+`$/u,
|
|
208
|
-
/^- ReviewRound: `[^`\r\n]+`$/u,
|
|
209
|
-
/^- Review base commit: `[0-9a-f]{40}`$/u,
|
|
210
|
-
/^- Frozen target: `[^`\r\n]+`$/u,
|
|
211
|
-
/^- Authorized workspace from the exact Context Pack: `[^`\r\n]+`$/u,
|
|
212
|
-
/^- Session-attached workspace: `[^`\r\n]+`$/u,
|
|
213
|
-
/^- Verification: both paths resolve distinctly and have different filesystem inodes \(`[^`\r\n]+` vs `[^`\r\n]+`\)\.$/u,
|
|
214
|
-
/^$/u,
|
|
215
|
-
/^## Findings$/u,
|
|
216
|
-
/^$/u,
|
|
217
|
-
/^- Verified-fixed findings: none; review did not start\.$/u,
|
|
218
|
-
/^- New findings: none; candidate sources were intentionally not inspected\.$/u,
|
|
219
|
-
/^- Accepted risks: none accepted\.$/u,
|
|
220
|
-
/^- Residual verification gaps: the complete frozen diff, changed control-flow paths, callers, data-integrity behavior, and required deterministic checks remain unreviewed because the Review workspace binding is mismatched\.$/u,
|
|
221
|
-
/^$/u,
|
|
222
|
-
/^## Checks actually run$/u,
|
|
223
|
-
/^$/u,
|
|
224
|
-
/^- Exact Context API load: passed for Task\/Turn\/Role\/purpose\/subject\/snapshot\/adapter\.$/u,
|
|
225
|
-
/^- Workspace binding verification: failed\.$/u,
|
|
226
|
-
/^- Candidate build\/tests\/package checks: not run\.$/u,
|
|
227
|
-
/^- Real-provider E2E: not run and not authorized\.$/u,
|
|
228
|
-
/^$/u,
|
|
229
|
-
/^## Required next action$/u,
|
|
230
|
-
/^$/u,
|
|
231
|
-
/^Attach the native Reviewer session to the exact workspace recorded by the Context Pack, or issue a fresh internally consistent Review Turn\/Context Pack\. Then perform the complete bounded Task-final review at the frozen head\.$/u
|
|
232
|
-
];
|
|
233
|
-
return lines.length === envelope.length
|
|
234
|
-
&& envelope.every((pattern, index) => pattern.test(lines[index]));
|
|
235
|
-
}
|
|
236
|
-
function runtimeFailureSummaryHasReviewerOutput(summary) {
|
|
237
|
-
const output = /(?:^|\n)last_assistant_message:[ \t]*([\s\S]*)$/u.exec(summary)?.[1];
|
|
238
|
-
return output !== undefined && output.trim().length > 0;
|
|
239
|
-
}
|
|
240
|
-
function looksLikeStructuredReviewReport(report) {
|
|
241
|
-
let parsed;
|
|
242
|
-
try {
|
|
243
|
-
parsed = JSON.parse(report);
|
|
244
|
-
}
|
|
245
|
-
catch {
|
|
246
|
-
return false;
|
|
247
|
-
}
|
|
248
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
249
|
-
return false;
|
|
250
|
-
const record = parsed;
|
|
251
|
-
return [
|
|
252
|
-
"summary", "report", "checks", "findings", "evidence", "evidenceCommit",
|
|
253
|
-
"deltaDisposition", "deltaReasoning"
|
|
254
|
-
].some((key) => Object.hasOwn(record, key));
|
|
255
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { currentWorkItemExecutionGroup } from "../workItem/workItem.js";
|
|
2
|
-
import { executionStageSpendClosed, observedExecutionResourceUsage, projectExecutionStageResources } from "../execution/resourceBroker.js";
|
|
3
|
-
/** Exact durable Broker queue used by resource admission. */
|
|
4
|
-
export function projectQueuedResourceLaneIdentities(store, now) {
|
|
5
|
-
return store.listActiveTaskIds().flatMap((taskId) => {
|
|
6
|
-
const taskTurns = store.listTurns(taskId);
|
|
7
|
-
const taskEvents = store.listEvents(taskId);
|
|
8
|
-
const workItemLanes = store.listWorkItems(taskId).flatMap((item) => {
|
|
9
|
-
if (item.status !== "running")
|
|
10
|
-
return [];
|
|
11
|
-
const group = currentWorkItemExecutionGroup(item);
|
|
12
|
-
if (group === undefined || group.resolution !== undefined)
|
|
13
|
-
return [];
|
|
14
|
-
if (group.stage !== undefined) {
|
|
15
|
-
const resources = projectExecutionStageResources({
|
|
16
|
-
group,
|
|
17
|
-
stageGroups: item.executionGroups,
|
|
18
|
-
usage: observedExecutionResourceUsage({
|
|
19
|
-
group,
|
|
20
|
-
stageGroups: item.executionGroups,
|
|
21
|
-
turns: taskTurns,
|
|
22
|
-
events: taskEvents
|
|
23
|
-
}),
|
|
24
|
-
now
|
|
25
|
-
});
|
|
26
|
-
if (executionStageSpendClosed(resources))
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
return group.lanes.flatMap((lane) => {
|
|
30
|
-
if (lane.status !== "pending"
|
|
31
|
-
|| lane.effective === undefined
|
|
32
|
-
|| lane.turnId !== undefined)
|
|
33
|
-
return [];
|
|
34
|
-
return [{
|
|
35
|
-
taskId,
|
|
36
|
-
workItemId: item.id,
|
|
37
|
-
executionGroupId: group.id,
|
|
38
|
-
executionLaneId: lane.id,
|
|
39
|
-
providerId: lane.effective.adapterId,
|
|
40
|
-
agentId: lane.effective.agentId,
|
|
41
|
-
...(lane.effective.model === undefined ? {} : { model: lane.effective.model }),
|
|
42
|
-
requestedAt: lane.updatedAt
|
|
43
|
-
}];
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
const reviewLanes = store.listReviewRounds(taskId).flatMap((round) => {
|
|
47
|
-
if (round.status !== "pending" && round.status !== "running")
|
|
48
|
-
return [];
|
|
49
|
-
const group = round.executionGroup;
|
|
50
|
-
if (group === undefined || group.resolution !== undefined)
|
|
51
|
-
return [];
|
|
52
|
-
return group.lanes.flatMap((lane) => {
|
|
53
|
-
if (lane.status !== "pending"
|
|
54
|
-
|| lane.effective === undefined
|
|
55
|
-
|| lane.turnId !== undefined)
|
|
56
|
-
return [];
|
|
57
|
-
return [{
|
|
58
|
-
taskId,
|
|
59
|
-
...(round.workItemId === undefined ? {} : { workItemId: round.workItemId }),
|
|
60
|
-
executionGroupId: group.id,
|
|
61
|
-
executionLaneId: lane.id,
|
|
62
|
-
providerId: lane.effective.adapterId,
|
|
63
|
-
agentId: lane.effective.agentId,
|
|
64
|
-
...(lane.effective.model === undefined ? {} : { model: lane.effective.model }),
|
|
65
|
-
requestedAt: lane.updatedAt
|
|
66
|
-
}];
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
return [...workItemLanes, ...reviewLanes];
|
|
70
|
-
});
|
|
71
|
-
}
|
package/dist/task/repairWave.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
const SEVERITY_RANK = {
|
|
2
|
-
p1: 5,
|
|
3
|
-
critical: 4,
|
|
4
|
-
high: 3,
|
|
5
|
-
p2: 2,
|
|
6
|
-
medium: 1,
|
|
7
|
-
low: 0
|
|
8
|
-
};
|
|
9
|
-
const PATH_PATTERN = /(?:[\w.-]+\/)+[\w.-]+\.(?:ts|tsx|js|mjs|cjs|json|md|py|sh|yml|yaml|toml|css|html)(?::\d+)?/gu;
|
|
10
|
-
/**
|
|
11
|
-
* Extract open findings from a ReviewRound. Structured ExecutionFindings on
|
|
12
|
-
* the Review's ExecutionGroup lanes win; when none exist, fall back to
|
|
13
|
-
* parsing P1/P2 lines from the Review report text.
|
|
14
|
-
*/
|
|
15
|
-
export function extractReviewFindings(round) {
|
|
16
|
-
const structured = (round.executionGroup?.lanes ?? [])
|
|
17
|
-
.flatMap((lane) => lane.result?.findings ?? [])
|
|
18
|
-
.filter((finding) => finding.status === "open");
|
|
19
|
-
if (structured.length > 0) {
|
|
20
|
-
return structured.map((finding) => ({
|
|
21
|
-
id: finding.id,
|
|
22
|
-
severity: finding.severity,
|
|
23
|
-
summary: finding.summary,
|
|
24
|
-
paths: extractPaths(finding.summary),
|
|
25
|
-
source: "structured"
|
|
26
|
-
}));
|
|
27
|
-
}
|
|
28
|
-
return parseReportFindings(round.report ?? "");
|
|
29
|
-
}
|
|
30
|
-
export function planRepairWave(reviewRoundId, findings, strategy = "consolidated") {
|
|
31
|
-
if (findings.length === 0) {
|
|
32
|
-
return { reviewRoundId, openFindingCount: 0, groups: [] };
|
|
33
|
-
}
|
|
34
|
-
if (strategy === "consolidated") {
|
|
35
|
-
const ordered = [...findings].sort((left, right) => (left.id.localeCompare(right.id, undefined, { numeric: true })));
|
|
36
|
-
return {
|
|
37
|
-
reviewRoundId,
|
|
38
|
-
openFindingCount: findings.length,
|
|
39
|
-
groups: [{
|
|
40
|
-
id: "repair-1",
|
|
41
|
-
findingIds: ordered.map(({ id }) => id),
|
|
42
|
-
paths: [...new Set(ordered.flatMap(({ paths }) => paths))].sort(),
|
|
43
|
-
reason: "Consolidated by default to minimize repair, integration, and review churn"
|
|
44
|
-
}]
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const parent = new Array(findings.length).fill(0).map((_, index) => index);
|
|
48
|
-
const find = (index) => {
|
|
49
|
-
let current = index;
|
|
50
|
-
while (parent[current] !== current)
|
|
51
|
-
current = parent[current];
|
|
52
|
-
return current;
|
|
53
|
-
};
|
|
54
|
-
const union = (left, right) => {
|
|
55
|
-
const leftRoot = find(left);
|
|
56
|
-
const rightRoot = find(right);
|
|
57
|
-
if (leftRoot !== rightRoot)
|
|
58
|
-
parent[rightRoot] = leftRoot;
|
|
59
|
-
};
|
|
60
|
-
const unpathable = [];
|
|
61
|
-
for (let index = 0; index < findings.length; index += 1) {
|
|
62
|
-
if (findings[index].paths.length === 0)
|
|
63
|
-
unpathable.push(index);
|
|
64
|
-
}
|
|
65
|
-
// Unprovable findings merge together: the planner cannot prove they are
|
|
66
|
-
// disjoint from anything, so serializing them is the fail-closed choice.
|
|
67
|
-
for (let index = 1; index < unpathable.length; index += 1) {
|
|
68
|
-
union(unpathable[0], unpathable[index]);
|
|
69
|
-
}
|
|
70
|
-
for (let left = 0; left < findings.length; left += 1) {
|
|
71
|
-
for (let right = left + 1; right < findings.length; right += 1) {
|
|
72
|
-
if (sharePath(findings[left], findings[right]))
|
|
73
|
-
union(left, right);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
const byRoot = new Map();
|
|
77
|
-
for (let index = 0; index < findings.length; index += 1) {
|
|
78
|
-
const root = find(index);
|
|
79
|
-
byRoot.set(root, [...(byRoot.get(root) ?? []), index]);
|
|
80
|
-
}
|
|
81
|
-
const groups = [...byRoot.values()]
|
|
82
|
-
.map((members, position) => {
|
|
83
|
-
const waveFindings = members.map((index) => findings[index]);
|
|
84
|
-
const paths = [...new Set(waveFindings.flatMap((finding) => finding.paths))]
|
|
85
|
-
.sort();
|
|
86
|
-
const reason = paths.length === 0
|
|
87
|
-
? "No parseable paths; merged conservatively"
|
|
88
|
-
: waveFindings.length === 1
|
|
89
|
-
? `Distinct path ${paths[0]}; parallel-safe`
|
|
90
|
-
: `Shared path(s) ${paths.join(", ")}; merged`;
|
|
91
|
-
return {
|
|
92
|
-
id: `repair-${position + 1}`,
|
|
93
|
-
findingIds: waveFindings.map((finding) => finding.id),
|
|
94
|
-
paths,
|
|
95
|
-
reason
|
|
96
|
-
};
|
|
97
|
-
})
|
|
98
|
-
.sort((left, right) => {
|
|
99
|
-
const leftRank = Math.max(...left.findingIds.map((id) => SEVERITY_RANK[findings.find((finding) => finding.id === id).severity]));
|
|
100
|
-
const rightRank = Math.max(...right.findingIds.map((id) => SEVERITY_RANK[findings.find((finding) => finding.id === id).severity]));
|
|
101
|
-
if (leftRank !== rightRank)
|
|
102
|
-
return rightRank - leftRank;
|
|
103
|
-
return left.id.localeCompare(right.id, undefined, { numeric: true });
|
|
104
|
-
})
|
|
105
|
-
.map((group, index) => ({ ...group, id: `repair-${index + 1}` }));
|
|
106
|
-
return {
|
|
107
|
-
reviewRoundId,
|
|
108
|
-
openFindingCount: findings.length,
|
|
109
|
-
groups
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
function sharePath(left, right) {
|
|
113
|
-
if (left.paths.length === 0 || right.paths.length === 0)
|
|
114
|
-
return false;
|
|
115
|
-
const rightPaths = new Set(right.paths.map(filePart));
|
|
116
|
-
return left.paths.some((path) => rightPaths.has(filePart(path)));
|
|
117
|
-
}
|
|
118
|
-
function filePart(path) {
|
|
119
|
-
return path.split(":")[0];
|
|
120
|
-
}
|
|
121
|
-
export function extractPaths(text) {
|
|
122
|
-
const matches = text.match(PATH_PATTERN) ?? [];
|
|
123
|
-
return [...new Set(matches)].sort();
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Fallback finding extraction for Reviews without structured findings: parse
|
|
127
|
-
* P1/P2 lines from the report body. A line like "P1: src/foo.ts:12 ..." or
|
|
128
|
-
* "- P2 src/bar.ts ..." becomes one finding.
|
|
129
|
-
*/
|
|
130
|
-
export function parseReportFindings(report) {
|
|
131
|
-
const findings = [];
|
|
132
|
-
const lines = report.split(/\r?\n/u);
|
|
133
|
-
let index = 0;
|
|
134
|
-
for (const line of lines) {
|
|
135
|
-
const match = /^\s*(?:[-*]\s*)?(P[12])\b[:\s-]+(.+)$/u.exec(line);
|
|
136
|
-
if (match === null)
|
|
137
|
-
continue;
|
|
138
|
-
index += 1;
|
|
139
|
-
const severity = match[1].toLowerCase();
|
|
140
|
-
const summary = match[2].trim();
|
|
141
|
-
findings.push({
|
|
142
|
-
id: `report-p${severity === "p1" ? 1 : 2}-${index}`,
|
|
143
|
-
severity,
|
|
144
|
-
summary,
|
|
145
|
-
paths: extractPaths(summary),
|
|
146
|
-
source: "report"
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
return findings;
|
|
150
|
-
}
|