@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.
Files changed (179) hide show
  1. package/ARCHITECTURE.md +64 -35
  2. package/README.md +258 -125
  3. package/dist/agent/argumentPolicy.js +2 -1
  4. package/dist/agent/managedRuntimeEnvironment.js +5 -8
  5. package/dist/cli/commandCatalog.js +74 -109
  6. package/dist/cli/helpRenderer.js +1 -2
  7. package/dist/cli/interactionCandidates.js +10 -0
  8. package/dist/cli/interactionPolicy.js +76 -37
  9. package/dist/cli/roleWizard.js +5 -6
  10. package/dist/cli/updateOrchestrator.js +10 -8
  11. package/dist/cli/updatePorts.js +17 -13
  12. package/dist/cli/upgradeCommand.js +2 -5
  13. package/dist/cli.js +268 -231
  14. package/dist/commands/agentCommands.js +13 -0
  15. package/dist/commands/configCommands.js +7 -19
  16. package/dist/commands/configOverview.js +3 -2
  17. package/dist/commands/durableJobCommands.js +1 -1
  18. package/dist/commands/executionAuditCommands.js +4 -9
  19. package/dist/commands/globalRoleCommands.js +17 -0
  20. package/dist/commands/profileCommands.js +200 -30
  21. package/dist/commands/sessionCommands.js +1 -1
  22. package/dist/commands/taskActor.js +29 -127
  23. package/dist/commands/taskChangeSetCommands.js +1 -3
  24. package/dist/commands/taskCommands.js +1771 -2107
  25. package/dist/commands/taskCompletionGate.js +27 -103
  26. package/dist/commands/taskContextCommand.js +47 -80
  27. package/dist/commands/taskExecutionCommands.js +9 -27
  28. package/dist/commands/taskInputCommands.js +10 -10
  29. package/dist/commands/taskIntegrationCommands.js +69 -61
  30. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  31. package/dist/commands/taskNextActionCommand.js +8 -29
  32. package/dist/commands/taskOverviewCommand.js +25 -3
  33. package/dist/commands/taskPublicationCommands.js +151 -85
  34. package/dist/commands/taskPublicationVerifyCommand.js +181 -0
  35. package/dist/commands/taskRemoteDeliveryCommand.js +134 -0
  36. package/dist/commands/taskRoleRuntimeStatus.js +5 -6
  37. package/dist/commands/taskUpstreamCommands.js +79 -95
  38. package/dist/config/configCatalog.js +1 -1
  39. package/dist/context/contextSnapshot.js +17 -2
  40. package/dist/context/sessionBootstrapManifest.js +18 -1
  41. package/dist/context/sourceTurnContext.js +30 -0
  42. package/dist/context/turnContextPack.js +107 -48
  43. package/dist/context/turnInputContract.js +11 -4
  44. package/dist/context/wakeNotification.js +84 -22
  45. package/dist/controller/agentRuntimeObserver.js +9 -12
  46. package/dist/controller/clientRuntime.js +13 -13
  47. package/dist/controller/controller.js +11 -11
  48. package/dist/controller/fileSchedulerStoreAdapter.js +262 -219
  49. package/dist/controller/jobControl.js +11 -10
  50. package/dist/controller/resourceInventory.js +6 -6
  51. package/dist/controller/resourceInventoryLinux.js +2 -2
  52. package/dist/controller/runtime.js +18 -61
  53. package/dist/controller/runtimeEventInbox.js +57 -34
  54. package/dist/controller/runtimeEventProcessor.js +36 -96
  55. package/dist/controller/runtimeHookTurnFence.js +33 -57
  56. package/dist/controller/runtimeLaunchCoordinator.js +44 -40
  57. package/dist/controller/runtimeObservationHook.js +18 -12
  58. package/dist/controller/sessionNotify.js +43 -28
  59. package/dist/controller/sessionOwnerReconciliation.js +21 -21
  60. package/dist/controller/structuredProviderObservation.js +13 -16
  61. package/dist/coordination/workMailboxQueue.js +132 -0
  62. package/dist/core/controllerServer.js +1 -0
  63. package/dist/domain/agentResultTransport.js +60 -0
  64. package/dist/execution/executionHealth.js +111 -118
  65. package/dist/execution/reviewMainTurn.js +161 -0
  66. package/dist/execution/workItemExecution.js +454 -0
  67. package/dist/execution/workItemExecutionProjection.js +309 -0
  68. package/dist/execution/workItemMainTurn.js +164 -0
  69. package/dist/executor/agentExecutor.js +19 -19
  70. package/dist/executor/executorRegistry.js +7 -28
  71. package/dist/executor/fileRoleLaunchPlanner.js +51 -83
  72. package/dist/external/githubPublicationVerifier.js +114 -0
  73. package/dist/external/gitlabPublicationVerifier.js +158 -0
  74. package/dist/external/pinnedCommandRunner.js +73 -0
  75. package/dist/integration/changeSetManifest.js +0 -3
  76. package/dist/integration/deliveryObligation.js +43 -6
  77. package/dist/integration/gitIntegrationService.js +284 -101
  78. package/dist/integration/integrationAttempt.js +64 -14
  79. package/dist/integration/integrationQueueEntry.js +5 -35
  80. package/dist/integration/integrationQueueService.js +65 -194
  81. package/dist/lifecycle/canonicalLifecycleEvent.js +16 -15
  82. package/dist/lifecycle/exactTurnTerminalization.js +100 -97
  83. package/dist/message/message.js +16 -0
  84. package/dist/observability/executionAudit.js +4 -25
  85. package/dist/observability/faultClassification.js +58 -70
  86. package/dist/observability/orchestrationMetrics.js +8 -50
  87. package/dist/profile/agentProfile.js +60 -15
  88. package/dist/profile/agentProfileRuntime.js +100 -0
  89. package/dist/release/releaseWorkflowPorts.js +5 -68
  90. package/dist/repository/executionLaneGitSnapshot.js +80 -0
  91. package/dist/repository/gitWorkspace.js +9 -67
  92. package/dist/repository/taskBaseFreshness.js +3 -1
  93. package/dist/repository/taskWorkspaceCoordinator.js +32 -4
  94. package/dist/repository/taskWorkspacePreparer.js +252 -411
  95. package/dist/resources/liveReferences.js +6 -55
  96. package/dist/resources/resourceDiscovery.js +1 -30
  97. package/dist/resources/resourceRegistrar.js +0 -23
  98. package/dist/review/deltaRecheck.js +8 -65
  99. package/dist/review/reviewAcceptance.js +22 -19
  100. package/dist/review/reviewConfig.js +0 -10
  101. package/dist/review/reviewDecision.js +2 -2
  102. package/dist/review/reviewRound.js +147 -273
  103. package/dist/review/reviewerAvailability.js +13 -23
  104. package/dist/role/role.js +3 -0
  105. package/dist/runtime/agentDriverObservation.js +1 -1
  106. package/dist/runtime/agentHost.js +51 -51
  107. package/dist/runtime/builtinAgentDrivers.js +9 -2
  108. package/dist/runtime/codexAppServerRuntime.js +23 -5
  109. package/dist/runtime/exactControlPlane.js +2 -267
  110. package/dist/runtime/firstProgressAdvisory.js +1 -1
  111. package/dist/runtime/index.js +1 -1
  112. package/dist/runtime/launchBroker.js +11 -11
  113. package/dist/runtime/lifecycleReservation.js +2 -2
  114. package/dist/runtime/managedCaller.js +111 -0
  115. package/dist/runtime/ports.js +16 -3
  116. package/dist/runtime/preallocatedNativeSession.js +2 -2
  117. package/dist/runtime/processExitObservation.js +3 -2
  118. package/dist/runtime/providerContinuationReconciliationService.js +1 -1
  119. package/dist/runtime/runtimeBinding.js +1 -1
  120. package/dist/runtime/runtimeObservation.js +33 -16
  121. package/dist/runtime/runtimeSessionCandidate.js +2 -2
  122. package/dist/runtime/runtimeStopReceipt.js +11 -11
  123. package/dist/runtime/sessionLaunchRequest.js +2 -2
  124. package/dist/runtime/sessionOwnerIdentity.js +9 -9
  125. package/dist/runtime/sessionOwnerRegistry.js +13 -13
  126. package/dist/runtime/sessionReconciliation.js +4 -4
  127. package/dist/runtime/sessionTerminationGuard.js +9 -9
  128. package/dist/runtime/sessionTokenMetrics.js +5 -7
  129. package/dist/runtime/structuredProviderHost.js +5 -5
  130. package/dist/runtime/taskRuntimeIsolation.js +24 -24
  131. package/dist/runtime/tmuxAdapters.js +32 -30
  132. package/dist/scheduler/activeRoleTurnDelivery.js +37 -15
  133. package/dist/scheduler/leaderWakeupProcessor.js +78 -55
  134. package/dist/scheduler/roleTurnLiveness.js +6 -6
  135. package/dist/scheduler/roleTurnStall.js +8 -9
  136. package/dist/scheduler/taskExecutionProjection.js +19 -41
  137. package/dist/scheduler/taskObservabilityProjection.js +75 -122
  138. package/dist/storage/sqliteSchema.js +1 -21
  139. package/dist/storage/sqliteStore.js +62 -47
  140. package/dist/storage/storageSchema.js +1 -8
  141. package/dist/storage/storageVersions.js +7 -4
  142. package/dist/storage/taskStore.js +8 -8
  143. package/dist/storage/upgrade/upgradeOrchestrator.js +112 -83
  144. package/dist/task/completionReadiness.js +17 -98
  145. package/dist/task/deliveryGuard.js +9 -11
  146. package/dist/task/draftPlan.js +142 -0
  147. package/dist/task/nextAction.js +179 -477
  148. package/dist/task/publicationVerification.js +1 -0
  149. package/dist/task/remoteDelivery.js +233 -0
  150. package/dist/task/task.js +108 -4
  151. package/dist/task/taskRecordReference.js +0 -1
  152. package/dist/turn/turn.js +109 -16
  153. package/dist/verification/verificationGateService.js +0 -26
  154. package/dist/web/assets/client/components.js +99 -121
  155. package/dist/web/assets/client/i18n.js +136 -58
  156. package/dist/web/assets/client/view.js +44 -0
  157. package/dist/web/assets/styles/cards.js +3 -15
  158. package/dist/web/assets/styles/widgets.js +4 -0
  159. package/dist/web/webSnapshot.js +29 -14
  160. package/dist/workItem/dependencyGate.js +34 -0
  161. package/dist/workItem/workItem.js +99 -266
  162. package/dist/workspace/workItemChangeSetManager.js +15 -59
  163. package/docs/task-local-identity.md +1 -1
  164. package/i18n/README.zh-CN.md +165 -59
  165. package/package.json +1 -1
  166. package/skills/yui-leader/SKILL.md +272 -782
  167. package/skills/yui-operator/SKILL.md +190 -365
  168. package/skills/yui-reviewer/SKILL.md +40 -33
  169. package/skills/yui-runtime/SKILL.md +27 -6
  170. package/skills/yui-worker/SKILL.md +19 -6
  171. package/dist/execution/candidateConvergence.js +0 -623
  172. package/dist/execution/executionGroup.js +0 -854
  173. package/dist/execution/resourceBroker.js +0 -426
  174. package/dist/executor/launchPlan.js +0 -16
  175. package/dist/review/reviewFinding.js +0 -240
  176. package/dist/review/reviewFindingLedger.js +0 -550
  177. package/dist/review/reviewOutcomeClassifier.js +0 -255
  178. package/dist/scheduler/resourceQueueProjection.js +0 -71
  179. 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
- }
@@ -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
- }