@claudexor/orchestrator 5.0.1 → 5.1.0
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/account-evidence.d.ts +7 -0
- package/dist/account-evidence.d.ts.map +1 -1
- package/dist/account-evidence.js +12 -0
- package/dist/account-evidence.js.map +1 -1
- package/dist/account-pool.d.ts +4 -0
- package/dist/account-pool.d.ts.map +1 -1
- package/dist/account-pool.js +8 -1
- package/dist/account-pool.js.map +1 -1
- package/dist/account-resolution.d.ts.map +1 -1
- package/dist/account-resolution.js +7 -5
- package/dist/account-resolution.js.map +1 -1
- package/dist/attemptFinalize.d.ts +22 -7
- package/dist/attemptFinalize.d.ts.map +1 -1
- package/dist/attemptFinalize.js +29 -7
- package/dist/attemptFinalize.js.map +1 -1
- package/dist/attemptTelemetry.d.ts +19 -18
- package/dist/attemptTelemetry.d.ts.map +1 -1
- package/dist/attemptTelemetry.js +32 -79
- package/dist/attemptTelemetry.js.map +1 -1
- package/dist/attemptUsage.d.ts.map +1 -1
- package/dist/attemptUsage.js +6 -14
- package/dist/attemptUsage.js.map +1 -1
- package/dist/attemptUsageCost.d.ts +11 -2
- package/dist/attemptUsageCost.d.ts.map +1 -1
- package/dist/attemptUsageCost.js +16 -3
- package/dist/attemptUsageCost.js.map +1 -1
- package/dist/candidateEvidence.d.ts +42 -8
- package/dist/candidateEvidence.d.ts.map +1 -1
- package/dist/candidateEvidence.js +75 -16
- package/dist/candidateEvidence.js.map +1 -1
- package/dist/candidateReview.d.ts.map +1 -1
- package/dist/candidateReview.js +4 -2
- package/dist/candidateReview.js.map +1 -1
- package/dist/candidateTerminals.d.ts +10 -0
- package/dist/candidateTerminals.d.ts.map +1 -1
- package/dist/candidateTerminals.js +55 -11
- package/dist/candidateTerminals.js.map +1 -1
- package/dist/captureRefusal.d.ts +14 -4
- package/dist/captureRefusal.d.ts.map +1 -1
- package/dist/captureRefusal.js +64 -27
- package/dist/captureRefusal.js.map +1 -1
- package/dist/carrier-planner.d.ts +5 -2
- package/dist/carrier-planner.d.ts.map +1 -1
- package/dist/carrier-planner.js +6 -3
- package/dist/carrier-planner.js.map +1 -1
- package/dist/command-telemetry.d.ts +15 -0
- package/dist/command-telemetry.d.ts.map +1 -0
- package/dist/command-telemetry.js +27 -0
- package/dist/command-telemetry.js.map +1 -0
- package/dist/continuation-custody.d.ts.map +1 -1
- package/dist/continuation-custody.js +3 -1
- package/dist/continuation-custody.js.map +1 -1
- package/dist/continuation-evidence-io.d.ts +13 -3
- package/dist/continuation-evidence-io.d.ts.map +1 -1
- package/dist/continuation-evidence-io.js +36 -4
- package/dist/continuation-evidence-io.js.map +1 -1
- package/dist/continuation-evidence.d.ts +13 -2
- package/dist/continuation-evidence.d.ts.map +1 -1
- package/dist/continuation-evidence.js +23 -4
- package/dist/continuation-evidence.js.map +1 -1
- package/dist/continuation-later.d.ts.map +1 -1
- package/dist/continuation-later.js +6 -6
- package/dist/continuation-later.js.map +1 -1
- package/dist/continuity-facts.d.ts +25 -1
- package/dist/continuity-facts.d.ts.map +1 -1
- package/dist/continuity-facts.js +71 -4
- package/dist/continuity-facts.js.map +1 -1
- package/dist/continuity-notice.d.ts.map +1 -1
- package/dist/continuity-notice.js +2 -1
- package/dist/continuity-notice.js.map +1 -1
- package/dist/continuity-summary.d.ts +4 -1
- package/dist/continuity-summary.d.ts.map +1 -1
- package/dist/continuity-summary.js +30 -12
- package/dist/continuity-summary.js.map +1 -1
- package/dist/continuity.d.ts +36 -8
- package/dist/continuity.d.ts.map +1 -1
- package/dist/continuity.js +96 -21
- package/dist/continuity.js.map +1 -1
- package/dist/credential-cooldown.d.ts +7 -0
- package/dist/credential-cooldown.d.ts.map +1 -1
- package/dist/credential-cooldown.js +31 -5
- package/dist/credential-cooldown.js.map +1 -1
- package/dist/credential-differential.d.ts +15 -1
- package/dist/credential-differential.d.ts.map +1 -1
- package/dist/credential-differential.js +32 -17
- package/dist/credential-differential.js.map +1 -1
- package/dist/credential-execution.d.ts.map +1 -1
- package/dist/credential-execution.js +14 -15
- package/dist/credential-execution.js.map +1 -1
- package/dist/credential-preflight.js +1 -1
- package/dist/credential-preflight.js.map +1 -1
- package/dist/credential-profile-rotation.d.ts +1 -0
- package/dist/credential-profile-rotation.d.ts.map +1 -1
- package/dist/credential-profile-rotation.js +1 -1
- package/dist/credential-profile-rotation.js.map +1 -1
- package/dist/deepScanReducer.d.ts.map +1 -1
- package/dist/deepScanReducer.js +8 -18
- package/dist/deepScanReducer.js.map +1 -1
- package/dist/delegatedHome.d.ts +6 -4
- package/dist/delegatedHome.d.ts.map +1 -1
- package/dist/delegatedHome.js.map +1 -1
- package/dist/delegationFailure.d.ts +75 -14
- package/dist/delegationFailure.d.ts.map +1 -1
- package/dist/delegationFailure.js +38 -9
- package/dist/delegationFailure.js.map +1 -1
- package/dist/directoryCandidate.d.ts +10 -0
- package/dist/directoryCandidate.d.ts.map +1 -1
- package/dist/directoryCandidate.js +59 -9
- package/dist/directoryCandidate.js.map +1 -1
- package/dist/harnessFailure.d.ts +6 -5
- package/dist/harnessFailure.d.ts.map +1 -1
- package/dist/harnessFailure.js +7 -6
- package/dist/harnessFailure.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/inrun-continuity-carrier.d.ts +4 -1
- package/dist/inrun-continuity-carrier.d.ts.map +1 -1
- package/dist/inrun-continuity-carrier.js +2 -0
- package/dist/inrun-continuity-carrier.js.map +1 -1
- package/dist/inrun-continuity.d.ts +2 -2
- package/dist/inrun-continuity.d.ts.map +1 -1
- package/dist/inrun-continuity.js +22 -19
- package/dist/inrun-continuity.js.map +1 -1
- package/dist/inrun-retained-output.d.ts +18 -4
- package/dist/inrun-retained-output.d.ts.map +1 -1
- package/dist/inrun-retained-output.js +39 -8
- package/dist/inrun-retained-output.js.map +1 -1
- package/dist/laneStreamEvents.d.ts +9 -10
- package/dist/laneStreamEvents.d.ts.map +1 -1
- package/dist/laneStreamEvents.js +21 -7
- package/dist/laneStreamEvents.js.map +1 -1
- package/dist/modelGovernance.d.ts +10 -4
- package/dist/modelGovernance.d.ts.map +1 -1
- package/dist/modelGovernance.js +21 -1
- package/dist/modelGovernance.js.map +1 -1
- package/dist/native-retry-telemetry.d.ts +4 -1
- package/dist/native-retry-telemetry.d.ts.map +1 -1
- package/dist/native-retry-telemetry.js +6 -1
- package/dist/native-retry-telemetry.js.map +1 -1
- package/dist/orchestrator.d.ts +10 -2
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +137 -156
- package/dist/orchestrator.js.map +1 -1
- package/dist/planRun.js +4 -4
- package/dist/planRun.js.map +1 -1
- package/dist/plannerAttempt.d.ts +1 -0
- package/dist/plannerAttempt.d.ts.map +1 -1
- package/dist/plannerAttempt.js +14 -19
- package/dist/plannerAttempt.js.map +1 -1
- package/dist/pool-attempt-evidence.d.ts +3 -1
- package/dist/pool-attempt-evidence.d.ts.map +1 -1
- package/dist/pool-attempt-evidence.js +16 -3
- package/dist/pool-attempt-evidence.js.map +1 -1
- package/dist/quota-refusal-scope.d.ts +1 -0
- package/dist/quota-refusal-scope.d.ts.map +1 -1
- package/dist/quota-refusal-scope.js +29 -1
- package/dist/quota-refusal-scope.js.map +1 -1
- package/dist/rawPatchLane.d.ts +42 -0
- package/dist/rawPatchLane.d.ts.map +1 -0
- package/dist/rawPatchLane.js +79 -0
- package/dist/rawPatchLane.js.map +1 -0
- package/dist/readonlyTerminals.d.ts +0 -3
- package/dist/readonlyTerminals.d.ts.map +1 -1
- package/dist/readonlyTerminals.js +30 -10
- package/dist/readonlyTerminals.js.map +1 -1
- package/dist/requestRequirements.d.ts +5 -4
- package/dist/requestRequirements.d.ts.map +1 -1
- package/dist/requestRequirements.js +6 -5
- package/dist/requestRequirements.js.map +1 -1
- package/dist/retainedOutput.d.ts +19 -2
- package/dist/retainedOutput.d.ts.map +1 -1
- package/dist/retainedOutput.js +83 -12
- package/dist/retainedOutput.js.map +1 -1
- package/dist/reviewerInventory.d.ts +2 -8
- package/dist/reviewerInventory.d.ts.map +1 -1
- package/dist/reviewerInventory.js +2 -3
- package/dist/reviewerInventory.js.map +1 -1
- package/dist/reviewerPanel.d.ts +1 -1
- package/dist/reviewerPanel.d.ts.map +1 -1
- package/dist/reviewerPanel.js +9 -4
- package/dist/reviewerPanel.js.map +1 -1
- package/dist/route-admission.d.ts.map +1 -1
- package/dist/route-admission.js +3 -1
- package/dist/route-admission.js.map +1 -1
- package/dist/routeControls.d.ts +32 -0
- package/dist/routeControls.d.ts.map +1 -0
- package/dist/routeControls.js +47 -0
- package/dist/routeControls.js.map +1 -0
- package/dist/run-input-resolution.d.ts +5 -0
- package/dist/run-input-resolution.d.ts.map +1 -1
- package/dist/run-input-resolution.js +12 -6
- package/dist/run-input-resolution.js.map +1 -1
- package/dist/run-runtime-root.d.ts +16 -0
- package/dist/run-runtime-root.d.ts.map +1 -0
- package/dist/run-runtime-root.js +16 -0
- package/dist/run-runtime-root.js.map +1 -0
- package/dist/runAdmission.d.ts.map +1 -1
- package/dist/runAdmission.js +2 -1
- package/dist/runAdmission.js.map +1 -1
- package/dist/runEventLog.d.ts +2 -1
- package/dist/runEventLog.d.ts.map +1 -1
- package/dist/runEventLog.js +3 -1
- package/dist/runEventLog.js.map +1 -1
- package/dist/runFacts.d.ts +5 -2
- package/dist/runFacts.d.ts.map +1 -1
- package/dist/runFacts.js +11 -11
- package/dist/runFacts.js.map +1 -1
- package/dist/runScope.d.ts +2 -0
- package/dist/runScope.d.ts.map +1 -1
- package/dist/runScope.js +3 -2
- package/dist/runScope.js.map +1 -1
- package/dist/runSupport.d.ts +3 -1
- package/dist/runSupport.d.ts.map +1 -1
- package/dist/runSupport.js +3 -1
- package/dist/runSupport.js.map +1 -1
- package/dist/runTelemetryWriter.d.ts +18 -5
- package/dist/runTelemetryWriter.d.ts.map +1 -1
- package/dist/runTelemetryWriter.js +7 -2
- package/dist/runTelemetryWriter.js.map +1 -1
- package/dist/runTerminalResults.d.ts.map +1 -1
- package/dist/runTerminalResults.js +22 -7
- package/dist/runTerminalResults.js.map +1 -1
- package/dist/runTerminals.d.ts.map +1 -1
- package/dist/runTerminals.js +19 -8
- package/dist/runTerminals.js.map +1 -1
- package/dist/secretDiff.d.ts.map +1 -1
- package/dist/secretDiff.js +2 -1
- package/dist/secretDiff.js.map +1 -1
- package/dist/transientClassify.d.ts +17 -9
- package/dist/transientClassify.d.ts.map +1 -1
- package/dist/transientClassify.js +33 -9
- package/dist/transientClassify.js.map +1 -1
- package/dist/webEvidence.d.ts +41 -0
- package/dist/webEvidence.d.ts.map +1 -0
- package/dist/webEvidence.js +99 -0
- package/dist/webEvidence.js.map +1 -0
- package/dist/workReportEnvelope.d.ts +12 -0
- package/dist/workReportEnvelope.d.ts.map +1 -1
- package/dist/workReportEnvelope.js +19 -0
- package/dist/workReportEnvelope.js.map +1 -1
- package/package.json +17 -17
- package/dist/continuation-chain.test-support.d.ts +0 -473
- package/dist/continuation-chain.test-support.d.ts.map +0 -1
- package/dist/continuation-chain.test-support.js +0 -206
- package/dist/continuation-chain.test-support.js.map +0 -1
- package/dist/inrun-continuity.test-support.d.ts +0 -504
- package/dist/inrun-continuity.test-support.d.ts.map +0 -1
- package/dist/inrun-continuity.test-support.js +0 -212
- package/dist/inrun-continuity.test-support.js.map +0 -1
package/dist/orchestrator.js
CHANGED
|
@@ -7,7 +7,7 @@ import { openRunScopeCustody, scopedRouteContext, scopedSpecEnv, } from "./runSc
|
|
|
7
7
|
import { delegationBeltFor } from "./delegationBelt.js";
|
|
8
8
|
import { routePromptCacheTtl, withReviewerPromptCacheTtl } from "./prompt-cache-routing.js";
|
|
9
9
|
import { bindProcessingAdmission, processingAttemptCostEvidence, processingAdmissionForLease, updateProcessingStreamHold, } from "./processing-dispatch.js";
|
|
10
|
-
import { cancelledCandidatesResult, emptyCandidateResult, failedCandidatesResult, failAfterCandidates, } from "./candidateTerminals.js";
|
|
10
|
+
import { cancelledCandidatesResult, emptyCandidateResult, erroredWinnerFailure, failedCandidatesResult, failAfterCandidates, } from "./candidateTerminals.js";
|
|
11
11
|
import { deepScanFailureResult, readOnlyChainFailureResult, } from "./readonlyTerminals.js";
|
|
12
12
|
import { effectiveAuthPreference, observeNativeSessionEvent, resumeSessionForProfile, } from "./credential-profiles.js";
|
|
13
13
|
import { AdmissionProfileProbes, OrchestratorCredentials, reviewerProfileResolver, } from "./orchestrator-credentials.js";
|
|
@@ -15,14 +15,14 @@ import { continuityWorkspace, carryingAttempts, resumableOf, resumableTerminal,
|
|
|
15
15
|
import { openContinuity } from "./continue-from.js";
|
|
16
16
|
import { accountPoolRows } from "./account-pool.js";
|
|
17
17
|
import { PoolAttemptEvidence, terminalPoolAttempts, withPoolAttempts, } from "./pool-attempt-evidence.js";
|
|
18
|
-
import { writeRunTelemetryArtifact } from "./runTelemetryWriter.js";
|
|
18
|
+
import { pickTelemetry, writeRunTelemetryArtifact, } from "./runTelemetryWriter.js";
|
|
19
19
|
import { buildFileBackedSynthesisInput, materializeWinnerOutputs, stageFileBackedContext, writeCandidateAttemptArtifacts, } from "./candidateOutputs.js";
|
|
20
20
|
import { processAttemptUsage } from "./attemptUsage.js";
|
|
21
|
-
import { captureDirectoryCandidate, directoryHasOutput, directoryCandidateStable, observeDirectoryPaths, publishDirectoryCandidate, } from "./directoryCandidate.js";
|
|
21
|
+
import { captureDirectoryCandidate, directoryPreparationNotice, directoryHasOutput, directoryCandidateStable, observeDirectoryPaths, publishDirectoryCandidate, } from "./directoryCandidate.js";
|
|
22
22
|
import { appliedAttemptFacts, assertDelegatedEvidence, isMutatingAccess, outerBoundaryNotice, scopedHarnessHome, selectLaneHome, followSpecHome, } from "./delegatedHome.js";
|
|
23
23
|
import * as AC from "./attemptUsageCost.js";
|
|
24
24
|
import * as custody from "./continuation-custody.js";
|
|
25
|
-
import { candidateRoster, candidateStatuses, convergenceOutcomeFacts, isWorkingCandidate, partitionCandidates, toCandidateEvidence, } from "./candidateEvidence.js";
|
|
25
|
+
import { capturedNoGitChangeValue, candidateCaptureRefusals, candidateCompletion, candidateRoster, candidateStatuses, convergenceOutcomeFacts, declaredFailureSpeaks, interruptionOf, isWorkingCandidate, needsPostTurnFence, partitionCandidates, toCandidateEvidence, } from "./candidateEvidence.js";
|
|
26
26
|
import { capabilityIntents } from "@claudexor/gateway";
|
|
27
27
|
import { reviewCandidateRuns, unreviewedCandidateEvidence, evaluateUnreviewedConvergence, } from "./candidateReview.js";
|
|
28
28
|
import { join } from "node:path";
|
|
@@ -33,7 +33,7 @@ import { globalConfigDir } from "@claudexor/config";
|
|
|
33
33
|
import { executionRunConfig } from "./run-defaults.js";
|
|
34
34
|
import { preflightOneShot } from "./one-shot-preflight.js";
|
|
35
35
|
import { prepareRoutedProcessing, processingCostEvidence, prepareReviewerProcessing, } from "./processing-routing.js";
|
|
36
|
-
import { acceptedTryOutput, AccessProfileIncompatibleError, AnswerAssembly, appendHarnessEvent, AuxiliaryWritableRootsUnsupportedError, CLAUDEXOR_BROWSER_ARTIFACT_SUBDIR, countsAsAgentProgress, HarnessUnavailableError, withInactivityWatchdog, } from "@claudexor/core";
|
|
36
|
+
import { acceptedTryOutput, AccessProfileIncompatibleError, AnswerAssembly, appendHarnessEvent, AuxiliaryWritableRootsUnsupportedError, CLAUDEXOR_BROWSER_ARTIFACT_SUBDIR, countsAsAgentProgress, HarnessUnavailableError, ModelSelectionRequiredError, missingRouteModel, withInactivityWatchdog, } from "@claudexor/core";
|
|
37
37
|
import { assertRouteModelsAllowed, isDispatchRefusal, runModelGovernedRoute, } from "./modelGovernance.js";
|
|
38
38
|
import { authModeForCredentialRoute, authModeForPreference, authRouteEvidenceFor, } from "./auth-route-classification.js";
|
|
39
39
|
import { isFullAccess, RequestRequirementsResolver } from "./requestRequirements.js";
|
|
@@ -50,21 +50,21 @@ import { cancelledResult, declaredFailure, failTerminally, guardAnnouncedRun, wr
|
|
|
50
50
|
import { budgetFailureRecord, classifyBudgetFailure } from "./budgetFailure.js";
|
|
51
51
|
import { finalizeStructuredOutput } from "./structuredOutput.js";
|
|
52
52
|
import { prepareRunAdmission } from "./runAdmission.js";
|
|
53
|
-
import { dropDeltaPastBudget, emitPlanProgress, emitTransientExhausted,
|
|
53
|
+
import { dropDeltaPastBudget, emitPlanProgress, emitTransientExhausted, observeUsageSpend, recordAdapterThrow, } from "./laneStreamEvents.js";
|
|
54
54
|
import { promptWithEngineConstraints, sleep, harnessEventPayload, safeErrorMessage, renderSummary, observeBudgetSignals, rotateOnStall, recordCleanAttemptMetrics, envInheritance, transientRetryPolicy, reviewerTimeoutMs, harnessInactivityTimeoutMs, observeAuthSwitch, emitPoolDegraded, deliveryRefusalFailure, winnerNeedsHuman, writeRaceDeliveryDecision, } from "./runSupport.js";
|
|
55
55
|
import { candidateStatusInRouteContext, resolveReadOnlyRouteContext, } from "./routeContext.js";
|
|
56
56
|
import { resolveAutoReviewerPanel, resolveExplicitReviewerPanel } from "./reviewerPanel.js";
|
|
57
57
|
import { ensureClaudeBridgeForRun, ensureWriteModeGitBoundary } from "./git-precondition.js";
|
|
58
|
-
import { buildContinuation
|
|
59
|
-
import {
|
|
58
|
+
import { buildContinuation } from "./continuity.js";
|
|
59
|
+
import { resolveContinuitySummary, threadContinuityRequest } from "./continuity-facts.js";
|
|
60
60
|
import { runDiffReview } from "./diffReview.js";
|
|
61
61
|
import { rawScoutBundle, resolveDeepScanSynthesis, } from "./deepScanReducer.js";
|
|
62
62
|
import { createAttemptTelemetry, observeAttemptTelemetry, setAttemptOutcome, telemetrySummary, toolWarnings, unrecoveredToolErrors, webUnsatisfied, } from "./attemptTelemetry.js";
|
|
63
63
|
import { beginNativeRetry } from "./native-retry-telemetry.js";
|
|
64
64
|
import * as delegateFailure from "./delegationFailure.js";
|
|
65
65
|
import * as secretDiff from "./secretDiff.js";
|
|
66
|
-
import { finalizeAttempt, unrecoveredToolErrorFailure, webEvidenceFailure, } from "./attemptFinalize.js";
|
|
67
|
-
import { resolveWorkReportEnvelope,
|
|
66
|
+
import { attemptInterruption, finalizeAttempt, interruptionDetail, unrecoveredToolErrorFailure, webEvidenceFailure, } from "./attemptFinalize.js";
|
|
67
|
+
import { resolveWorkReportEnvelope, unwrapAttemptAnswer, } from "./workReportEnvelope.js";
|
|
68
68
|
import { buildContinuationPacket, decideContinuation, synthesizeContinuationRequest, } from "./continuation.js";
|
|
69
69
|
import { interactionChannelFor } from "./interaction.js";
|
|
70
70
|
import { liveAttempt } from "./live-input.js";
|
|
@@ -74,15 +74,17 @@ import { recordProcessingIntent } from "./retry-processing-intent.js";
|
|
|
74
74
|
import { prepareReviewEvidenceDir, recordReviewEvidenceCleanup } from "./reviewEvidence.js";
|
|
75
75
|
import { savedForSynthesis } from "./savedCandidate.js";
|
|
76
76
|
import { ArtifactStore } from "@claudexor/artifact-store";
|
|
77
|
-
import { buildContextPack,
|
|
78
|
-
import {
|
|
77
|
+
import { buildContextPack, writeEvidencePacket } from "@claudexor/context";
|
|
78
|
+
import { RawPatchLane, correctableRefusal, endsConvergence } from "./rawPatchLane.js";
|
|
79
|
+
import { runRuntimeRoot } from "./run-runtime-root.js";
|
|
80
|
+
import { WorkspaceManager, snapshotTree, } from "@claudexor/workspace";
|
|
79
81
|
import { blockedDecisionOverride, finalVerifyBlocks, verifyAndDeliverFiles, verifyAndDeliver, } from "@claudexor/delivery";
|
|
80
82
|
import { HarnessGateway } from "@claudexor/gateway";
|
|
81
|
-
import { ReadinessLedger, evaluateConvergence, failureSignature, gatesPassed, reviewCandidate, runGates, } from "@claudexor/review";
|
|
83
|
+
import { ReadinessLedger, evaluateConvergence, failureSignature, gatesPassed, requireReadingReviewers, reviewCandidate, runGates, } from "@claudexor/review";
|
|
82
84
|
import { arbitrate } from "@claudexor/arbitration";
|
|
83
85
|
import { buildSynthesisPlan, decideSynthesis } from "@claudexor/synthesis";
|
|
84
86
|
import { billingKnowledgeForAuthRoute, attemptUsageCostSettlement, BudgetLedger, isBudgetTerminal, explainRanking, loadHarnessMetrics, promptFingerprint, rankHarnesses, } from "@claudexor/budget";
|
|
85
|
-
import {
|
|
87
|
+
import { hashJson, newId, noProjectRepoRoot, redactSecrets, safeInvoke, userConfigDir, } from "@claudexor/util";
|
|
86
88
|
const LABELS = "ABCDEFGHIJ".split("");
|
|
87
89
|
const NO_PROJECT_ROOT = noProjectRepoRoot();
|
|
88
90
|
export class Orchestrator {
|
|
@@ -191,7 +193,7 @@ export class Orchestrator {
|
|
|
191
193
|
}
|
|
192
194
|
async resolveReviewers(run, onIgnoredSetting) {
|
|
193
195
|
if (this.deps.reviewers)
|
|
194
|
-
return this.deps.reviewers;
|
|
196
|
+
return requireReadingReviewers(this.deps.reviewers);
|
|
195
197
|
const { repoRoot: cwd, authPreference, signal } = run;
|
|
196
198
|
const panelDeps = {
|
|
197
199
|
cwd,
|
|
@@ -269,7 +271,7 @@ export class Orchestrator {
|
|
|
269
271
|
if (input.mode === "ask" && input.contextMode === "off" && input.repoRoot === NO_PROJECT_ROOT) {
|
|
270
272
|
return new ArtifactStore(input.repoRoot, { claudexorDir: userConfigDir() });
|
|
271
273
|
}
|
|
272
|
-
return new ArtifactStore(input.repoRoot);
|
|
274
|
+
return new ArtifactStore(input.repoRoot, { claudexorDir: runRuntimeRoot(input) });
|
|
273
275
|
}
|
|
274
276
|
/** The producing intent a candidate plays (create flag switches it; not hardcoded to implement). */
|
|
275
277
|
candidateIntent(input) {
|
|
@@ -425,6 +427,8 @@ export class Orchestrator {
|
|
|
425
427
|
throw new AuxiliaryWritableRootsUnsupportedError(detail);
|
|
426
428
|
if (stage === "access")
|
|
427
429
|
throw new AccessProfileIncompatibleError(detail);
|
|
430
|
+
if (stage === "model")
|
|
431
|
+
throw new ModelSelectionRequiredError(detail);
|
|
428
432
|
throw new HarnessUnavailableError(detail);
|
|
429
433
|
}
|
|
430
434
|
dropped.push(detail);
|
|
@@ -587,6 +591,13 @@ export class Orchestrator {
|
|
|
587
591
|
dropLane(id, "capability", readRefusal);
|
|
588
592
|
continue;
|
|
589
593
|
}
|
|
594
|
+
const modelRefusal = status.enabledIntents.includes(intent)
|
|
595
|
+
? missingRouteModel(adapter, input.models?.[id] ?? cfgEntry?.default_model)
|
|
596
|
+
: null;
|
|
597
|
+
if (modelRefusal) {
|
|
598
|
+
dropLane(id, "model", modelRefusal);
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
590
601
|
const reason = status.reasons.length > 0 ? `: ${status.reasons.join("; ")}` : "";
|
|
591
602
|
if (status.enabledIntents.includes(intent) && accessSupported) {
|
|
592
603
|
pool.push({
|
|
@@ -594,6 +605,7 @@ export class Orchestrator {
|
|
|
594
605
|
adapterAccess: requiredAccess,
|
|
595
606
|
auxiliaryWritableRoots,
|
|
596
607
|
webSupport,
|
|
608
|
+
accessControl: manifest.capability_profile.access_control,
|
|
597
609
|
providerFamily: manifest.provider_family,
|
|
598
610
|
supportsMaxTurns: manifest.capabilities.max_turns,
|
|
599
611
|
supportsToolLists: manifest.capabilities.tool_lists,
|
|
@@ -1136,33 +1148,7 @@ export class Orchestrator {
|
|
|
1136
1148
|
return null;
|
|
1137
1149
|
try {
|
|
1138
1150
|
const profileId = resolvedProfileId ?? ctx.profileId ?? null;
|
|
1139
|
-
const
|
|
1140
|
-
const checkpoint = ctx.laneCheckpoints.find((c) => c.harness === harnessId && (c.profileId ?? null) === profileId);
|
|
1141
|
-
const headTurnId = ctx.priorTurns.length
|
|
1142
|
-
? ctx.priorTurns[ctx.priorTurns.length - 1].id
|
|
1143
|
-
: null;
|
|
1144
|
-
const priorHeadOwner = headTurnId
|
|
1145
|
-
? ctx.laneCheckpoints.find((c) => c.turnId === headTurnId)
|
|
1146
|
-
: undefined;
|
|
1147
|
-
const priorHeadLane = priorHeadOwner
|
|
1148
|
-
? { harness: priorHeadOwner.harness, profileId: priorHeadOwner.profileId ?? null }
|
|
1149
|
-
: null;
|
|
1150
|
-
const priorTurns = ctx.priorTurns.map((t) => ({
|
|
1151
|
-
id: t.id,
|
|
1152
|
-
prompt: t.prompt,
|
|
1153
|
-
outputText: t.runId
|
|
1154
|
-
? (readTextSafe(join(store.runPaths(t.runId).finalDir, "answer.md")) ?? "")
|
|
1155
|
-
: "",
|
|
1156
|
-
}));
|
|
1157
|
-
const req = {
|
|
1158
|
-
lane,
|
|
1159
|
-
priorTurns,
|
|
1160
|
-
laneCheckpointTurnId: checkpoint?.turnId ?? null,
|
|
1161
|
-
nativeResumeAvailable,
|
|
1162
|
-
priorHeadLane,
|
|
1163
|
-
activePlan: activePlanPointer(ctx.priorTurns, store),
|
|
1164
|
-
anchor: await workspaceAnchor(repoRoot),
|
|
1165
|
-
};
|
|
1151
|
+
const req = await threadContinuityRequest(ctx, { harness: harnessId, profileId }, nativeResumeAvailable, store, repoRoot);
|
|
1166
1152
|
// V9c: when the packet would collapse an older prefix, replace the
|
|
1167
1153
|
// mechanical one-liners with a cached (or freshly summarized) prose
|
|
1168
1154
|
// summary. Same credential route + scoped lane home a real read-only
|
|
@@ -1174,6 +1160,7 @@ export class Orchestrator {
|
|
|
1174
1160
|
projectRoot: runInput.repoRoot,
|
|
1175
1161
|
cwd: repoRoot,
|
|
1176
1162
|
adapter: this.deps.registry.get(harnessId),
|
|
1163
|
+
model: this.deps.registry.get(harnessId)?.modelRequirement && runInput.models?.[harnessId],
|
|
1177
1164
|
credentialProfile: sessionFields.credential_profile,
|
|
1178
1165
|
authPreference: sessionFields.auth_preference ?? "auto",
|
|
1179
1166
|
laneEnv: scopedSpecEnv(runInput.runScopeMarker, this.laneHomeEnvFor(runInput, harnessId, profileId) ?? {}) ?? {},
|
|
@@ -1262,11 +1249,12 @@ export class Orchestrator {
|
|
|
1262
1249
|
const inPlaceEnvelope = envelope.worktree_path === envelope.repo_root;
|
|
1263
1250
|
const directory = envelope.workspace_kind === "directory";
|
|
1264
1251
|
let directoryCapture = {};
|
|
1265
|
-
const captureDirectory = async () => (directoryCapture = await captureDirectoryCandidate({
|
|
1252
|
+
const captureDirectory = async (final = false) => (directoryCapture = await captureDirectoryCandidate({
|
|
1266
1253
|
manager: wsm,
|
|
1267
1254
|
envelope,
|
|
1268
1255
|
artifactRoot: join(paths.attemptsDir, attemptId),
|
|
1269
1256
|
observedPaths: [...observedPaths],
|
|
1257
|
+
...(final ? { holder: { runId: paths.runId, runDir: paths.root } } : {}),
|
|
1270
1258
|
}));
|
|
1271
1259
|
const sessionFields = runInput
|
|
1272
1260
|
? await this.sessionSpecFields(runInput, adapter.id, knobs.model, log, routed.authRouteEstimate, routed.quotaAdmission)
|
|
@@ -1304,6 +1292,7 @@ export class Orchestrator {
|
|
|
1304
1292
|
[
|
|
1305
1293
|
prompt,
|
|
1306
1294
|
outerBoundaryNotice(harnessHome, routed.auxiliaryWritableRoots),
|
|
1295
|
+
await directoryPreparationNotice(envelope, attemptId, log),
|
|
1307
1296
|
laneContinuity?.pointerLine,
|
|
1308
1297
|
continuationPointer,
|
|
1309
1298
|
]
|
|
@@ -1340,13 +1329,8 @@ export class Orchestrator {
|
|
|
1340
1329
|
// #147: bound to the project's context config; each try's dispatch sizes its own
|
|
1341
1330
|
// packet for THIS request from the catalog read the gate makes for that try.
|
|
1342
1331
|
const { context } = this.projectConfig(contract.repo.root);
|
|
1343
|
-
const
|
|
1344
|
-
|
|
1345
|
-
const dispatch = sizeRawContext
|
|
1346
|
-
? {
|
|
1347
|
-
rawContext: async (capacity) => (rawContextPacket = await sizeRawContext(capacity)),
|
|
1348
|
-
}
|
|
1349
|
-
: {};
|
|
1332
|
+
const rawLane = new RawPatchLane(routed.implementationTransport, envelope, context);
|
|
1333
|
+
const { dispatch } = rawLane;
|
|
1350
1334
|
bindProcessingAdmission(spec, ledger, processingLease.lease, adapter.id, attemptId, processingLease.onDenied, processingAdmission);
|
|
1351
1335
|
// Profile-less processing keeps its existing route estimate. Named rows
|
|
1352
1336
|
// receive their own verification at the shared physical-dispatch gate.
|
|
@@ -1431,8 +1415,7 @@ export class Orchestrator {
|
|
|
1431
1415
|
const refusal = continuity.beginTry(runSpec, nativeTry, attemptAbort);
|
|
1432
1416
|
const transientStart = telemetry.transientFailures.length;
|
|
1433
1417
|
const rateLimitStart = telemetry.rateLimits.length;
|
|
1434
|
-
|
|
1435
|
-
rawContextPacket = null; // a patch binds only the packet its own try sent
|
|
1418
|
+
rawLane.beginTry();
|
|
1436
1419
|
try {
|
|
1437
1420
|
const watched = withInactivityWatchdog(runModelGovernedRoute(routed, runSpec, dispatch), {
|
|
1438
1421
|
timeoutMs: inactivityMs,
|
|
@@ -1452,7 +1435,7 @@ export class Orchestrator {
|
|
|
1452
1435
|
// After Stop: stored evidence only, but file paths are still collected for the capture.
|
|
1453
1436
|
const stopped = signal?.aborted === true;
|
|
1454
1437
|
if (!stopped)
|
|
1455
|
-
|
|
1438
|
+
rawLane.observe(ev);
|
|
1456
1439
|
if (ev.type === "patch_produced")
|
|
1457
1440
|
continue;
|
|
1458
1441
|
if (directory)
|
|
@@ -1523,14 +1506,7 @@ export class Orchestrator {
|
|
|
1523
1506
|
observeBudgetSignals(ledger, log, adapter.id, attemptId, ev, budgetSignalState);
|
|
1524
1507
|
this.deps.quotaEventSink?.(adapter.id, ev);
|
|
1525
1508
|
}
|
|
1526
|
-
|
|
1527
|
-
await consumeRawPatchEnvelope({
|
|
1528
|
-
repoRoot: envelope.repo_root,
|
|
1529
|
-
worktreePath: envelope.worktree_path,
|
|
1530
|
-
baseCommitSha: envelope.base_sha ?? "HEAD",
|
|
1531
|
-
context: rawContextPacket,
|
|
1532
|
-
envelope: rawPatch,
|
|
1533
|
-
});
|
|
1509
|
+
await rawLane.settle(harnessErrored);
|
|
1534
1510
|
}
|
|
1535
1511
|
catch (err) {
|
|
1536
1512
|
// A throwing adapter must not lose the cost already streamed: record the
|
|
@@ -1543,14 +1519,12 @@ export class Orchestrator {
|
|
|
1543
1519
|
processingRefusal = err;
|
|
1544
1520
|
break;
|
|
1545
1521
|
}
|
|
1546
|
-
if (!recordAdapterThrow(telemetry, err))
|
|
1522
|
+
if (!rawLane.refused(err) && !recordAdapterThrow(telemetry, err))
|
|
1547
1523
|
break;
|
|
1548
1524
|
}
|
|
1549
1525
|
finally {
|
|
1550
1526
|
clearFileBackedContext();
|
|
1551
1527
|
}
|
|
1552
|
-
if (telemetry.requestRefusal)
|
|
1553
|
-
break;
|
|
1554
1528
|
const newTransients = telemetry.transientFailures.slice(transientStart);
|
|
1555
1529
|
// #31: the centralized retry gate reads the classified `retryable` verdict.
|
|
1556
1530
|
const sawRetryable = newTransients.some((f) => f.retryable);
|
|
@@ -1580,6 +1554,8 @@ export class Orchestrator {
|
|
|
1580
1554
|
this.credentials.noteTryServed(refusal, telemetry.outputMarkers, delivered);
|
|
1581
1555
|
const verdict = await continuity.afterTry({
|
|
1582
1556
|
...tryFacts,
|
|
1557
|
+
// A refused patch is its account row above, but no retry or rotation repairs it.
|
|
1558
|
+
requestRefused: tryFacts.requestRefused || rawLane.refusal !== null,
|
|
1583
1559
|
// A cancel or deadline that landed during capture still stops the
|
|
1584
1560
|
// attempt; the try's own facts above stay its evidence.
|
|
1585
1561
|
stopped: signal?.aborted === true,
|
|
@@ -1619,6 +1595,7 @@ export class Orchestrator {
|
|
|
1619
1595
|
if (harnessErrored &&
|
|
1620
1596
|
!poolExhausted &&
|
|
1621
1597
|
!processingRefusal &&
|
|
1598
|
+
!rawLane.refusal &&
|
|
1622
1599
|
!telemetry.requestRefusal &&
|
|
1623
1600
|
!signal?.aborted) {
|
|
1624
1601
|
emitTransientExhausted((t, p) => log?.emit(t, p), adapter.id, attemptId, telemetry, retryPolicy.maxRetries);
|
|
@@ -1629,10 +1606,10 @@ export class Orchestrator {
|
|
|
1629
1606
|
}
|
|
1630
1607
|
// D-16: answer.md persists only the deliverable. A3: an errored attempt
|
|
1631
1608
|
// with no typed final contributes no answer material (acceptedTryOutput).
|
|
1632
|
-
const unwrapped =
|
|
1609
|
+
const unwrapped = unwrapAttemptAnswer(acceptedTryOutput(answer, harnessErrored), harnessErrored && !answer.hasFinal(), workReportMode, { sideToolReport: telemetry.sideToolWorkReport ?? undefined });
|
|
1633
1610
|
const answerText = unwrapped.deliverable.trim().length > 0 ? unwrapped.deliverable : undefined;
|
|
1634
1611
|
if (directory)
|
|
1635
|
-
await captureDirectory();
|
|
1612
|
+
await captureDirectory(true);
|
|
1636
1613
|
const captured = directory
|
|
1637
1614
|
? { diff: "", captureRefusal: directoryCapture.refusal }
|
|
1638
1615
|
: await secretDiff.captureCandidateWorkspace({
|
|
@@ -1695,7 +1672,7 @@ export class Orchestrator {
|
|
|
1695
1672
|
workReportSource: unwrapped.source,
|
|
1696
1673
|
workReportViolation: unwrapped.contractViolation,
|
|
1697
1674
|
workReportUnverified: unwrapped.unverified ?? null,
|
|
1698
|
-
|
|
1675
|
+
interruption: attemptInterruption(telemetry),
|
|
1699
1676
|
});
|
|
1700
1677
|
harnessErrored = finalized.harnessErrored;
|
|
1701
1678
|
if (finalized.outcomeClass === "contract_failure" && unwrapped.contractViolation)
|
|
@@ -1723,6 +1700,7 @@ export class Orchestrator {
|
|
|
1723
1700
|
const attemptDir = join(paths.attemptsDir, attemptId);
|
|
1724
1701
|
recordCleanAttemptMetrics(globalConfigDir(), adapter.id, {
|
|
1725
1702
|
costUsd: cost,
|
|
1703
|
+
usageCost: telemetry.usageCost,
|
|
1726
1704
|
streamMs: attemptStreamEndedMs - attemptStartedMs,
|
|
1727
1705
|
errored,
|
|
1728
1706
|
aborted: signal?.aborted === true,
|
|
@@ -1795,8 +1773,10 @@ export class Orchestrator {
|
|
|
1795
1773
|
// A5: the typed refusal survives NORMAL attempt finalization (no throw).
|
|
1796
1774
|
...(telemetry.requestRefusal
|
|
1797
1775
|
? { declaredFailure: requestRefusalFailure(telemetry.requestRefusal) }
|
|
1798
|
-
: poolExhausted || processingRefusal
|
|
1799
|
-
? {
|
|
1776
|
+
: poolExhausted || processingRefusal || rawLane.refusal
|
|
1777
|
+
? {
|
|
1778
|
+
declaredFailure: declaredFailure(processingRefusal ?? rawLane.refusal ?? poolExhausted),
|
|
1779
|
+
}
|
|
1800
1780
|
: {}),
|
|
1801
1781
|
outcomeClass: finalized.outcomeClass,
|
|
1802
1782
|
applied,
|
|
@@ -1876,7 +1856,7 @@ export class Orchestrator {
|
|
|
1876
1856
|
// this SINGLE root.
|
|
1877
1857
|
const execRoot = this.execRootOf(input);
|
|
1878
1858
|
const projectRoot = input.repoRoot;
|
|
1879
|
-
const wsm = new WorkspaceManager(execRoot, { projectRoot });
|
|
1859
|
+
const wsm = new WorkspaceManager(execRoot, { projectRoot, runtimeRoot: runRuntimeRoot(input) });
|
|
1880
1860
|
const anchors = secretDiff.revertAnchors(execRoot, projectRoot);
|
|
1881
1861
|
store.writeYaml(join(paths.contextDir, "task.yaml"), contract);
|
|
1882
1862
|
log.emit("task.contract.created", { task_contract_hash: hashJson(contract) });
|
|
@@ -2108,17 +2088,7 @@ export class Orchestrator {
|
|
|
2108
2088
|
}, input, requestedSingleCandidate, // W-C4 deltas: single-candidate chat lane only (racing = noise x N)
|
|
2109
2089
|
undefined, undefined, harnessHome, undefined, tried);
|
|
2110
2090
|
ledger.settle(slot.lease.lease_id, attemptUsageCostSettlement(run.cost, run.costEstimated, run.attemptId, run.harnessId, run.telemetry.authMode, run.telemetry.usageCost));
|
|
2111
|
-
log.emit("harness.completed",
|
|
2112
|
-
harness_id: adapter.id,
|
|
2113
|
-
attempt_id: slot.attemptId,
|
|
2114
|
-
// QA-027: never claim `success` over an attempt the operator/deadline
|
|
2115
|
-
// cut short. An abort makes the run non-successful; the top-level
|
|
2116
|
-
// status axis must say `cancelled` (the nested outcome axis already
|
|
2117
|
-
// rides in telemetrySummary), not launder a torn-off stream as clean.
|
|
2118
|
-
status: input.signal?.aborted ? "cancelled" : run.errored ? "failed" : "success",
|
|
2119
|
-
cost_usd: run.cost,
|
|
2120
|
-
...telemetrySummary(run.telemetry),
|
|
2121
|
-
});
|
|
2091
|
+
log.emit("harness.completed", candidateCompletion(run, input.signal));
|
|
2122
2092
|
// D-16d one-shot continuation for an ENVELOPED candidate (parity with the
|
|
2123
2093
|
// read-only loop, which had the ONLY continuation wiring). An eligible
|
|
2124
2094
|
// terminal context exhaustion (repeated_refill, no completed report) gets
|
|
@@ -2187,21 +2157,18 @@ export class Orchestrator {
|
|
|
2187
2157
|
return true;
|
|
2188
2158
|
}, input, requestedSingleCandidate, undefined, packet.pointerLine ?? undefined, harnessHome, undefined, contTried);
|
|
2189
2159
|
ledger.settle(contLeaseId, attemptUsageCostSettlement(contRun.cost, contRun.costEstimated, contRun.attemptId, contRun.harnessId, contRun.telemetry.authMode, contRun.telemetry.usageCost));
|
|
2190
|
-
log.emit("harness.completed",
|
|
2191
|
-
harness_id: adapter.id,
|
|
2192
|
-
attempt_id: contAttemptId,
|
|
2193
|
-
status: input.signal?.aborted
|
|
2194
|
-
? "cancelled"
|
|
2195
|
-
: contRun.errored
|
|
2196
|
-
? "failed"
|
|
2197
|
-
: "success",
|
|
2198
|
-
cost_usd: contRun.cost,
|
|
2199
|
-
...telemetrySummary(contRun.telemetry),
|
|
2200
|
-
});
|
|
2160
|
+
log.emit("harness.completed", candidateCompletion(contRun, input.signal));
|
|
2201
2161
|
// Supersede the exhausted candidate ONLY after the continuation
|
|
2202
2162
|
// actually completes cleanly (never over a torn-off/aborted stream).
|
|
2203
2163
|
if (!contRun.errored && !input.signal?.aborted)
|
|
2204
2164
|
effectiveRun = contRun;
|
|
2165
|
+
// A refused capture is errored: the original keeps leading, and
|
|
2166
|
+
// the copy they share stays kept under the continuation's receipt.
|
|
2167
|
+
if (contRun.captureRefusal)
|
|
2168
|
+
effectiveRun.continuationRefusal = {
|
|
2169
|
+
attemptId: contRun.attemptId,
|
|
2170
|
+
refusal: contRun.captureRefusal,
|
|
2171
|
+
};
|
|
2205
2172
|
}
|
|
2206
2173
|
catch (err) {
|
|
2207
2174
|
ledger.settle(contLeaseId, AC.attemptFailureCost(err, "continuation-error", 0).settlement);
|
|
@@ -2263,7 +2230,7 @@ export class Orchestrator {
|
|
|
2263
2230
|
// Keep a TYPED pre-spawn refusal (spent quota window + its reset)
|
|
2264
2231
|
// alive past this catch; `message` alone would force the terminal to
|
|
2265
2232
|
// read prose back out.
|
|
2266
|
-
...(declared.code ? { declaredFailure: declared } : {}),
|
|
2233
|
+
...(declared.code || declared.quotaRefusal ? { declaredFailure: declared } : {}),
|
|
2267
2234
|
applied: appliedAttemptFacts(harnessHome, slot.routed.adapterAccess, this.credentials.effectiveProfileId(input, adapter.id)),
|
|
2268
2235
|
};
|
|
2269
2236
|
}
|
|
@@ -2311,18 +2278,17 @@ export class Orchestrator {
|
|
|
2311
2278
|
: undefined,
|
|
2312
2279
|
signal: input.signal,
|
|
2313
2280
|
});
|
|
2314
|
-
// Revert divergence fence for the single-candidate in-place path
|
|
2315
|
-
// candidate mutated the LIVE tree
|
|
2316
|
-
//
|
|
2317
|
-
//
|
|
2318
|
-
//
|
|
2319
|
-
// into the revert target and let a later revert clobber them.
|
|
2281
|
+
// Revert divergence fence for the single-candidate in-place path.
|
|
2282
|
+
// The candidate mutated the LIVE tree above. Snapshot NOW, before slow
|
|
2283
|
+
// review/synthesis/arbitration, or later user edits enter the revert target
|
|
2284
|
+
// and a revert can clobber them. The race-adoption path snapshots later.
|
|
2285
|
+
// No change, no fence.
|
|
2320
2286
|
let earlyPostTurnSha = null;
|
|
2321
2287
|
if (mutatingRun &&
|
|
2322
2288
|
input.workspaceKind !== "directory" &&
|
|
2323
2289
|
input.inPlace &&
|
|
2324
2290
|
requestedSingleCandidate &&
|
|
2325
|
-
runs
|
|
2291
|
+
needsPostTurnFence(runs)) {
|
|
2326
2292
|
try {
|
|
2327
2293
|
earlyPostTurnSha = await snapshotTree(execRoot);
|
|
2328
2294
|
}
|
|
@@ -2334,7 +2300,7 @@ export class Orchestrator {
|
|
|
2334
2300
|
await disposeReviewEnvelopes();
|
|
2335
2301
|
return cancelledRaceResult();
|
|
2336
2302
|
}
|
|
2337
|
-
const failedDelegation = delegateFailure.dominantRaceCandidateFailure(runs);
|
|
2303
|
+
const failedDelegation = delegateFailure.dominantRaceCandidateFailure(runs, input);
|
|
2338
2304
|
if (failedDelegation) {
|
|
2339
2305
|
await disposeReviewEnvelopes();
|
|
2340
2306
|
const failedOutput = {
|
|
@@ -2360,7 +2326,7 @@ export class Orchestrator {
|
|
|
2360
2326
|
budgetDenial,
|
|
2361
2327
|
...(mutatingRun ? { liveCapture: failedOutput } : {}),
|
|
2362
2328
|
});
|
|
2363
|
-
const failure = delegateFailure.candidateFailureTerminal(failedDelegation, "race");
|
|
2329
|
+
const failure = delegateFailure.candidateFailureTerminal(failedDelegation, "race", runs);
|
|
2364
2330
|
if (mutatingRun)
|
|
2365
2331
|
await delegateFailure.persistFailedCandidateOutput(failedOutput);
|
|
2366
2332
|
raceTerminal.writeTelemetry();
|
|
@@ -2768,6 +2734,7 @@ export class Orchestrator {
|
|
|
2768
2734
|
if (inPlaceWinner && requestedSingleCandidate && adopted === true) {
|
|
2769
2735
|
revertAnchorId = await anchors.turn(preTurnSha, postTurnSha);
|
|
2770
2736
|
}
|
|
2737
|
+
const capturedNoGitChange = capturedNoGitChangeValue(winnerRun);
|
|
2771
2738
|
store.writeYaml(join(paths.finalDir, "work_product.yaml"), {
|
|
2772
2739
|
id: newId("wp"),
|
|
2773
2740
|
kind: input.create === true ? "new_repo" : "patch",
|
|
@@ -2787,6 +2754,7 @@ export class Orchestrator {
|
|
|
2787
2754
|
budget_stopped: budgetStopped,
|
|
2788
2755
|
...{ patch_sha256: patchSha256, ...savedPatch.meta },
|
|
2789
2756
|
result_kind: resultKind,
|
|
2757
|
+
...(capturedNoGitChange !== null ? { capturedNoGitChange } : {}),
|
|
2790
2758
|
diffstat: {
|
|
2791
2759
|
files: wstats.paths.length,
|
|
2792
2760
|
additions: wstats.additions,
|
|
@@ -2802,7 +2770,7 @@ export class Orchestrator {
|
|
|
2802
2770
|
},
|
|
2803
2771
|
});
|
|
2804
2772
|
}
|
|
2805
|
-
store.writeText(join(paths.finalDir, "summary.md"), withPoolAttempts(renderSummary(runId, mode, { ...result.decision, facts }, evidences, synth.reason, actualReviewVerified,
|
|
2773
|
+
store.writeText(join(paths.finalDir, "summary.md"), withPoolAttempts(renderSummary(runId, mode, { ...result.decision, facts }, evidences, synth.reason, actualReviewVerified, delegateFailure.raceSummaryDisclosure(winnerRun, runs)), racePool()));
|
|
2806
2774
|
// summary.md is a DIAGNOSTIC artifact only (V8/PLAN addendum 2): it no
|
|
2807
2775
|
// longer carries primary-output authority. A clean applyable success or a
|
|
2808
2776
|
// winner answer still marks it ready for legacy INV-116 ordering; any
|
|
@@ -2829,12 +2797,15 @@ export class Orchestrator {
|
|
|
2829
2797
|
const needsDecisionTerminal = facts.review === "blocked" || facts.checks === "failed";
|
|
2830
2798
|
const isFailureTerminal = facts.lifecycle !== "succeeded" || needsDecisionTerminal;
|
|
2831
2799
|
const pool = racePool();
|
|
2800
|
+
// Beside whichever failure record leads, a source another attempt kept stays named.
|
|
2801
|
+
const keptSources = candidateCaptureRefusals(runs).flatMap(secretDiff.captureInspectionActions);
|
|
2832
2802
|
if (deliveryFailureReason && !finalVerifyFailed) {
|
|
2833
2803
|
const refused = deliveryRefusalFailure(deliveryFailureReason, paths.root);
|
|
2834
2804
|
writeFailure(store, paths, {
|
|
2835
2805
|
...refused,
|
|
2836
2806
|
safeMessage: withPoolAttempts(refused.safeMessage, pool),
|
|
2837
2807
|
poolAttempts: pool,
|
|
2808
|
+
nextActions: [...refused.nextActions, ...keptSources],
|
|
2838
2809
|
});
|
|
2839
2810
|
}
|
|
2840
2811
|
else if (finalVerifyFailed) {
|
|
@@ -2848,15 +2819,18 @@ export class Orchestrator {
|
|
|
2848
2819
|
: `final verify failed: ${finalVerify?.reason ?? (finalVerify?.gates_passed === false ? "deterministic gates failed on the fresh verify tree" : "unknown")}`, pool),
|
|
2849
2820
|
poolAttempts: pool,
|
|
2850
2821
|
runDir: paths.root,
|
|
2851
|
-
nextActions:
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2822
|
+
nextActions: [
|
|
2823
|
+
...(finalVerify?.applied_cleanly === null
|
|
2824
|
+
? [
|
|
2825
|
+
"Inspect arbitration/decision.yaml (final_verify) for the verifier error",
|
|
2826
|
+
"Fix the verify infrastructure (git worktree/tmp) and re-run, or accept_risk to override",
|
|
2827
|
+
]
|
|
2828
|
+
: [
|
|
2829
|
+
"Inspect arbitration/decision.yaml (final_verify)",
|
|
2830
|
+
"Re-run after fixing the base conflict or the failing gates",
|
|
2831
|
+
]),
|
|
2832
|
+
...keptSources,
|
|
2833
|
+
],
|
|
2860
2834
|
});
|
|
2861
2835
|
}
|
|
2862
2836
|
else if (isFailureTerminal) {
|
|
@@ -2888,19 +2862,23 @@ export class Orchestrator {
|
|
|
2888
2862
|
? `attempts/${winnerRun.attemptId}/attempt.yaml`
|
|
2889
2863
|
: undefined,
|
|
2890
2864
|
runDir: paths.root,
|
|
2891
|
-
nextActions:
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2865
|
+
nextActions: [
|
|
2866
|
+
...(decisionBlock
|
|
2867
|
+
? [
|
|
2868
|
+
"Review the blocking findings on the run's turn",
|
|
2869
|
+
"Accept the risk to apply this exact patch, or discard the change",
|
|
2870
|
+
...(facts.checks === "failed"
|
|
2871
|
+
? ["Configure/approve the deterministic test command, then re-run"]
|
|
2872
|
+
: []),
|
|
2873
|
+
]
|
|
2874
|
+
: [
|
|
2875
|
+
"Open diagnostics",
|
|
2876
|
+
"Inspect candidate artifacts",
|
|
2877
|
+
"Retry with a narrower prompt or different harness pool",
|
|
2878
|
+
]),
|
|
2879
|
+
...keptSources,
|
|
2880
|
+
],
|
|
2881
|
+
...(decisionBlock ? {} : erroredWinnerFailure(winnerRun, keptSources)),
|
|
2904
2882
|
});
|
|
2905
2883
|
if (!winnerRun) {
|
|
2906
2884
|
store.writeText(join(paths.finalDir, "summary.md"), `# Run ${runId} (${mode})\n\n- Lifecycle: ${facts.lifecycle}${facts.reason ? ` (${facts.reason})` : ""}\n- Phase: arbitration\n\n${withPoolAttempts(result.decision.why_winner, pool)}\n`);
|
|
@@ -3056,7 +3034,10 @@ export class Orchestrator {
|
|
|
3056
3034
|
// local `execRoot`; this path previously ensured the boundary on repoRoot,
|
|
3057
3035
|
// which for an isolated thread is the project, not the mutated worktree.
|
|
3058
3036
|
const execRoot = this.execRootOf(input);
|
|
3059
|
-
const wsm = new WorkspaceManager(execRoot, {
|
|
3037
|
+
const wsm = new WorkspaceManager(execRoot, {
|
|
3038
|
+
projectRoot: input.repoRoot,
|
|
3039
|
+
runtimeRoot: runRuntimeRoot(input),
|
|
3040
|
+
});
|
|
3060
3041
|
const anchors = secretDiff.revertAnchors(execRoot, input.repoRoot);
|
|
3061
3042
|
const readiness = new ReadinessLedger();
|
|
3062
3043
|
store.writeYaml(join(paths.contextDir, "task.yaml"), contract);
|
|
@@ -3172,7 +3153,7 @@ export class Orchestrator {
|
|
|
3172
3153
|
let converged = false;
|
|
3173
3154
|
let exhausted = false;
|
|
3174
3155
|
let processingBudgetDenial = null;
|
|
3175
|
-
let interrupted =
|
|
3156
|
+
let interrupted = null; // D-16 r8, #299
|
|
3176
3157
|
let lastFindings = [];
|
|
3177
3158
|
let lastRun = null;
|
|
3178
3159
|
const convergenceRuns = [];
|
|
@@ -3323,18 +3304,17 @@ export class Orchestrator {
|
|
|
3323
3304
|
costEstimated: failureCost.estimated,
|
|
3324
3305
|
errors: [message],
|
|
3325
3306
|
poolAttempts: tried.snapshot(),
|
|
3326
|
-
...(declared.code ? { declaredFailure: declared } : {}),
|
|
3307
|
+
...(declared.code || declared.quotaRefusal ? { declaredFailure: declared } : {}),
|
|
3327
3308
|
telemetry: createAttemptTelemetry(knobs.webPolicy, contract.external_context.web_required, effectiveWeb, [routed.browserRequirement, routed.denyRequirement, routed.delegationRequirement], knobs.model),
|
|
3328
3309
|
};
|
|
3329
3310
|
if (envelope.workspace_kind === "directory") {
|
|
3330
|
-
|
|
3311
|
+
({ files: run.files, refusal: run.captureRefusal } = await captureDirectoryCandidate({
|
|
3331
3312
|
manager: wsm,
|
|
3332
3313
|
envelope,
|
|
3333
3314
|
artifactRoot: join(paths.attemptsDir, attemptId),
|
|
3334
3315
|
observedPaths: [...observedPaths],
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
run.captureRefusal = captured.refusal;
|
|
3316
|
+
holder: { runId: paths.runId, runDir: paths.root },
|
|
3317
|
+
}));
|
|
3338
3318
|
}
|
|
3339
3319
|
}
|
|
3340
3320
|
lastRun = run;
|
|
@@ -3342,12 +3322,12 @@ export class Orchestrator {
|
|
|
3342
3322
|
// Fail-closed twin of the candidate lane's gate: this loop terminalizes
|
|
3343
3323
|
// per attempt, so the proof is spent per attempt.
|
|
3344
3324
|
assertDelegatedEvidence(input.delegated === true, convergenceAccess, [run]);
|
|
3345
|
-
attemptTelemetries.push({ attemptId, harnessId: adapter.id,
|
|
3325
|
+
attemptTelemetries.push({ attemptId, harnessId: adapter.id, ...pickTelemetry(run) });
|
|
3346
3326
|
lastPostTurnSha = null;
|
|
3347
3327
|
// Post-mutation fence for in-place: snapshot the live tree NOW (after the
|
|
3348
3328
|
// harness mutated it, before this attempt's review). The last attempt's
|
|
3349
|
-
// value is the revert target persisted into work_product.yaml.
|
|
3350
|
-
if (input.inPlace
|
|
3329
|
+
// value is the revert target persisted into work_product.yaml (an unchanged one has none).
|
|
3330
|
+
if (input.inPlace && input.workspaceKind !== "directory" && needsPostTurnFence([run])) {
|
|
3351
3331
|
try {
|
|
3352
3332
|
lastPostTurnSha = await snapshotTree(execRoot);
|
|
3353
3333
|
}
|
|
@@ -3367,8 +3347,7 @@ export class Orchestrator {
|
|
|
3367
3347
|
exhausted = true;
|
|
3368
3348
|
break;
|
|
3369
3349
|
}
|
|
3370
|
-
if (run
|
|
3371
|
-
run.telemetry.effortResolution?.resolution === "rejected")
|
|
3350
|
+
if (endsConvergence(run))
|
|
3372
3351
|
break;
|
|
3373
3352
|
if (delegateFailure.candidateFailureKind(run)) {
|
|
3374
3353
|
const failure = delegateFailure.candidateFailureTerminal(run, "convergence");
|
|
@@ -3399,7 +3378,7 @@ export class Orchestrator {
|
|
|
3399
3378
|
// D-16 r8: interrupted (errored===false) would CONVERGE a partial diff
|
|
3400
3379
|
// as clean — break BEFORE review; a harness error still gate-retries.
|
|
3401
3380
|
if (run.outcomeClass === "interrupted") {
|
|
3402
|
-
interrupted =
|
|
3381
|
+
interrupted = interruptionOf(run);
|
|
3403
3382
|
break;
|
|
3404
3383
|
}
|
|
3405
3384
|
// The review round is wrapped so a preflight/revalidation throw ends the
|
|
@@ -3469,7 +3448,8 @@ export class Orchestrator {
|
|
|
3469
3448
|
converged = true;
|
|
3470
3449
|
break;
|
|
3471
3450
|
}
|
|
3472
|
-
const
|
|
3451
|
+
const refusal = correctableRefusal(run); // INV-047: a refused patch has no result
|
|
3452
|
+
const requiredGateFailing = !refusal && run.gates.length > 0 && !gatesPassed(run.gates);
|
|
3473
3453
|
const diffHash = run.files
|
|
3474
3454
|
? run.files.manifestSha256
|
|
3475
3455
|
: input.workspaceKind === "directory"
|
|
@@ -3478,7 +3458,7 @@ export class Orchestrator {
|
|
|
3478
3458
|
if (requiredGateFailing && diffHash !== null && diffHash === lastFailingGateDiffHash) {
|
|
3479
3459
|
sameFailingGateDiffs += 1;
|
|
3480
3460
|
}
|
|
3481
|
-
else {
|
|
3461
|
+
else if (!refusal) {
|
|
3482
3462
|
sameFailingGateDiffs = requiredGateFailing ? 1 : 0;
|
|
3483
3463
|
lastFailingGateDiffHash = requiredGateFailing ? (diffHash ?? "") : "";
|
|
3484
3464
|
}
|
|
@@ -3496,11 +3476,9 @@ export class Orchestrator {
|
|
|
3496
3476
|
});
|
|
3497
3477
|
break;
|
|
3498
3478
|
}
|
|
3499
|
-
const
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
]);
|
|
3503
|
-
readiness.recordRound(sig, conv.reasons.join("; "));
|
|
3479
|
+
const manifest = run.files ? [`files_manifest:${run.files.manifestSha256}`] : [];
|
|
3480
|
+
const sig = refusal ?? failureSignature([...conv.reasons, ...manifest]);
|
|
3481
|
+
readiness.recordRound(sig, refusal ?? conv.reasons.join("; "));
|
|
3504
3482
|
if (sig !== lastSig) {
|
|
3505
3483
|
triedSinceProgress = new Set();
|
|
3506
3484
|
lastSig = sig;
|
|
@@ -3681,6 +3659,7 @@ export class Orchestrator {
|
|
|
3681
3659
|
: "applied_review_blocked"
|
|
3682
3660
|
: "not_applied";
|
|
3683
3661
|
const revertAnchorId = convAdopted === true ? await anchors.turn(preTurnSha, lastPostTurnSha) : null;
|
|
3662
|
+
const capturedNoGitChange = capturedNoGitChangeValue(lastRun);
|
|
3684
3663
|
store.writeYaml(join(paths.finalDir, "work_product.yaml"), {
|
|
3685
3664
|
id: newId("wp"),
|
|
3686
3665
|
kind: "patch",
|
|
@@ -3689,6 +3668,7 @@ export class Orchestrator {
|
|
|
3689
3668
|
meta: {
|
|
3690
3669
|
harness_id: lastRun.harnessId,
|
|
3691
3670
|
result_kind: "patch",
|
|
3671
|
+
...(capturedNoGitChange !== null ? { capturedNoGitChange } : {}),
|
|
3692
3672
|
mode,
|
|
3693
3673
|
attempts: attempt,
|
|
3694
3674
|
lifecycle: facts.lifecycle,
|
|
@@ -4087,6 +4067,8 @@ export class Orchestrator {
|
|
|
4087
4067
|
if (outcome.status !== "success") {
|
|
4088
4068
|
if (outcome.telemetry?.effortResolution?.resolution === "rejected")
|
|
4089
4069
|
break;
|
|
4070
|
+
if (outcome.telemetry?.turnLimitReached)
|
|
4071
|
+
break; // #299: the cap ends the run
|
|
4090
4072
|
const next = adapters[idx + 1];
|
|
4091
4073
|
if (next && !input.signal?.aborted) {
|
|
4092
4074
|
fallbackFrom = outcome.harnessId;
|
|
@@ -4556,7 +4538,8 @@ export class Orchestrator {
|
|
|
4556
4538
|
report: "",
|
|
4557
4539
|
error: message,
|
|
4558
4540
|
telemetry,
|
|
4559
|
-
|
|
4541
|
+
// A typed pre-spawn refusal, a provider refusal with no code of its own included (#558).
|
|
4542
|
+
...(declaredFailureSpeaks(preDeclared) ? { declaredFailure: preDeclared } : {}),
|
|
4560
4543
|
});
|
|
4561
4544
|
attemptTelemetries.push({ attemptId, harnessId: adapter.id, telemetry });
|
|
4562
4545
|
if (opts.deepScan) {
|
|
@@ -4664,7 +4647,7 @@ export class Orchestrator {
|
|
|
4664
4647
|
// the loudest) — same single owner as the agent loop.
|
|
4665
4648
|
observeBudgetSignals(ledger, log, adapter.id, attemptId, ev, budgetSignalState);
|
|
4666
4649
|
this.deps.quotaEventSink?.(adapter.id, ev);
|
|
4667
|
-
const spend =
|
|
4650
|
+
const spend = observeUsageSpend(ev, (t, p) => log.emit(t, p), adapter.id, attemptId, telemetry.usageCost);
|
|
4668
4651
|
cost += spend.costUsd;
|
|
4669
4652
|
costEstimated ||= spend.estimated;
|
|
4670
4653
|
const streamDenial = updateProcessingStreamHold(runSpec, telemetry.usageCost, ledger, lease.lease.lease_id, adapter.id, attemptId);
|
|
@@ -4692,8 +4675,6 @@ export class Orchestrator {
|
|
|
4692
4675
|
if (!recordAdapterThrow(telemetry, err))
|
|
4693
4676
|
break;
|
|
4694
4677
|
}
|
|
4695
|
-
if (telemetry.requestRefusal)
|
|
4696
|
-
break;
|
|
4697
4678
|
const newTransients = telemetry.transientFailures.slice(transientStart);
|
|
4698
4679
|
const sawRetryable = newTransients.some((f) => f.retryable);
|
|
4699
4680
|
const sawTypedLimit = telemetry.rateLimits.length > rateLimitStart;
|
|
@@ -4755,7 +4736,7 @@ export class Orchestrator {
|
|
|
4755
4736
|
attemptTelemetries.push({ attemptId, harnessId: adapter.id, telemetry });
|
|
4756
4737
|
// D-16: the deliverable is the report. A3: an errored attempt with no
|
|
4757
4738
|
// typed final contributes no report material (acceptedTryOutput).
|
|
4758
|
-
const roUnwrapped =
|
|
4739
|
+
const roUnwrapped = unwrapAttemptAnswer(acceptedTryOutput(answer, harnessError !== null), harnessError !== null && !answer.hasFinal(), readonlyWorkMode, { sideToolReport: telemetry.sideToolWorkReport ?? undefined });
|
|
4759
4740
|
// Trim symmetrically with the plan path: a whitespace-only answer is not
|
|
4760
4741
|
// a delivered report (the final-artifact wrapper heading would otherwise
|
|
4761
4742
|
// make it read as present content by construction).
|
|
@@ -4774,7 +4755,7 @@ export class Orchestrator {
|
|
|
4774
4755
|
workReportSource: roUnwrapped.source,
|
|
4775
4756
|
workReportViolation: roUnwrapped.contractViolation,
|
|
4776
4757
|
workReportUnverified: roUnwrapped.unverified ?? null,
|
|
4777
|
-
|
|
4758
|
+
interruption: attemptInterruption(telemetry),
|
|
4778
4759
|
});
|
|
4779
4760
|
// A broken WorkReport contract is a hard failure ONLY when the finalizer
|
|
4780
4761
|
// ranked it so — a concurrent terminal context exhaustion outranks it
|
|
@@ -4845,9 +4826,8 @@ export class Orchestrator {
|
|
|
4845
4826
|
harnessId: adapter.id,
|
|
4846
4827
|
status: scoutInterrupted ? "failed" : "success",
|
|
4847
4828
|
report: report || "(no output)",
|
|
4848
|
-
error: scoutInterrupted ?
|
|
4829
|
+
error: scoutInterrupted ? interruptionDetail(roFinalized.reason) : null,
|
|
4849
4830
|
telemetry,
|
|
4850
|
-
...(scoutInterrupted ? { interrupted: true } : {}),
|
|
4851
4831
|
...continuity.terminalFacts(roResumable),
|
|
4852
4832
|
});
|
|
4853
4833
|
launched.delete(tried);
|
|
@@ -4858,7 +4838,7 @@ export class Orchestrator {
|
|
|
4858
4838
|
.join("; ")}\n`
|
|
4859
4839
|
: "";
|
|
4860
4840
|
const scoutTag = scoutInterrupted
|
|
4861
|
-
?
|
|
4841
|
+
? ` interrupted (${interruptionDetail(roFinalized.reason)})`
|
|
4862
4842
|
: ` (${adapter.id})`;
|
|
4863
4843
|
store.writeText(join(paths.findingsDir, `${attemptId}${scoutInterrupted ? "-interrupted" : ""}.md`), `# Explorer ${attemptId}${scoutTag}\n\n${report || "(no output)"}${warningNote}\n`);
|
|
4864
4844
|
}
|
|
@@ -4936,12 +4916,13 @@ export class Orchestrator {
|
|
|
4936
4916
|
if (last?.telemetry.effortResolution?.resolution === "rejected")
|
|
4937
4917
|
break;
|
|
4938
4918
|
// Per-harness fallback_model: one same-harness retry on FAILURE (not
|
|
4939
|
-
// policy blocks
|
|
4919
|
+
// policy blocks or the caller's max-turns cap, #299) before the next harness.
|
|
4940
4920
|
const fallbackModel = routed.settings?.fallbackModel;
|
|
4941
4921
|
const firstModel = contract.routing_models[routed.adapter.id] ?? routed.settings?.defaultModel ?? null;
|
|
4942
4922
|
if (last &&
|
|
4943
4923
|
last.status === "failed" &&
|
|
4944
4924
|
!last.telemetry.requestRefusal &&
|
|
4925
|
+
!last.telemetry.turnLimitReached &&
|
|
4945
4926
|
fallbackModel &&
|
|
4946
4927
|
fallbackModel !== firstModel &&
|
|
4947
4928
|
!budgetStopped &&
|