@kbediako/codex-orchestrator 0.1.37 → 0.2.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/.agents/plugins/marketplace.json +20 -0
- package/README.md +73 -291
- package/bin/codex-orchestrator.js +161 -0
- package/codex.orchestrator.json +149 -13
- package/dist/bin/codex-orchestrator.js +795 -1154
- package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +22 -4
- package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +3 -3
- package/dist/orchestrator/src/cli/adapters/CommandTester.js +2 -2
- package/dist/orchestrator/src/cli/adapters/cloudFailureDiagnostics.js +183 -11
- package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
- package/dist/orchestrator/src/cli/coStatusCliShell.js +429 -0
- package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
- package/dist/orchestrator/src/cli/codexCliShell.js +72 -0
- package/dist/orchestrator/src/cli/codexDefaultsSetup.js +49 -11
- package/dist/orchestrator/src/cli/config/delegationConfig.js +317 -5
- package/dist/orchestrator/src/cli/config/repoConfigPolicy.js +2 -3
- package/dist/orchestrator/src/cli/config/userConfig.js +28 -13
- package/dist/orchestrator/src/cli/control/authenticatedControlRouteGate.js +69 -0
- package/dist/orchestrator/src/cli/control/authenticatedRouteComposition.js +267 -0
- package/dist/orchestrator/src/cli/control/authenticatedRouteController.js +5 -0
- package/dist/orchestrator/src/cli/control/authenticatedRouteDispatcher.js +41 -0
- package/dist/orchestrator/src/cli/control/compatibilityIssuePresenter.js +1035 -0
- package/dist/orchestrator/src/cli/control/confirmationApproveController.js +62 -0
- package/dist/orchestrator/src/cli/control/confirmationCreateController.js +69 -0
- package/dist/orchestrator/src/cli/control/confirmationIssueConsumeController.js +43 -0
- package/dist/orchestrator/src/cli/control/confirmationListController.js +22 -0
- package/dist/orchestrator/src/cli/control/confirmationValidateController.js +58 -0
- package/dist/orchestrator/src/cli/control/confirmations.js +25 -3
- package/dist/orchestrator/src/cli/control/controlActionCancelConfirmation.js +65 -0
- package/dist/orchestrator/src/cli/control/controlActionController.js +77 -0
- package/dist/orchestrator/src/cli/control/controlActionControllerSequencing.js +161 -0
- package/dist/orchestrator/src/cli/control/controlActionExecution.js +142 -0
- package/dist/orchestrator/src/cli/control/controlActionFinalization.js +43 -0
- package/dist/orchestrator/src/cli/control/controlActionOutcome.js +60 -0
- package/dist/orchestrator/src/cli/control/controlActionPreflight.js +476 -0
- package/dist/orchestrator/src/cli/control/controlAuthenticatedRouteHandoff.js +57 -0
- package/dist/orchestrator/src/cli/control/controlBootstrapAssembly.js +39 -0
- package/dist/orchestrator/src/cli/control/controlBootstrapMetadataPersistence.js +16 -0
- package/dist/orchestrator/src/cli/control/controlEventTransport.js +49 -0
- package/dist/orchestrator/src/cli/control/controlExpiryLifecycle.js +102 -0
- package/dist/orchestrator/src/cli/control/controlHostOwnership.js +480 -0
- package/dist/orchestrator/src/cli/control/controlHostSupervision.js +608 -0
- package/dist/orchestrator/src/cli/control/controlOversightFacade.js +8 -0
- package/dist/orchestrator/src/cli/control/controlOversightReadContract.js +1 -0
- package/dist/orchestrator/src/cli/control/controlOversightReadService.js +16 -0
- package/dist/orchestrator/src/cli/control/controlOversightUpdateContract.js +1 -0
- package/dist/orchestrator/src/cli/control/controlPersistenceFiles.js +6 -0
- package/dist/orchestrator/src/cli/control/controlQuestionChildResolution.js +18 -0
- package/dist/orchestrator/src/cli/control/controlRequestContext.js +42 -0
- package/dist/orchestrator/src/cli/control/controlRequestController.js +9 -0
- package/dist/orchestrator/src/cli/control/controlRequestPredispatch.js +17 -0
- package/dist/orchestrator/src/cli/control/controlRequestRouteDispatch.js +44 -0
- package/dist/orchestrator/src/cli/control/controlRuntime.js +992 -0
- package/dist/orchestrator/src/cli/control/controlServer.js +23 -1456
- package/dist/orchestrator/src/cli/control/controlServerAuditAndErrorHelpers.js +115 -0
- package/dist/orchestrator/src/cli/control/controlServerAuthenticatedRouteBranch.js +29 -0
- package/dist/orchestrator/src/cli/control/controlServerBootstrapLifecycle.js +30 -0
- package/dist/orchestrator/src/cli/control/controlServerBootstrapStartSequence.js +21 -0
- package/dist/orchestrator/src/cli/control/controlServerOwnedRuntimeLifecycle.js +67 -0
- package/dist/orchestrator/src/cli/control/controlServerPublicLifecycle.js +756 -0
- package/dist/orchestrator/src/cli/control/controlServerPublicRouteHelpers.js +86 -0
- package/dist/orchestrator/src/cli/control/controlServerReadyInstanceLifecycle.js +25 -0
- package/dist/orchestrator/src/cli/control/controlServerReadyInstanceStartup.js +18 -0
- package/dist/orchestrator/src/cli/control/controlServerRequestBodyHelpers.js +37 -0
- package/dist/orchestrator/src/cli/control/controlServerRequestShell.js +40 -0
- package/dist/orchestrator/src/cli/control/controlServerRequestShellBinding.js +17 -0
- package/dist/orchestrator/src/cli/control/controlServerSeedLoading.js +27 -0
- package/dist/orchestrator/src/cli/control/controlServerSeededRuntimeAssembly.js +186 -0
- package/dist/orchestrator/src/cli/control/controlServerStartupInputPreparation.js +31 -0
- package/dist/orchestrator/src/cli/control/controlServerStartupSequence.js +49 -0
- package/dist/orchestrator/src/cli/control/controlState.js +233 -2
- package/dist/orchestrator/src/cli/control/controlStatusDashboard.js +1899 -0
- package/dist/orchestrator/src/cli/control/controlTelegramBridgeBootstrapLifecycle.js +22 -0
- package/dist/orchestrator/src/cli/control/controlTelegramBridgeLifecycle.js +67 -0
- package/dist/orchestrator/src/cli/control/controlTelegramBridgeOversightFacadeFactory.js +8 -0
- package/dist/orchestrator/src/cli/control/controlTelegramCommandController.js +49 -0
- package/dist/orchestrator/src/cli/control/controlTelegramDispatchRead.js +40 -0
- package/dist/orchestrator/src/cli/control/controlTelegramPollingController.js +89 -0
- package/dist/orchestrator/src/cli/control/controlTelegramProjectionNotificationController.js +29 -0
- package/dist/orchestrator/src/cli/control/controlTelegramPushState.js +63 -0
- package/dist/orchestrator/src/cli/control/controlTelegramQuestionRead.js +13 -0
- package/dist/orchestrator/src/cli/control/controlTelegramReadController.js +216 -0
- package/dist/orchestrator/src/cli/control/controlTelegramUpdateHandler.js +63 -0
- package/dist/orchestrator/src/cli/control/controlWatcher.js +73 -5
- package/dist/orchestrator/src/cli/control/delegationRegisterController.js +35 -0
- package/dist/orchestrator/src/cli/control/dynamicToolBridgePolicy.js +139 -0
- package/dist/orchestrator/src/cli/control/eventsSseController.js +12 -0
- package/dist/orchestrator/src/cli/control/linearBudgetState.js +1789 -0
- package/dist/orchestrator/src/cli/control/linearDispatchSource.js +1137 -0
- package/dist/orchestrator/src/cli/control/linearGraphqlClient.js +150 -0
- package/dist/orchestrator/src/cli/control/linearRateLimit.js +102 -0
- package/dist/orchestrator/src/cli/control/linearWebhookController.js +499 -0
- package/dist/orchestrator/src/cli/control/liveLinearAdvisoryRuntime.js +70 -0
- package/dist/orchestrator/src/cli/control/observabilityApiController.js +173 -0
- package/dist/orchestrator/src/cli/control/observabilityReadModel.js +500 -0
- package/dist/orchestrator/src/cli/control/observabilitySurface.js +284 -0
- package/dist/orchestrator/src/cli/control/observabilityUpdateNotifier.js +22 -0
- package/dist/orchestrator/src/cli/control/operatorDashboardPresenter.js +252 -0
- package/dist/orchestrator/src/cli/control/providerAgentCapacity.js +70 -0
- package/dist/orchestrator/src/cli/control/providerControlHostFreshnessGauge.js +1068 -0
- package/dist/orchestrator/src/cli/control/providerIntakeState.js +473 -0
- package/dist/orchestrator/src/cli/control/providerIssueHandoff.js +6811 -0
- package/dist/orchestrator/src/cli/control/providerIssueObservability.js +1348 -0
- package/dist/orchestrator/src/cli/control/providerIssueRetryQueue.js +84 -0
- package/dist/orchestrator/src/cli/control/providerLinearRuntimeProof.js +588 -0
- package/dist/orchestrator/src/cli/control/providerLinearScreenshotProof.js +473 -0
- package/dist/orchestrator/src/cli/control/providerLinearWorkerTruth.js +383 -0
- package/dist/orchestrator/src/cli/control/providerLinearWorkflowAudit.js +254 -0
- package/dist/orchestrator/src/cli/control/providerLinearWorkflowFacade.js +5573 -0
- package/dist/orchestrator/src/cli/control/providerLinearWorkflowStates.js +115 -0
- package/dist/orchestrator/src/cli/control/providerMergeCloseout.js +1868 -0
- package/dist/orchestrator/src/cli/control/providerOperatorAutopilot.js +1580 -0
- package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLifecycle.js +154 -0
- package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLocalRolloutExecution.js +1006 -0
- package/dist/orchestrator/src/cli/control/providerPollingHealth.js +435 -0
- package/dist/orchestrator/src/cli/control/providerTerminalCleanup.js +516 -0
- package/dist/orchestrator/src/cli/control/providerWorkerHosts.js +191 -0
- package/dist/orchestrator/src/cli/control/providerWorkflowConfigStore.js +515 -0
- package/dist/orchestrator/src/cli/control/questionChildResolutionAdapter.js +361 -0
- package/dist/orchestrator/src/cli/control/questionQueueController.js +181 -0
- package/dist/orchestrator/src/cli/control/questionReadRetryDeduplication.js +9 -0
- package/dist/orchestrator/src/cli/control/questionReadSequence.js +10 -0
- package/dist/orchestrator/src/cli/control/securityViolationController.js +27 -0
- package/dist/orchestrator/src/cli/control/selectedRunProjection.js +1838 -0
- package/dist/orchestrator/src/cli/control/telegramOversightApiClient.js +48 -0
- package/dist/orchestrator/src/cli/control/telegramOversightBridge.js +180 -0
- package/dist/orchestrator/src/cli/control/telegramOversightBridgeProjectionDeliveryQueue.js +25 -0
- package/dist/orchestrator/src/cli/control/telegramOversightBridgeRuntimeLifecycle.js +45 -0
- package/dist/orchestrator/src/cli/control/telegramOversightBridgeStateStore.js +77 -0
- package/dist/orchestrator/src/cli/control/telegramOversightControlActionApiClient.js +45 -0
- package/dist/orchestrator/src/cli/control/trackerDispatchPilot.js +439 -0
- package/dist/orchestrator/src/cli/control/uiDataController.js +34 -0
- package/dist/orchestrator/src/cli/control/uiSessionController.js +100 -0
- package/dist/orchestrator/src/cli/controlHostCliShell.js +860 -0
- package/dist/orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js +129 -0
- package/dist/orchestrator/src/cli/controlHostSupervisionCliShell.js +2127 -0
- package/dist/orchestrator/src/cli/delegationCliShell.js +62 -0
- package/dist/orchestrator/src/cli/delegationServer.js +567 -678
- package/dist/orchestrator/src/cli/delegationServerCliShell.js +52 -0
- package/dist/orchestrator/src/cli/delegationServerQuestionFlowShell.js +228 -0
- package/dist/orchestrator/src/cli/delegationServerToolDispatchShell.js +411 -0
- package/dist/orchestrator/src/cli/delegationServerTransport.js +274 -0
- package/dist/orchestrator/src/cli/delegationSetup.js +51 -171
- package/dist/orchestrator/src/cli/devtoolsCliShell.js +34 -0
- package/dist/orchestrator/src/cli/doctor.js +542 -122
- package/dist/orchestrator/src/cli/doctorCliRequestShell.js +72 -0
- package/dist/orchestrator/src/cli/doctorCliShell.js +138 -0
- package/dist/orchestrator/src/cli/doctorUsage.js +136 -16
- package/dist/orchestrator/src/cli/exec/experience.js +16 -2
- package/dist/orchestrator/src/cli/exec/summary.js +3 -0
- package/dist/orchestrator/src/cli/execCliShell.js +51 -0
- package/dist/orchestrator/src/cli/flowCliRequestShell.js +44 -0
- package/dist/orchestrator/src/cli/flowCliShell.js +239 -0
- package/dist/orchestrator/src/cli/frontendTestCliRequestShell.js +80 -0
- package/dist/orchestrator/src/cli/frontendTestCliShell.js +41 -0
- package/dist/orchestrator/src/cli/init.js +1 -0
- package/dist/orchestrator/src/cli/initCliShell.js +50 -0
- package/dist/orchestrator/src/cli/linearCliShell.js +1200 -0
- package/dist/orchestrator/src/cli/mcpEnableCliShell.js +132 -0
- package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +3 -2
- package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +56 -0
- package/dist/orchestrator/src/cli/orchestrator.js +66 -1376
- package/dist/orchestrator/src/cli/planCliShell.js +19 -0
- package/dist/orchestrator/src/cli/prCliShell.js +41 -0
- package/dist/orchestrator/src/cli/providerLinearChildLanePhaseContract.js +204 -0
- package/dist/orchestrator/src/cli/providerLinearChildLaneRunner.js +1772 -0
- package/dist/orchestrator/src/cli/providerLinearChildLaneShell.js +2420 -0
- package/dist/orchestrator/src/cli/providerLinearChildStreamShell.js +385 -0
- package/dist/orchestrator/src/cli/providerLinearWorkerRunner.js +5738 -0
- package/dist/orchestrator/src/cli/resumeCliShell.js +14 -0
- package/dist/orchestrator/src/cli/reviewCliLaunchShell.js +72 -0
- package/dist/orchestrator/src/cli/rlm/alignment.js +3 -3
- package/dist/orchestrator/src/cli/rlm/context.js +94 -7
- package/dist/orchestrator/src/cli/rlm/rlmCodexRuntimeShell.js +546 -0
- package/dist/orchestrator/src/cli/rlm/symbolic.js +4 -2
- package/dist/orchestrator/src/cli/rlmCliRequestShell.js +42 -0
- package/dist/orchestrator/src/cli/rlmCompletionCliShell.js +46 -0
- package/dist/orchestrator/src/cli/rlmLaunchCliShell.js +51 -0
- package/dist/orchestrator/src/cli/rlmRunner.js +83 -523
- package/dist/orchestrator/src/cli/run/blockMemory.js +500 -0
- package/dist/orchestrator/src/cli/run/manifest.js +410 -73
- package/dist/orchestrator/src/cli/run/manifestPersister.js +45 -14
- package/dist/orchestrator/src/cli/run/runMemoryController.js +216 -0
- package/dist/orchestrator/src/cli/run/source0.js +690 -0
- package/dist/orchestrator/src/cli/run/workspacePath.js +101 -0
- package/dist/orchestrator/src/cli/runtime/mode.js +2 -1
- package/dist/orchestrator/src/cli/runtime/provider.js +39 -2
- package/dist/orchestrator/src/cli/selfCheckCliShell.js +12 -0
- package/dist/orchestrator/src/cli/services/commandRunner.js +668 -18
- package/dist/orchestrator/src/cli/services/execRuntime.js +66 -1
- package/dist/orchestrator/src/cli/services/orchestratorAutoScoutEvidenceRecorder.js +71 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudBranchResolution.js +8 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudEnvironmentResolution.js +22 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudExecutionLifecycleShell.js +39 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudPromptBuilder.js +37 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudRouteFallbackContract.js +45 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudRouteShell.js +36 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudTargetExecutor.js +277 -0
- package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycle.js +98 -0
- package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycleShell.js +54 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionLifecycle.js +112 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionModePolicy.js +27 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteAdapterShell.js +59 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteDecisionShell.js +57 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteState.js +21 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionRouter.js +2 -0
- package/dist/orchestrator/src/cli/services/orchestratorLocalPipelineExecutor.js +149 -0
- package/dist/orchestrator/src/cli/services/orchestratorLocalRouteShell.js +63 -0
- package/dist/orchestrator/src/cli/services/orchestratorPlanShell.js +54 -0
- package/dist/orchestrator/src/cli/services/orchestratorPlanTargetTracker.js +16 -0
- package/dist/orchestrator/src/cli/services/orchestratorResumePreparationShell.js +84 -0
- package/dist/orchestrator/src/cli/services/orchestratorResumeTokenValidation.js +15 -0
- package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleCompletion.js +31 -0
- package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleExecutionRegistration.js +37 -0
- package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleOrchestrationShell.js +83 -0
- package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleTaskManagerShell.js +37 -0
- package/dist/orchestrator/src/cli/services/orchestratorRuntimeManifestMutation.js +20 -0
- package/dist/orchestrator/src/cli/services/orchestratorStartPreparationShell.js +56 -0
- package/dist/orchestrator/src/cli/services/orchestratorStatusShell.js +70 -0
- package/dist/orchestrator/src/cli/services/pipelineResolver.js +7 -3
- package/dist/orchestrator/src/cli/services/plannerMemory.js +119 -0
- package/dist/orchestrator/src/cli/services/runPreparation.js +7 -3
- package/dist/orchestrator/src/cli/services/runSummaryWriter.js +9 -0
- package/dist/orchestrator/src/cli/setupBootstrapShell.js +114 -0
- package/dist/orchestrator/src/cli/setupCliShell.js +51 -0
- package/dist/orchestrator/src/cli/skillsCliShell.js +56 -0
- package/dist/orchestrator/src/cli/startCliRequestShell.js +53 -0
- package/dist/orchestrator/src/cli/startCliShell.js +68 -0
- package/dist/orchestrator/src/cli/statusCliShell.js +22 -0
- package/dist/orchestrator/src/cli/utils/authProvenanceFingerprint.js +27 -0
- package/dist/orchestrator/src/cli/utils/cloudPreflight.js +83 -1
- package/dist/orchestrator/src/cli/utils/delegationConfigParser.js +250 -0
- package/dist/orchestrator/src/cli/utils/delegationMcpHealth.js +1382 -0
- package/dist/orchestrator/src/cli/utils/devtools.js +2 -54
- package/dist/orchestrator/src/cli/utils/mcpServerEntry.js +53 -0
- package/dist/orchestrator/src/cli/utils/packageProgramResolver.js +151 -0
- package/dist/orchestrator/src/cli/utils/providerOverrideEnv.js +71 -0
- package/dist/orchestrator/src/cli/utils/trailingJsonObject.js +59 -0
- package/dist/orchestrator/src/learning/crystalizer.js +2 -2
- package/dist/orchestrator/src/persistence/ExperienceStore.js +233 -49
- package/dist/orchestrator/src/persistence/TaskStateStore.js +6 -6
- package/dist/orchestrator/src/persistence/lockFile.js +70 -4
- package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +39 -0
- package/dist/orchestrator/src/sync/createCloudSyncWorker.js +3 -2
- package/dist/orchestrator/src/utils/atomicWrite.js +17 -2
- package/dist/packages/orchestrator/src/exec/unified-exec.js +99 -6
- package/dist/packages/orchestrator/src/instructions/promptPacks.js +150 -19
- package/dist/packages/sdk-node/src/orchestrator.js +137 -13
- package/dist/packages/shared/config/designConfig.js +8 -1
- package/dist/packages/shared/streams/stdio.js +1 -1
- package/dist/scripts/design/pipeline/permit.js +15 -0
- package/dist/scripts/lib/docs-catalog.js +365 -0
- package/dist/scripts/lib/docs-helpers.js +87 -5
- package/dist/scripts/lib/pr-watch-merge.js +1088 -80
- package/dist/scripts/lib/provider-run-contract.js +26 -0
- package/dist/scripts/lib/review-command-intent-classification.js +532 -0
- package/dist/scripts/lib/review-command-probe-classification.js +385 -0
- package/dist/scripts/lib/review-execution-boundary-preflight.js +279 -0
- package/dist/scripts/lib/review-execution-runtime.js +753 -0
- package/dist/scripts/lib/review-execution-state.js +1144 -0
- package/dist/scripts/lib/review-execution-telemetry.js +215 -0
- package/dist/scripts/lib/review-inspection-target-parsing.js +78 -0
- package/dist/scripts/lib/review-launch-attempt.js +601 -0
- package/dist/scripts/lib/review-meta-surface-boundary-analysis.js +300 -0
- package/dist/scripts/lib/review-meta-surface-normalization.js +746 -0
- package/dist/scripts/lib/review-non-interactive-handoff.js +61 -0
- package/dist/scripts/lib/review-prompt-context.js +376 -0
- package/dist/scripts/lib/review-scope-advisory.js +286 -0
- package/dist/scripts/lib/review-scope-paths.js +123 -0
- package/dist/scripts/lib/review-shell-command-parser.js +389 -0
- package/dist/scripts/lib/review-shell-env-interpreter.js +340 -0
- package/dist/scripts/lib/run-manifests.js +192 -36
- package/dist/scripts/lib/spark-policy-classifier.js +593 -0
- package/dist/scripts/run-review.js +507 -1777
- package/docs/public/downstream-setup.md +106 -0
- package/docs/public/provider-onboarding.md +173 -0
- package/package.json +30 -11
- package/plugins/codex-orchestrator/.codex-plugin/plugin.json +30 -0
- package/plugins/codex-orchestrator/.mcp.json +13 -0
- package/plugins/codex-orchestrator/launcher.mjs +359 -0
- package/schemas/manifest.json +395 -0
- package/skills/chrome-devtools/SKILL.md +1 -1
- package/skills/codex-orchestrator/SKILL.md +83 -0
- package/skills/collab-subagents-first/SKILL.md +2 -1
- package/skills/delegation-usage/DELEGATION_GUIDE.md +24 -11
- package/skills/delegation-usage/SKILL.md +20 -13
- package/skills/land/SKILL.md +77 -0
- package/skills/linear/SKILL.md +255 -0
- package/skills/release/SKILL.md +47 -3
- package/skills/standalone-review/SKILL.md +6 -1
- package/templates/README.md +4 -2
- package/templates/codex/.codex/agents/awaiter-high.toml +2 -2
- package/templates/codex/.codex/agents/explorer-fast.toml +1 -0
- package/templates/codex/.codex/agents/worker-complex.toml +1 -1
- package/templates/codex/.codex/config.toml +3 -4
- package/templates/codex/.codex/providers/README.md +13 -0
- package/templates/codex/.codex/providers/control.example.json +18 -0
- package/templates/codex/.codex/providers/provider.env.example +15 -0
- package/templates/codex/AGENTS.md +12 -7
- package/templates/codex/mcp-client.json +5 -1
- package/docs/README.md +0 -307
- package/docs/assets/setup.gif +0 -0
|
@@ -0,0 +1,690 @@
|
|
|
1
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
3
|
+
import { buildContextObject } from '../rlm/context.js';
|
|
4
|
+
import { isoTimestamp } from '../utils/time.js';
|
|
5
|
+
const RUN_SOURCE0_SCHEMA_VERSION = 1;
|
|
6
|
+
const RUN_MEMORY_OBSERVABILITY_SCHEMA_VERSION = 1;
|
|
7
|
+
const RUN_SOURCE0_CONTEXT_KIND = 'context_object';
|
|
8
|
+
const RUN_SOURCE0_PAYLOAD_KIND = 'run_source_0';
|
|
9
|
+
const RUN_SOURCE0_CHUNK_TARGET_BYTES = 65_536;
|
|
10
|
+
const RUN_SOURCE0_CHUNK_OVERLAP_BYTES = 4_096;
|
|
11
|
+
const RUN_MEMORY_REPAIR_DETAIL_MARKER = 'memory-repair:';
|
|
12
|
+
const INVALID_INHERITED_SOURCE0_OBJECT_ID = 'sha256:invalid-inherited-source0-descriptor';
|
|
13
|
+
const INVALID_INHERITED_SOURCE0_CHUNK_ID = 'invalid';
|
|
14
|
+
const SANITIZED_REJECTED_CANDIDATE_PATH_PREFIX = 'invalid-source0';
|
|
15
|
+
const WINDOWS_DRIVE_ABSOLUTE_PATH_RE = /^[A-Za-z]:[\\/]/u;
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
function readNonEmptyString(value) {
|
|
20
|
+
if (typeof value !== 'string') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const trimmed = value.trim();
|
|
24
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
25
|
+
}
|
|
26
|
+
function readInteger(value) {
|
|
27
|
+
if (typeof value === 'number' && Number.isInteger(value)) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function readRunSource0Lineage(value) {
|
|
33
|
+
if (!isRecord(value)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const runId = readNonEmptyString(value.run_id);
|
|
37
|
+
const taskId = readNonEmptyString(value.task_id);
|
|
38
|
+
const manifestPath = readNonEmptyString(value.manifest_path);
|
|
39
|
+
if (!runId || !taskId || !manifestPath) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
run_id: runId,
|
|
44
|
+
task_id: taskId,
|
|
45
|
+
manifest_path: manifestPath
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function readSource0Candidate(input) {
|
|
49
|
+
if (!isRecord(input)) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
if (isRecord(input.memory) && isRecord(input.memory.source_0)) {
|
|
53
|
+
return input.memory.source_0;
|
|
54
|
+
}
|
|
55
|
+
return input;
|
|
56
|
+
}
|
|
57
|
+
function readManifestSource0Value(input) {
|
|
58
|
+
if (!isRecord(input) ||
|
|
59
|
+
!isRecord(input.memory) ||
|
|
60
|
+
!Object.prototype.hasOwnProperty.call(input.memory, 'source_0')) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return input.memory.source_0;
|
|
64
|
+
}
|
|
65
|
+
function buildRunSource0Payload(params) {
|
|
66
|
+
const promptPacks = Array.isArray(params.manifest.prompt_packs) ? params.manifest.prompt_packs : [];
|
|
67
|
+
const manifestPath = join(params.manifest.artifact_root, 'manifest.json');
|
|
68
|
+
return {
|
|
69
|
+
schema_version: RUN_SOURCE0_SCHEMA_VERSION,
|
|
70
|
+
kind: RUN_SOURCE0_PAYLOAD_KIND,
|
|
71
|
+
generated_at: params.manifest.updated_at,
|
|
72
|
+
run_contract: {
|
|
73
|
+
task_id: params.manifest.task_id,
|
|
74
|
+
run_id: params.manifest.run_id,
|
|
75
|
+
parent_run_id: params.manifest.parent_run_id ?? null,
|
|
76
|
+
pipeline_id: params.manifest.pipeline_id,
|
|
77
|
+
pipeline_title: params.manifest.pipeline_title
|
|
78
|
+
},
|
|
79
|
+
artifacts: {
|
|
80
|
+
manifest_path: manifestPath,
|
|
81
|
+
artifact_root: params.manifest.artifact_root,
|
|
82
|
+
log_path: params.manifest.log_path,
|
|
83
|
+
workspace_path: params.manifest.workspace_path ?? null
|
|
84
|
+
},
|
|
85
|
+
issue: {
|
|
86
|
+
provider: params.manifest.issue_provider ?? null,
|
|
87
|
+
id: params.manifest.issue_id ?? null,
|
|
88
|
+
identifier: params.manifest.issue_identifier ?? null,
|
|
89
|
+
updated_at: params.manifest.issue_updated_at ?? null
|
|
90
|
+
},
|
|
91
|
+
instructions: {
|
|
92
|
+
hash: params.manifest.instructions_hash ?? null,
|
|
93
|
+
sources: [...params.manifest.instructions_sources],
|
|
94
|
+
prompt_packs: promptPacks.map((pack) => ({
|
|
95
|
+
id: pack.id,
|
|
96
|
+
domain: pack.domain,
|
|
97
|
+
stamp: pack.stamp,
|
|
98
|
+
source_count: Array.isArray(pack.sources) ? pack.sources.length : 0,
|
|
99
|
+
experience_count: Array.isArray(pack.experiences) ? pack.experiences.length : 0
|
|
100
|
+
}))
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function buildRunMemoryProvenanceDescriptor(descriptor) {
|
|
105
|
+
return {
|
|
106
|
+
pointer: descriptor.pointer,
|
|
107
|
+
object_id: descriptor.object_id,
|
|
108
|
+
dir_path: descriptor.dir_path,
|
|
109
|
+
index_path: descriptor.index_path,
|
|
110
|
+
source_path: descriptor.source_path,
|
|
111
|
+
created_at: descriptor.created_at,
|
|
112
|
+
origin: descriptor.origin,
|
|
113
|
+
inherited_from: descriptor.inherited_from
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function buildRunMemorySelectedDescriptor(params) {
|
|
117
|
+
return {
|
|
118
|
+
selection: params.selection,
|
|
119
|
+
...buildRunMemoryProvenanceDescriptor(params.descriptor)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function buildRunMemoryRejectedCandidate(params) {
|
|
123
|
+
const descriptor = buildRunMemoryProvenanceDescriptor(params.descriptor);
|
|
124
|
+
return {
|
|
125
|
+
...descriptor,
|
|
126
|
+
dir_path: sanitizeRejectedCandidatePath(descriptor.dir_path, 'dir_path'),
|
|
127
|
+
index_path: sanitizeRejectedCandidatePath(descriptor.index_path, 'index_path'),
|
|
128
|
+
source_path: sanitizeRejectedCandidatePath(descriptor.source_path, 'source_path'),
|
|
129
|
+
reason: params.reason,
|
|
130
|
+
detail: params.detail
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function sanitizeRejectedCandidatePath(candidate, field) {
|
|
134
|
+
const trimmed = candidate.trim();
|
|
135
|
+
const normalizedCandidate = trimmed.replaceAll('\\', '/');
|
|
136
|
+
if (trimmed.length === 0 ||
|
|
137
|
+
normalizedCandidate === '.' ||
|
|
138
|
+
hasInvalidPathCharacters(normalizedCandidate) ||
|
|
139
|
+
normalizedCandidate.startsWith('/') ||
|
|
140
|
+
isAbsolute(trimmed) ||
|
|
141
|
+
WINDOWS_DRIVE_ABSOLUTE_PATH_RE.test(trimmed) ||
|
|
142
|
+
normalizedCandidate.split('/').some((segment) => segment === '..')) {
|
|
143
|
+
return `${SANITIZED_REJECTED_CANDIDATE_PATH_PREFIX}/${field}`;
|
|
144
|
+
}
|
|
145
|
+
return normalizedCandidate;
|
|
146
|
+
}
|
|
147
|
+
function buildMalformedInheritedSource0Descriptor(params) {
|
|
148
|
+
const candidate = isRecord(params.candidate) ? params.candidate : {};
|
|
149
|
+
const fallbackDir = join(dirname(params.fallbackOrigin.manifest_path), 'memory', 'source-0');
|
|
150
|
+
const objectId = readNonEmptyString(candidate.object_id) ?? INVALID_INHERITED_SOURCE0_OBJECT_ID;
|
|
151
|
+
return {
|
|
152
|
+
schema_version: RUN_SOURCE0_SCHEMA_VERSION,
|
|
153
|
+
kind: RUN_SOURCE0_CONTEXT_KIND,
|
|
154
|
+
object_id: objectId,
|
|
155
|
+
pointer: readNonEmptyString(candidate.pointer) ??
|
|
156
|
+
buildRunSource0Pointer(objectId, INVALID_INHERITED_SOURCE0_CHUNK_ID),
|
|
157
|
+
dir_path: readNonEmptyString(candidate.dir_path) ?? fallbackDir,
|
|
158
|
+
index_path: readNonEmptyString(candidate.index_path) ?? join(fallbackDir, 'index.json'),
|
|
159
|
+
source_path: readNonEmptyString(candidate.source_path) ?? join(fallbackDir, 'source.txt'),
|
|
160
|
+
byte_length: readInteger(candidate.byte_length) ?? 0,
|
|
161
|
+
chunk_count: Math.max(1, readInteger(candidate.chunk_count) ?? 1),
|
|
162
|
+
created_at: readNonEmptyString(candidate.created_at) ?? params.fallbackCreatedAt,
|
|
163
|
+
origin: readRunSource0Lineage(candidate.origin) ?? params.fallbackOrigin,
|
|
164
|
+
inherited_from: candidate.inherited_from === null
|
|
165
|
+
? null
|
|
166
|
+
: readRunSource0Lineage(candidate.inherited_from)
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function buildRunSource0Pointer(objectId, chunkId) {
|
|
170
|
+
return `ctx:${objectId}#chunk:${chunkId}`;
|
|
171
|
+
}
|
|
172
|
+
function buildRunMemoryRediscovery(params) {
|
|
173
|
+
return {
|
|
174
|
+
from_pointer: params.rejected.descriptor.pointer,
|
|
175
|
+
from_object_id: params.rejected.descriptor.object_id,
|
|
176
|
+
to_pointer: params.selected.pointer,
|
|
177
|
+
to_object_id: params.selected.object_id,
|
|
178
|
+
reason: params.rejected.reason
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function readAcceptedManualRepairEvents(manifest) {
|
|
182
|
+
return manifest.resume_events
|
|
183
|
+
.filter((event) => event.outcome === 'accepted' &&
|
|
184
|
+
event.reason === 'manual-resume' &&
|
|
185
|
+
typeof event.detail === 'string' &&
|
|
186
|
+
event.detail.trim().toLowerCase().startsWith(RUN_MEMORY_REPAIR_DETAIL_MARKER))
|
|
187
|
+
.map((event) => ({
|
|
188
|
+
timestamp: event.timestamp,
|
|
189
|
+
actor: event.actor,
|
|
190
|
+
reason: event.reason,
|
|
191
|
+
outcome: 'accepted',
|
|
192
|
+
detail: event.detail ?? null
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
function resolveResumeLatencyMs(recordedAt, manualRepairs) {
|
|
196
|
+
const latestRepair = manualRepairs.at(-1);
|
|
197
|
+
if (!latestRepair) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
const recordedAtMs = Date.parse(recordedAt);
|
|
201
|
+
const repairAtMs = Date.parse(latestRepair.timestamp);
|
|
202
|
+
if (Number.isNaN(recordedAtMs) || Number.isNaN(repairAtMs)) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return Math.max(0, recordedAtMs - repairAtMs);
|
|
206
|
+
}
|
|
207
|
+
function readRepeatedFailureStreak(manifest) {
|
|
208
|
+
const streak = manifest?.memory?.observability?.counters?.repeated_failure_streak;
|
|
209
|
+
return typeof streak === 'number' && Number.isInteger(streak) && streak >= 0 ? streak : 0;
|
|
210
|
+
}
|
|
211
|
+
function applyRunMemoryManualRepairState(observability, manifest, recordedAt) {
|
|
212
|
+
const manualRepairs = readAcceptedManualRepairEvents(manifest);
|
|
213
|
+
observability.recorded_at = recordedAt;
|
|
214
|
+
observability.manual_repairs = manualRepairs;
|
|
215
|
+
observability.counters.manual_repair_count = manualRepairs.length;
|
|
216
|
+
observability.counters.resume_latency_ms = resolveResumeLatencyMs(recordedAt, manualRepairs);
|
|
217
|
+
}
|
|
218
|
+
function buildRunMemoryObservability(params) {
|
|
219
|
+
const rejectedCandidates = params.rejectedCandidates.map((candidate) => buildRunMemoryRejectedCandidate(candidate));
|
|
220
|
+
const rediscoveredMemory = params.selection === 'fresh_rebuild' && params.rejectedCandidates[0]
|
|
221
|
+
? buildRunMemoryRediscovery({
|
|
222
|
+
rejected: params.rejectedCandidates[0],
|
|
223
|
+
selected: params.selected
|
|
224
|
+
})
|
|
225
|
+
: null;
|
|
226
|
+
const observability = {
|
|
227
|
+
schema_version: RUN_MEMORY_OBSERVABILITY_SCHEMA_VERSION,
|
|
228
|
+
recorded_at: params.recordedAt,
|
|
229
|
+
selected_memory: buildRunMemorySelectedDescriptor({
|
|
230
|
+
descriptor: params.selected,
|
|
231
|
+
selection: params.selection
|
|
232
|
+
}),
|
|
233
|
+
rejected_candidates: rejectedCandidates,
|
|
234
|
+
rediscovered_memory: rediscoveredMemory,
|
|
235
|
+
manual_repairs: [],
|
|
236
|
+
counters: {
|
|
237
|
+
contradiction_count: params.rejectedCandidates.filter((candidate) => candidate.reason === 'provenance_contradiction').length,
|
|
238
|
+
rediscovery_count: rediscoveredMemory ? 1 : 0,
|
|
239
|
+
resume_latency_ms: null,
|
|
240
|
+
manual_repair_count: 0,
|
|
241
|
+
repeated_failure_streak: params.repeatedFailureStreak,
|
|
242
|
+
retrieval_hits: params.selection === 'inherited_reuse' ? 1 : 0,
|
|
243
|
+
retrieval_misses: params.rejectedCandidates.length > 0 ? 1 : 0
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
applyRunMemoryManualRepairState(observability, params.manifest, params.recordedAt);
|
|
247
|
+
return observability;
|
|
248
|
+
}
|
|
249
|
+
async function assessInheritedRunSource0Candidate(params) {
|
|
250
|
+
try {
|
|
251
|
+
resolveRunSource0Paths(params.repoRoot, params.descriptor);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
return {
|
|
255
|
+
descriptor: params.descriptor,
|
|
256
|
+
reason: 'provenance_contradiction',
|
|
257
|
+
detail: error?.message ?? 'invalid inherited source_0 descriptor paths'
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const hasArtifacts = await hasRunSource0Artifacts(params.repoRoot, params.descriptor);
|
|
261
|
+
if (!hasArtifacts) {
|
|
262
|
+
return {
|
|
263
|
+
descriptor: params.descriptor,
|
|
264
|
+
reason: 'missing_artifacts',
|
|
265
|
+
detail: 'inherited source_0 artifacts are missing'
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
const payload = await readRunSource0Payload(params.repoRoot, params.descriptor);
|
|
270
|
+
if (!payload) {
|
|
271
|
+
return {
|
|
272
|
+
descriptor: params.descriptor,
|
|
273
|
+
reason: 'provenance_contradiction',
|
|
274
|
+
detail: 'inherited source_0 payload is invalid'
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
if (payload.run_contract.run_id !== params.descriptor.origin.run_id) {
|
|
278
|
+
return {
|
|
279
|
+
descriptor: params.descriptor,
|
|
280
|
+
reason: 'provenance_contradiction',
|
|
281
|
+
detail: 'inherited source_0 payload run_id does not match descriptor origin'
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
if (payload.run_contract.task_id !== params.descriptor.origin.task_id) {
|
|
285
|
+
return {
|
|
286
|
+
descriptor: params.descriptor,
|
|
287
|
+
reason: 'provenance_contradiction',
|
|
288
|
+
detail: 'inherited source_0 payload task_id does not match descriptor origin'
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
if (payload.artifacts.manifest_path !== params.descriptor.origin.manifest_path) {
|
|
292
|
+
return {
|
|
293
|
+
descriptor: params.descriptor,
|
|
294
|
+
reason: 'provenance_contradiction',
|
|
295
|
+
detail: 'inherited source_0 payload manifest_path does not match descriptor origin'
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
const inheritedPaths = resolveRunSource0Paths(params.repoRoot, params.descriptor);
|
|
299
|
+
const contextObject = await buildContextObject({
|
|
300
|
+
source: { type: 'dir', value: inheritedPaths.dirPath },
|
|
301
|
+
targetDir: inheritedPaths.dirPath,
|
|
302
|
+
chunking: {
|
|
303
|
+
targetBytes: RUN_SOURCE0_CHUNK_TARGET_BYTES,
|
|
304
|
+
overlapBytes: RUN_SOURCE0_CHUNK_OVERLAP_BYTES,
|
|
305
|
+
strategy: 'byte'
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
validateRunSource0DescriptorAgainstArtifacts({
|
|
309
|
+
repoRoot: params.repoRoot,
|
|
310
|
+
descriptor: params.descriptor,
|
|
311
|
+
contextObject
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
return {
|
|
316
|
+
descriptor: params.descriptor,
|
|
317
|
+
reason: 'provenance_contradiction',
|
|
318
|
+
detail: error?.message ?? 'failed to read inherited source_0 payload'
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
export function readRunSource0Descriptor(input) {
|
|
324
|
+
const candidate = readSource0Candidate(input);
|
|
325
|
+
if (!candidate) {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
const schemaVersion = readInteger(candidate.schema_version);
|
|
329
|
+
const kind = readNonEmptyString(candidate.kind);
|
|
330
|
+
const objectId = readNonEmptyString(candidate.object_id);
|
|
331
|
+
const pointer = readNonEmptyString(candidate.pointer);
|
|
332
|
+
const dirPath = readNonEmptyString(candidate.dir_path);
|
|
333
|
+
const indexPath = readNonEmptyString(candidate.index_path);
|
|
334
|
+
const sourcePath = readNonEmptyString(candidate.source_path);
|
|
335
|
+
const byteLength = readInteger(candidate.byte_length);
|
|
336
|
+
const chunkCount = readInteger(candidate.chunk_count);
|
|
337
|
+
const createdAt = readNonEmptyString(candidate.created_at);
|
|
338
|
+
const origin = readRunSource0Lineage(candidate.origin);
|
|
339
|
+
const inheritedFrom = candidate.inherited_from === null ? null : readRunSource0Lineage(candidate.inherited_from);
|
|
340
|
+
if (schemaVersion === null ||
|
|
341
|
+
schemaVersion < 1 ||
|
|
342
|
+
kind !== RUN_SOURCE0_CONTEXT_KIND ||
|
|
343
|
+
!objectId ||
|
|
344
|
+
!pointer ||
|
|
345
|
+
!dirPath ||
|
|
346
|
+
!indexPath ||
|
|
347
|
+
!sourcePath ||
|
|
348
|
+
byteLength === null ||
|
|
349
|
+
byteLength < 0 ||
|
|
350
|
+
chunkCount === null ||
|
|
351
|
+
chunkCount < 1 ||
|
|
352
|
+
!createdAt ||
|
|
353
|
+
!origin ||
|
|
354
|
+
candidate.inherited_from === undefined ||
|
|
355
|
+
(candidate.inherited_from !== null && inheritedFrom === null)) {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
schema_version: schemaVersion,
|
|
360
|
+
kind: RUN_SOURCE0_CONTEXT_KIND,
|
|
361
|
+
object_id: objectId,
|
|
362
|
+
pointer,
|
|
363
|
+
dir_path: dirPath,
|
|
364
|
+
index_path: indexPath,
|
|
365
|
+
source_path: sourcePath,
|
|
366
|
+
byte_length: byteLength,
|
|
367
|
+
chunk_count: chunkCount,
|
|
368
|
+
created_at: createdAt,
|
|
369
|
+
origin,
|
|
370
|
+
inherited_from: inheritedFrom
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
export function resolveRunSource0Paths(repoRoot, descriptor) {
|
|
374
|
+
const resolvedRepoRoot = resolve(repoRoot);
|
|
375
|
+
return {
|
|
376
|
+
dirPath: resolveRepoRelativeSource0Path(resolvedRepoRoot, descriptor.dir_path, 'dir_path'),
|
|
377
|
+
indexPath: resolveRepoRelativeSource0Path(resolvedRepoRoot, descriptor.index_path, 'index_path'),
|
|
378
|
+
sourcePath: resolveRepoRelativeSource0Path(resolvedRepoRoot, descriptor.source_path, 'source_path')
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
function resolveRepoRelativeSource0Path(repoRoot, candidate, field) {
|
|
382
|
+
const normalizedCandidate = candidate.replaceAll('\\', '/');
|
|
383
|
+
if (isAbsolute(candidate) ||
|
|
384
|
+
WINDOWS_DRIVE_ABSOLUTE_PATH_RE.test(candidate) ||
|
|
385
|
+
normalizedCandidate.startsWith('/')) {
|
|
386
|
+
throw new Error(`source_0 ${field} must be repo-relative`);
|
|
387
|
+
}
|
|
388
|
+
if (hasInvalidPathCharacters(normalizedCandidate)) {
|
|
389
|
+
throw new Error(`source_0 ${field} must not contain control characters or line separators`);
|
|
390
|
+
}
|
|
391
|
+
if (normalizedCandidate.split('/').some((segment) => segment === '..')) {
|
|
392
|
+
throw new Error(`source_0 ${field} must not traverse outside the repo root`);
|
|
393
|
+
}
|
|
394
|
+
const resolvedPath = resolve(repoRoot, candidate);
|
|
395
|
+
const relativePath = relative(repoRoot, resolvedPath);
|
|
396
|
+
if (!relativePath ||
|
|
397
|
+
relativePath === '.' ||
|
|
398
|
+
isAbsolute(relativePath) ||
|
|
399
|
+
WINDOWS_DRIVE_ABSOLUTE_PATH_RE.test(relativePath) ||
|
|
400
|
+
relativePath.split(/[\\/]+/u).some((segment) => segment === '..')) {
|
|
401
|
+
throw new Error(`source_0 ${field} escapes the repo root`);
|
|
402
|
+
}
|
|
403
|
+
return resolvedPath;
|
|
404
|
+
}
|
|
405
|
+
function hasInvalidPathCharacters(value) {
|
|
406
|
+
return Array.from(value).some((character) => {
|
|
407
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
408
|
+
return (codePoint < 0x20 ||
|
|
409
|
+
codePoint === 0x7f ||
|
|
410
|
+
codePoint === 0x2028 ||
|
|
411
|
+
codePoint === 0x2029);
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
export function buildRunSource0PromptLines(descriptor) {
|
|
415
|
+
if (!descriptor) {
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
const lines = [
|
|
419
|
+
'Shared source 0 anchor:',
|
|
420
|
+
`- Pointer: \`${descriptor.pointer}\``,
|
|
421
|
+
`- Object id: \`${descriptor.object_id}\``,
|
|
422
|
+
`- Context dir: \`${descriptor.dir_path}\``,
|
|
423
|
+
`- Source payload: \`${descriptor.source_path}\``,
|
|
424
|
+
`- Origin: run=\`${descriptor.origin.run_id}\`, task=\`${descriptor.origin.task_id}\`, manifest=\`${descriptor.origin.manifest_path}\``
|
|
425
|
+
];
|
|
426
|
+
if (descriptor.inherited_from) {
|
|
427
|
+
lines.push(`- Inherited from: run=\`${descriptor.inherited_from.run_id}\`, task=\`${descriptor.inherited_from.task_id}\`, manifest=\`${descriptor.inherited_from.manifest_path}\``);
|
|
428
|
+
}
|
|
429
|
+
return lines;
|
|
430
|
+
}
|
|
431
|
+
export async function readRunSource0Payload(repoRoot, descriptor) {
|
|
432
|
+
const raw = await readFile(resolveRunSource0Paths(repoRoot, descriptor).sourcePath, 'utf8');
|
|
433
|
+
const parsed = JSON.parse(raw);
|
|
434
|
+
if (!isRecord(parsed)) {
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
if (readInteger(parsed.schema_version) !== RUN_SOURCE0_SCHEMA_VERSION) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
if (readNonEmptyString(parsed.kind) !== RUN_SOURCE0_PAYLOAD_KIND) {
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
return parsed;
|
|
444
|
+
}
|
|
445
|
+
export async function hasRunSource0Artifacts(repoRoot, descriptor) {
|
|
446
|
+
try {
|
|
447
|
+
const paths = resolveRunSource0Paths(repoRoot, descriptor);
|
|
448
|
+
const [dirInfo, indexInfo, sourceInfo] = await Promise.all([
|
|
449
|
+
stat(paths.dirPath),
|
|
450
|
+
stat(paths.indexPath),
|
|
451
|
+
stat(paths.sourcePath)
|
|
452
|
+
]);
|
|
453
|
+
return dirInfo.isDirectory() && indexInfo.isFile() && sourceInfo.isFile();
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
function buildRunSource0Descriptor(params) {
|
|
460
|
+
const firstChunk = params.contextObject.index.chunks[0];
|
|
461
|
+
if (!firstChunk) {
|
|
462
|
+
throw new Error('source_0 context object must contain at least one chunk');
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
schema_version: RUN_SOURCE0_SCHEMA_VERSION,
|
|
466
|
+
kind: RUN_SOURCE0_CONTEXT_KIND,
|
|
467
|
+
object_id: params.contextObject.index.object_id,
|
|
468
|
+
pointer: buildRunSource0Pointer(params.contextObject.index.object_id, firstChunk.id),
|
|
469
|
+
dir_path: relative(params.repoRoot, params.runDir),
|
|
470
|
+
index_path: relative(params.repoRoot, params.contextObject.indexPath),
|
|
471
|
+
source_path: relative(params.repoRoot, params.contextObject.sourcePath),
|
|
472
|
+
byte_length: params.contextObject.index.source.byte_length,
|
|
473
|
+
chunk_count: params.contextObject.index.chunks.length,
|
|
474
|
+
created_at: params.contextObject.index.created_at,
|
|
475
|
+
origin: params.origin,
|
|
476
|
+
inherited_from: params.inheritedFrom
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
function validateRunSource0DescriptorAgainstArtifacts(params) {
|
|
480
|
+
const firstChunk = params.contextObject.index.chunks[0];
|
|
481
|
+
if (!firstChunk) {
|
|
482
|
+
throw new Error('source_0 context object must contain at least one chunk');
|
|
483
|
+
}
|
|
484
|
+
const expectedPointer = buildRunSource0Pointer(params.contextObject.index.object_id, firstChunk.id);
|
|
485
|
+
const expectedDirPath = relative(params.repoRoot, params.contextObject.dir);
|
|
486
|
+
const expectedIndexPath = relative(params.repoRoot, params.contextObject.indexPath);
|
|
487
|
+
const expectedSourcePath = relative(params.repoRoot, params.contextObject.sourcePath);
|
|
488
|
+
if (params.descriptor.object_id !== params.contextObject.index.object_id) {
|
|
489
|
+
throw new Error('inherited source_0 descriptor object_id does not match artifacts');
|
|
490
|
+
}
|
|
491
|
+
if (params.descriptor.pointer !== expectedPointer) {
|
|
492
|
+
throw new Error('inherited source_0 descriptor pointer does not match artifacts');
|
|
493
|
+
}
|
|
494
|
+
if (params.descriptor.dir_path !== expectedDirPath) {
|
|
495
|
+
throw new Error('inherited source_0 descriptor dir_path does not match artifacts');
|
|
496
|
+
}
|
|
497
|
+
if (params.descriptor.index_path !== expectedIndexPath) {
|
|
498
|
+
throw new Error('inherited source_0 descriptor index_path does not match artifacts');
|
|
499
|
+
}
|
|
500
|
+
if (params.descriptor.source_path !== expectedSourcePath) {
|
|
501
|
+
throw new Error('inherited source_0 descriptor source_path does not match artifacts');
|
|
502
|
+
}
|
|
503
|
+
if (params.descriptor.byte_length !== params.contextObject.index.source.byte_length) {
|
|
504
|
+
throw new Error('inherited source_0 descriptor byte_length does not match artifacts');
|
|
505
|
+
}
|
|
506
|
+
if (params.descriptor.chunk_count !== params.contextObject.index.chunks.length) {
|
|
507
|
+
throw new Error('inherited source_0 descriptor chunk_count does not match artifacts');
|
|
508
|
+
}
|
|
509
|
+
if (params.descriptor.created_at !== params.contextObject.index.created_at) {
|
|
510
|
+
throw new Error('inherited source_0 descriptor created_at does not match artifacts');
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function buildCurrentRunLineage(manifest) {
|
|
514
|
+
return {
|
|
515
|
+
run_id: manifest.run_id,
|
|
516
|
+
task_id: manifest.task_id,
|
|
517
|
+
manifest_path: join(manifest.artifact_root, 'manifest.json')
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
async function materializeFreshRunSource0(params) {
|
|
521
|
+
const payload = buildRunSource0Payload({
|
|
522
|
+
manifest: params.manifest
|
|
523
|
+
});
|
|
524
|
+
const contextObject = await buildContextObject({
|
|
525
|
+
source: {
|
|
526
|
+
type: 'text',
|
|
527
|
+
value: `${JSON.stringify(payload, null, 2)}\n`
|
|
528
|
+
},
|
|
529
|
+
targetDir: params.targetDir,
|
|
530
|
+
chunking: {
|
|
531
|
+
targetBytes: RUN_SOURCE0_CHUNK_TARGET_BYTES,
|
|
532
|
+
overlapBytes: RUN_SOURCE0_CHUNK_OVERLAP_BYTES,
|
|
533
|
+
strategy: 'byte'
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
return {
|
|
537
|
+
source_0: buildRunSource0Descriptor({
|
|
538
|
+
repoRoot: params.env.repoRoot,
|
|
539
|
+
runDir: params.targetDir,
|
|
540
|
+
contextObject,
|
|
541
|
+
origin: buildCurrentRunLineage(params.manifest),
|
|
542
|
+
inheritedFrom: params.inheritedFrom
|
|
543
|
+
})
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
export async function materializeRunSource0(params) {
|
|
547
|
+
const targetDir = join(params.paths.runDir, 'memory', 'source-0');
|
|
548
|
+
const inheritedSource0Value = params.inheritedFrom
|
|
549
|
+
? readManifestSource0Value(params.inheritedFrom.manifest)
|
|
550
|
+
: undefined;
|
|
551
|
+
const inheritedDescriptor = params.inheritedFrom
|
|
552
|
+
? readRunSource0Descriptor(params.inheritedFrom.manifest)
|
|
553
|
+
: null;
|
|
554
|
+
const inheritedLineage = params.inheritedFrom
|
|
555
|
+
? buildCurrentRunLineage(params.inheritedFrom.manifest)
|
|
556
|
+
: null;
|
|
557
|
+
const recordedAt = isoTimestamp();
|
|
558
|
+
if (params.inheritedFrom &&
|
|
559
|
+
inheritedLineage &&
|
|
560
|
+
inheritedSource0Value !== undefined &&
|
|
561
|
+
!inheritedDescriptor) {
|
|
562
|
+
const fresh = await materializeFreshRunSource0({
|
|
563
|
+
env: params.env,
|
|
564
|
+
paths: params.paths,
|
|
565
|
+
manifest: params.manifest,
|
|
566
|
+
targetDir,
|
|
567
|
+
inheritedFrom: inheritedLineage
|
|
568
|
+
});
|
|
569
|
+
return {
|
|
570
|
+
source_0: fresh.source_0,
|
|
571
|
+
observability: buildRunMemoryObservability({
|
|
572
|
+
manifest: params.manifest,
|
|
573
|
+
recordedAt,
|
|
574
|
+
selected: fresh.source_0,
|
|
575
|
+
selection: 'fresh_rebuild',
|
|
576
|
+
rejectedCandidates: [
|
|
577
|
+
{
|
|
578
|
+
descriptor: buildMalformedInheritedSource0Descriptor({
|
|
579
|
+
candidate: inheritedSource0Value,
|
|
580
|
+
fallbackOrigin: inheritedLineage,
|
|
581
|
+
fallbackCreatedAt: params.inheritedFrom.manifest.updated_at
|
|
582
|
+
}),
|
|
583
|
+
reason: 'provenance_contradiction',
|
|
584
|
+
detail: 'inherited source_0 descriptor is invalid'
|
|
585
|
+
}
|
|
586
|
+
],
|
|
587
|
+
repeatedFailureStreak: readRepeatedFailureStreak(params.inheritedFrom.manifest) + 1
|
|
588
|
+
})
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
if (inheritedDescriptor) {
|
|
592
|
+
let rejectedCandidate = await assessInheritedRunSource0Candidate({
|
|
593
|
+
repoRoot: params.env.repoRoot,
|
|
594
|
+
descriptor: inheritedDescriptor
|
|
595
|
+
});
|
|
596
|
+
if (!rejectedCandidate) {
|
|
597
|
+
try {
|
|
598
|
+
const inheritedPaths = resolveRunSource0Paths(params.env.repoRoot, inheritedDescriptor);
|
|
599
|
+
const contextObject = await buildContextObject({
|
|
600
|
+
source: { type: 'dir', value: inheritedPaths.dirPath },
|
|
601
|
+
targetDir,
|
|
602
|
+
chunking: {
|
|
603
|
+
targetBytes: RUN_SOURCE0_CHUNK_TARGET_BYTES,
|
|
604
|
+
overlapBytes: RUN_SOURCE0_CHUNK_OVERLAP_BYTES,
|
|
605
|
+
strategy: 'byte'
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
const source0 = buildRunSource0Descriptor({
|
|
609
|
+
repoRoot: params.env.repoRoot,
|
|
610
|
+
runDir: targetDir,
|
|
611
|
+
contextObject,
|
|
612
|
+
origin: inheritedDescriptor.origin,
|
|
613
|
+
inheritedFrom: inheritedLineage
|
|
614
|
+
});
|
|
615
|
+
return {
|
|
616
|
+
source_0: source0,
|
|
617
|
+
observability: buildRunMemoryObservability({
|
|
618
|
+
manifest: params.manifest,
|
|
619
|
+
recordedAt,
|
|
620
|
+
selected: source0,
|
|
621
|
+
selection: 'inherited_reuse',
|
|
622
|
+
rejectedCandidates: [],
|
|
623
|
+
repeatedFailureStreak: 0
|
|
624
|
+
})
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
catch (error) {
|
|
628
|
+
rejectedCandidate = {
|
|
629
|
+
descriptor: inheritedDescriptor,
|
|
630
|
+
reason: 'provenance_contradiction',
|
|
631
|
+
detail: error?.message ?? 'failed to materialize inherited source_0 context'
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
const fresh = await materializeFreshRunSource0({
|
|
636
|
+
env: params.env,
|
|
637
|
+
paths: params.paths,
|
|
638
|
+
manifest: params.manifest,
|
|
639
|
+
targetDir,
|
|
640
|
+
inheritedFrom: inheritedLineage
|
|
641
|
+
});
|
|
642
|
+
return {
|
|
643
|
+
source_0: fresh.source_0,
|
|
644
|
+
observability: buildRunMemoryObservability({
|
|
645
|
+
manifest: params.manifest,
|
|
646
|
+
recordedAt,
|
|
647
|
+
selected: fresh.source_0,
|
|
648
|
+
selection: 'fresh_rebuild',
|
|
649
|
+
rejectedCandidates: [rejectedCandidate],
|
|
650
|
+
repeatedFailureStreak: readRepeatedFailureStreak(params.inheritedFrom?.manifest) + 1
|
|
651
|
+
})
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
const fresh = await materializeFreshRunSource0({
|
|
655
|
+
env: params.env,
|
|
656
|
+
paths: params.paths,
|
|
657
|
+
manifest: params.manifest,
|
|
658
|
+
targetDir,
|
|
659
|
+
inheritedFrom: null
|
|
660
|
+
});
|
|
661
|
+
return {
|
|
662
|
+
source_0: fresh.source_0,
|
|
663
|
+
observability: buildRunMemoryObservability({
|
|
664
|
+
manifest: params.manifest,
|
|
665
|
+
recordedAt,
|
|
666
|
+
selected: fresh.source_0,
|
|
667
|
+
selection: 'root',
|
|
668
|
+
rejectedCandidates: [],
|
|
669
|
+
repeatedFailureStreak: 0
|
|
670
|
+
})
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
export function refreshRunMemoryObservability(manifest, recordedAt = isoTimestamp()) {
|
|
674
|
+
const observability = manifest.memory?.observability;
|
|
675
|
+
if (!observability) {
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
applyRunMemoryManualRepairState(observability, manifest, recordedAt);
|
|
679
|
+
return true;
|
|
680
|
+
}
|
|
681
|
+
export function buildRunMemoryObservabilityMetrics(observability) {
|
|
682
|
+
if (!observability) {
|
|
683
|
+
return undefined;
|
|
684
|
+
}
|
|
685
|
+
return {
|
|
686
|
+
recorded_at: observability.recorded_at,
|
|
687
|
+
selected_memory: observability.selected_memory,
|
|
688
|
+
counters: observability.counters
|
|
689
|
+
};
|
|
690
|
+
}
|