synorch 0.2.0 → 0.4.0-beta.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/CHANGELOG.md +55 -1
- package/README.md +338 -28
- package/dist/application/doctor-service.d.ts +16 -0
- package/dist/application/doctor-service.d.ts.map +1 -1
- package/dist/application/doctor-service.js +230 -32
- package/dist/application/doctor-service.js.map +1 -1
- package/dist/application/generated-skill-doctor.d.ts +9 -0
- package/dist/application/generated-skill-doctor.d.ts.map +1 -0
- package/dist/application/generated-skill-doctor.js +433 -0
- package/dist/application/generated-skill-doctor.js.map +1 -0
- package/dist/application/project-discovery.d.ts +26 -1
- package/dist/application/project-discovery.d.ts.map +1 -1
- package/dist/application/project-discovery.js +99 -6
- package/dist/application/project-discovery.js.map +1 -1
- package/dist/application/safe-path.d.ts +19 -0
- package/dist/application/safe-path.d.ts.map +1 -0
- package/dist/application/safe-path.js +35 -0
- package/dist/application/safe-path.js.map +1 -0
- package/dist/application/size-ceiling.d.ts +15 -0
- package/dist/application/size-ceiling.d.ts.map +1 -0
- package/dist/application/size-ceiling.js +32 -0
- package/dist/application/size-ceiling.js.map +1 -0
- package/dist/application/structure-service.d.ts.map +1 -1
- package/dist/application/structure-service.js +10 -1
- package/dist/application/structure-service.js.map +1 -1
- package/dist/build-info.json +4 -0
- package/dist/cli.js +135 -18
- package/dist/cli.js.map +1 -1
- package/dist/domain/canonical-contracts.d.ts +69 -0
- package/dist/domain/canonical-contracts.d.ts.map +1 -0
- package/dist/domain/canonical-contracts.js +92 -0
- package/dist/domain/canonical-contracts.js.map +1 -0
- package/dist/domain/generated-skill.d.ts +55 -0
- package/dist/domain/generated-skill.d.ts.map +1 -0
- package/dist/domain/generated-skill.js +90 -0
- package/dist/domain/generated-skill.js.map +1 -0
- package/dist/domain/generation.d.ts +15 -2
- package/dist/domain/generation.d.ts.map +1 -1
- package/dist/domain/observation-ledger.d.ts +118 -0
- package/dist/domain/observation-ledger.d.ts.map +1 -0
- package/dist/domain/observation-ledger.js +183 -0
- package/dist/domain/observation-ledger.js.map +1 -0
- package/dist/domain/product.d.ts +1 -1
- package/dist/domain/product.d.ts.map +1 -1
- package/dist/domain/product.js +1 -1
- package/dist/domain/product.js.map +1 -1
- package/dist/domain/relative-path.d.ts +21 -0
- package/dist/domain/relative-path.d.ts.map +1 -0
- package/dist/domain/relative-path.js +43 -0
- package/dist/domain/relative-path.js.map +1 -0
- package/dist/domain/skill-packs.d.ts.map +1 -1
- package/dist/domain/skill-packs.js +1 -0
- package/dist/domain/skill-packs.js.map +1 -1
- package/dist/domain/suggest.d.ts +5 -0
- package/dist/domain/suggest.d.ts.map +1 -0
- package/dist/domain/suggest.js +32 -0
- package/dist/domain/suggest.js.map +1 -0
- package/dist/domain/zod-issues.d.ts +21 -0
- package/dist/domain/zod-issues.d.ts.map +1 -0
- package/dist/domain/zod-issues.js +27 -0
- package/dist/domain/zod-issues.js.map +1 -0
- package/dist/harness/auth/api-key.d.ts +13 -0
- package/dist/harness/auth/api-key.d.ts.map +1 -0
- package/dist/harness/auth/api-key.js +87 -0
- package/dist/harness/auth/api-key.js.map +1 -0
- package/dist/harness/auth/claude-bridge.d.ts +22 -0
- package/dist/harness/auth/claude-bridge.d.ts.map +1 -0
- package/dist/harness/auth/claude-bridge.js +92 -0
- package/dist/harness/auth/claude-bridge.js.map +1 -0
- package/dist/harness/auth/command.d.ts +17 -0
- package/dist/harness/auth/command.d.ts.map +1 -0
- package/dist/harness/auth/command.js +223 -0
- package/dist/harness/auth/command.js.map +1 -0
- package/dist/harness/auth/credential-store.d.ts +30 -0
- package/dist/harness/auth/credential-store.d.ts.map +1 -0
- package/dist/harness/auth/credential-store.js +270 -0
- package/dist/harness/auth/credential-store.js.map +1 -0
- package/dist/harness/auth/index.d.ts +13 -0
- package/dist/harness/auth/index.d.ts.map +1 -0
- package/dist/harness/auth/index.js +10 -0
- package/dist/harness/auth/index.js.map +1 -0
- package/dist/harness/auth/json-file.d.ts +8 -0
- package/dist/harness/auth/json-file.d.ts.map +1 -0
- package/dist/harness/auth/json-file.js +57 -0
- package/dist/harness/auth/json-file.js.map +1 -0
- package/dist/harness/auth/jwt.d.ts +11 -0
- package/dist/harness/auth/jwt.d.ts.map +1 -0
- package/dist/harness/auth/jwt.js +37 -0
- package/dist/harness/auth/jwt.js.map +1 -0
- package/dist/harness/auth/keychain.d.ts +39 -0
- package/dist/harness/auth/keychain.d.ts.map +1 -0
- package/dist/harness/auth/keychain.js +191 -0
- package/dist/harness/auth/keychain.js.map +1 -0
- package/dist/harness/auth/locks.d.ts +19 -0
- package/dist/harness/auth/locks.d.ts.map +1 -0
- package/dist/harness/auth/locks.js +102 -0
- package/dist/harness/auth/locks.js.map +1 -0
- package/dist/harness/auth/notices.d.ts +6 -0
- package/dist/harness/auth/notices.d.ts.map +1 -0
- package/dist/harness/auth/notices.js +29 -0
- package/dist/harness/auth/notices.js.map +1 -0
- package/dist/harness/auth/openai-chatgpt.d.ts +32 -0
- package/dist/harness/auth/openai-chatgpt.d.ts.map +1 -0
- package/dist/harness/auth/openai-chatgpt.js +446 -0
- package/dist/harness/auth/openai-chatgpt.js.map +1 -0
- package/dist/harness/auth/profile-state.d.ts +25 -0
- package/dist/harness/auth/profile-state.d.ts.map +1 -0
- package/dist/harness/auth/profile-state.js +77 -0
- package/dist/harness/auth/profile-state.js.map +1 -0
- package/dist/harness/auth/providers.d.ts +27 -0
- package/dist/harness/auth/providers.d.ts.map +1 -0
- package/dist/harness/auth/providers.js +66 -0
- package/dist/harness/auth/providers.js.map +1 -0
- package/dist/harness/auth/resolved-credential.d.ts +11 -0
- package/dist/harness/auth/resolved-credential.d.ts.map +1 -0
- package/dist/harness/auth/resolved-credential.js +35 -0
- package/dist/harness/auth/resolved-credential.js.map +1 -0
- package/dist/harness/cli/appearance.d.ts +28 -0
- package/dist/harness/cli/appearance.d.ts.map +1 -0
- package/dist/harness/cli/appearance.js +123 -0
- package/dist/harness/cli/appearance.js.map +1 -0
- package/dist/harness/cli/args.d.ts +429 -0
- package/dist/harness/cli/args.d.ts.map +1 -0
- package/dist/harness/cli/args.js +372 -0
- package/dist/harness/cli/args.js.map +1 -0
- package/dist/harness/cli/attachments.d.ts +44 -0
- package/dist/harness/cli/attachments.d.ts.map +1 -0
- package/dist/harness/cli/attachments.js +176 -0
- package/dist/harness/cli/attachments.js.map +1 -0
- package/dist/harness/cli/canonical.d.ts +64 -0
- package/dist/harness/cli/canonical.d.ts.map +1 -0
- package/dist/harness/cli/canonical.js +455 -0
- package/dist/harness/cli/canonical.js.map +1 -0
- package/dist/harness/cli/claude-native-approvals.d.ts +45 -0
- package/dist/harness/cli/claude-native-approvals.d.ts.map +1 -0
- package/dist/harness/cli/claude-native-approvals.js +183 -0
- package/dist/harness/cli/claude-native-approvals.js.map +1 -0
- package/dist/harness/cli/command-grants.d.ts +23 -0
- package/dist/harness/cli/command-grants.d.ts.map +1 -0
- package/dist/harness/cli/command-grants.js +76 -0
- package/dist/harness/cli/command-grants.js.map +1 -0
- package/dist/harness/cli/config-command.d.ts +98 -0
- package/dist/harness/cli/config-command.d.ts.map +1 -0
- package/dist/harness/cli/config-command.js +561 -0
- package/dist/harness/cli/config-command.js.map +1 -0
- package/dist/harness/cli/config.d.ts +429 -0
- package/dist/harness/cli/config.d.ts.map +1 -0
- package/dist/harness/cli/config.js +504 -0
- package/dist/harness/cli/config.js.map +1 -0
- package/dist/harness/cli/conversation.d.ts +35 -0
- package/dist/harness/cli/conversation.d.ts.map +1 -0
- package/dist/harness/cli/conversation.js +3755 -0
- package/dist/harness/cli/conversation.js.map +1 -0
- package/dist/harness/cli/doctor.d.ts +32 -0
- package/dist/harness/cli/doctor.d.ts.map +1 -0
- package/dist/harness/cli/doctor.js +329 -0
- package/dist/harness/cli/doctor.js.map +1 -0
- package/dist/harness/cli/effort-command.d.ts +41 -0
- package/dist/harness/cli/effort-command.d.ts.map +1 -0
- package/dist/harness/cli/effort-command.js +133 -0
- package/dist/harness/cli/effort-command.js.map +1 -0
- package/dist/harness/cli/extensions/agents.d.ts +40 -0
- package/dist/harness/cli/extensions/agents.d.ts.map +1 -0
- package/dist/harness/cli/extensions/agents.js +66 -0
- package/dist/harness/cli/extensions/agents.js.map +1 -0
- package/dist/harness/cli/extensions/catalog.d.ts +134 -0
- package/dist/harness/cli/extensions/catalog.d.ts.map +1 -0
- package/dist/harness/cli/extensions/catalog.js +213 -0
- package/dist/harness/cli/extensions/catalog.js.map +1 -0
- package/dist/harness/cli/extensions/claude-home.d.ts +33 -0
- package/dist/harness/cli/extensions/claude-home.d.ts.map +1 -0
- package/dist/harness/cli/extensions/claude-home.js +78 -0
- package/dist/harness/cli/extensions/claude-home.js.map +1 -0
- package/dist/harness/cli/extensions/controller.d.ts +51 -0
- package/dist/harness/cli/extensions/controller.d.ts.map +1 -0
- package/dist/harness/cli/extensions/controller.js +67 -0
- package/dist/harness/cli/extensions/controller.js.map +1 -0
- package/dist/harness/cli/extensions/hooks.d.ts +164 -0
- package/dist/harness/cli/extensions/hooks.d.ts.map +1 -0
- package/dist/harness/cli/extensions/hooks.js +442 -0
- package/dist/harness/cli/extensions/hooks.js.map +1 -0
- package/dist/harness/cli/extensions/index.d.ts +10 -0
- package/dist/harness/cli/extensions/index.d.ts.map +1 -0
- package/dist/harness/cli/extensions/index.js +10 -0
- package/dist/harness/cli/extensions/index.js.map +1 -0
- package/dist/harness/cli/extensions/markdown.d.ts +46 -0
- package/dist/harness/cli/extensions/markdown.d.ts.map +1 -0
- package/dist/harness/cli/extensions/markdown.js +139 -0
- package/dist/harness/cli/extensions/markdown.js.map +1 -0
- package/dist/harness/cli/extensions/plugins.d.ts +160 -0
- package/dist/harness/cli/extensions/plugins.d.ts.map +1 -0
- package/dist/harness/cli/extensions/plugins.js +645 -0
- package/dist/harness/cli/extensions/plugins.js.map +1 -0
- package/dist/harness/cli/extensions/tool-hooks.d.ts +28 -0
- package/dist/harness/cli/extensions/tool-hooks.d.ts.map +1 -0
- package/dist/harness/cli/extensions/tool-hooks.js +63 -0
- package/dist/harness/cli/extensions/tool-hooks.js.map +1 -0
- package/dist/harness/cli/extensions-command.d.ts +64 -0
- package/dist/harness/cli/extensions-command.d.ts.map +1 -0
- package/dist/harness/cli/extensions-command.js +639 -0
- package/dist/harness/cli/extensions-command.js.map +1 -0
- package/dist/harness/cli/help.d.ts +9 -0
- package/dist/harness/cli/help.d.ts.map +1 -0
- package/dist/harness/cli/help.js +191 -0
- package/dist/harness/cli/help.js.map +1 -0
- package/dist/harness/cli/index.d.ts +52 -0
- package/dist/harness/cli/index.d.ts.map +1 -0
- package/dist/harness/cli/index.js +297 -0
- package/dist/harness/cli/index.js.map +1 -0
- package/dist/harness/cli/inspect.d.ts +40 -0
- package/dist/harness/cli/inspect.d.ts.map +1 -0
- package/dist/harness/cli/inspect.js +185 -0
- package/dist/harness/cli/inspect.js.map +1 -0
- package/dist/harness/cli/mcp-command.d.ts +61 -0
- package/dist/harness/cli/mcp-command.d.ts.map +1 -0
- package/dist/harness/cli/mcp-command.js +519 -0
- package/dist/harness/cli/mcp-command.js.map +1 -0
- package/dist/harness/cli/memory-desk.d.ts +28 -0
- package/dist/harness/cli/memory-desk.d.ts.map +1 -0
- package/dist/harness/cli/memory-desk.js +275 -0
- package/dist/harness/cli/memory-desk.js.map +1 -0
- package/dist/harness/cli/model-picker.d.ts +44 -0
- package/dist/harness/cli/model-picker.d.ts.map +1 -0
- package/dist/harness/cli/model-picker.js +267 -0
- package/dist/harness/cli/model-picker.js.map +1 -0
- package/dist/harness/cli/onboarding.d.ts +29 -0
- package/dist/harness/cli/onboarding.d.ts.map +1 -0
- package/dist/harness/cli/onboarding.js +101 -0
- package/dist/harness/cli/onboarding.js.map +1 -0
- package/dist/harness/cli/orchestrate-tool.d.ts +60 -0
- package/dist/harness/cli/orchestrate-tool.d.ts.map +1 -0
- package/dist/harness/cli/orchestrate-tool.js +167 -0
- package/dist/harness/cli/orchestrate-tool.js.map +1 -0
- package/dist/harness/cli/orchestration-view.d.ts +57 -0
- package/dist/harness/cli/orchestration-view.d.ts.map +1 -0
- package/dist/harness/cli/orchestration-view.js +371 -0
- package/dist/harness/cli/orchestration-view.js.map +1 -0
- package/dist/harness/cli/outcome.d.ts +11 -0
- package/dist/harness/cli/outcome.d.ts.map +1 -0
- package/dist/harness/cli/outcome.js +70 -0
- package/dist/harness/cli/outcome.js.map +1 -0
- package/dist/harness/cli/panels/common.d.ts +30 -0
- package/dist/harness/cli/panels/common.d.ts.map +1 -0
- package/dist/harness/cli/panels/common.js +143 -0
- package/dist/harness/cli/panels/common.js.map +1 -0
- package/dist/harness/cli/panels/mcp.d.ts +18 -0
- package/dist/harness/cli/panels/mcp.d.ts.map +1 -0
- package/dist/harness/cli/panels/mcp.js +132 -0
- package/dist/harness/cli/panels/mcp.js.map +1 -0
- package/dist/harness/cli/panels/plugins.d.ts +8 -0
- package/dist/harness/cli/panels/plugins.d.ts.map +1 -0
- package/dist/harness/cli/panels/plugins.js +114 -0
- package/dist/harness/cli/panels/plugins.js.map +1 -0
- package/dist/harness/cli/panels/session.d.ts +54 -0
- package/dist/harness/cli/panels/session.d.ts.map +1 -0
- package/dist/harness/cli/panels/session.js +221 -0
- package/dist/harness/cli/panels/session.js.map +1 -0
- package/dist/harness/cli/panels/skills.d.ts +16 -0
- package/dist/harness/cli/panels/skills.d.ts.map +1 -0
- package/dist/harness/cli/panels/skills.js +146 -0
- package/dist/harness/cli/panels/skills.js.map +1 -0
- package/dist/harness/cli/project-profile.d.ts +87 -0
- package/dist/harness/cli/project-profile.d.ts.map +1 -0
- package/dist/harness/cli/project-profile.js +709 -0
- package/dist/harness/cli/project-profile.js.map +1 -0
- package/dist/harness/cli/project-scope.d.ts +2 -0
- package/dist/harness/cli/project-scope.d.ts.map +1 -0
- package/dist/harness/cli/project-scope.js +55 -0
- package/dist/harness/cli/project-scope.js.map +1 -0
- package/dist/harness/cli/renderers.d.ts +75 -0
- package/dist/harness/cli/renderers.d.ts.map +1 -0
- package/dist/harness/cli/renderers.js +162 -0
- package/dist/harness/cli/renderers.js.map +1 -0
- package/dist/harness/cli/rewind.d.ts +54 -0
- package/dist/harness/cli/rewind.d.ts.map +1 -0
- package/dist/harness/cli/rewind.js +80 -0
- package/dist/harness/cli/rewind.js.map +1 -0
- package/dist/harness/cli/role-policy.d.ts +8 -0
- package/dist/harness/cli/role-policy.d.ts.map +1 -0
- package/dist/harness/cli/role-policy.js +53 -0
- package/dist/harness/cli/role-policy.js.map +1 -0
- package/dist/harness/cli/run-summary.d.ts +16 -0
- package/dist/harness/cli/run-summary.d.ts.map +1 -0
- package/dist/harness/cli/run-summary.js +105 -0
- package/dist/harness/cli/run-summary.js.map +1 -0
- package/dist/harness/cli/runtime.d.ts +182 -0
- package/dist/harness/cli/runtime.d.ts.map +1 -0
- package/dist/harness/cli/runtime.js +999 -0
- package/dist/harness/cli/runtime.js.map +1 -0
- package/dist/harness/cli/scripted-script.d.ts +50 -0
- package/dist/harness/cli/scripted-script.d.ts.map +1 -0
- package/dist/harness/cli/scripted-script.js +110 -0
- package/dist/harness/cli/scripted-script.js.map +1 -0
- package/dist/harness/cli/session-git.d.ts +76 -0
- package/dist/harness/cli/session-git.d.ts.map +1 -0
- package/dist/harness/cli/session-git.js +146 -0
- package/dist/harness/cli/session-git.js.map +1 -0
- package/dist/harness/cli/session.d.ts +22 -0
- package/dist/harness/cli/session.d.ts.map +1 -0
- package/dist/harness/cli/session.js +203 -0
- package/dist/harness/cli/session.js.map +1 -0
- package/dist/harness/cli/slash-commands.d.ts +85 -0
- package/dist/harness/cli/slash-commands.d.ts.map +1 -0
- package/dist/harness/cli/slash-commands.js +114 -0
- package/dist/harness/cli/slash-commands.js.map +1 -0
- package/dist/harness/cli/startup-notices.d.ts +32 -0
- package/dist/harness/cli/startup-notices.d.ts.map +1 -0
- package/dist/harness/cli/startup-notices.js +93 -0
- package/dist/harness/cli/startup-notices.js.map +1 -0
- package/dist/harness/cli/terminal.d.ts +32 -0
- package/dist/harness/cli/terminal.d.ts.map +1 -0
- package/dist/harness/cli/terminal.js +21 -0
- package/dist/harness/cli/terminal.js.map +1 -0
- package/dist/harness/cli/transparency.d.ts +39 -0
- package/dist/harness/cli/transparency.d.ts.map +1 -0
- package/dist/harness/cli/transparency.js +491 -0
- package/dist/harness/cli/transparency.js.map +1 -0
- package/dist/harness/cli/trust.d.ts +40 -0
- package/dist/harness/cli/trust.d.ts.map +1 -0
- package/dist/harness/cli/trust.js +133 -0
- package/dist/harness/cli/trust.js.map +1 -0
- package/dist/harness/cli/usage-stats.d.ts +57 -0
- package/dist/harness/cli/usage-stats.d.ts.map +1 -0
- package/dist/harness/cli/usage-stats.js +341 -0
- package/dist/harness/cli/usage-stats.js.map +1 -0
- package/dist/harness/context/compaction.d.ts +69 -0
- package/dist/harness/context/compaction.d.ts.map +1 -0
- package/dist/harness/context/compaction.js +149 -0
- package/dist/harness/context/compaction.js.map +1 -0
- package/dist/harness/context/context-builder.d.ts +76 -0
- package/dist/harness/context/context-builder.d.ts.map +1 -0
- package/dist/harness/context/context-builder.js +367 -0
- package/dist/harness/context/context-builder.js.map +1 -0
- package/dist/harness/context/history.d.ts +31 -0
- package/dist/harness/context/history.d.ts.map +1 -0
- package/dist/harness/context/history.js +105 -0
- package/dist/harness/context/history.js.map +1 -0
- package/dist/harness/context/index.d.ts +11 -0
- package/dist/harness/context/index.d.ts.map +1 -0
- package/dist/harness/context/index.js +9 -0
- package/dist/harness/context/index.js.map +1 -0
- package/dist/harness/context/instructions.d.ts +30 -0
- package/dist/harness/context/instructions.d.ts.map +1 -0
- package/dist/harness/context/instructions.js +82 -0
- package/dist/harness/context/instructions.js.map +1 -0
- package/dist/harness/context/model-view.d.ts +46 -0
- package/dist/harness/context/model-view.d.ts.map +1 -0
- package/dist/harness/context/model-view.js +136 -0
- package/dist/harness/context/model-view.js.map +1 -0
- package/dist/harness/context/scope.d.ts +9 -0
- package/dist/harness/context/scope.d.ts.map +1 -0
- package/dist/harness/context/scope.js +50 -0
- package/dist/harness/context/scope.js.map +1 -0
- package/dist/harness/context/skills.d.ts +75 -0
- package/dist/harness/context/skills.d.ts.map +1 -0
- package/dist/harness/context/skills.js +109 -0
- package/dist/harness/context/skills.js.map +1 -0
- package/dist/harness/context/tokens.d.ts +10 -0
- package/dist/harness/context/tokens.d.ts.map +1 -0
- package/dist/harness/context/tokens.js +39 -0
- package/dist/harness/context/tokens.js.map +1 -0
- package/dist/harness/contracts/auth.d.ts +214 -0
- package/dist/harness/contracts/auth.d.ts.map +1 -0
- package/dist/harness/contracts/auth.js +120 -0
- package/dist/harness/contracts/auth.js.map +1 -0
- package/dist/harness/contracts/choice.d.ts +115 -0
- package/dist/harness/contracts/choice.d.ts.map +1 -0
- package/dist/harness/contracts/choice.js +115 -0
- package/dist/harness/contracts/choice.js.map +1 -0
- package/dist/harness/contracts/common.d.ts +119 -0
- package/dist/harness/contracts/common.d.ts.map +1 -0
- package/dist/harness/contracts/common.js +66 -0
- package/dist/harness/contracts/common.js.map +1 -0
- package/dist/harness/contracts/digest.d.ts +59 -0
- package/dist/harness/contracts/digest.d.ts.map +1 -0
- package/dist/harness/contracts/digest.js +88 -0
- package/dist/harness/contracts/digest.js.map +1 -0
- package/dist/harness/contracts/errors.d.ts +70 -0
- package/dist/harness/contracts/errors.d.ts.map +1 -0
- package/dist/harness/contracts/errors.js +87 -0
- package/dist/harness/contracts/errors.js.map +1 -0
- package/dist/harness/contracts/events.d.ts +3094 -0
- package/dist/harness/contracts/events.d.ts.map +1 -0
- package/dist/harness/contracts/events.js +426 -0
- package/dist/harness/contracts/events.js.map +1 -0
- package/dist/harness/contracts/evidence.d.ts +286 -0
- package/dist/harness/contracts/evidence.d.ts.map +1 -0
- package/dist/harness/contracts/evidence.js +234 -0
- package/dist/harness/contracts/evidence.js.map +1 -0
- package/dist/harness/contracts/ids.d.ts +77 -0
- package/dist/harness/contracts/ids.d.ts.map +1 -0
- package/dist/harness/contracts/ids.js +126 -0
- package/dist/harness/contracts/ids.js.map +1 -0
- package/dist/harness/contracts/index.d.ts +23 -0
- package/dist/harness/contracts/index.d.ts.map +1 -0
- package/dist/harness/contracts/index.js +23 -0
- package/dist/harness/contracts/index.js.map +1 -0
- package/dist/harness/contracts/jsonl.d.ts +3386 -0
- package/dist/harness/contracts/jsonl.d.ts.map +1 -0
- package/dist/harness/contracts/jsonl.js +87 -0
- package/dist/harness/contracts/jsonl.js.map +1 -0
- package/dist/harness/contracts/memory.d.ts +271 -0
- package/dist/harness/contracts/memory.d.ts.map +1 -0
- package/dist/harness/contracts/memory.js +152 -0
- package/dist/harness/contracts/memory.js.map +1 -0
- package/dist/harness/contracts/model.d.ts +1201 -0
- package/dist/harness/contracts/model.d.ts.map +1 -0
- package/dist/harness/contracts/model.js +386 -0
- package/dist/harness/contracts/model.js.map +1 -0
- package/dist/harness/contracts/packets.d.ts +945 -0
- package/dist/harness/contracts/packets.d.ts.map +1 -0
- package/dist/harness/contracts/packets.js +535 -0
- package/dist/harness/contracts/packets.js.map +1 -0
- package/dist/harness/contracts/panel.d.ts +140 -0
- package/dist/harness/contracts/panel.d.ts.map +1 -0
- package/dist/harness/contracts/panel.js +19 -0
- package/dist/harness/contracts/panel.js.map +1 -0
- package/dist/harness/contracts/paths.d.ts +58 -0
- package/dist/harness/contracts/paths.d.ts.map +1 -0
- package/dist/harness/contracts/paths.js +204 -0
- package/dist/harness/contracts/paths.js.map +1 -0
- package/dist/harness/contracts/policy.d.ts +459 -0
- package/dist/harness/contracts/policy.d.ts.map +1 -0
- package/dist/harness/contracts/policy.js +338 -0
- package/dist/harness/contracts/policy.js.map +1 -0
- package/dist/harness/contracts/projection.d.ts +111 -0
- package/dist/harness/contracts/projection.d.ts.map +1 -0
- package/dist/harness/contracts/projection.js +2 -0
- package/dist/harness/contracts/projection.js.map +1 -0
- package/dist/harness/contracts/renderer.d.ts +291 -0
- package/dist/harness/contracts/renderer.d.ts.map +1 -0
- package/dist/harness/contracts/renderer.js +36 -0
- package/dist/harness/contracts/renderer.js.map +1 -0
- package/dist/harness/contracts/roles.d.ts +28 -0
- package/dist/harness/contracts/roles.d.ts.map +1 -0
- package/dist/harness/contracts/roles.js +36 -0
- package/dist/harness/contracts/roles.js.map +1 -0
- package/dist/harness/contracts/runtime.d.ts +283 -0
- package/dist/harness/contracts/runtime.d.ts.map +1 -0
- package/dist/harness/contracts/runtime.js +13 -0
- package/dist/harness/contracts/runtime.js.map +1 -0
- package/dist/harness/contracts/state.d.ts +124 -0
- package/dist/harness/contracts/state.d.ts.map +1 -0
- package/dist/harness/contracts/state.js +172 -0
- package/dist/harness/contracts/state.js.map +1 -0
- package/dist/harness/contracts/store.d.ts +117 -0
- package/dist/harness/contracts/store.d.ts.map +1 -0
- package/dist/harness/contracts/store.js +54 -0
- package/dist/harness/contracts/store.js.map +1 -0
- package/dist/harness/contracts/tools.d.ts +296 -0
- package/dist/harness/contracts/tools.d.ts.map +1 -0
- package/dist/harness/contracts/tools.js +117 -0
- package/dist/harness/contracts/tools.js.map +1 -0
- package/dist/harness/contracts/views.d.ts +468 -0
- package/dist/harness/contracts/views.d.ts.map +1 -0
- package/dist/harness/contracts/views.js +2 -0
- package/dist/harness/contracts/views.js.map +1 -0
- package/dist/harness/core/driver.d.ts +53 -0
- package/dist/harness/core/driver.d.ts.map +1 -0
- package/dist/harness/core/driver.js +566 -0
- package/dist/harness/core/driver.js.map +1 -0
- package/dist/harness/core/envelope.d.ts +11 -0
- package/dist/harness/core/envelope.d.ts.map +1 -0
- package/dist/harness/core/envelope.js +35 -0
- package/dist/harness/core/envelope.js.map +1 -0
- package/dist/harness/core/index.d.ts +7 -0
- package/dist/harness/core/index.d.ts.map +1 -0
- package/dist/harness/core/index.js +5 -0
- package/dist/harness/core/index.js.map +1 -0
- package/dist/harness/core/projection.d.ts +10 -0
- package/dist/harness/core/projection.d.ts.map +1 -0
- package/dist/harness/core/projection.js +268 -0
- package/dist/harness/core/projection.js.map +1 -0
- package/dist/harness/core/recovery.d.ts +14 -0
- package/dist/harness/core/recovery.d.ts.map +1 -0
- package/dist/harness/core/recovery.js +115 -0
- package/dist/harness/core/recovery.js.map +1 -0
- package/dist/harness/core/stream.d.ts +23 -0
- package/dist/harness/core/stream.d.ts.map +1 -0
- package/dist/harness/core/stream.js +102 -0
- package/dist/harness/core/stream.js.map +1 -0
- package/dist/harness/core/testing.d.ts +80 -0
- package/dist/harness/core/testing.d.ts.map +1 -0
- package/dist/harness/core/testing.js +258 -0
- package/dist/harness/core/testing.js.map +1 -0
- package/dist/harness/mcp/approvals.d.ts +14 -0
- package/dist/harness/mcp/approvals.d.ts.map +1 -0
- package/dist/harness/mcp/approvals.js +60 -0
- package/dist/harness/mcp/approvals.js.map +1 -0
- package/dist/harness/mcp/client.d.ts +74 -0
- package/dist/harness/mcp/client.d.ts.map +1 -0
- package/dist/harness/mcp/client.js +214 -0
- package/dist/harness/mcp/client.js.map +1 -0
- package/dist/harness/mcp/config.d.ts +156 -0
- package/dist/harness/mcp/config.d.ts.map +1 -0
- package/dist/harness/mcp/config.js +180 -0
- package/dist/harness/mcp/config.js.map +1 -0
- package/dist/harness/mcp/errors.d.ts +24 -0
- package/dist/harness/mcp/errors.d.ts.map +1 -0
- package/dist/harness/mcp/errors.js +67 -0
- package/dist/harness/mcp/errors.js.map +1 -0
- package/dist/harness/mcp/index.d.ts +9 -0
- package/dist/harness/mcp/index.d.ts.map +1 -0
- package/dist/harness/mcp/index.js +9 -0
- package/dist/harness/mcp/index.js.map +1 -0
- package/dist/harness/mcp/manager.d.ts +115 -0
- package/dist/harness/mcp/manager.d.ts.map +1 -0
- package/dist/harness/mcp/manager.js +361 -0
- package/dist/harness/mcp/manager.js.map +1 -0
- package/dist/harness/mcp/oauth.d.ts +54 -0
- package/dist/harness/mcp/oauth.d.ts.map +1 -0
- package/dist/harness/mcp/oauth.js +253 -0
- package/dist/harness/mcp/oauth.js.map +1 -0
- package/dist/harness/mcp/tools.d.ts +24 -0
- package/dist/harness/mcp/tools.d.ts.map +1 -0
- package/dist/harness/mcp/tools.js +142 -0
- package/dist/harness/mcp/tools.js.map +1 -0
- package/dist/harness/memory/bootstrap.d.ts +55 -0
- package/dist/harness/memory/bootstrap.d.ts.map +1 -0
- package/dist/harness/memory/bootstrap.js +124 -0
- package/dist/harness/memory/bootstrap.js.map +1 -0
- package/dist/harness/memory/desk.d.ts +74 -0
- package/dist/harness/memory/desk.d.ts.map +1 -0
- package/dist/harness/memory/desk.js +211 -0
- package/dist/harness/memory/desk.js.map +1 -0
- package/dist/harness/memory/graph.d.ts +24 -0
- package/dist/harness/memory/graph.d.ts.map +1 -0
- package/dist/harness/memory/graph.js +92 -0
- package/dist/harness/memory/graph.js.map +1 -0
- package/dist/harness/memory/index.d.ts +12 -0
- package/dist/harness/memory/index.d.ts.map +1 -0
- package/dist/harness/memory/index.js +10 -0
- package/dist/harness/memory/index.js.map +1 -0
- package/dist/harness/memory/markdown-memory-store.d.ts +122 -0
- package/dist/harness/memory/markdown-memory-store.d.ts.map +1 -0
- package/dist/harness/memory/markdown-memory-store.js +419 -0
- package/dist/harness/memory/markdown-memory-store.js.map +1 -0
- package/dist/harness/memory/memory-command.d.ts +22 -0
- package/dist/harness/memory/memory-command.d.ts.map +1 -0
- package/dist/harness/memory/memory-command.js +335 -0
- package/dist/harness/memory/memory-command.js.map +1 -0
- package/dist/harness/memory/memory-index.d.ts +71 -0
- package/dist/harness/memory/memory-index.d.ts.map +1 -0
- package/dist/harness/memory/memory-index.js +206 -0
- package/dist/harness/memory/memory-index.js.map +1 -0
- package/dist/harness/memory/note-format.d.ts +20 -0
- package/dist/harness/memory/note-format.d.ts.map +1 -0
- package/dist/harness/memory/note-format.js +69 -0
- package/dist/harness/memory/note-format.js.map +1 -0
- package/dist/harness/memory/obsidian.d.ts +14 -0
- package/dist/harness/memory/obsidian.d.ts.map +1 -0
- package/dist/harness/memory/obsidian.js +64 -0
- package/dist/harness/memory/obsidian.js.map +1 -0
- package/dist/harness/memory/redaction.d.ts +15 -0
- package/dist/harness/memory/redaction.d.ts.map +1 -0
- package/dist/harness/memory/redaction.js +64 -0
- package/dist/harness/memory/redaction.js.map +1 -0
- package/dist/harness/memory/relations.d.ts +29 -0
- package/dist/harness/memory/relations.d.ts.map +1 -0
- package/dist/harness/memory/relations.js +117 -0
- package/dist/harness/memory/relations.js.map +1 -0
- package/dist/harness/memory/vault.d.ts +35 -0
- package/dist/harness/memory/vault.d.ts.map +1 -0
- package/dist/harness/memory/vault.js +194 -0
- package/dist/harness/memory/vault.js.map +1 -0
- package/dist/harness/orchestration/approval.d.ts +29 -0
- package/dist/harness/orchestration/approval.d.ts.map +1 -0
- package/dist/harness/orchestration/approval.js +86 -0
- package/dist/harness/orchestration/approval.js.map +1 -0
- package/dist/harness/orchestration/artifact-review.d.ts +219 -0
- package/dist/harness/orchestration/artifact-review.d.ts.map +1 -0
- package/dist/harness/orchestration/artifact-review.js +319 -0
- package/dist/harness/orchestration/artifact-review.js.map +1 -0
- package/dist/harness/orchestration/attempt-log.d.ts +53 -0
- package/dist/harness/orchestration/attempt-log.d.ts.map +1 -0
- package/dist/harness/orchestration/attempt-log.js +138 -0
- package/dist/harness/orchestration/attempt-log.js.map +1 -0
- package/dist/harness/orchestration/budget.d.ts +110 -0
- package/dist/harness/orchestration/budget.d.ts.map +1 -0
- package/dist/harness/orchestration/budget.js +197 -0
- package/dist/harness/orchestration/budget.js.map +1 -0
- package/dist/harness/orchestration/capabilities.d.ts +6 -0
- package/dist/harness/orchestration/capabilities.d.ts.map +1 -0
- package/dist/harness/orchestration/capabilities.js +80 -0
- package/dist/harness/orchestration/capabilities.js.map +1 -0
- package/dist/harness/orchestration/claims.d.ts +148 -0
- package/dist/harness/orchestration/claims.d.ts.map +1 -0
- package/dist/harness/orchestration/claims.js +64 -0
- package/dist/harness/orchestration/claims.js.map +1 -0
- package/dist/harness/orchestration/control-plane.d.ts +18 -0
- package/dist/harness/orchestration/control-plane.d.ts.map +1 -0
- package/dist/harness/orchestration/control-plane.js +74 -0
- package/dist/harness/orchestration/control-plane.js.map +1 -0
- package/dist/harness/orchestration/coordinator.d.ts +132 -0
- package/dist/harness/orchestration/coordinator.d.ts.map +1 -0
- package/dist/harness/orchestration/coordinator.js +1628 -0
- package/dist/harness/orchestration/coordinator.js.map +1 -0
- package/dist/harness/orchestration/delegation.d.ts +80 -0
- package/dist/harness/orchestration/delegation.d.ts.map +1 -0
- package/dist/harness/orchestration/delegation.js +81 -0
- package/dist/harness/orchestration/delegation.js.map +1 -0
- package/dist/harness/orchestration/evidence.d.ts +124 -0
- package/dist/harness/orchestration/evidence.d.ts.map +1 -0
- package/dist/harness/orchestration/evidence.js +576 -0
- package/dist/harness/orchestration/evidence.js.map +1 -0
- package/dist/harness/orchestration/factories.d.ts +13 -0
- package/dist/harness/orchestration/factories.d.ts.map +1 -0
- package/dist/harness/orchestration/factories.js +20 -0
- package/dist/harness/orchestration/factories.js.map +1 -0
- package/dist/harness/orchestration/git.d.ts +77 -0
- package/dist/harness/orchestration/git.d.ts.map +1 -0
- package/dist/harness/orchestration/git.js +214 -0
- package/dist/harness/orchestration/git.js.map +1 -0
- package/dist/harness/orchestration/index.d.ts +25 -0
- package/dist/harness/orchestration/index.d.ts.map +1 -0
- package/dist/harness/orchestration/index.js +23 -0
- package/dist/harness/orchestration/index.js.map +1 -0
- package/dist/harness/orchestration/isolation.d.ts +181 -0
- package/dist/harness/orchestration/isolation.d.ts.map +1 -0
- package/dist/harness/orchestration/isolation.js +1357 -0
- package/dist/harness/orchestration/isolation.js.map +1 -0
- package/dist/harness/orchestration/paths.d.ts +18 -0
- package/dist/harness/orchestration/paths.d.ts.map +1 -0
- package/dist/harness/orchestration/paths.js +56 -0
- package/dist/harness/orchestration/paths.js.map +1 -0
- package/dist/harness/orchestration/plan.d.ts +219 -0
- package/dist/harness/orchestration/plan.d.ts.map +1 -0
- package/dist/harness/orchestration/plan.js +537 -0
- package/dist/harness/orchestration/plan.js.map +1 -0
- package/dist/harness/orchestration/planner.d.ts +137 -0
- package/dist/harness/orchestration/planner.d.ts.map +1 -0
- package/dist/harness/orchestration/planner.js +162 -0
- package/dist/harness/orchestration/planner.js.map +1 -0
- package/dist/harness/orchestration/recorder.d.ts +23 -0
- package/dist/harness/orchestration/recorder.d.ts.map +1 -0
- package/dist/harness/orchestration/recorder.js +50 -0
- package/dist/harness/orchestration/recorder.js.map +1 -0
- package/dist/harness/orchestration/scheduler.d.ts +40 -0
- package/dist/harness/orchestration/scheduler.d.ts.map +1 -0
- package/dist/harness/orchestration/scheduler.js +157 -0
- package/dist/harness/orchestration/scheduler.js.map +1 -0
- package/dist/harness/orchestration/testing.d.ts +233 -0
- package/dist/harness/orchestration/testing.d.ts.map +1 -0
- package/dist/harness/orchestration/testing.js +734 -0
- package/dist/harness/orchestration/testing.js.map +1 -0
- package/dist/harness/orchestration/verification-preflight.d.ts +46 -0
- package/dist/harness/orchestration/verification-preflight.d.ts.map +1 -0
- package/dist/harness/orchestration/verification-preflight.js +104 -0
- package/dist/harness/orchestration/verification-preflight.js.map +1 -0
- package/dist/harness/orchestration/worker-control.d.ts +64 -0
- package/dist/harness/orchestration/worker-control.d.ts.map +1 -0
- package/dist/harness/orchestration/worker-control.js +199 -0
- package/dist/harness/orchestration/worker-control.js.map +1 -0
- package/dist/harness/orchestration/worker-manager.d.ts +225 -0
- package/dist/harness/orchestration/worker-manager.d.ts.map +1 -0
- package/dist/harness/orchestration/worker-manager.js +1347 -0
- package/dist/harness/orchestration/worker-manager.js.map +1 -0
- package/dist/harness/orchestration/workspace-digest.d.ts +39 -0
- package/dist/harness/orchestration/workspace-digest.d.ts.map +1 -0
- package/dist/harness/orchestration/workspace-digest.js +147 -0
- package/dist/harness/orchestration/workspace-digest.js.map +1 -0
- package/dist/harness/policy/approval-broker.d.ts +13 -0
- package/dist/harness/policy/approval-broker.d.ts.map +1 -0
- package/dist/harness/policy/approval-broker.js +26 -0
- package/dist/harness/policy/approval-broker.js.map +1 -0
- package/dist/harness/policy/command-classifier.d.ts +29 -0
- package/dist/harness/policy/command-classifier.d.ts.map +1 -0
- package/dist/harness/policy/command-classifier.js +459 -0
- package/dist/harness/policy/command-classifier.js.map +1 -0
- package/dist/harness/policy/command-rules.d.ts +56 -0
- package/dist/harness/policy/command-rules.d.ts.map +1 -0
- package/dist/harness/policy/command-rules.js +588 -0
- package/dist/harness/policy/command-rules.js.map +1 -0
- package/dist/harness/policy/config.d.ts +27 -0
- package/dist/harness/policy/config.d.ts.map +1 -0
- package/dist/harness/policy/config.js +37 -0
- package/dist/harness/policy/config.js.map +1 -0
- package/dist/harness/policy/engine.d.ts +67 -0
- package/dist/harness/policy/engine.d.ts.map +1 -0
- package/dist/harness/policy/engine.js +483 -0
- package/dist/harness/policy/engine.js.map +1 -0
- package/dist/harness/policy/exec-allowlist.d.ts +66 -0
- package/dist/harness/policy/exec-allowlist.d.ts.map +1 -0
- package/dist/harness/policy/exec-allowlist.js +449 -0
- package/dist/harness/policy/exec-allowlist.js.map +1 -0
- package/dist/harness/policy/index.d.ts +10 -0
- package/dist/harness/policy/index.d.ts.map +1 -0
- package/dist/harness/policy/index.js +8 -0
- package/dist/harness/policy/index.js.map +1 -0
- package/dist/harness/policy/secret-patterns.d.ts +12 -0
- package/dist/harness/policy/secret-patterns.d.ts.map +1 -0
- package/dist/harness/policy/secret-patterns.js +48 -0
- package/dist/harness/policy/secret-patterns.js.map +1 -0
- package/dist/harness/policy/shell-parser.d.ts +40 -0
- package/dist/harness/policy/shell-parser.d.ts.map +1 -0
- package/dist/harness/policy/shell-parser.js +278 -0
- package/dist/harness/policy/shell-parser.js.map +1 -0
- package/dist/harness/policy/workspace-trust.d.ts +37 -0
- package/dist/harness/policy/workspace-trust.d.ts.map +1 -0
- package/dist/harness/policy/workspace-trust.js +164 -0
- package/dist/harness/policy/workspace-trust.js.map +1 -0
- package/dist/harness/providers/anthropic-messages.d.ts +48 -0
- package/dist/harness/providers/anthropic-messages.d.ts.map +1 -0
- package/dist/harness/providers/anthropic-messages.js +360 -0
- package/dist/harness/providers/anthropic-messages.js.map +1 -0
- package/dist/harness/providers/assembler.d.ts +29 -0
- package/dist/harness/providers/assembler.d.ts.map +1 -0
- package/dist/harness/providers/assembler.js +130 -0
- package/dist/harness/providers/assembler.js.map +1 -0
- package/dist/harness/providers/authenticated-stream.d.ts +9 -0
- package/dist/harness/providers/authenticated-stream.d.ts.map +1 -0
- package/dist/harness/providers/authenticated-stream.js +81 -0
- package/dist/harness/providers/authenticated-stream.js.map +1 -0
- package/dist/harness/providers/catalog.d.ts +75 -0
- package/dist/harness/providers/catalog.d.ts.map +1 -0
- package/dist/harness/providers/catalog.js +124 -0
- package/dist/harness/providers/catalog.js.map +1 -0
- package/dist/harness/providers/claude-code/adapter.d.ts +96 -0
- package/dist/harness/providers/claude-code/adapter.d.ts.map +1 -0
- package/dist/harness/providers/claude-code/adapter.js +863 -0
- package/dist/harness/providers/claude-code/adapter.js.map +1 -0
- package/dist/harness/providers/claude-code/mcp-relay.d.ts +2 -0
- package/dist/harness/providers/claude-code/mcp-relay.d.ts.map +1 -0
- package/dist/harness/providers/claude-code/mcp-relay.js +27 -0
- package/dist/harness/providers/claude-code/mcp-relay.js.map +1 -0
- package/dist/harness/providers/claude-code/mcp-server.d.ts +40 -0
- package/dist/harness/providers/claude-code/mcp-server.d.ts.map +1 -0
- package/dist/harness/providers/claude-code/mcp-server.js +171 -0
- package/dist/harness/providers/claude-code/mcp-server.js.map +1 -0
- package/dist/harness/providers/claude-code/native.d.ts +36 -0
- package/dist/harness/providers/claude-code/native.d.ts.map +1 -0
- package/dist/harness/providers/claude-code/native.js +153 -0
- package/dist/harness/providers/claude-code/native.js.map +1 -0
- package/dist/harness/providers/claude-code/process.d.ts +48 -0
- package/dist/harness/providers/claude-code/process.d.ts.map +1 -0
- package/dist/harness/providers/claude-code/process.js +128 -0
- package/dist/harness/providers/claude-code/process.js.map +1 -0
- package/dist/harness/providers/codex-app-server.d.ts +8 -0
- package/dist/harness/providers/codex-app-server.d.ts.map +1 -0
- package/dist/harness/providers/codex-app-server.js +45 -0
- package/dist/harness/providers/codex-app-server.js.map +1 -0
- package/dist/harness/providers/effort.d.ts +51 -0
- package/dist/harness/providers/effort.d.ts.map +1 -0
- package/dist/harness/providers/effort.js +108 -0
- package/dist/harness/providers/effort.js.map +1 -0
- package/dist/harness/providers/errors.d.ts +34 -0
- package/dist/harness/providers/errors.d.ts.map +1 -0
- package/dist/harness/providers/errors.js +143 -0
- package/dist/harness/providers/errors.js.map +1 -0
- package/dist/harness/providers/grammar.d.ts +17 -0
- package/dist/harness/providers/grammar.d.ts.map +1 -0
- package/dist/harness/providers/grammar.js +89 -0
- package/dist/harness/providers/grammar.js.map +1 -0
- package/dist/harness/providers/http-stream.d.ts +40 -0
- package/dist/harness/providers/http-stream.d.ts.map +1 -0
- package/dist/harness/providers/http-stream.js +134 -0
- package/dist/harness/providers/http-stream.js.map +1 -0
- package/dist/harness/providers/index.d.ts +20 -0
- package/dist/harness/providers/index.d.ts.map +1 -0
- package/dist/harness/providers/index.js +17 -0
- package/dist/harness/providers/index.js.map +1 -0
- package/dist/harness/providers/responses.d.ts +36 -0
- package/dist/harness/providers/responses.d.ts.map +1 -0
- package/dist/harness/providers/responses.js +435 -0
- package/dist/harness/providers/responses.js.map +1 -0
- package/dist/harness/providers/reviewer-route.d.ts +14 -0
- package/dist/harness/providers/reviewer-route.d.ts.map +1 -0
- package/dist/harness/providers/reviewer-route.js +31 -0
- package/dist/harness/providers/reviewer-route.js.map +1 -0
- package/dist/harness/providers/router.d.ts +50 -0
- package/dist/harness/providers/router.d.ts.map +1 -0
- package/dist/harness/providers/router.js +295 -0
- package/dist/harness/providers/router.js.map +1 -0
- package/dist/harness/providers/scripted.d.ts +22 -0
- package/dist/harness/providers/scripted.d.ts.map +1 -0
- package/dist/harness/providers/scripted.js +111 -0
- package/dist/harness/providers/scripted.js.map +1 -0
- package/dist/harness/providers/sse.d.ts +13 -0
- package/dist/harness/providers/sse.d.ts.map +1 -0
- package/dist/harness/providers/sse.js +82 -0
- package/dist/harness/providers/sse.js.map +1 -0
- package/dist/harness/providers/testing.d.ts +35 -0
- package/dist/harness/providers/testing.d.ts.map +1 -0
- package/dist/harness/providers/testing.js +93 -0
- package/dist/harness/providers/testing.js.map +1 -0
- package/dist/harness/providers/web-search.d.ts +110 -0
- package/dist/harness/providers/web-search.d.ts.map +1 -0
- package/dist/harness/providers/web-search.js +476 -0
- package/dist/harness/providers/web-search.js.map +1 -0
- package/dist/harness/store/blob-store.d.ts +4 -0
- package/dist/harness/store/blob-store.d.ts.map +1 -0
- package/dist/harness/store/blob-store.js +79 -0
- package/dist/harness/store/blob-store.js.map +1 -0
- package/dist/harness/store/durable-file.d.ts +17 -0
- package/dist/harness/store/durable-file.d.ts.map +1 -0
- package/dist/harness/store/durable-file.js +84 -0
- package/dist/harness/store/durable-file.js.map +1 -0
- package/dist/harness/store/event-store.d.ts +56 -0
- package/dist/harness/store/event-store.d.ts.map +1 -0
- package/dist/harness/store/event-store.js +210 -0
- package/dist/harness/store/event-store.js.map +1 -0
- package/dist/harness/store/index.d.ts +8 -0
- package/dist/harness/store/index.d.ts.map +1 -0
- package/dist/harness/store/index.js +4 -0
- package/dist/harness/store/index.js.map +1 -0
- package/dist/harness/store/layout.d.ts +12 -0
- package/dist/harness/store/layout.d.ts.map +1 -0
- package/dist/harness/store/layout.js +27 -0
- package/dist/harness/store/layout.js.map +1 -0
- package/dist/harness/store/lease.d.ts +37 -0
- package/dist/harness/store/lease.d.ts.map +1 -0
- package/dist/harness/store/lease.js +326 -0
- package/dist/harness/store/lease.js.map +1 -0
- package/dist/harness/store/segments.d.ts +49 -0
- package/dist/harness/store/segments.d.ts.map +1 -0
- package/dist/harness/store/segments.js +216 -0
- package/dist/harness/store/segments.js.map +1 -0
- package/dist/harness/store/session-store.d.ts +18 -0
- package/dist/harness/store/session-store.d.ts.map +1 -0
- package/dist/harness/store/session-store.js +319 -0
- package/dist/harness/store/session-store.js.map +1 -0
- package/dist/harness/tools/builtin/control-tools.d.ts +57 -0
- package/dist/harness/tools/builtin/control-tools.d.ts.map +1 -0
- package/dist/harness/tools/builtin/control-tools.js +72 -0
- package/dist/harness/tools/builtin/control-tools.js.map +1 -0
- package/dist/harness/tools/builtin/glob.d.ts +15 -0
- package/dist/harness/tools/builtin/glob.d.ts.map +1 -0
- package/dist/harness/tools/builtin/glob.js +164 -0
- package/dist/harness/tools/builtin/glob.js.map +1 -0
- package/dist/harness/tools/builtin/process-bg.d.ts +72 -0
- package/dist/harness/tools/builtin/process-bg.d.ts.map +1 -0
- package/dist/harness/tools/builtin/process-bg.js +360 -0
- package/dist/harness/tools/builtin/process-bg.js.map +1 -0
- package/dist/harness/tools/builtin/process-tools.d.ts +46 -0
- package/dist/harness/tools/builtin/process-tools.d.ts.map +1 -0
- package/dist/harness/tools/builtin/process-tools.js +263 -0
- package/dist/harness/tools/builtin/process-tools.js.map +1 -0
- package/dist/harness/tools/builtin/read-media.d.ts +10 -0
- package/dist/harness/tools/builtin/read-media.d.ts.map +1 -0
- package/dist/harness/tools/builtin/read-media.js +128 -0
- package/dist/harness/tools/builtin/read-media.js.map +1 -0
- package/dist/harness/tools/builtin/read-tools.d.ts +29 -0
- package/dist/harness/tools/builtin/read-tools.d.ts.map +1 -0
- package/dist/harness/tools/builtin/read-tools.js +329 -0
- package/dist/harness/tools/builtin/read-tools.js.map +1 -0
- package/dist/harness/tools/builtin/shared.d.ts +47 -0
- package/dist/harness/tools/builtin/shared.d.ts.map +1 -0
- package/dist/harness/tools/builtin/shared.js +94 -0
- package/dist/harness/tools/builtin/shared.js.map +1 -0
- package/dist/harness/tools/builtin/todo.d.ts +38 -0
- package/dist/harness/tools/builtin/todo.d.ts.map +1 -0
- package/dist/harness/tools/builtin/todo.js +55 -0
- package/dist/harness/tools/builtin/todo.js.map +1 -0
- package/dist/harness/tools/builtin/web-common.d.ts +18 -0
- package/dist/harness/tools/builtin/web-common.d.ts.map +1 -0
- package/dist/harness/tools/builtin/web-common.js +53 -0
- package/dist/harness/tools/builtin/web-common.js.map +1 -0
- package/dist/harness/tools/builtin/web-fetch.d.ts +33 -0
- package/dist/harness/tools/builtin/web-fetch.d.ts.map +1 -0
- package/dist/harness/tools/builtin/web-fetch.js +173 -0
- package/dist/harness/tools/builtin/web-fetch.js.map +1 -0
- package/dist/harness/tools/builtin/web-html.d.ts +14 -0
- package/dist/harness/tools/builtin/web-html.d.ts.map +1 -0
- package/dist/harness/tools/builtin/web-html.js +314 -0
- package/dist/harness/tools/builtin/web-html.js.map +1 -0
- package/dist/harness/tools/builtin/web-net.d.ts +59 -0
- package/dist/harness/tools/builtin/web-net.d.ts.map +1 -0
- package/dist/harness/tools/builtin/web-net.js +347 -0
- package/dist/harness/tools/builtin/web-net.js.map +1 -0
- package/dist/harness/tools/builtin/web-search.d.ts +40 -0
- package/dist/harness/tools/builtin/web-search.d.ts.map +1 -0
- package/dist/harness/tools/builtin/web-search.js +60 -0
- package/dist/harness/tools/builtin/web-search.js.map +1 -0
- package/dist/harness/tools/builtin/web-state.d.ts +67 -0
- package/dist/harness/tools/builtin/web-state.d.ts.map +1 -0
- package/dist/harness/tools/builtin/web-state.js +227 -0
- package/dist/harness/tools/builtin/web-state.js.map +1 -0
- package/dist/harness/tools/builtin/write-tools.d.ts +18 -0
- package/dist/harness/tools/builtin/write-tools.d.ts.map +1 -0
- package/dist/harness/tools/builtin/write-tools.js +335 -0
- package/dist/harness/tools/builtin/write-tools.js.map +1 -0
- package/dist/harness/tools/environment.d.ts +9 -0
- package/dist/harness/tools/environment.d.ts.map +1 -0
- package/dist/harness/tools/environment.js +59 -0
- package/dist/harness/tools/environment.js.map +1 -0
- package/dist/harness/tools/file-ledger.d.ts +9 -0
- package/dist/harness/tools/file-ledger.d.ts.map +1 -0
- package/dist/harness/tools/file-ledger.js +26 -0
- package/dist/harness/tools/file-ledger.js.map +1 -0
- package/dist/harness/tools/gateway.d.ts +52 -0
- package/dist/harness/tools/gateway.d.ts.map +1 -0
- package/dist/harness/tools/gateway.js +435 -0
- package/dist/harness/tools/gateway.js.map +1 -0
- package/dist/harness/tools/index.d.ts +20 -0
- package/dist/harness/tools/index.d.ts.map +1 -0
- package/dist/harness/tools/index.js +17 -0
- package/dist/harness/tools/index.js.map +1 -0
- package/dist/harness/tools/patch.d.ts +51 -0
- package/dist/harness/tools/patch.d.ts.map +1 -0
- package/dist/harness/tools/patch.js +450 -0
- package/dist/harness/tools/patch.js.map +1 -0
- package/dist/harness/tools/process.d.ts +28 -0
- package/dist/harness/tools/process.d.ts.map +1 -0
- package/dist/harness/tools/process.js +263 -0
- package/dist/harness/tools/process.js.map +1 -0
- package/dist/harness/tools/redaction.d.ts +26 -0
- package/dist/harness/tools/redaction.d.ts.map +1 -0
- package/dist/harness/tools/redaction.js +77 -0
- package/dist/harness/tools/redaction.js.map +1 -0
- package/dist/harness/tools/registry.d.ts +26 -0
- package/dist/harness/tools/registry.d.ts.map +1 -0
- package/dist/harness/tools/registry.js +57 -0
- package/dist/harness/tools/registry.js.map +1 -0
- package/dist/harness/tools/sandbox.d.ts +23 -0
- package/dist/harness/tools/sandbox.d.ts.map +1 -0
- package/dist/harness/tools/sandbox.js +117 -0
- package/dist/harness/tools/sandbox.js.map +1 -0
- package/dist/harness/tools/testing.d.ts +42 -0
- package/dist/harness/tools/testing.d.ts.map +1 -0
- package/dist/harness/tools/testing.js +143 -0
- package/dist/harness/tools/testing.js.map +1 -0
- package/dist/harness/tools/text-file.d.ts +38 -0
- package/dist/harness/tools/text-file.d.ts.map +1 -0
- package/dist/harness/tools/text-file.js +90 -0
- package/dist/harness/tools/text-file.js.map +1 -0
- package/dist/harness/tools/windows-launch.d.ts +52 -0
- package/dist/harness/tools/windows-launch.d.ts.map +1 -0
- package/dist/harness/tools/windows-launch.js +261 -0
- package/dist/harness/tools/windows-launch.js.map +1 -0
- package/dist/harness/tools/workspace-path.d.ts +34 -0
- package/dist/harness/tools/workspace-path.d.ts.map +1 -0
- package/dist/harness/tools/workspace-path.js +133 -0
- package/dist/harness/tools/workspace-path.js.map +1 -0
- package/dist/harness/tui/approvals.d.ts +44 -0
- package/dist/harness/tui/approvals.d.ts.map +1 -0
- package/dist/harness/tui/approvals.js +127 -0
- package/dist/harness/tui/approvals.js.map +1 -0
- package/dist/harness/tui/auth-interaction.d.ts +36 -0
- package/dist/harness/tui/auth-interaction.d.ts.map +1 -0
- package/dist/harness/tui/auth-interaction.js +76 -0
- package/dist/harness/tui/auth-interaction.js.map +1 -0
- package/dist/harness/tui/choice-modal.d.ts +58 -0
- package/dist/harness/tui/choice-modal.d.ts.map +1 -0
- package/dist/harness/tui/choice-modal.js +244 -0
- package/dist/harness/tui/choice-modal.js.map +1 -0
- package/dist/harness/tui/conversation-view.d.ts +250 -0
- package/dist/harness/tui/conversation-view.d.ts.map +1 -0
- package/dist/harness/tui/conversation-view.js +1115 -0
- package/dist/harness/tui/conversation-view.js.map +1 -0
- package/dist/harness/tui/describe.d.ts +21 -0
- package/dist/harness/tui/describe.d.ts.map +1 -0
- package/dist/harness/tui/describe.js +110 -0
- package/dist/harness/tui/describe.js.map +1 -0
- package/dist/harness/tui/index.d.ts +30 -0
- package/dist/harness/tui/index.d.ts.map +1 -0
- package/dist/harness/tui/index.js +26 -0
- package/dist/harness/tui/index.js.map +1 -0
- package/dist/harness/tui/input/attachments.d.ts +20 -0
- package/dist/harness/tui/input/attachments.d.ts.map +1 -0
- package/dist/harness/tui/input/attachments.js +100 -0
- package/dist/harness/tui/input/attachments.js.map +1 -0
- package/dist/harness/tui/input/autocomplete.d.ts +41 -0
- package/dist/harness/tui/input/autocomplete.d.ts.map +1 -0
- package/dist/harness/tui/input/autocomplete.js +85 -0
- package/dist/harness/tui/input/autocomplete.js.map +1 -0
- package/dist/harness/tui/input/clipboard.d.ts +44 -0
- package/dist/harness/tui/input/clipboard.d.ts.map +1 -0
- package/dist/harness/tui/input/clipboard.js +181 -0
- package/dist/harness/tui/input/clipboard.js.map +1 -0
- package/dist/harness/tui/input/commands.d.ts +23 -0
- package/dist/harness/tui/input/commands.d.ts.map +1 -0
- package/dist/harness/tui/input/commands.js +71 -0
- package/dist/harness/tui/input/commands.js.map +1 -0
- package/dist/harness/tui/input/file-index.d.ts +49 -0
- package/dist/harness/tui/input/file-index.d.ts.map +1 -0
- package/dist/harness/tui/input/file-index.js +170 -0
- package/dist/harness/tui/input/file-index.js.map +1 -0
- package/dist/harness/tui/input/index.d.ts +8 -0
- package/dist/harness/tui/input/index.d.ts.map +1 -0
- package/dist/harness/tui/input/index.js +8 -0
- package/dist/harness/tui/input/index.js.map +1 -0
- package/dist/harness/tui/input/mouse.d.ts +68 -0
- package/dist/harness/tui/input/mouse.d.ts.map +1 -0
- package/dist/harness/tui/input/mouse.js +141 -0
- package/dist/harness/tui/input/mouse.js.map +1 -0
- package/dist/harness/tui/interrupt.d.ts +25 -0
- package/dist/harness/tui/interrupt.d.ts.map +1 -0
- package/dist/harness/tui/interrupt.js +49 -0
- package/dist/harness/tui/interrupt.js.map +1 -0
- package/dist/harness/tui/jsonl-renderer.d.ts +68 -0
- package/dist/harness/tui/jsonl-renderer.d.ts.map +1 -0
- package/dist/harness/tui/jsonl-renderer.js +172 -0
- package/dist/harness/tui/jsonl-renderer.js.map +1 -0
- package/dist/harness/tui/line-source.d.ts +39 -0
- package/dist/harness/tui/line-source.d.ts.map +1 -0
- package/dist/harness/tui/line-source.js +137 -0
- package/dist/harness/tui/line-source.js.map +1 -0
- package/dist/harness/tui/logo-art.d.ts +9 -0
- package/dist/harness/tui/logo-art.d.ts.map +1 -0
- package/dist/harness/tui/logo-art.js +24 -0
- package/dist/harness/tui/logo-art.js.map +1 -0
- package/dist/harness/tui/logo.d.ts +28 -0
- package/dist/harness/tui/logo.d.ts.map +1 -0
- package/dist/harness/tui/logo.js +88 -0
- package/dist/harness/tui/logo.js.map +1 -0
- package/dist/harness/tui/open-browser.d.ts +17 -0
- package/dist/harness/tui/open-browser.d.ts.map +1 -0
- package/dist/harness/tui/open-browser.js +45 -0
- package/dist/harness/tui/open-browser.js.map +1 -0
- package/dist/harness/tui/output-chunks.d.ts +8 -0
- package/dist/harness/tui/output-chunks.d.ts.map +1 -0
- package/dist/harness/tui/output-chunks.js +48 -0
- package/dist/harness/tui/output-chunks.js.map +1 -0
- package/dist/harness/tui/panels/index.d.ts +2 -0
- package/dist/harness/tui/panels/index.d.ts.map +1 -0
- package/dist/harness/tui/panels/index.js +2 -0
- package/dist/harness/tui/panels/index.js.map +1 -0
- package/dist/harness/tui/panels/panel-view.d.ts +98 -0
- package/dist/harness/tui/panels/panel-view.d.ts.map +1 -0
- package/dist/harness/tui/panels/panel-view.js +596 -0
- package/dist/harness/tui/panels/panel-view.js.map +1 -0
- package/dist/harness/tui/pi-tui-renderer.d.ts +363 -0
- package/dist/harness/tui/pi-tui-renderer.d.ts.map +1 -0
- package/dist/harness/tui/pi-tui-renderer.js +2696 -0
- package/dist/harness/tui/pi-tui-renderer.js.map +1 -0
- package/dist/harness/tui/plain-line-renderer.d.ts +102 -0
- package/dist/harness/tui/plain-line-renderer.d.ts.map +1 -0
- package/dist/harness/tui/plain-line-renderer.js +491 -0
- package/dist/harness/tui/plain-line-renderer.js.map +1 -0
- package/dist/harness/tui/render-queue.d.ts +34 -0
- package/dist/harness/tui/render-queue.d.ts.map +1 -0
- package/dist/harness/tui/render-queue.js +92 -0
- package/dist/harness/tui/render-queue.js.map +1 -0
- package/dist/harness/tui/sanitize.d.ts +9 -0
- package/dist/harness/tui/sanitize.d.ts.map +1 -0
- package/dist/harness/tui/sanitize.js +31 -0
- package/dist/harness/tui/sanitize.js.map +1 -0
- package/dist/harness/tui/style.d.ts +54 -0
- package/dist/harness/tui/style.d.ts.map +1 -0
- package/dist/harness/tui/style.js +64 -0
- package/dist/harness/tui/style.js.map +1 -0
- package/dist/harness/tui/terminal-lifecycle.d.ts +49 -0
- package/dist/harness/tui/terminal-lifecycle.d.ts.map +1 -0
- package/dist/harness/tui/terminal-lifecycle.js +100 -0
- package/dist/harness/tui/terminal-lifecycle.js.map +1 -0
- package/dist/harness/tui/theme.d.ts +77 -0
- package/dist/harness/tui/theme.d.ts.map +1 -0
- package/dist/harness/tui/theme.js +501 -0
- package/dist/harness/tui/theme.js.map +1 -0
- package/dist/harness/tui/tool-cards.d.ts +35 -0
- package/dist/harness/tui/tool-cards.d.ts.map +1 -0
- package/dist/harness/tui/tool-cards.js +122 -0
- package/dist/harness/tui/tool-cards.js.map +1 -0
- package/dist/harness/tui/tool-row.d.ts +51 -0
- package/dist/harness/tui/tool-row.d.ts.map +1 -0
- package/dist/harness/tui/tool-row.js +98 -0
- package/dist/harness/tui/tool-row.js.map +1 -0
- package/dist/harness/tui/views/board.d.ts +49 -0
- package/dist/harness/tui/views/board.d.ts.map +1 -0
- package/dist/harness/tui/views/board.js +293 -0
- package/dist/harness/tui/views/board.js.map +1 -0
- package/dist/harness/tui/views/cards.d.ts +8 -0
- package/dist/harness/tui/views/cards.d.ts.map +1 -0
- package/dist/harness/tui/views/cards.js +206 -0
- package/dist/harness/tui/views/cards.js.map +1 -0
- package/dist/harness/tui/views/components.d.ts +101 -0
- package/dist/harness/tui/views/components.d.ts.map +1 -0
- package/dist/harness/tui/views/components.js +186 -0
- package/dist/harness/tui/views/components.js.map +1 -0
- package/dist/harness/tui/views/diff.d.ts +11 -0
- package/dist/harness/tui/views/diff.d.ts.map +1 -0
- package/dist/harness/tui/views/diff.js +150 -0
- package/dist/harness/tui/views/diff.js.map +1 -0
- package/dist/harness/tui/views/graph.d.ts +49 -0
- package/dist/harness/tui/views/graph.d.ts.map +1 -0
- package/dist/harness/tui/views/graph.js +361 -0
- package/dist/harness/tui/views/graph.js.map +1 -0
- package/dist/harness/tui/views/index.d.ts +15 -0
- package/dist/harness/tui/views/index.d.ts.map +1 -0
- package/dist/harness/tui/views/index.js +15 -0
- package/dist/harness/tui/views/index.js.map +1 -0
- package/dist/harness/tui/views/kit.d.ts +112 -0
- package/dist/harness/tui/views/kit.d.ts.map +1 -0
- package/dist/harness/tui/views/kit.js +282 -0
- package/dist/harness/tui/views/kit.js.map +1 -0
- package/dist/harness/tui/views/trust-cards.d.ts +27 -0
- package/dist/harness/tui/views/trust-cards.d.ts.map +1 -0
- package/dist/harness/tui/views/trust-cards.js +181 -0
- package/dist/harness/tui/views/trust-cards.js.map +1 -0
- package/dist/harness/tui/views/usage.d.ts +4 -0
- package/dist/harness/tui/views/usage.d.ts.map +1 -0
- package/dist/harness/tui/views/usage.js +182 -0
- package/dist/harness/tui/views/usage.js.map +1 -0
- package/dist/harness/tui/views/worker.d.ts +47 -0
- package/dist/harness/tui/views/worker.d.ts.map +1 -0
- package/dist/harness/tui/views/worker.js +221 -0
- package/dist/harness/tui/views/worker.js.map +1 -0
- package/dist/harness/tui/welcome.d.ts +97 -0
- package/dist/harness/tui/welcome.d.ts.map +1 -0
- package/dist/harness/tui/welcome.js +271 -0
- package/dist/harness/tui/welcome.js.map +1 -0
- package/dist/harness/tui/wrap.d.ts +26 -0
- package/dist/harness/tui/wrap.d.ts.map +1 -0
- package/dist/harness/tui/wrap.js +38 -0
- package/dist/harness/tui/wrap.js.map +1 -0
- package/dist/infrastructure/build-info.d.ts +5 -0
- package/dist/infrastructure/build-info.d.ts.map +1 -0
- package/dist/infrastructure/build-info.js +21 -0
- package/dist/infrastructure/build-info.js.map +1 -0
- package/dist/infrastructure/frontmatter.d.ts +25 -0
- package/dist/infrastructure/frontmatter.d.ts.map +1 -0
- package/dist/infrastructure/frontmatter.js +75 -0
- package/dist/infrastructure/frontmatter.js.map +1 -0
- package/dist/templates/agent-manifests.d.ts +19 -0
- package/dist/templates/agent-manifests.d.ts.map +1 -0
- package/dist/templates/agent-manifests.js +302 -0
- package/dist/templates/agent-manifests.js.map +1 -0
- package/dist/templates/base-skills.d.ts +23 -0
- package/dist/templates/base-skills.d.ts.map +1 -0
- package/dist/templates/base-skills.js +477 -0
- package/dist/templates/base-skills.js.map +1 -0
- package/dist/templates/skill-creator-skill.d.ts +23 -0
- package/dist/templates/skill-creator-skill.d.ts.map +1 -0
- package/dist/templates/skill-creator-skill.js +235 -0
- package/dist/templates/skill-creator-skill.js.map +1 -0
- package/dist/templates/skill-references.d.ts +13 -0
- package/dist/templates/skill-references.d.ts.map +1 -0
- package/dist/templates/skill-references.js +280 -0
- package/dist/templates/skill-references.js.map +1 -0
- package/dist/templates/structure-templates.d.ts.map +1 -1
- package/dist/templates/structure-templates.js +20 -144
- package/dist/templates/structure-templates.js.map +1 -1
- package/dist/templates/task-conductor-skill.d.ts +1 -1
- package/dist/templates/task-conductor-skill.d.ts.map +1 -1
- package/dist/templates/task-conductor-skill.js +50 -22
- package/dist/templates/task-conductor-skill.js.map +1 -1
- package/package.json +8 -2
|
@@ -0,0 +1,1347 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { canonicalJson, completionPacketSchema, createId, DEFAULT_ORCHESTRATION_BUDGETS, digestOf, findStaleSources, formatEvidenceCorrection, HarnessError, packetDigest, ProviderFailure, REPORT_CORRECTION_ROUNDS, REPORT_TOOL_NAMES, reviewPacketSchema, taskContextPacketSchema, INLINE_SOURCE_MAX_BYTES, INLINE_SOURCES_MAX_TOTAL_BYTES, workspaceDigest, } from "../contracts/index.js";
|
|
4
|
+
import { buildAttemptLog, readEvents } from "./attempt-log.js";
|
|
5
|
+
import { readClaim, REVIEWER_REPORT_INSTRUCTIONS, reviewerClaimSchema, WORKER_REPORT_INSTRUCTIONS, workerClaimSchema, } from "./claims.js";
|
|
6
|
+
import { REPORT_RECORDED } from "./delegation.js";
|
|
7
|
+
import { commandArgv, commandsFromLog, evidenceCandidates, evidenceProblems, INDEPENDENT_EVIDENCE_HINT, isPlanCausedVerification, isIndependentReviewEvidence, provingVerification, resolveCompletionEvidence, resolvePointer, unresolvedPointer, verifyCompletion, verifyReview, } from "./evidence.js";
|
|
8
|
+
import { matchesAny, normalizeWorkspacePath } from "./paths.js";
|
|
9
|
+
import { createWorkspaceDigestReader, resolveOnDiskPath } from "./workspace-digest.js";
|
|
10
|
+
import { COMPLETION_MEDIA_TYPE, createWorkspaceSourceReader, currentDigests, PACKET_MEDIA_TYPE, REVIEW_MEDIA_TYPE, } from "./recorder.js";
|
|
11
|
+
/** Default distance (steps) of the finish-now message from an attempt's step limit. */
|
|
12
|
+
export const DEFAULT_FINISH_WARNING = 3;
|
|
13
|
+
/** The runtime message an attempt gets when it is `steps` steps from its limit without a report. */
|
|
14
|
+
export function renderFinishNowMessage(tool, steps) {
|
|
15
|
+
const what = tool === REPORT_TOOL_NAMES.review ? "your verdicts so far (unverifiable where you could not check)" : "what you have (status partial if work remains)";
|
|
16
|
+
return `Harness: ${steps} step(s) left before the step limit. Finish now: call \`${tool}\` with ${what}, citing the [#n] refs you already have. Do not start new work.`;
|
|
17
|
+
}
|
|
18
|
+
/** The message of the forced report-only turn (the limit was hit without a report). */
|
|
19
|
+
export function renderReportOnlyMessage(tool) {
|
|
20
|
+
return `Harness: the step limit is reached. This is a report-only turn: \`${tool}\` is the only tool available. Call it now with what you have; anything unfinished goes into the report (status partial, or verdict unverifiable).`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Classifies a failed turn from its own log: a provider error (a non-cancelled
|
|
24
|
+
* `model/response_failed`, or a `ProviderFailure` thrown by credential resolution) or a tool whose
|
|
25
|
+
* execution broke the turn. A turn that ended normally, or was cancelled, has no failure cause.
|
|
26
|
+
*/
|
|
27
|
+
export function classifyAttemptFailure(outcome, error, events) {
|
|
28
|
+
if (error === undefined && outcome?.outcome !== "failed")
|
|
29
|
+
return undefined;
|
|
30
|
+
if (error instanceof ProviderFailure)
|
|
31
|
+
return error.error.code === "cancelled" ? undefined : "provider_failed";
|
|
32
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
33
|
+
const event = events[index];
|
|
34
|
+
if (event === undefined)
|
|
35
|
+
continue;
|
|
36
|
+
if (event.type === "model/response_failed")
|
|
37
|
+
return event.data.error.code === "cancelled" ? undefined : "provider_failed";
|
|
38
|
+
if (event.type === "tool/execution_started" || event.type === "tool/interrupted")
|
|
39
|
+
return error === undefined ? undefined : "tool_failed";
|
|
40
|
+
if (event.type === "tool/result_recorded")
|
|
41
|
+
return error !== undefined ? "tool_failed" : undefined;
|
|
42
|
+
if (event.type === "model/response_settled")
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
/** A one-shot timer whose clock stops while paused. */
|
|
48
|
+
class PausableTimer {
|
|
49
|
+
#remaining;
|
|
50
|
+
#startedAt = 0;
|
|
51
|
+
#timer;
|
|
52
|
+
#fire;
|
|
53
|
+
constructor(ms, fire, paused) {
|
|
54
|
+
this.#remaining = ms;
|
|
55
|
+
this.#fire = fire;
|
|
56
|
+
if (!paused)
|
|
57
|
+
this.resume();
|
|
58
|
+
}
|
|
59
|
+
pause() {
|
|
60
|
+
if (this.#timer === undefined)
|
|
61
|
+
return;
|
|
62
|
+
clearTimeout(this.#timer);
|
|
63
|
+
this.#timer = undefined;
|
|
64
|
+
this.#remaining = Math.max(0, this.#remaining - (Date.now() - this.#startedAt));
|
|
65
|
+
}
|
|
66
|
+
resume() {
|
|
67
|
+
if (this.#timer !== undefined)
|
|
68
|
+
return;
|
|
69
|
+
this.#startedAt = Date.now();
|
|
70
|
+
this.#timer = setTimeout(this.#fire, this.#remaining);
|
|
71
|
+
this.#timer.unref?.();
|
|
72
|
+
}
|
|
73
|
+
clear() {
|
|
74
|
+
if (this.#timer !== undefined)
|
|
75
|
+
clearTimeout(this.#timer);
|
|
76
|
+
this.#timer = undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function pausable(driver) {
|
|
80
|
+
const candidate = driver;
|
|
81
|
+
return typeof candidate?.pause === "function" && typeof candidate.resume === "function" ? candidate : undefined;
|
|
82
|
+
}
|
|
83
|
+
const REVIEW_BRIEF_CONTENT_LIMIT = 48 * 1024;
|
|
84
|
+
const OUTPUT_EXCERPT_LIMIT = 4096;
|
|
85
|
+
const CORRECTABLE_STATUSES = new Set(["completed", "partial"]);
|
|
86
|
+
function harnessError(code, message, ids) {
|
|
87
|
+
return new HarnessError({
|
|
88
|
+
code,
|
|
89
|
+
message,
|
|
90
|
+
...(ids === undefined ? {} : { ids }),
|
|
91
|
+
workspace_effect: "none",
|
|
92
|
+
retry_safe: true,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function linkSignals(outer) {
|
|
96
|
+
const controller = new AbortController();
|
|
97
|
+
if (outer.aborted)
|
|
98
|
+
controller.abort(outer.reason);
|
|
99
|
+
else
|
|
100
|
+
outer.addEventListener("abort", () => controller.abort(outer.reason), { once: true });
|
|
101
|
+
return controller;
|
|
102
|
+
}
|
|
103
|
+
function excerpt(text) {
|
|
104
|
+
if (text.length <= OUTPUT_EXCERPT_LIMIT)
|
|
105
|
+
return text;
|
|
106
|
+
const half = Math.floor((OUTPUT_EXCERPT_LIMIT - 32) / 2);
|
|
107
|
+
return `${text.slice(0, half)}\n[... ${text.length - 2 * half} characters ...]\n${text.slice(-half)}`;
|
|
108
|
+
}
|
|
109
|
+
function toolOk(text) {
|
|
110
|
+
return { status: "ok", text: text.slice(0, 16 * 1024), truncated: false, redactions: 0 };
|
|
111
|
+
}
|
|
112
|
+
function toolRejected(text, message) {
|
|
113
|
+
return { status: "error", text: text.slice(0, 16 * 1024), truncated: false, redactions: 0, error: { code: "invalid_arguments", message: message.slice(0, 2000) } };
|
|
114
|
+
}
|
|
115
|
+
export function renderWorkerMessage(packet, notes = []) {
|
|
116
|
+
const scope = packet.write_mode === "owned-paths"
|
|
117
|
+
? `You may change only: ${packet.scope.owned_paths.join(", ")}.`
|
|
118
|
+
: packet.write_mode === "rca-only"
|
|
119
|
+
? "Root-cause analysis only: do not change files; report root_cause."
|
|
120
|
+
: "Read-only: do not change files.";
|
|
121
|
+
const commands = packet.verification.commands;
|
|
122
|
+
return [
|
|
123
|
+
`Task ${packet.task_id} (${packet.role}): ${packet.objective}`,
|
|
124
|
+
"Your task packet is in the system context; use it first. You may read any file in the workspace (e.g. another task's files you must match); the packet's decisions list the other tasks and any shared contract.",
|
|
125
|
+
scope,
|
|
126
|
+
...(notes.length === 0 ? [] : [`Notes for this attempt (from the previous attempt and the orchestrator):\n${notes.map((note) => `- ${note}`).join("\n")}`]),
|
|
127
|
+
...(packet.write_mode === "owned-paths" || packet.role === "debugger"
|
|
128
|
+
? [
|
|
129
|
+
`The harness runs ${commands.length > 0 ? `the verification (${commands.join("; ")})` : "the verification"} itself after your report and an independent reviewer checks the criteria: do not invent extra exec checks (inline scripts, ad-hoc parsers). If a check you tried is refused, list it in skipped_checks; that alone never makes the report partial. Report completed when your change meets the criteria, citing your reads/writes as evidence.`,
|
|
130
|
+
]
|
|
131
|
+
: []),
|
|
132
|
+
"If the packet is insufficient or a cited source changed, stop and report status needs_context.",
|
|
133
|
+
WORKER_REPORT_INSTRUCTIONS,
|
|
134
|
+
].join("\n\n");
|
|
135
|
+
}
|
|
136
|
+
function statementsOf(packet) {
|
|
137
|
+
return new Map(packet.acceptance_criteria.map((criterion) => [criterion.id, criterion.statement]));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The harness records a reviewer may cite (ADR-18 amendment of ADR-09, review R1): a passed
|
|
141
|
+
* build/test run (or one a criterion names) is independent evidence; a read-only or failed run and
|
|
142
|
+
* the diff are supporting only.
|
|
143
|
+
*/
|
|
144
|
+
function harnessLines(harness, packet) {
|
|
145
|
+
if (harness === undefined)
|
|
146
|
+
return [];
|
|
147
|
+
const proving = new Set(provingVerification(packet, harness).map((record) => record.evidence.ref));
|
|
148
|
+
return [
|
|
149
|
+
...harness.verification.map((record) => ` ${record.evidence.ref} harness-verification "${record.command}" -> ${record.status}${record.exit_code === null ? "" : ` (exit ${record.exit_code})`}${proving.has(record.evidence.ref) ? "" : " [supporting only]"}`),
|
|
150
|
+
...(harness.diff === undefined ? [] : [` ${harness.diff.evidence.ref} harness-diff (${harness.diff.changed_paths.join(", ")}) [supporting only]`]),
|
|
151
|
+
];
|
|
152
|
+
}
|
|
153
|
+
export function renderRepairMessage(kind, problems, log, harness) {
|
|
154
|
+
const verification = (harness?.verification ?? []).filter((record) => record.status !== "passed" && !isPlanCausedVerification(record));
|
|
155
|
+
const lead = kind === "verification-repair"
|
|
156
|
+
? "The harness ran the packet's verification commands in your workspace after your turn, and they did not pass. Your workspace and changes are kept."
|
|
157
|
+
: "The harness checked your report. Your workspace and changes are kept, but the report is incomplete.";
|
|
158
|
+
const valid = evidenceCandidates(log).map((candidate) => ` #${candidate.ref} ${candidate.toolName} ${candidate.summary}`);
|
|
159
|
+
return [
|
|
160
|
+
lead,
|
|
161
|
+
`Problems:\n${problems.slice(0, 20).map((problem) => `- ${problem}`).join("\n")}`,
|
|
162
|
+
verification.length > 0 ? `Harness verification:\n${verification.map((record) => `- ${record.command}: ${record.status}${record.exit_code === null ? "" : ` (exit ${record.exit_code})`}${record.reason === undefined ? "" : ` - ${record.reason}`}`).join("\n")}` : "",
|
|
163
|
+
valid.length > 0 ? `Valid evidence refs (cite as "#n"):\n${valid.join("\n")}` : "",
|
|
164
|
+
kind === "verification-repair"
|
|
165
|
+
? `Fix the change inside your owned paths, run the failing command yourself to confirm, then call \`${REPORT_TOOL_NAMES.task}\` again with the complete report.`
|
|
166
|
+
: `Fix only what is listed (cite valid refs, or run a missing check), do not redo finished work, then call \`${REPORT_TOOL_NAMES.task}\` again with the complete report.`,
|
|
167
|
+
]
|
|
168
|
+
.filter((part) => part !== "")
|
|
169
|
+
.join("\n\n");
|
|
170
|
+
}
|
|
171
|
+
export function renderReviewBrief(target, completion, changeSet) {
|
|
172
|
+
let budget = REVIEW_BRIEF_CONTENT_LIMIT;
|
|
173
|
+
const files = [];
|
|
174
|
+
for (const change of changeSet.changes) {
|
|
175
|
+
const content = changeSet.contents.get(change.path);
|
|
176
|
+
const header = `--- ${change.path} (before ${change.before ?? "absent"}, after ${change.after ?? "deleted"})`;
|
|
177
|
+
if (content === null || content === undefined) {
|
|
178
|
+
files.push(`${header}\n[deleted]`);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const text = content.toString("utf8");
|
|
182
|
+
const shown = text.slice(0, Math.max(0, budget));
|
|
183
|
+
budget -= shown.length;
|
|
184
|
+
files.push(`${header}\n${shown}${shown.length < text.length ? "\n[truncated; read the file with your tools]" : ""}`);
|
|
185
|
+
}
|
|
186
|
+
const harness = harnessLines(completion.harness_evidence, target.packet);
|
|
187
|
+
return [
|
|
188
|
+
`Independent review of attempt ${target.attemptId} for task ${target.taskId}.`,
|
|
189
|
+
`The artifact under review is pinned at ${changeSet.artifactDigest}. Your workspace is that artifact, read-only; you may read any file in it, not only the changed ones.`,
|
|
190
|
+
"You receive the worker's completion packet and the changed files, not the worker's conversation. Verify every acceptance criterion yourself with your own tool calls.",
|
|
191
|
+
`Worker completion packet:\n\`\`\`json\n${canonicalJson(completion)}\n\`\`\``,
|
|
192
|
+
harness.length > 0 ? `Harness records (computed by the harness, independent of the worker; cite with produced_by: harness):\n${harness.join("\n")}` : "",
|
|
193
|
+
`Changed files (${changeSet.changes.length}):\n${files.join("\n\n") || "[no file changes]"}`,
|
|
194
|
+
REVIEWER_REPORT_INSTRUCTIONS,
|
|
195
|
+
]
|
|
196
|
+
.filter((part) => part !== "")
|
|
197
|
+
.join("\n\n");
|
|
198
|
+
}
|
|
199
|
+
export function renderIntegrationReviewBrief(packet, dependencies) {
|
|
200
|
+
const tasks = dependencies.map((dependency) => [
|
|
201
|
+
`- ${dependency.key} (${dependency.taskId}): ${dependency.summary.slice(0, 600)}`,
|
|
202
|
+
` integrated: ${dependency.paths.join(", ") || "no file changes"}`,
|
|
203
|
+
...dependency.notes.slice(0, 5).map((note) => ` note: ${note.slice(0, 400)}`),
|
|
204
|
+
].join("\n"));
|
|
205
|
+
const criteria = packet.acceptance_criteria.map((criterion) => `- ${criterion.id}: ${criterion.statement}`);
|
|
206
|
+
return [
|
|
207
|
+
`Integration review for task ${packet.task_id}: ${packet.objective}`,
|
|
208
|
+
"Every task below passed its own verification and independent review and is integrated into the workspace. Your workspace is the combined result, read-only; read any file you need.",
|
|
209
|
+
`Integrated tasks:\n${tasks.join("\n")}`,
|
|
210
|
+
`Check only these criteria, each with your own tool calls (read the files; run ${packet.verification.commands.length > 0 ? `the verification commands ${packet.verification.commands.join("; ")}` : "a check when a criterion needs one"}):\n${criteria.join("\n")}`,
|
|
211
|
+
REVIEWER_REPORT_INSTRUCTIONS,
|
|
212
|
+
].join("\n\n");
|
|
213
|
+
}
|
|
214
|
+
function emptyLog(sessionId) {
|
|
215
|
+
return { sessionId, toolCalls: new Map(), eventTypes: new Map(), compactionBlobs: new Set(), finalAssistantText: undefined, assistantTexts: [], reports: [], ordinals: new Map() };
|
|
216
|
+
}
|
|
217
|
+
/** The one workspace digest (ADR-19) of files in an attempt root: the isolation's reader, or raw bytes read here. */
|
|
218
|
+
function readerFor(workspace, platform) {
|
|
219
|
+
return workspace.digest ?? createWorkspaceDigestReader(workspace.root, { platform });
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Small read_paths files inlined into the packet (ADR-20, F19), read in the attempt workspace so
|
|
223
|
+
* their digests are valid write preconditions there: each at most `INLINE_SOURCE_MAX_BYTES`, all
|
|
224
|
+
* together at most `INLINE_SOURCES_MAX_TOTAL_BYTES`, only valid UTF-8 text, never truncated.
|
|
225
|
+
*/
|
|
226
|
+
async function inlineSources(packet, workspace, sources, platform) {
|
|
227
|
+
const inline = [];
|
|
228
|
+
let total = 0;
|
|
229
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
230
|
+
for (const source of sources) {
|
|
231
|
+
if (!packet.scope.read_paths.includes(source.path) || inline.length >= 32)
|
|
232
|
+
continue;
|
|
233
|
+
const normalized = normalizeWorkspacePath(source.path);
|
|
234
|
+
if (normalized === undefined || normalized === ".")
|
|
235
|
+
continue;
|
|
236
|
+
let bytes;
|
|
237
|
+
try {
|
|
238
|
+
const onDisk = await resolveOnDiskPath(workspace.root, normalized, platform);
|
|
239
|
+
if (onDisk === undefined)
|
|
240
|
+
continue;
|
|
241
|
+
bytes = await readFile(path.join(workspace.root, ...onDisk.split("/")));
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (bytes.byteLength > INLINE_SOURCE_MAX_BYTES || total + bytes.byteLength > INLINE_SOURCES_MAX_TOTAL_BYTES || workspaceDigest(bytes) !== source.digest)
|
|
247
|
+
continue;
|
|
248
|
+
let content;
|
|
249
|
+
try {
|
|
250
|
+
content = decoder.decode(bytes);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
total += bytes.byteLength;
|
|
256
|
+
inline.push({ path: source.path, digest: source.digest, content, truncated: false });
|
|
257
|
+
}
|
|
258
|
+
return inline;
|
|
259
|
+
}
|
|
260
|
+
/** Paths the attempt's tools reported as changed (for in-call file evidence, before the real diff exists). */
|
|
261
|
+
function loggedChanges(log) {
|
|
262
|
+
return [...new Set([...log.toolCalls.values()].flatMap((call) => (call.state === "succeeded" ? call.changedPaths ?? [] : [])))];
|
|
263
|
+
}
|
|
264
|
+
export function createWorkerManager(deps) {
|
|
265
|
+
const now = deps.now ?? (() => new Date());
|
|
266
|
+
const platform = deps.platform ?? process.platform;
|
|
267
|
+
const sources = deps.sources ?? createWorkspaceSourceReader(deps.run.workspaceRoot);
|
|
268
|
+
const recorder = deps.run.recorder;
|
|
269
|
+
const budgets = deps.run.budgets ?? DEFAULT_ORCHESTRATION_BUDGETS;
|
|
270
|
+
const records = new Map();
|
|
271
|
+
const handles = new Map();
|
|
272
|
+
const controllers = new Map();
|
|
273
|
+
// One driver per attempt: a backend-owned loop (Claude Code bridge) keeps its session across the
|
|
274
|
+
// attempt's follow-up turns (finish-now, report-only, corrections) instead of starting cold (K1.5).
|
|
275
|
+
const drivers = new Map();
|
|
276
|
+
/** K1.7: user control of each running attempt; applied to its driver when the driver is created. */
|
|
277
|
+
const controls = new Map();
|
|
278
|
+
const pendingStores = new Map();
|
|
279
|
+
/** Packets as the coordinator issued them (main-tree digests): the in-flight freshness gate compares against these. */
|
|
280
|
+
const baselines = new Map();
|
|
281
|
+
const unregister = new Map();
|
|
282
|
+
const countedCalls = new Map();
|
|
283
|
+
/** In-session repairs spent per task (shared by evidence and verification repairs, ADR-18 D2). */
|
|
284
|
+
const repairsUsed = new Map();
|
|
285
|
+
deps.budget?.onCancel((exceeded) => {
|
|
286
|
+
for (const controller of controllers.values())
|
|
287
|
+
controller.abort(new Error(`budget ${exceeded.metric} exceeded`));
|
|
288
|
+
});
|
|
289
|
+
const gate = async (packet, inFlight) => {
|
|
290
|
+
const current = await currentDigests(packet.context.sources.map((source) => source.path), sources);
|
|
291
|
+
const stale = findStaleSources(packet, current).filter((source) => !inFlight || !matchesAny(source.path, packet.scope.owned_paths, platform));
|
|
292
|
+
for (const source of stale) {
|
|
293
|
+
await recorder.record("context/source_changed", { task_id: packet.task_id, path: source.path, expected: source.expected, actual: source.actual ?? null }, { taskId: packet.task_id, actor: { kind: "system" } });
|
|
294
|
+
}
|
|
295
|
+
if (stale.length > 0 && !inFlight) {
|
|
296
|
+
throw harnessError("stale_packet", `packet sources changed: ${stale.map((source) => source.path).join(", ")}`, {
|
|
297
|
+
task_id: packet.task_id,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
if (stale.length > 0)
|
|
301
|
+
throw new StaleInFlight(stale.map((source) => source.path));
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* ADR-19: once the workspace exists, packet sources are digested in *that* root with the one
|
|
305
|
+
* workspace scheme, so a digest the worker reads from its packet is a valid write precondition.
|
|
306
|
+
*/
|
|
307
|
+
const inWorkspace = async (packet, workspace, signal) => {
|
|
308
|
+
const digest = readerFor(workspace, platform);
|
|
309
|
+
if (packet.context.digest_scheme === "workspace-raw-v1" || packet.context.sources.length === 0)
|
|
310
|
+
return packet;
|
|
311
|
+
const remapped = new Map();
|
|
312
|
+
const next = [];
|
|
313
|
+
for (const source of packet.context.sources) {
|
|
314
|
+
const value = await digest(source.path, signal);
|
|
315
|
+
if (value === undefined)
|
|
316
|
+
continue;
|
|
317
|
+
next.push({ path: source.path, digest: value });
|
|
318
|
+
remapped.set(`${source.path}\u0000${source.digest}`, value);
|
|
319
|
+
}
|
|
320
|
+
const facts = packet.known_facts.flatMap((fact) => {
|
|
321
|
+
const value = remapped.get(`${fact.source}\u0000${fact.source_digest}`);
|
|
322
|
+
return value === undefined ? [] : [{ ...fact, source_digest: value }];
|
|
323
|
+
});
|
|
324
|
+
const inline = await inlineSources(packet, workspace, next, platform);
|
|
325
|
+
return taskContextPacketSchema.parse({
|
|
326
|
+
...packet,
|
|
327
|
+
known_facts: facts,
|
|
328
|
+
context: {
|
|
329
|
+
...packet.context,
|
|
330
|
+
sources: next,
|
|
331
|
+
digest_scheme: "workspace-raw-v1",
|
|
332
|
+
...(inline.length === 0 ? {} : { inline_sources: inline }),
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
};
|
|
336
|
+
const prepare = async (packet, signal, options, readRoot) => {
|
|
337
|
+
const issued = taskContextPacketSchema.parse(packet);
|
|
338
|
+
await gate(issued, false);
|
|
339
|
+
const attemptId = createId("attempt");
|
|
340
|
+
const decision = options?.route ?? (await deps.router.resolve({ tier: issued.model_tier, role: issued.role }, signal));
|
|
341
|
+
await recorder.record("route/decided", { decision }, { taskId: issued.task_id, attemptId, actor: { kind: "system" } });
|
|
342
|
+
const overlay = [...new Set([...issued.scope.read_paths, ...issued.context.sources.map((source) => source.path)])].filter((candidate) => !matchesAny(candidate, issued.scope.owned_paths, platform));
|
|
343
|
+
const previous = options?.reuseAttempt;
|
|
344
|
+
const reuse = previous === undefined ? undefined : records.get(previous);
|
|
345
|
+
const workspace = await deps.isolation.create(issued, attemptId, signal, {
|
|
346
|
+
...(readRoot === undefined ? {} : { readRoot }),
|
|
347
|
+
...(overlay.length === 0 ? {} : { overlay }),
|
|
348
|
+
...(reuse === undefined || reuse.taskId !== issued.task_id ? {} : { reuse: reuse.workspace }),
|
|
349
|
+
});
|
|
350
|
+
if (options?.seedArtifact !== undefined)
|
|
351
|
+
await deps.isolation.seed(workspace, options.seedArtifact, signal);
|
|
352
|
+
const valid = await inWorkspace(issued, workspace, signal);
|
|
353
|
+
const policy = deps.policy.compute({
|
|
354
|
+
mode: deps.run.mode,
|
|
355
|
+
role: valid.role,
|
|
356
|
+
runId: deps.run.runId,
|
|
357
|
+
taskId: valid.task_id,
|
|
358
|
+
workspaceRoot: workspace.root,
|
|
359
|
+
taskScope: {
|
|
360
|
+
owned: valid.write_mode === "owned-paths" ? valid.scope.owned_paths : [],
|
|
361
|
+
read: valid.scope.read_paths,
|
|
362
|
+
// ADR-19: linked dependency directories are never touched through file tools (the policy has
|
|
363
|
+
// no write-only forbid, and a path through the link resolves outside the workspace anyway,
|
|
364
|
+
// `link-escape`); only processes a build or test runs read them. While links exist, commands
|
|
365
|
+
// that install, add, remove or update dependencies are denied (`dependency_links`).
|
|
366
|
+
forbidden: [...valid.scope.forbidden_paths, ...(workspace.dependencyLinks ?? [])],
|
|
367
|
+
verification_commands: valid.verification.commands,
|
|
368
|
+
...(workspace.dependencyLinks === undefined || workspace.dependencyLinks.length === 0 ? {} : { dependency_links: [...workspace.dependencyLinks] }),
|
|
369
|
+
},
|
|
370
|
+
userConfig: deps.userConfig,
|
|
371
|
+
workspaceConfig: deps.workspaceConfig,
|
|
372
|
+
sandbox: deps.sandbox,
|
|
373
|
+
grants: [],
|
|
374
|
+
});
|
|
375
|
+
await recorder.record("policy/snapshot", { policy, digest: digestOf(policy) }, { taskId: valid.task_id, attemptId, actor: { kind: "policy" } });
|
|
376
|
+
const events = await deps.sessions.create({
|
|
377
|
+
session_id: createId("session"),
|
|
378
|
+
project_id: deps.run.projectId,
|
|
379
|
+
workspace_root: workspace.root,
|
|
380
|
+
created_at: now().toISOString(),
|
|
381
|
+
title: `${valid.role} attempt ${attemptId}`,
|
|
382
|
+
});
|
|
383
|
+
const blob = await recorder.putJson(valid, PACKET_MEDIA_TYPE);
|
|
384
|
+
await recorder.record("task/packet_issued", { task_id: valid.task_id, kind: "full", packet_digest: packetDigest(valid), blob }, { taskId: valid.task_id, attemptId });
|
|
385
|
+
await recorder.record("attempt/started", {
|
|
386
|
+
attempt_id: attemptId,
|
|
387
|
+
task_id: valid.task_id,
|
|
388
|
+
role: valid.role,
|
|
389
|
+
route: decision.route,
|
|
390
|
+
packet_digest: packetDigest(valid),
|
|
391
|
+
isolation: {
|
|
392
|
+
mode: workspace.mode,
|
|
393
|
+
path: workspace.root,
|
|
394
|
+
...(workspace.baseCommit === undefined ? {} : { base_commit: workspace.baseCommit }),
|
|
395
|
+
...(workspace.reused === true ? { reused: true } : {}),
|
|
396
|
+
...(workspace.fallback === undefined ? {} : { fallback: workspace.fallback }),
|
|
397
|
+
...(workspace.overlaid === undefined || workspace.overlaid.length === 0 ? {} : { overlaid: [...workspace.overlaid] }),
|
|
398
|
+
...(workspace.dependencyLinks === undefined || workspace.dependencyLinks.length === 0 ? {} : { dependency_links: [...workspace.dependencyLinks] }),
|
|
399
|
+
...(workspace.submodules === undefined || workspace.submodules.length === 0 ? {} : { submodules: [...workspace.submodules] }),
|
|
400
|
+
},
|
|
401
|
+
session_id: events.sessionId,
|
|
402
|
+
}, { taskId: valid.task_id, attemptId });
|
|
403
|
+
const record = {
|
|
404
|
+
attemptId,
|
|
405
|
+
taskId: valid.task_id,
|
|
406
|
+
packet: valid,
|
|
407
|
+
route: decision.route,
|
|
408
|
+
sessionId: events.sessionId,
|
|
409
|
+
workspace,
|
|
410
|
+
policy,
|
|
411
|
+
changeSet: undefined,
|
|
412
|
+
log: undefined,
|
|
413
|
+
completion: undefined,
|
|
414
|
+
outcome: undefined,
|
|
415
|
+
failure: undefined,
|
|
416
|
+
stale: undefined,
|
|
417
|
+
harness: undefined,
|
|
418
|
+
repairs: { report_corrections: 0, evidence_repairs: 0, verification_repairs: 0 },
|
|
419
|
+
notes: options?.notes ?? [],
|
|
420
|
+
};
|
|
421
|
+
records.set(attemptId, record);
|
|
422
|
+
baselines.set(attemptId, issued);
|
|
423
|
+
const controller = linkSignals(signal);
|
|
424
|
+
controllers.set(attemptId, controller);
|
|
425
|
+
controls.set(attemptId, { paused: false, steers: [], wall: undefined });
|
|
426
|
+
pendingStores.set(attemptId, events);
|
|
427
|
+
return { record, controller };
|
|
428
|
+
};
|
|
429
|
+
const currentLog = async (record) => {
|
|
430
|
+
const events = pendingStores.get(record.attemptId);
|
|
431
|
+
if (events === undefined)
|
|
432
|
+
return record.log ?? emptyLog(record.sessionId);
|
|
433
|
+
return buildAttemptLog(record.sessionId, await readEvents(events), deps.blobs);
|
|
434
|
+
};
|
|
435
|
+
const execute = async (record, userMessage, controller, trigger, options = {}) => {
|
|
436
|
+
const events = pendingStores.get(record.attemptId);
|
|
437
|
+
if (events === undefined)
|
|
438
|
+
throw harnessError("internal", `attempt ${record.attemptId} has no session`);
|
|
439
|
+
const attemptControl = controls.get(record.attemptId);
|
|
440
|
+
const timer = new PausableTimer(record.packet.limits.max_wall_time_seconds * 1000, () => controller.abort(new Error("wall-time limit reached")), attemptControl?.paused === true);
|
|
441
|
+
if (attemptControl !== undefined)
|
|
442
|
+
attemptControl.wall = timer;
|
|
443
|
+
let outcome;
|
|
444
|
+
let error;
|
|
445
|
+
try {
|
|
446
|
+
const input = {
|
|
447
|
+
sessionId: record.sessionId,
|
|
448
|
+
runId: deps.run.runId,
|
|
449
|
+
taskId: record.taskId,
|
|
450
|
+
attemptId: record.attemptId,
|
|
451
|
+
role: record.packet.role,
|
|
452
|
+
route: record.route,
|
|
453
|
+
policy: record.policy,
|
|
454
|
+
packet: record.packet,
|
|
455
|
+
userMessage,
|
|
456
|
+
trigger,
|
|
457
|
+
maxSteps: options.maxSteps ?? record.packet.limits.max_steps,
|
|
458
|
+
sources: readerFor(record.workspace, platform),
|
|
459
|
+
...(options.reportOnly === undefined ? {} : { reportOnly: options.reportOnly }),
|
|
460
|
+
};
|
|
461
|
+
let driver = drivers.get(record.attemptId);
|
|
462
|
+
if (driver === undefined) {
|
|
463
|
+
driver = deps.createDriver(events);
|
|
464
|
+
drivers.set(record.attemptId, driver);
|
|
465
|
+
const control = controls.get(record.attemptId);
|
|
466
|
+
if (control !== undefined) {
|
|
467
|
+
for (const text of control.steers.splice(0))
|
|
468
|
+
driver.steer(text);
|
|
469
|
+
if (control.paused)
|
|
470
|
+
pausable(driver)?.pause();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
outcome = await driver.runTurn(input, controller.signal);
|
|
474
|
+
}
|
|
475
|
+
catch (caught) {
|
|
476
|
+
error = caught;
|
|
477
|
+
}
|
|
478
|
+
finally {
|
|
479
|
+
timer.clear();
|
|
480
|
+
if (attemptControl?.wall === timer)
|
|
481
|
+
attemptControl.wall = undefined;
|
|
482
|
+
}
|
|
483
|
+
const recorded = await readEvents(events);
|
|
484
|
+
const log = await buildAttemptLog(record.sessionId, recorded, deps.blobs);
|
|
485
|
+
const counted = countedCalls.get(record.attemptId) ?? 0;
|
|
486
|
+
deps.budget?.recordToolCalls(Math.max(0, log.toolCalls.size - counted));
|
|
487
|
+
countedCalls.set(record.attemptId, log.toolCalls.size);
|
|
488
|
+
record.log = log;
|
|
489
|
+
record.outcome = outcome;
|
|
490
|
+
record.failure = classifyAttemptFailure(outcome, error, recorded);
|
|
491
|
+
return { outcome, error, log };
|
|
492
|
+
};
|
|
493
|
+
const reportsIn = (log, tool) => log.reports.filter((report) => report.name === tool && log.toolCalls.get(report.toolCallId)?.state === "succeeded").length;
|
|
494
|
+
/** Steps the run budget still admits (undefined: no step limit). */
|
|
495
|
+
const runStepsLeft = () => {
|
|
496
|
+
const max = deps.budget?.limits().maxSteps;
|
|
497
|
+
return max === undefined || deps.budget === undefined ? undefined : Math.max(0, max - deps.budget.usage().steps);
|
|
498
|
+
};
|
|
499
|
+
/**
|
|
500
|
+
* One worker or reviewer turn that always ends with a chance to report (live run 01M37V2J: both
|
|
501
|
+
* reviewers hit the step budget mid-review and left no report, so the task failed "no valid
|
|
502
|
+
* review"). The turn runs until `finishWarning` steps before the attempt's limit (or what the run
|
|
503
|
+
* budget still admits); if it stops there without a report, the harness tells the model to finish
|
|
504
|
+
* now with the remaining steps; if the limit is then hit without a report, one forced report-only
|
|
505
|
+
* turn follows (only the report tool is offered, and the run's step budget graces that request).
|
|
506
|
+
*/
|
|
507
|
+
const executeBounded = async (record, userMessage, controller, trigger, tool) => {
|
|
508
|
+
const limit = record.packet.limits.max_steps;
|
|
509
|
+
const warn = Math.max(0, Math.min(deps.run.finishWarning ?? DEFAULT_FINISH_WARNING, limit - 1));
|
|
510
|
+
const before = reportsIn(await currentLog(record), tool);
|
|
511
|
+
const reported = (execution) => reportsIn(execution.log, tool) > before;
|
|
512
|
+
const stopped = (execution) => execution.error !== undefined || controller.signal.aborted || execution.outcome === undefined;
|
|
513
|
+
const available = Math.min(limit, runStepsLeft() ?? limit);
|
|
514
|
+
let execution;
|
|
515
|
+
if (available > warn) {
|
|
516
|
+
execution = await execute(record, userMessage, controller, trigger, { maxSteps: available - warn });
|
|
517
|
+
if (warn > 0 && execution.outcome?.outcome === "max_steps" && !reported(execution) && !stopped(execution)) {
|
|
518
|
+
const left = Math.min(warn, runStepsLeft() ?? warn);
|
|
519
|
+
if (left > 0)
|
|
520
|
+
execution = await execute(record, renderFinishNowMessage(tool, left), controller, "follow-up", { maxSteps: left });
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
execution = await execute(record, `${userMessage}\n\n${renderFinishNowMessage(tool, Math.max(1, available))}`, controller, trigger, { maxSteps: Math.max(1, available) });
|
|
525
|
+
}
|
|
526
|
+
const exhausted = execution.outcome?.outcome === "max_steps" || execution.outcome?.outcome === "budget_exceeded";
|
|
527
|
+
if (exhausted && !reported(execution) && !stopped(execution)) {
|
|
528
|
+
execution = await execute(record, renderReportOnlyMessage(tool), controller, "follow-up", { maxSteps: 1, reportOnly: tool });
|
|
529
|
+
}
|
|
530
|
+
return execution;
|
|
531
|
+
};
|
|
532
|
+
/**
|
|
533
|
+
* A review with no worker artifact or harness run to cite (integration and artifact reviews):
|
|
534
|
+
* only the reviewer's own resolved tool results count; `check` gives the report one correction round.
|
|
535
|
+
*/
|
|
536
|
+
const ownEvidenceJudging = (record, label) => {
|
|
537
|
+
const statements = statementsOf(record.packet);
|
|
538
|
+
const judge = async (log, criteria) => {
|
|
539
|
+
const index = indexFor(record, undefined, record.workspace.root, log);
|
|
540
|
+
const problems = [];
|
|
541
|
+
const judged = [];
|
|
542
|
+
for (const criterion of criteria) {
|
|
543
|
+
const kept = [];
|
|
544
|
+
for (const evidence of criterion.evidence) {
|
|
545
|
+
const resolution = evidence.produced_by === "reviewer" ? await resolvePointer(evidence, index, criterion.criterion_id) : unresolvedPointer(evidence, criterion.criterion_id, `${label} cites only its own tool results (produced_by: reviewer)`);
|
|
546
|
+
if (resolution.status === "resolved" && isIndependentReviewEvidence(evidence, undefined, statements.get(criterion.criterion_id)))
|
|
547
|
+
kept.push(evidence);
|
|
548
|
+
else
|
|
549
|
+
problems.push({ criterionId: criterion.criterion_id, ref: evidence.ref.slice(0, 200), reason: resolution.reason ?? "does not resolve" });
|
|
550
|
+
}
|
|
551
|
+
if (criterion.verdict === "met" && kept.length === 0) {
|
|
552
|
+
problems.push({ criterionId: criterion.criterion_id, ref: "(met)", reason: INDEPENDENT_EVIDENCE_HINT });
|
|
553
|
+
judged.push({ ...criterion, verdict: "unverifiable", evidence: kept });
|
|
554
|
+
}
|
|
555
|
+
else
|
|
556
|
+
judged.push({ ...criterion, evidence: kept });
|
|
557
|
+
}
|
|
558
|
+
return { problems, judged };
|
|
559
|
+
};
|
|
560
|
+
const check = async (input) => {
|
|
561
|
+
const report = input;
|
|
562
|
+
const { problems } = await judge(await currentLog(record), report.criteria);
|
|
563
|
+
if (problems.length === 0)
|
|
564
|
+
return toolOk(REPORT_RECORDED);
|
|
565
|
+
if (record.repairs.report_corrections < REPORT_CORRECTION_ROUNDS) {
|
|
566
|
+
record.repairs.report_corrections += 1;
|
|
567
|
+
const text = formatEvidenceCorrection(problems, evidenceCandidates(await currentLog(record)), REPORT_CORRECTION_ROUNDS - record.repairs.report_corrections);
|
|
568
|
+
return toolRejected(text, `${problems.length} evidence problem(s) in the review; nothing was recorded. Correct them as listed above and call ${REPORT_TOOL_NAMES.review} again.`);
|
|
569
|
+
}
|
|
570
|
+
return toolOk(`review recorded with ${problems.length} unresolved evidence problem(s); a met verdict without your own evidence counts as unverifiable. End your turn now.`);
|
|
571
|
+
};
|
|
572
|
+
return { judge, check };
|
|
573
|
+
};
|
|
574
|
+
const closeAttempt = async (record) => {
|
|
575
|
+
unregister.get(record.attemptId)?.();
|
|
576
|
+
unregister.delete(record.attemptId);
|
|
577
|
+
const events = pendingStores.get(record.attemptId);
|
|
578
|
+
pendingStores.delete(record.attemptId);
|
|
579
|
+
controllers.delete(record.attemptId);
|
|
580
|
+
controls.delete(record.attemptId);
|
|
581
|
+
drivers.delete(record.attemptId);
|
|
582
|
+
await events?.close().catch(() => undefined);
|
|
583
|
+
};
|
|
584
|
+
const finished = new Set();
|
|
585
|
+
const failUnfinished = async (record, error) => {
|
|
586
|
+
await closeAttempt(record);
|
|
587
|
+
if (finished.has(record.attemptId))
|
|
588
|
+
return;
|
|
589
|
+
finished.add(record.attemptId);
|
|
590
|
+
await recorder
|
|
591
|
+
.record("attempt/state_changed", { attempt_id: record.attemptId, from: "running", to: "failed", reason: `harness error: ${error instanceof Error ? error.message : String(error)}`.slice(0, 500) }, { taskId: record.taskId, attemptId: record.attemptId })
|
|
592
|
+
.catch(() => undefined);
|
|
593
|
+
};
|
|
594
|
+
const finishAttempt = async (record, execution, cancelled) => {
|
|
595
|
+
finished.add(record.attemptId);
|
|
596
|
+
const to = cancelled || execution.outcome?.outcome === "cancelled" ? "cancelled" : execution.error !== undefined || execution.outcome?.outcome === "failed" ? "failed" : "succeeded";
|
|
597
|
+
const reason = execution.error !== undefined
|
|
598
|
+
? `driver error: ${execution.error instanceof Error ? execution.error.message : String(execution.error)}`.slice(0, 500)
|
|
599
|
+
: `turn ${execution.outcome?.outcome ?? "ended"}`;
|
|
600
|
+
await recorder.record("attempt/state_changed", { attempt_id: record.attemptId, from: "running", to, reason }, { taskId: record.taskId, attemptId: record.attemptId });
|
|
601
|
+
};
|
|
602
|
+
const indexFor = (record, artifact, root, log) => {
|
|
603
|
+
const source = log ?? record.log ?? emptyLog(record.sessionId);
|
|
604
|
+
return {
|
|
605
|
+
log: source,
|
|
606
|
+
artifactDigest: artifact?.artifactDigest,
|
|
607
|
+
changedPaths: artifact?.changes.map((change) => change.path) ?? loggedChanges(source),
|
|
608
|
+
fileDigest: (relative) => (root === record.workspace.root ? readerFor(record.workspace, platform) : createWorkspaceDigestReader(root, { platform }))(relative),
|
|
609
|
+
harness: record.harness,
|
|
610
|
+
};
|
|
611
|
+
};
|
|
612
|
+
/** P0-A: per task, the last passing run of each verification command (see `isInstallCommand`). */
|
|
613
|
+
const verificationCache = new Map();
|
|
614
|
+
/** ADR-18 D1: the harness runs the packet's verification commands itself and records each run. */
|
|
615
|
+
const runHarnessVerification = async (record, changeSet, signal) => {
|
|
616
|
+
const diff = changeSet.changes.length === 0
|
|
617
|
+
? undefined
|
|
618
|
+
: {
|
|
619
|
+
evidence: { kind: "harness-diff", ref: changeSet.artifactDigest, produced_by: "harness" },
|
|
620
|
+
changed_paths: changeSet.changes.map((change) => change.path),
|
|
621
|
+
};
|
|
622
|
+
const runner = deps.verification;
|
|
623
|
+
const verification = [];
|
|
624
|
+
const cache = verificationCache.get(record.taskId) ?? new Map();
|
|
625
|
+
verificationCache.set(record.taskId, cache);
|
|
626
|
+
const scoped = record.workspace.mode === "scoped-dir";
|
|
627
|
+
const manifests = manifestFingerprint(changeSet);
|
|
628
|
+
let ranCommand = false;
|
|
629
|
+
const passedCommands = [];
|
|
630
|
+
if (runner !== undefined) {
|
|
631
|
+
for (const [position, command] of record.packet.verification.commands.slice(0, 100).entries()) {
|
|
632
|
+
const started = Date.now();
|
|
633
|
+
const argv = commandArgv(command);
|
|
634
|
+
const install = argv !== undefined && argv.length > 0 && isInstallCommand(argv);
|
|
635
|
+
const cached = cache.get(command);
|
|
636
|
+
const sameTree = cached !== undefined && (cached.attemptId === record.attemptId || (scoped && cached.scoped && cached.root === record.workspace.root));
|
|
637
|
+
const reusable = cached !== undefined && sameTree && (install ? cached.manifests === manifests : cached.artifact === changeSet.artifactDigest);
|
|
638
|
+
let result;
|
|
639
|
+
if (reusable && argv !== undefined && argv.length > 0) {
|
|
640
|
+
const why = install ? "the dependency manifests are unchanged" : "the artifact is unchanged";
|
|
641
|
+
result = { status: "passed", termination: "exited", exitCode: 0, output: `(reused) passed earlier in this task (${cached.ref}); ${why}, so the harness did not run it again`, durationMs: 0 };
|
|
642
|
+
}
|
|
643
|
+
else if (argv === undefined || argv.length === 0) {
|
|
644
|
+
result = { status: "not-run", exitCode: null, output: "", durationMs: 0, reason: "the command uses shell syntax and cannot be run as a plain argv" };
|
|
645
|
+
}
|
|
646
|
+
else if (signal.aborted) {
|
|
647
|
+
result = { status: "not-run", exitCode: null, output: "", durationMs: 0, reason: "the attempt was cancelled" };
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
ranCommand = true;
|
|
651
|
+
try {
|
|
652
|
+
result = await runner({
|
|
653
|
+
command,
|
|
654
|
+
argv: argv,
|
|
655
|
+
workspaceRoot: record.workspace.root,
|
|
656
|
+
policy: record.policy,
|
|
657
|
+
runId: deps.run.runId,
|
|
658
|
+
taskId: record.taskId,
|
|
659
|
+
attemptId: record.attemptId,
|
|
660
|
+
role: record.packet.role,
|
|
661
|
+
signal,
|
|
662
|
+
events: pendingStores.get(record.attemptId),
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
catch (error) {
|
|
666
|
+
result = { status: "not-run", exitCode: null, output: "", durationMs: Date.now() - started, reason: `the harness could not run it: ${error instanceof Error ? error.message : String(error)}` };
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
const normalized = normalizeVerification(result);
|
|
670
|
+
let outputBlob;
|
|
671
|
+
if (normalized.output.length > OUTPUT_EXCERPT_LIMIT) {
|
|
672
|
+
outputBlob = await deps.blobs.put(new Uint8Array(Buffer.from(normalized.output, "utf8")), "text/plain; charset=utf-8").catch(() => undefined);
|
|
673
|
+
}
|
|
674
|
+
const event = await recorder.record("attempt/verification_ran", {
|
|
675
|
+
attempt_id: record.attemptId,
|
|
676
|
+
task_id: record.taskId,
|
|
677
|
+
ordinal: position + 1,
|
|
678
|
+
command: command.slice(0, 4000),
|
|
679
|
+
...(argv === undefined || argv.length === 0 ? {} : { argv: argv.slice(0, 256) }),
|
|
680
|
+
...(normalized.commandClass === undefined ? {} : { command_class: normalized.commandClass }),
|
|
681
|
+
status: normalized.status,
|
|
682
|
+
...(normalized.termination === undefined ? {} : { termination: normalized.termination }),
|
|
683
|
+
exit_code: normalized.exitCode,
|
|
684
|
+
duration_ms: Math.max(0, Math.round(normalized.durationMs)),
|
|
685
|
+
output_excerpt: excerpt(normalized.output),
|
|
686
|
+
...(outputBlob === undefined ? {} : { output_blob: outputBlob }),
|
|
687
|
+
...(changeSet.changes.length === 0 ? {} : { artifact_digest: changeSet.artifactDigest }),
|
|
688
|
+
...(normalized.reason === undefined ? {} : { reason: normalized.reason.slice(0, 500) }),
|
|
689
|
+
}, { taskId: record.taskId, attemptId: record.attemptId, actor: { kind: "system" } });
|
|
690
|
+
if (normalized.status === "passed" && !reusable) {
|
|
691
|
+
cache.set(command, { attemptId: record.attemptId, root: record.workspace.root, scoped, artifact: changeSet.artifactDigest, manifests, ref: `${recorder.log.sessionId}#${event.seq}` });
|
|
692
|
+
}
|
|
693
|
+
else if (normalized.status !== "passed")
|
|
694
|
+
cache.delete(command);
|
|
695
|
+
if (normalized.status === "passed")
|
|
696
|
+
passedCommands.push(command);
|
|
697
|
+
verification.push({
|
|
698
|
+
ordinal: position + 1,
|
|
699
|
+
command: command.slice(0, 4000),
|
|
700
|
+
...(normalized.commandClass === undefined ? {} : { command_class: normalized.commandClass }),
|
|
701
|
+
status: normalized.status,
|
|
702
|
+
...(normalized.termination === undefined ? {} : { termination: normalized.termination }),
|
|
703
|
+
exit_code: normalized.exitCode,
|
|
704
|
+
...(normalized.reason === undefined ? {} : { reason: normalized.reason.slice(0, 500) }),
|
|
705
|
+
evidence: {
|
|
706
|
+
kind: "harness-verification",
|
|
707
|
+
ref: `${recorder.log.sessionId}#${event.seq}`,
|
|
708
|
+
produced_by: "harness",
|
|
709
|
+
...(outputBlob === undefined ? {} : { digest: outputBlob.digest }),
|
|
710
|
+
},
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
if (!ranCommand)
|
|
715
|
+
return { harness: { verification, ...(diff === undefined ? {} : { diff }) }, changeSet };
|
|
716
|
+
// P0-A: a verification command may write non-ignored outputs (an install's lockfile): the verified
|
|
717
|
+
// state is the one pinned, reviewed and integrated, so a later integrate never sees a moved artifact.
|
|
718
|
+
const verified = await record.workspace.changeSet(new AbortController().signal);
|
|
719
|
+
if (verified.artifactDigest === changeSet.artifactDigest)
|
|
720
|
+
return { harness: { verification, ...(diff === undefined ? {} : { diff }) }, changeSet };
|
|
721
|
+
const verifiedManifests = manifestFingerprint(verified);
|
|
722
|
+
for (const command of passedCommands) {
|
|
723
|
+
const entry = cache.get(command);
|
|
724
|
+
if (entry !== undefined)
|
|
725
|
+
cache.set(command, { ...entry, artifact: verified.artifactDigest, manifests: verifiedManifests });
|
|
726
|
+
}
|
|
727
|
+
return {
|
|
728
|
+
harness: {
|
|
729
|
+
verification,
|
|
730
|
+
...(verified.changes.length === 0
|
|
731
|
+
? {}
|
|
732
|
+
: { diff: { evidence: { kind: "harness-diff", ref: verified.artifactDigest, produced_by: "harness" }, changed_paths: verified.changes.map((change) => change.path) } }),
|
|
733
|
+
},
|
|
734
|
+
changeSet: verified,
|
|
735
|
+
};
|
|
736
|
+
};
|
|
737
|
+
const assemble = async (record, execution, changeSet, claimResult, stale, cancelledReason) => {
|
|
738
|
+
const claim = claimResult.ok ? claimResult.claim : undefined;
|
|
739
|
+
const notes = [];
|
|
740
|
+
let status;
|
|
741
|
+
if (stale !== undefined) {
|
|
742
|
+
status = "needs_context";
|
|
743
|
+
notes.push(`sources changed during the attempt: ${stale.join(", ")}`);
|
|
744
|
+
}
|
|
745
|
+
else if (cancelledReason !== undefined || execution.outcome?.outcome === "cancelled") {
|
|
746
|
+
status = "failed";
|
|
747
|
+
notes.push(`attempt cancelled: ${cancelledReason ?? "signal"}`);
|
|
748
|
+
}
|
|
749
|
+
else if (execution.error !== undefined || execution.outcome === undefined) {
|
|
750
|
+
status = "failed";
|
|
751
|
+
notes.push("the agent turn failed");
|
|
752
|
+
}
|
|
753
|
+
else if (execution.outcome.outcome === "awaiting_approval") {
|
|
754
|
+
status = "blocked";
|
|
755
|
+
notes.push("the attempt is waiting for an approval that was not granted");
|
|
756
|
+
}
|
|
757
|
+
else if (execution.outcome.outcome === "budget_exceeded" || execution.outcome.outcome === "failed") {
|
|
758
|
+
status = "failed";
|
|
759
|
+
notes.push(`turn ended ${execution.outcome.outcome}`);
|
|
760
|
+
}
|
|
761
|
+
else if (claim === undefined) {
|
|
762
|
+
status = execution.outcome.outcome === "max_steps" ? "partial" : "failed";
|
|
763
|
+
notes.push(`no valid completion claim: ${claimResult.ok ? "" : claimResult.problems.join("; ")}`);
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
status = claim.status;
|
|
767
|
+
if (execution.outcome.outcome === "max_steps" && status === "completed") {
|
|
768
|
+
status = "partial";
|
|
769
|
+
notes.push("the step limit was reached");
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
const claimed = (claim?.acceptance_evidence ?? [])
|
|
773
|
+
.map((entry) => ({ criterion_id: entry.criterion_id, evidence: entry.evidence.filter((evidence) => evidence.produced_by !== "reviewer" && evidence.produced_by !== "harness") }))
|
|
774
|
+
.filter((entry) => entry.evidence.length > 0);
|
|
775
|
+
if (claim !== undefined && claimed.length < claim.acceptance_evidence.length) {
|
|
776
|
+
notes.push("evidence attributed to a reviewer or the harness was removed: a worker cites only its own evidence");
|
|
777
|
+
}
|
|
778
|
+
const index = indexFor(record, changeSet, record.workspace.root, execution.log);
|
|
779
|
+
const claimedCommands = (claim?.commands_run ?? []).filter((command) => command.evidence.produced_by === "worker");
|
|
780
|
+
const resolved = await resolveCompletionEvidence(record.packet, claimed, claimedCommands, index, platform);
|
|
781
|
+
if (status === "completed" && resolved.acceptanceEvidence.length === 0) {
|
|
782
|
+
status = "partial";
|
|
783
|
+
notes.push("completed was claimed without evidence");
|
|
784
|
+
}
|
|
785
|
+
if (resolved.substituted.length > 0) {
|
|
786
|
+
notes.push(`the harness verification evidenced ${resolved.substituted.join(", ")} (the report's pointers did not resolve)`);
|
|
787
|
+
}
|
|
788
|
+
const logged = commandsFromLog(execution.log);
|
|
789
|
+
const seen = new Set(logged.map((command) => command.evidence.ref));
|
|
790
|
+
const fromClaim = claimedCommands.flatMap((command) => {
|
|
791
|
+
const resolution = resolved.resolution.find((entry) => entry.criterion_id === undefined && entry.ref === command.evidence.ref.slice(0, 2000) && entry.status === "resolved");
|
|
792
|
+
const id = resolution?.tool_call_id;
|
|
793
|
+
const call = id === undefined ? undefined : execution.log.toolCalls.get(id);
|
|
794
|
+
if (id === undefined || call === undefined || seen.has(id) || call.name !== "exec" || call.state !== "succeeded")
|
|
795
|
+
return [];
|
|
796
|
+
seen.add(id);
|
|
797
|
+
return [{ command: command.command, exit_code: call.exitCode ?? 0, evidence: { kind: "tool-call", ref: id, produced_by: "worker" } }];
|
|
798
|
+
});
|
|
799
|
+
const repairs = { ...record.repairs };
|
|
800
|
+
const base = {
|
|
801
|
+
schema_version: 2,
|
|
802
|
+
task_id: record.taskId,
|
|
803
|
+
attempt_id: record.attemptId,
|
|
804
|
+
packet_digest: packetDigest(record.packet),
|
|
805
|
+
status,
|
|
806
|
+
summary: [claim?.summary ?? `Attempt ${record.attemptId} ended without a usable report.`, ...notes].join(" | ").slice(0, 4000),
|
|
807
|
+
changed_paths: changeSet.changes.map((change) => ({ path: change.path, before: change.before, after: change.after })),
|
|
808
|
+
artifact_digest: changeSet.artifactDigest,
|
|
809
|
+
tool_call_ids: [...execution.log.toolCalls.keys()],
|
|
810
|
+
acceptance_evidence: resolved.acceptanceEvidence,
|
|
811
|
+
commands_run: [...logged, ...fromClaim],
|
|
812
|
+
decisions_made: claim?.decisions_made ?? [],
|
|
813
|
+
skipped_checks: claim?.skipped_checks ?? [],
|
|
814
|
+
unresolved_risks: [...(claim?.unresolved_risks ?? []), ...(notes.length > 0 && status !== "completed" ? notes : [])],
|
|
815
|
+
recommended_context_updates: claim?.recommended_context_updates ?? [],
|
|
816
|
+
...(claim?.root_cause === undefined ? {} : { root_cause: claim.root_cause }),
|
|
817
|
+
...(record.harness === undefined ? {} : { harness_evidence: record.harness }),
|
|
818
|
+
...(resolved.resolution.length === 0 ? {} : { evidence_resolution: resolved.resolution }),
|
|
819
|
+
repairs,
|
|
820
|
+
};
|
|
821
|
+
const parsed = completionPacketSchema.safeParse(base);
|
|
822
|
+
if (parsed.success)
|
|
823
|
+
return parsed.data;
|
|
824
|
+
const changed = base.changed_paths.filter((change) => normalizeWorkspacePath(change.path) !== undefined);
|
|
825
|
+
return completionPacketSchema.parse({
|
|
826
|
+
...base,
|
|
827
|
+
status: status === "completed" ? "partial" : status,
|
|
828
|
+
summary: `${base.summary} | completion rejected by schema: ${parsed.error.issues.map((issue) => issue.message).join("; ")}`.slice(0, 4000),
|
|
829
|
+
changed_paths: changed,
|
|
830
|
+
acceptance_evidence: claimed,
|
|
831
|
+
commands_run: logged,
|
|
832
|
+
harness_evidence: record.harness === undefined ? undefined : { verification: record.harness.verification },
|
|
833
|
+
evidence_resolution: undefined,
|
|
834
|
+
});
|
|
835
|
+
};
|
|
836
|
+
/**
|
|
837
|
+
* The in-call check of `task_report` (ADR-18 D1): every pointer is resolved against the attempt
|
|
838
|
+
* log while the model can still act on the answer. Unresolved pointers get one actionable
|
|
839
|
+
* correction round; the second rejection is recorded and the report is accepted as it is.
|
|
840
|
+
*/
|
|
841
|
+
const taskReportCheck = (record) => async (input) => {
|
|
842
|
+
const report = input;
|
|
843
|
+
if (!CORRECTABLE_STATUSES.has(report.status))
|
|
844
|
+
return toolOk(REPORT_RECORDED);
|
|
845
|
+
const log = await currentLog(record);
|
|
846
|
+
const index = indexFor(record, undefined, record.workspace.root, log);
|
|
847
|
+
const known = new Set(record.packet.acceptance_criteria.map((criterion) => criterion.id));
|
|
848
|
+
const resolutions = [];
|
|
849
|
+
const problems = [];
|
|
850
|
+
for (const entry of report.acceptance_evidence) {
|
|
851
|
+
if (!known.has(entry.criterion_id)) {
|
|
852
|
+
problems.push({ criterionId: entry.criterion_id, ref: entry.criterion_id, reason: `is not a criterion of this task (criteria: ${[...known].join(", ")})` });
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
855
|
+
for (const evidence of entry.evidence) {
|
|
856
|
+
resolutions.push(evidence.produced_by === "worker"
|
|
857
|
+
? await resolvePointer(evidence, index, entry.criterion_id)
|
|
858
|
+
: unresolvedPointer(evidence, entry.criterion_id, "a worker cites only its own evidence (produced_by: worker)"));
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
const listed = new Set(report.acceptance_evidence.map((entry) => entry.criterion_id));
|
|
862
|
+
if (report.status === "completed") {
|
|
863
|
+
for (const id of known)
|
|
864
|
+
if (!listed.has(id))
|
|
865
|
+
problems.push({ criterionId: id, ref: "(none)", reason: "has no evidence listed" });
|
|
866
|
+
}
|
|
867
|
+
problems.push(...evidenceProblems(resolutions));
|
|
868
|
+
if (problems.length === 0)
|
|
869
|
+
return toolOk(REPORT_RECORDED);
|
|
870
|
+
if (record.repairs.report_corrections < REPORT_CORRECTION_ROUNDS) {
|
|
871
|
+
record.repairs.report_corrections += 1;
|
|
872
|
+
const text = formatEvidenceCorrection(problems, evidenceCandidates(log), REPORT_CORRECTION_ROUNDS - record.repairs.report_corrections);
|
|
873
|
+
return toolRejected(text, `${problems.length} evidence problem(s) in the report; nothing was recorded. Correct the refs listed above and call ${REPORT_TOOL_NAMES.task} again.`);
|
|
874
|
+
}
|
|
875
|
+
return toolOk(`report recorded with ${problems.length} unresolved evidence pointer(s); the harness records them as they are. End your turn now.`);
|
|
876
|
+
};
|
|
877
|
+
const complete = async (record, controller) => {
|
|
878
|
+
unregister.set(record.attemptId, deps.reports?.register(record.attemptId, taskReportCheck(record)) ?? (() => undefined));
|
|
879
|
+
let execution = await executeBounded(record, renderWorkerMessage(record.packet, record.notes), controller, "dispatch", REPORT_TOOL_NAMES.task);
|
|
880
|
+
let completion;
|
|
881
|
+
let cancelledReason;
|
|
882
|
+
let rounds = 0;
|
|
883
|
+
for (;;) {
|
|
884
|
+
let changeSet = await record.workspace.changeSet(new AbortController().signal);
|
|
885
|
+
record.changeSet = changeSet;
|
|
886
|
+
let stale;
|
|
887
|
+
if (execution.outcome?.outcome !== "cancelled") {
|
|
888
|
+
try {
|
|
889
|
+
await gate(baselines.get(record.attemptId) ?? record.packet, true);
|
|
890
|
+
}
|
|
891
|
+
catch (error) {
|
|
892
|
+
if (error instanceof StaleInFlight)
|
|
893
|
+
stale = error.paths;
|
|
894
|
+
else
|
|
895
|
+
throw error;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
record.stale = stale;
|
|
899
|
+
cancelledReason = controller.signal.aborted ? String(controller.signal.reason?.message ?? controller.signal.reason) : undefined;
|
|
900
|
+
const claim = readClaim(workerClaimSchema, execution.log, REPORT_TOOL_NAMES.task);
|
|
901
|
+
const turnEnded = execution.error === undefined && (execution.outcome?.outcome === "completed" || execution.outcome?.outcome === "max_steps");
|
|
902
|
+
const claimedStatus = claim.ok ? claim.claim.status : undefined;
|
|
903
|
+
const verifies = turnEnded && stale === undefined && cancelledReason === undefined && claimedStatus !== "needs_context" && claimedStatus !== "blocked" && claimedStatus !== "failed";
|
|
904
|
+
record.harness = undefined;
|
|
905
|
+
if (verifies) {
|
|
906
|
+
const verified = await runHarnessVerification(record, changeSet, controller.signal);
|
|
907
|
+
record.harness = verified.harness;
|
|
908
|
+
changeSet = verified.changeSet;
|
|
909
|
+
record.changeSet = changeSet;
|
|
910
|
+
}
|
|
911
|
+
completion = await assemble(record, execution, changeSet, claim, stale, cancelledReason);
|
|
912
|
+
if (completion.status !== "completed" || stale !== undefined || cancelledReason !== undefined)
|
|
913
|
+
break;
|
|
914
|
+
const check = await verifyCompletion(record.packet, completion, indexFor(record, changeSet, record.workspace.root, execution.log), platform);
|
|
915
|
+
if (check.decision !== "revise")
|
|
916
|
+
break;
|
|
917
|
+
// Plan-caused verification problems (a refused / unrunnable / missing command) are the
|
|
918
|
+
// orchestrator's to decide (triage): the worker cannot change its plan, so they never cost a
|
|
919
|
+
// repair round. Only what the worker can fix is sent back.
|
|
920
|
+
const planProblems = new Set(check.planProblems ?? []);
|
|
921
|
+
const workerProblems = check.problems.filter((problem) => !planProblems.has(problem));
|
|
922
|
+
if (workerProblems.length === 0)
|
|
923
|
+
break;
|
|
924
|
+
const used = repairsUsed.get(record.taskId) ?? 0;
|
|
925
|
+
if (used >= budgets.evidence_repairs)
|
|
926
|
+
break;
|
|
927
|
+
const kind = (check.failedVerification ?? []).length > 0 ? "verification-repair" : "evidence-repair";
|
|
928
|
+
repairsUsed.set(record.taskId, used + 1);
|
|
929
|
+
rounds += 1;
|
|
930
|
+
if (kind === "verification-repair")
|
|
931
|
+
record.repairs.verification_repairs += 1;
|
|
932
|
+
else
|
|
933
|
+
record.repairs.evidence_repairs += 1;
|
|
934
|
+
const problems = workerProblems.slice(0, 50).map((problem) => problem.slice(0, 2000));
|
|
935
|
+
await recorder.record("attempt/repair_requested", { attempt_id: record.attemptId, task_id: record.taskId, kind, round: Math.min(rounds, budgets.evidence_repairs), budget: budgets.evidence_repairs, problems }, { taskId: record.taskId, attemptId: record.attemptId, actor: { kind: "system" } });
|
|
936
|
+
execution = await executeBounded(record, renderRepairMessage(kind, problems, execution.log, record.harness), controller, "follow-up", REPORT_TOOL_NAMES.task);
|
|
937
|
+
}
|
|
938
|
+
record.completion = completion;
|
|
939
|
+
await closeAttempt(record);
|
|
940
|
+
await finishAttempt(record, execution, cancelledReason !== undefined);
|
|
941
|
+
const blob = await recorder.putJson(completion, COMPLETION_MEDIA_TYPE);
|
|
942
|
+
await recorder.record("attempt/completion_recorded", { attempt_id: record.attemptId, task_id: record.taskId, status: completion.status, completion_digest: packetDigest(completion), blob }, { taskId: record.taskId, attemptId: record.attemptId, actor: { kind: "worker", role: record.packet.role, attempt_id: record.attemptId } });
|
|
943
|
+
return completion;
|
|
944
|
+
};
|
|
945
|
+
const fallbackCompletion = (record, error) => completionPacketSchema.parse({
|
|
946
|
+
schema_version: 2,
|
|
947
|
+
task_id: record.taskId,
|
|
948
|
+
attempt_id: record.attemptId,
|
|
949
|
+
packet_digest: packetDigest(record.packet),
|
|
950
|
+
status: "failed",
|
|
951
|
+
summary: `attempt failed inside the harness: ${error instanceof Error ? error.message : String(error)}`.slice(0, 2000),
|
|
952
|
+
changed_paths: [],
|
|
953
|
+
tool_call_ids: [],
|
|
954
|
+
acceptance_evidence: [],
|
|
955
|
+
commands_run: [],
|
|
956
|
+
decisions_made: [],
|
|
957
|
+
skipped_checks: [],
|
|
958
|
+
unresolved_risks: ["the attempt workspace may hold partial changes; it was not integrated"],
|
|
959
|
+
recommended_context_updates: [],
|
|
960
|
+
});
|
|
961
|
+
/** Reviewer pointers resolve against the reviewer's attempt, harness pointers against the target's records. */
|
|
962
|
+
const reviewIndexes = (target, reviewer, pinned, completion, reviewerLog) => {
|
|
963
|
+
const worker = { ...indexFor(target, pinned, target.workspace.root), harness: target.harness ?? completion.harness_evidence };
|
|
964
|
+
const own = { ...indexFor(reviewer, pinned, target.workspace.root, reviewerLog), harness: worker.harness };
|
|
965
|
+
return { worker, reviewer: own };
|
|
966
|
+
};
|
|
967
|
+
const resolveReviewPointer = async (evidence, criterionId, indexes) => {
|
|
968
|
+
if (evidence.produced_by === "reviewer")
|
|
969
|
+
return resolvePointer(evidence, indexes.reviewer, criterionId);
|
|
970
|
+
if (evidence.produced_by === "harness" || evidence.produced_by === "worker")
|
|
971
|
+
return resolvePointer(evidence, indexes.worker, criterionId);
|
|
972
|
+
return unresolvedPointer(evidence, criterionId, `${evidence.produced_by} evidence is not accepted in a review`);
|
|
973
|
+
};
|
|
974
|
+
/** The in-call check of `review_report`: reviewer pointers must resolve and every met verdict needs independent evidence. */
|
|
975
|
+
const reviewReportCheck = (record, target, pinned, completion) => async (input) => {
|
|
976
|
+
const report = input;
|
|
977
|
+
const log = await currentLog(record);
|
|
978
|
+
const indexes = reviewIndexes(target, record, pinned, completion, log);
|
|
979
|
+
const problems = [];
|
|
980
|
+
const statements = statementsOf(target.packet);
|
|
981
|
+
for (const criterion of report.criteria) {
|
|
982
|
+
let independent = 0;
|
|
983
|
+
for (const evidence of criterion.evidence) {
|
|
984
|
+
const resolution = await resolveReviewPointer(evidence, criterion.criterion_id, indexes);
|
|
985
|
+
if (resolution.status === "resolved" && isIndependentReviewEvidence(evidence, indexes.worker.harness, statements.get(criterion.criterion_id)))
|
|
986
|
+
independent += 1;
|
|
987
|
+
else if (resolution.status !== "resolved")
|
|
988
|
+
problems.push({ criterionId: criterion.criterion_id, ref: evidence.ref.slice(0, 200), reason: resolution.reason ?? "does not resolve" });
|
|
989
|
+
}
|
|
990
|
+
if (criterion.verdict === "met" && independent === 0) {
|
|
991
|
+
problems.push({ criterionId: criterion.criterion_id, ref: "(met)", reason: INDEPENDENT_EVIDENCE_HINT });
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
if (problems.length === 0)
|
|
995
|
+
return toolOk(REPORT_RECORDED);
|
|
996
|
+
if (record.repairs.report_corrections < REPORT_CORRECTION_ROUNDS) {
|
|
997
|
+
record.repairs.report_corrections += 1;
|
|
998
|
+
const harness = harnessLines(indexes.worker.harness, target.packet);
|
|
999
|
+
const text = [
|
|
1000
|
+
formatEvidenceCorrection(problems, evidenceCandidates(log), REPORT_CORRECTION_ROUNDS - record.repairs.report_corrections),
|
|
1001
|
+
harness.length > 0 ? `Harness records (kind harness-verification / harness-diff, produced_by: harness):\n${harness.join("\n")}` : "",
|
|
1002
|
+
]
|
|
1003
|
+
.filter((part) => part !== "")
|
|
1004
|
+
.join("\n");
|
|
1005
|
+
return toolRejected(text, `${problems.length} evidence problem(s) in the review; nothing was recorded. Correct them as listed above and call ${REPORT_TOOL_NAMES.review} again.`);
|
|
1006
|
+
}
|
|
1007
|
+
return toolOk(`review recorded with ${problems.length} unresolved evidence problem(s); unresolved pointers are dropped and a met verdict without independent evidence counts as unverifiable. End your turn now.`);
|
|
1008
|
+
};
|
|
1009
|
+
const liveControl = (attemptId) => controllers.has(attemptId) && !finished.has(attemptId) ? controls.get(attemptId) : undefined;
|
|
1010
|
+
const manager = {
|
|
1011
|
+
async dispatch(packet, signal, options) {
|
|
1012
|
+
const { record, controller } = await prepare(packet, signal, options, undefined);
|
|
1013
|
+
const completion = complete(record, controller).catch(async (error) => {
|
|
1014
|
+
await failUnfinished(record, error);
|
|
1015
|
+
record.completion = fallbackCompletion(record, error);
|
|
1016
|
+
return record.completion;
|
|
1017
|
+
});
|
|
1018
|
+
const handle = {
|
|
1019
|
+
attemptId: record.attemptId,
|
|
1020
|
+
taskId: record.taskId,
|
|
1021
|
+
completion,
|
|
1022
|
+
cancel: (reason) => controller.abort(new Error(reason)),
|
|
1023
|
+
};
|
|
1024
|
+
handles.set(record.attemptId, handle);
|
|
1025
|
+
void completion.finally(() => handles.delete(record.attemptId));
|
|
1026
|
+
return handle;
|
|
1027
|
+
},
|
|
1028
|
+
async dispatchReview(packet, targetId, signal, options) {
|
|
1029
|
+
const target = records.get(targetId);
|
|
1030
|
+
if (target?.completion === undefined || target.changeSet === undefined) {
|
|
1031
|
+
throw harnessError("review_blocked", `attempt ${targetId} has no pinned completion to review`);
|
|
1032
|
+
}
|
|
1033
|
+
if (packet.role !== "reviewer" || packet.write_mode !== "read-only") {
|
|
1034
|
+
throw harnessError("review_blocked", "a review runs as a read-only reviewer packet");
|
|
1035
|
+
}
|
|
1036
|
+
const pinned = target.changeSet;
|
|
1037
|
+
const completion = target.completion;
|
|
1038
|
+
const { record, controller } = await prepare(packet, signal, options, target.workspace.root);
|
|
1039
|
+
const run = async () => {
|
|
1040
|
+
unregister.set(record.attemptId, deps.reports?.register(record.attemptId, reviewReportCheck(record, target, pinned, completion)) ?? (() => undefined));
|
|
1041
|
+
const execution = await executeBounded(record, renderReviewBrief(target, completion, pinned), controller, "dispatch", REPORT_TOOL_NAMES.review);
|
|
1042
|
+
await closeAttempt(record);
|
|
1043
|
+
await finishAttempt(record, execution, controller.signal.aborted);
|
|
1044
|
+
const claim = readClaim(reviewerClaimSchema, execution.log, REPORT_TOOL_NAMES.review);
|
|
1045
|
+
if (!claim.ok)
|
|
1046
|
+
return { attemptId: record.attemptId, review: undefined, verification: { decision: "invalid", problems: claim.problems } };
|
|
1047
|
+
// ADR-18: unresolved pointers are dropped (and recorded); a met verdict left without independent evidence is unverifiable.
|
|
1048
|
+
const indexes = reviewIndexes(target, record, pinned, completion, execution.log);
|
|
1049
|
+
const statements = statementsOf(target.packet);
|
|
1050
|
+
const resolution = [];
|
|
1051
|
+
const downgraded = [];
|
|
1052
|
+
const criteria = [];
|
|
1053
|
+
for (const criterion of claim.claim.criteria) {
|
|
1054
|
+
const kept = [];
|
|
1055
|
+
for (const evidence of criterion.evidence) {
|
|
1056
|
+
const result = await resolveReviewPointer(evidence, criterion.criterion_id, indexes);
|
|
1057
|
+
resolution.push(result);
|
|
1058
|
+
if (result.status === "resolved")
|
|
1059
|
+
kept.push(evidence);
|
|
1060
|
+
}
|
|
1061
|
+
const independent = kept.some((evidence) => isIndependentReviewEvidence(evidence, indexes.worker.harness, statements.get(criterion.criterion_id)));
|
|
1062
|
+
if (criterion.verdict === "met" && !independent) {
|
|
1063
|
+
downgraded.push(criterion.criterion_id);
|
|
1064
|
+
criteria.push({ ...criterion, verdict: "unverifiable", evidence: kept, note: `${criterion.note === undefined ? "" : `${criterion.note} | `}harness: no independent evidence (own tool result or passed build/test verification; harness-diff alone is not enough)` });
|
|
1065
|
+
}
|
|
1066
|
+
else
|
|
1067
|
+
criteria.push({ ...criterion, evidence: kept });
|
|
1068
|
+
}
|
|
1069
|
+
const decision = claim.claim.decision === "accept" && downgraded.length > 0 ? "revise" : claim.claim.decision;
|
|
1070
|
+
const candidate = {
|
|
1071
|
+
schema_version: 2,
|
|
1072
|
+
task_id: target.taskId,
|
|
1073
|
+
reviewed_attempt_id: target.attemptId,
|
|
1074
|
+
reviewer_attempt_id: record.attemptId,
|
|
1075
|
+
completion_digest: packetDigest(completion),
|
|
1076
|
+
reviewed_artifact_digest: pinned.artifactDigest,
|
|
1077
|
+
reviewer_route: { provider_id: record.route.provider_id, model_id: record.route.model_id },
|
|
1078
|
+
independence: {
|
|
1079
|
+
separate_context: true,
|
|
1080
|
+
same_provider: record.route.provider_id === target.route.provider_id,
|
|
1081
|
+
same_model: record.route.provider_id === target.route.provider_id && record.route.model_id === target.route.model_id,
|
|
1082
|
+
},
|
|
1083
|
+
criteria,
|
|
1084
|
+
findings: claim.claim.findings,
|
|
1085
|
+
decision,
|
|
1086
|
+
...(resolution.length === 0 ? {} : { evidence_resolution: resolution.slice(0, 200) }),
|
|
1087
|
+
repairs: { report_corrections: record.repairs.report_corrections },
|
|
1088
|
+
};
|
|
1089
|
+
const parsed = reviewPacketSchema.safeParse(candidate);
|
|
1090
|
+
if (!parsed.success) {
|
|
1091
|
+
return {
|
|
1092
|
+
attemptId: record.attemptId,
|
|
1093
|
+
review: undefined,
|
|
1094
|
+
verification: { decision: "invalid", problems: parsed.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`) },
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
const review = parsed.data;
|
|
1098
|
+
const blob = await recorder.putJson(review, REVIEW_MEDIA_TYPE);
|
|
1099
|
+
await recorder.record("review/recorded", { task_id: target.taskId, reviewer_attempt_id: record.attemptId, review_digest: packetDigest(review), decision: review.decision, blob }, { taskId: target.taskId, attemptId: record.attemptId, actor: { kind: "worker", role: "reviewer", attempt_id: record.attemptId } });
|
|
1100
|
+
const after = await target.workspace.changeSet(new AbortController().signal);
|
|
1101
|
+
if (after.artifactDigest !== pinned.artifactDigest) {
|
|
1102
|
+
return { attemptId: record.attemptId, review, verification: { decision: "invalid", problems: ["the artifact changed during review"] } };
|
|
1103
|
+
}
|
|
1104
|
+
// Judged against the criteria the reviewer was given: the implementation's, minus waived ones, plus reviewer-task extras.
|
|
1105
|
+
const verification = await verifyReview(review, record.packet, completion, indexes);
|
|
1106
|
+
return { attemptId: record.attemptId, review, verification: { decision: verification.decision, problems: verification.problems } };
|
|
1107
|
+
};
|
|
1108
|
+
const result = run().catch(async (error) => {
|
|
1109
|
+
await failUnfinished(record, error);
|
|
1110
|
+
return {
|
|
1111
|
+
attemptId: record.attemptId,
|
|
1112
|
+
review: undefined,
|
|
1113
|
+
verification: { decision: "invalid", problems: [`review failed inside the harness: ${error instanceof Error ? error.message : String(error)}`] },
|
|
1114
|
+
};
|
|
1115
|
+
});
|
|
1116
|
+
return { attemptId: record.attemptId, result, cancel: (reason) => controller.abort(new Error(reason)) };
|
|
1117
|
+
},
|
|
1118
|
+
async dispatchIntegrationReview(packet, dependencies, signal, options) {
|
|
1119
|
+
if (packet.role !== "reviewer" || packet.write_mode !== "read-only") {
|
|
1120
|
+
throw harnessError("review_blocked", "an integration review runs as a read-only reviewer packet");
|
|
1121
|
+
}
|
|
1122
|
+
const { record, controller } = await prepare(packet, signal, options, undefined);
|
|
1123
|
+
const { judge, check } = ownEvidenceJudging(record, "an integration review");
|
|
1124
|
+
const run = async () => {
|
|
1125
|
+
unregister.set(record.attemptId, deps.reports?.register(record.attemptId, check) ?? (() => undefined));
|
|
1126
|
+
const execution = await executeBounded(record, renderIntegrationReviewBrief(record.packet, dependencies), controller, "dispatch", REPORT_TOOL_NAMES.review);
|
|
1127
|
+
await closeAttempt(record);
|
|
1128
|
+
await finishAttempt(record, execution, controller.signal.aborted);
|
|
1129
|
+
const claim = readClaim(reviewerClaimSchema, execution.log, REPORT_TOOL_NAMES.review);
|
|
1130
|
+
if (!claim.ok)
|
|
1131
|
+
return { attemptId: record.attemptId, decision: "invalid", problems: claim.problems, findings: [] };
|
|
1132
|
+
const { judged } = await judge(execution.log, claim.claim.criteria);
|
|
1133
|
+
const problems = [];
|
|
1134
|
+
for (const criterion of record.packet.acceptance_criteria) {
|
|
1135
|
+
const verdict = judged.find((candidate) => candidate.criterion_id === criterion.id);
|
|
1136
|
+
if (verdict === undefined)
|
|
1137
|
+
problems.push(`${criterion.id} was not assessed`);
|
|
1138
|
+
else if (verdict.verdict !== "met")
|
|
1139
|
+
problems.push(`${criterion.id} is ${verdict.verdict}${verdict.note === undefined ? "" : `: ${verdict.note.slice(0, 300)}`}`);
|
|
1140
|
+
}
|
|
1141
|
+
const blocker = claim.claim.findings.some((finding) => finding.severity === "blocker");
|
|
1142
|
+
const decision = claim.claim.decision === "block" ? "block" : claim.claim.decision === "revise" || problems.length > 0 || blocker ? "revise" : "accept";
|
|
1143
|
+
const review = {
|
|
1144
|
+
kind: "integration-review",
|
|
1145
|
+
task_id: record.taskId,
|
|
1146
|
+
reviewer_attempt_id: record.attemptId,
|
|
1147
|
+
reviewer_route: { provider_id: record.route.provider_id, model_id: record.route.model_id },
|
|
1148
|
+
dependencies: dependencies.map((dependency) => ({ key: dependency.key, task_id: dependency.taskId, paths: dependency.paths })),
|
|
1149
|
+
criteria: judged,
|
|
1150
|
+
findings: claim.claim.findings,
|
|
1151
|
+
decision,
|
|
1152
|
+
};
|
|
1153
|
+
const blob = await recorder.putJson(review, REVIEW_MEDIA_TYPE);
|
|
1154
|
+
await recorder.record("review/recorded", { task_id: record.taskId, reviewer_attempt_id: record.attemptId, review_digest: digestOf(review), decision, blob }, { taskId: record.taskId, attemptId: record.attemptId, actor: { kind: "worker", role: "reviewer", attempt_id: record.attemptId } });
|
|
1155
|
+
return {
|
|
1156
|
+
attemptId: record.attemptId,
|
|
1157
|
+
decision,
|
|
1158
|
+
problems: [...problems, ...claim.claim.findings.map((finding) => `${finding.id} (${finding.severity}): ${finding.summary}`)],
|
|
1159
|
+
findings: claim.claim.findings,
|
|
1160
|
+
};
|
|
1161
|
+
};
|
|
1162
|
+
const result = run().catch(async (error) => {
|
|
1163
|
+
await failUnfinished(record, error);
|
|
1164
|
+
return { attemptId: record.attemptId, decision: "invalid", problems: [`integration review failed inside the harness: ${error instanceof Error ? error.message : String(error)}`], findings: [] };
|
|
1165
|
+
});
|
|
1166
|
+
return { attemptId: record.attemptId, result, cancel: (reason) => controller.abort(new Error(reason)) };
|
|
1167
|
+
},
|
|
1168
|
+
async dispatchArtifactReview(packet, artifact, signal, options) {
|
|
1169
|
+
if (packet.role !== "reviewer" || packet.write_mode !== "read-only") {
|
|
1170
|
+
throw harnessError("review_blocked", "an artifact review runs as a read-only reviewer packet");
|
|
1171
|
+
}
|
|
1172
|
+
const { record, controller } = await prepare(packet, signal, options, undefined);
|
|
1173
|
+
const { judge, check } = ownEvidenceJudging(record, "this review");
|
|
1174
|
+
const run = async () => {
|
|
1175
|
+
unregister.set(record.attemptId, deps.reports?.register(record.attemptId, check) ?? (() => undefined));
|
|
1176
|
+
const execution = await executeBounded(record, `${artifact.brief}\n\n${REVIEWER_REPORT_INSTRUCTIONS}`, controller, "dispatch", REPORT_TOOL_NAMES.review);
|
|
1177
|
+
await closeAttempt(record);
|
|
1178
|
+
const cancelled = controller.signal.aborted;
|
|
1179
|
+
await finishAttempt(record, execution, cancelled);
|
|
1180
|
+
const after = await artifact.repin(new AbortController().signal).catch(() => undefined);
|
|
1181
|
+
const artifactChanged = after !== artifact.digest;
|
|
1182
|
+
const claim = readClaim(reviewerClaimSchema, execution.log, REPORT_TOOL_NAMES.review);
|
|
1183
|
+
if (!claim.ok)
|
|
1184
|
+
return { attemptId: record.attemptId, route: record.route, report: undefined, problems: claim.problems, artifactChanged, cancelled };
|
|
1185
|
+
const { judged, problems } = await judge(execution.log, claim.claim.criteria);
|
|
1186
|
+
return {
|
|
1187
|
+
attemptId: record.attemptId,
|
|
1188
|
+
route: record.route,
|
|
1189
|
+
report: { ...claim.claim, criteria: judged },
|
|
1190
|
+
problems: problems.map((problem) => `${problem.criterionId} ${problem.ref}: ${problem.reason}`),
|
|
1191
|
+
artifactChanged,
|
|
1192
|
+
cancelled,
|
|
1193
|
+
};
|
|
1194
|
+
};
|
|
1195
|
+
const result = run().catch(async (error) => {
|
|
1196
|
+
await failUnfinished(record, error);
|
|
1197
|
+
return { attemptId: record.attemptId, route: record.route, report: undefined, problems: [`review failed inside the harness: ${error instanceof Error ? error.message : String(error)}`], artifactChanged: false, cancelled: controller.signal.aborted };
|
|
1198
|
+
});
|
|
1199
|
+
return { attemptId: record.attemptId, result, cancel: (reason) => controller.abort(new Error(reason)) };
|
|
1200
|
+
},
|
|
1201
|
+
running() {
|
|
1202
|
+
return [...handles.values()];
|
|
1203
|
+
},
|
|
1204
|
+
attempt(attemptId) {
|
|
1205
|
+
return records.get(attemptId);
|
|
1206
|
+
},
|
|
1207
|
+
async verify(attemptId, options) {
|
|
1208
|
+
const record = records.get(attemptId);
|
|
1209
|
+
if (record?.completion === undefined || record.changeSet === undefined) {
|
|
1210
|
+
return { decision: "reject", problems: [`attempt ${attemptId} has no completion`], unevidenced: [] };
|
|
1211
|
+
}
|
|
1212
|
+
return verifyCompletion(record.packet, record.completion, indexFor(record, record.changeSet, record.workspace.root), platform, options);
|
|
1213
|
+
},
|
|
1214
|
+
async integrate(attemptId, expectedArtifact, signal) {
|
|
1215
|
+
const record = records.get(attemptId);
|
|
1216
|
+
if (record === undefined)
|
|
1217
|
+
throw harnessError("internal", `unknown attempt ${attemptId}`);
|
|
1218
|
+
await deps.isolation.integrate(record.workspace, expectedArtifact, signal);
|
|
1219
|
+
await recorder.record("task/integrated", {
|
|
1220
|
+
task_id: record.taskId,
|
|
1221
|
+
attempt_id: record.attemptId,
|
|
1222
|
+
artifact_digest: expectedArtifact,
|
|
1223
|
+
paths: (record.changeSet?.changes ?? []).flatMap((change) => {
|
|
1224
|
+
const normalized = normalizeWorkspacePath(change.path);
|
|
1225
|
+
return normalized === undefined ? [] : [normalized];
|
|
1226
|
+
}),
|
|
1227
|
+
}, { taskId: record.taskId, attemptId: record.attemptId, actor: { kind: "orchestrator", role: "orchestrator" } });
|
|
1228
|
+
},
|
|
1229
|
+
async revert(attemptId, signal) {
|
|
1230
|
+
const record = records.get(attemptId);
|
|
1231
|
+
if (record === undefined || record.workspace.mode !== "scoped-dir")
|
|
1232
|
+
return [];
|
|
1233
|
+
return record.workspace.revert(signal);
|
|
1234
|
+
},
|
|
1235
|
+
async dispose(attemptId) {
|
|
1236
|
+
const record = records.get(attemptId);
|
|
1237
|
+
if (record !== undefined)
|
|
1238
|
+
await record.workspace.dispose();
|
|
1239
|
+
},
|
|
1240
|
+
steer(attemptId, text) {
|
|
1241
|
+
const control = liveControl(attemptId);
|
|
1242
|
+
if (control === undefined || text.trim() === "")
|
|
1243
|
+
return false;
|
|
1244
|
+
const driver = drivers.get(attemptId);
|
|
1245
|
+
if (driver === undefined)
|
|
1246
|
+
control.steers.push(text);
|
|
1247
|
+
else
|
|
1248
|
+
driver.steer(text);
|
|
1249
|
+
return true;
|
|
1250
|
+
},
|
|
1251
|
+
pause(attemptId) {
|
|
1252
|
+
const control = liveControl(attemptId);
|
|
1253
|
+
if (control === undefined)
|
|
1254
|
+
return false;
|
|
1255
|
+
control.paused = true;
|
|
1256
|
+
pausable(drivers.get(attemptId))?.pause();
|
|
1257
|
+
control.wall?.pause();
|
|
1258
|
+
return true;
|
|
1259
|
+
},
|
|
1260
|
+
resume(attemptId) {
|
|
1261
|
+
const control = liveControl(attemptId);
|
|
1262
|
+
if (control === undefined)
|
|
1263
|
+
return false;
|
|
1264
|
+
control.paused = false;
|
|
1265
|
+
pausable(drivers.get(attemptId))?.resume();
|
|
1266
|
+
control.wall?.resume();
|
|
1267
|
+
return true;
|
|
1268
|
+
},
|
|
1269
|
+
cancel(attemptId, reason) {
|
|
1270
|
+
const controller = liveControl(attemptId) === undefined ? undefined : controllers.get(attemptId);
|
|
1271
|
+
if (controller === undefined)
|
|
1272
|
+
return false;
|
|
1273
|
+
// A paused driver wakes on abort; the attempt then ends through the normal cancellation path.
|
|
1274
|
+
controller.abort(new Error(reason));
|
|
1275
|
+
return true;
|
|
1276
|
+
},
|
|
1277
|
+
live(attemptId) {
|
|
1278
|
+
const control = liveControl(attemptId);
|
|
1279
|
+
return control === undefined ? undefined : { paused: control.paused };
|
|
1280
|
+
},
|
|
1281
|
+
};
|
|
1282
|
+
return manager;
|
|
1283
|
+
}
|
|
1284
|
+
/** Enforces the contract's outcome rules on a runner result (passed means exited 0; not-run has a reason and no exit code). */
|
|
1285
|
+
function normalizeVerification(result) {
|
|
1286
|
+
if (result.termination === undefined || result.status === "not-run") {
|
|
1287
|
+
return { status: "not-run", exitCode: null, output: result.output, durationMs: result.durationMs, reason: result.reason ?? "the harness did not start the command", ...(result.commandClass === undefined ? {} : { commandClass: result.commandClass }) };
|
|
1288
|
+
}
|
|
1289
|
+
const passed = result.termination === "exited" && result.exitCode === 0;
|
|
1290
|
+
return { status: passed ? "passed" : "failed", termination: result.termination, exitCode: result.exitCode, output: result.output, durationMs: result.durationMs, ...(result.commandClass === undefined ? {} : { commandClass: result.commandClass }) };
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* P0-A verification cost: dependency-install commands. Within one task's attempt chain an install
|
|
1294
|
+
* that passed is reused (not re-run) while the dependency manifests are unchanged and the
|
|
1295
|
+
* installed tree is still there (same attempt, or the same in-place scoped-dir workspace).
|
|
1296
|
+
*/
|
|
1297
|
+
const INSTALL_COMMAND = /^(?:(?:npm|pnpm|yarn|bun)(?:\s+(?:install|i|ci|add)\b.*)?|(?:pip3?|python3?\s+-m\s+pip)\s+install\b.*|(?:uv|poetry|pipenv)\s+(?:sync|install|pip\s+install)\b.*|bundle\s+install\b.*|composer\s+install\b.*|go\s+mod\s+download\b.*|cargo\s+fetch\b.*|dotnet\s+restore\b.*)$/i;
|
|
1298
|
+
const DEPENDENCY_MANIFESTS = new Set([
|
|
1299
|
+
"package.json",
|
|
1300
|
+
"package-lock.json",
|
|
1301
|
+
"npm-shrinkwrap.json",
|
|
1302
|
+
"pnpm-lock.yaml",
|
|
1303
|
+
"pnpm-workspace.yaml",
|
|
1304
|
+
"yarn.lock",
|
|
1305
|
+
"bun.lockb",
|
|
1306
|
+
"bun.lock",
|
|
1307
|
+
"requirements.txt",
|
|
1308
|
+
"requirements-dev.txt",
|
|
1309
|
+
"pyproject.toml",
|
|
1310
|
+
"uv.lock",
|
|
1311
|
+
"poetry.lock",
|
|
1312
|
+
"Pipfile",
|
|
1313
|
+
"Pipfile.lock",
|
|
1314
|
+
"Gemfile",
|
|
1315
|
+
"Gemfile.lock",
|
|
1316
|
+
"composer.json",
|
|
1317
|
+
"composer.lock",
|
|
1318
|
+
"go.mod",
|
|
1319
|
+
"go.sum",
|
|
1320
|
+
"Cargo.toml",
|
|
1321
|
+
"Cargo.lock",
|
|
1322
|
+
]);
|
|
1323
|
+
export function isInstallCommand(argv) {
|
|
1324
|
+
const [first, second] = argv;
|
|
1325
|
+
if (first === undefined)
|
|
1326
|
+
return false;
|
|
1327
|
+
const tool = path.basename(first).replace(/\.(?:cmd|exe|bat)$/i, "").toLowerCase();
|
|
1328
|
+
if (["npm", "pnpm", "yarn", "bun"].includes(tool) && second === undefined)
|
|
1329
|
+
return tool !== "npm" && tool !== "bun";
|
|
1330
|
+
return INSTALL_COMMAND.test([tool, ...argv.slice(1)].join(" "));
|
|
1331
|
+
}
|
|
1332
|
+
function manifestFingerprint(changeSet) {
|
|
1333
|
+
return changeSet.changes
|
|
1334
|
+
.filter((change) => DEPENDENCY_MANIFESTS.has(change.path.split("/").at(-1) ?? ""))
|
|
1335
|
+
.map((change) => `${change.path}:${change.after ?? "-"}`)
|
|
1336
|
+
.sort()
|
|
1337
|
+
.join("|");
|
|
1338
|
+
}
|
|
1339
|
+
class StaleInFlight extends Error {
|
|
1340
|
+
paths;
|
|
1341
|
+
constructor(paths) {
|
|
1342
|
+
super(`sources changed: ${paths.join(", ")}`);
|
|
1343
|
+
this.name = "StaleInFlight";
|
|
1344
|
+
this.paths = paths;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
//# sourceMappingURL=worker-manager.js.map
|