@gajae-code/coding-agent 0.10.2 → 0.11.1
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 +58 -2
- package/dist/types/append-only-mode.d.ts +1 -1
- package/dist/types/async/job-manager.d.ts +46 -7
- package/dist/types/cli/args.d.ts +4 -5
- package/dist/types/cli/daemon-cli.d.ts +12 -1
- package/dist/types/cli/notify-cli.d.ts +21 -1
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +39 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/commands/notify.d.ts +28 -1
- package/dist/types/commands/sdk.d.ts +33 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
- package/dist/types/config/model-profile-activation.d.ts +35 -15
- package/dist/types/config/model-profiles.d.ts +11 -5
- package/dist/types/config/model-registry.d.ts +3 -3
- package/dist/types/config/model-resolver.d.ts +39 -6
- package/dist/types/config/model-selector-value.d.ts +17 -0
- package/dist/types/config/models-config-schema.d.ts +10 -6
- package/dist/types/config/settings-schema.d.ts +133 -6
- package/dist/types/config/settings.d.ts +63 -35
- package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
- package/dist/types/coordinator-mcp/server.d.ts +6 -49
- package/dist/types/daemon/builtin.d.ts +6 -5
- package/dist/types/daemon/control-types.d.ts +1 -1
- package/dist/types/discovery/mcp-json.d.ts +12 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
- package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
- package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
- package/dist/types/extensibility/extensions/loader.d.ts +10 -1
- package/dist/types/extensibility/extensions/runner.d.ts +3 -3
- package/dist/types/extensibility/extensions/types.d.ts +141 -16
- package/dist/types/extensibility/hooks/types.d.ts +1 -1
- package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
- package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
- package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
- package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +11 -0
- package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
- package/dist/types/harness-control-plane/operate.d.ts +5 -5
- package/dist/types/harness-control-plane/owner.d.ts +18 -4
- package/dist/types/harness-control-plane/receipts.d.ts +0 -1
- package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
- package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
- package/dist/types/harness-control-plane/types.d.ts +3 -4
- package/dist/types/lsp/index.d.ts +1 -1
- package/dist/types/main.d.ts +32 -38
- package/dist/types/modes/acp/acp-agent.d.ts +224 -53
- package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
- package/dist/types/modes/acp/acp-mode.d.ts +6 -15
- package/dist/types/modes/acp/permission-mode.d.ts +4 -0
- package/dist/types/modes/acp/startup-options.d.ts +6 -0
- package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
- package/dist/types/modes/components/model-selector.d.ts +1 -0
- package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -4
- package/dist/types/modes/components/welcome.d.ts +1 -1
- package/dist/types/modes/controllers/command-controller.d.ts +2 -2
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
- package/dist/types/modes/index.d.ts +0 -4
- package/dist/types/modes/interactive-mode.d.ts +5 -2
- package/dist/types/modes/runtime-init.d.ts +2 -2
- package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
- package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
- package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
- package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +170 -30
- package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
- package/dist/types/modes/types.d.ts +7 -2
- package/dist/types/runtime-mcp/client.d.ts +2 -0
- package/dist/types/runtime-mcp/config.d.ts +5 -1
- package/dist/types/runtime-mcp/manager.d.ts +8 -1
- package/dist/types/runtime-mcp/types.d.ts +4 -0
- package/dist/types/sdk/acp/adapter.d.ts +67 -0
- package/dist/types/sdk/acp/index.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +53 -0
- package/dist/types/sdk/broker/discovery.d.ts +30 -0
- package/dist/types/sdk/broker/ensure.d.ts +42 -0
- package/dist/types/sdk/broker/identity.d.ts +3 -0
- package/dist/types/sdk/broker/index.d.ts +8 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
- package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
- package/dist/types/sdk/broker/runtime.d.ts +33 -0
- package/dist/types/sdk/broker/session-index.d.ts +57 -0
- package/dist/types/sdk/broker/state-version.d.ts +8 -0
- package/dist/types/sdk/broker/transport.d.ts +9 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
- package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
- package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
- package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
- package/dist/types/sdk/bus/config.d.ts +274 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +50 -0
- package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
- package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
- package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
- package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
- package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
- package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
- package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
- package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
- package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
- package/dist/types/sdk/bus/session-control.d.ts +83 -0
- package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
- package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
- package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
- package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
- package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
- package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +78 -17
- package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
- package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
- package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
- package/dist/types/sdk/cli/index.d.ts +1 -0
- package/dist/types/sdk/cli/session-cli.d.ts +19 -0
- package/dist/types/sdk/client/client.d.ts +1 -0
- package/dist/types/sdk/client/discovery.d.ts +27 -0
- package/dist/types/sdk/client/index.d.ts +2 -0
- package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
- package/dist/types/sdk/host/control/index.d.ts +2 -0
- package/dist/types/sdk/host/control/operations.d.ts +65 -0
- package/dist/types/sdk/host/events.d.ts +35 -0
- package/dist/types/sdk/host/host.d.ts +35 -0
- package/dist/types/sdk/host/index.d.ts +4 -0
- package/dist/types/sdk/host/query/cursor.d.ts +62 -0
- package/dist/types/sdk/host/query/handlers.d.ts +70 -0
- package/dist/types/sdk/host/query/index.d.ts +3 -0
- package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
- package/dist/types/sdk/host/types.d.ts +32 -0
- package/dist/types/sdk/index.d.ts +6 -0
- package/dist/types/sdk/lifecycle-session.d.ts +14 -0
- package/dist/types/sdk/mcp/index.d.ts +1 -0
- package/dist/types/sdk/mcp/server.d.ts +37 -0
- package/dist/types/sdk/models.d.ts +44 -0
- package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
- package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
- package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
- package/dist/types/sdk/startup-capability.d.ts +50 -0
- package/dist/types/session/agent-session.d.ts +114 -21
- package/dist/types/session/default-model-selection.d.ts +25 -0
- package/dist/types/session/fallback-chain-controller.d.ts +52 -0
- package/dist/types/session/session-manager.d.ts +58 -1
- package/dist/types/setup/credential-auto-import.d.ts +36 -6
- package/dist/types/tools/ask-answer-registry.d.ts +1 -1
- package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
- package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
- package/dist/types/tools/browser/launch.d.ts +22 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
- package/dist/types/tools/browser/profile-posture.d.ts +37 -0
- package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
- package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
- package/dist/types/tools/browser/registry.d.ts +19 -0
- package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
- package/dist/types/tools/index.d.ts +8 -8
- package/dist/types/tools/subagent-render.d.ts +1 -0
- package/dist/types/tools/subagent.d.ts +6 -1
- package/package.json +34 -13
- package/scripts/build-sdk-package-smoke.ts +99 -0
- package/scripts/capture-notifications-settings-showcase.ts +435 -0
- package/scripts/compile-args.ts +4 -2
- package/scripts/g005-daemon-smoke.ts +4 -5
- package/scripts/g011-daemon-path-smoke.ts +5 -5
- package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
- package/scripts/generate-sdk-operation-inventory.ts +867 -0
- package/scripts/generate-telegram-baseline-manifest.ts +128 -0
- package/scripts/manifest-schema.ts +124 -0
- package/scripts/run-test-manifest.ts +153 -0
- package/scripts/run-threat-model-check.ts +157 -0
- package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
- package/scripts/verify-gjc-sdk-rename.ts +90 -0
- package/src/append-only-mode.ts +1 -1
- package/src/async/job-manager.ts +406 -63
- package/src/cli/args.ts +43 -12
- package/src/cli/auth-gateway-cli.ts +2 -2
- package/src/cli/config-cli.ts +2 -1
- package/src/cli/daemon-cli.ts +63 -14
- package/src/cli/list-models.ts +1 -1
- package/src/cli/notify-cli.ts +288 -286
- package/src/cli.ts +21 -2
- package/src/commands/daemon.ts +50 -6
- package/src/commands/harness.ts +93 -36
- package/src/commands/launch.ts +5 -2
- package/src/commands/mcp-serve.ts +19 -12
- package/src/commands/notify.ts +36 -3
- package/src/commands/sdk.ts +426 -0
- package/src/commit/agentic/agent.ts +1 -0
- package/src/config/atomic-yaml-patch.ts +423 -0
- package/src/config/model-profile-activation.ts +240 -89
- package/src/config/model-profiles.ts +18 -15
- package/src/config/model-registry.ts +51 -26
- package/src/config/model-resolver.ts +138 -51
- package/src/config/model-selector-value.ts +50 -0
- package/src/config/models-config-schema.ts +14 -21
- package/src/config/settings-schema.ts +128 -10
- package/src/config/settings.ts +1120 -158
- package/src/coordinator-mcp/model-preset.ts +74 -20
- package/src/coordinator-mcp/server.ts +1597 -3052
- package/src/daemon/builtin.ts +8 -5
- package/src/daemon/control-types.ts +1 -1
- package/src/defaults/gjc/skills/team/SKILL.md +4 -4
- package/src/discovery/mcp-json.ts +327 -20
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/compact-handler.ts +3 -3
- package/src/extensibility/extensions/get-commands-handler.ts +2 -2
- package/src/extensibility/extensions/loader.ts +69 -5
- package/src/extensibility/extensions/runner.ts +112 -4
- package/src/extensibility/extensions/types.ts +176 -17
- package/src/extensibility/hooks/types.ts +1 -1
- package/src/gjc-runtime/launch-tmux.ts +170 -86
- package/src/gjc-runtime/psmux-detect.ts +82 -4
- package/src/gjc-runtime/session-state-sidecar.ts +41 -31
- package/src/gjc-runtime/team-runtime.ts +54 -35
- package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
- package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
- package/src/gjc-runtime/tmux-sessions.ts +19 -13
- package/src/gjc-runtime/ultragoal-guard.ts +108 -14
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +102 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +227 -11
- package/src/gjc-runtime/windows-powershell-command.ts +58 -0
- package/src/harness-control-plane/operate.ts +9 -9
- package/src/harness-control-plane/owner.ts +283 -39
- package/src/harness-control-plane/receipts.ts +0 -1
- package/src/harness-control-plane/sdk-transport.ts +395 -0
- package/src/harness-control-plane/session-transport.ts +94 -0
- package/src/harness-control-plane/types.ts +1 -1
- package/src/internal-urls/docs-index.generated.ts +34 -35
- package/src/lsp/client.ts +42 -6
- package/src/lsp/index.ts +2 -2
- package/src/main.ts +299 -204
- package/src/modes/DESIGN.md +258 -0
- package/src/modes/acp/acp-agent.ts +1228 -2612
- package/src/modes/acp/acp-client-bridge.ts +2 -20
- package/src/modes/acp/acp-event-mapper.ts +18 -2
- package/src/modes/acp/acp-mode.ts +8 -36
- package/src/modes/acp/permission-mode.ts +25 -0
- package/src/modes/acp/startup-options.ts +6 -0
- package/src/modes/components/agent-dashboard.ts +37 -17
- package/src/modes/components/model-selector.ts +93 -35
- package/src/modes/components/notifications-settings-editor.ts +1379 -0
- package/src/modes/components/settings-selector.ts +60 -11
- package/src/modes/components/welcome.ts +4 -4
- package/src/modes/controllers/command-controller.ts +10 -17
- package/src/modes/controllers/event-controller.ts +11 -16
- package/src/modes/controllers/extension-ui-controller.ts +396 -28
- package/src/modes/controllers/selector-controller.ts +674 -36
- package/src/modes/index.ts +0 -22
- package/src/modes/interactive-mode.ts +87 -36
- package/src/modes/runtime-init.ts +298 -6
- package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
- package/src/modes/shared/agent-wire/event-contract.ts +7 -8
- package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
- package/src/modes/shared/agent-wire/event-observation.ts +16 -7
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1258 -87
- package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
- package/src/modes/types.ts +7 -2
- package/src/runtime-mcp/client.ts +94 -19
- package/src/runtime-mcp/config.ts +27 -15
- package/src/runtime-mcp/manager.ts +343 -105
- package/src/runtime-mcp/oauth-flow.ts +42 -12
- package/src/runtime-mcp/transports/http.ts +49 -19
- package/src/runtime-mcp/transports/stdio.ts +47 -28
- package/src/runtime-mcp/types.ts +10 -0
- package/src/sdk/acp/adapter.ts +418 -0
- package/src/sdk/acp/index.ts +2 -0
- package/src/sdk/broker/broker.ts +642 -0
- package/src/sdk/broker/discovery.ts +113 -0
- package/src/sdk/broker/ensure.ts +307 -0
- package/src/sdk/broker/identity.ts +42 -0
- package/src/sdk/broker/index.ts +8 -0
- package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
- package/src/sdk/broker/internal-source.bunfig.toml +1 -0
- package/src/sdk/broker/lifecycle-ledger.ts +286 -0
- package/src/sdk/broker/lifecycle.ts +2157 -0
- package/src/sdk/broker/process-incarnation.ts +159 -0
- package/src/sdk/broker/runtime.ts +164 -0
- package/src/sdk/broker/session-index.ts +318 -0
- package/src/sdk/broker/state-version.ts +23 -0
- package/src/sdk/broker/transport.ts +125 -0
- package/src/sdk/bus/chat-command-policy.ts +107 -0
- package/src/sdk/bus/chat-daemon-cli.ts +214 -0
- package/src/sdk/bus/chat-daemon-control.ts +713 -0
- package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
- package/src/sdk/bus/chat-effect-journal.ts +355 -0
- package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
- package/src/sdk/bus/config.ts +433 -0
- package/src/sdk/bus/conversation-store.ts +391 -0
- package/src/sdk/bus/discord-conversation.ts +85 -0
- package/src/sdk/bus/discord-daemon.ts +2292 -0
- package/src/sdk/bus/discord-live-provider.ts +521 -0
- package/src/sdk/bus/discord-provider.ts +56 -0
- package/src/{notifications → sdk/bus}/html-format.ts +2 -2
- package/src/sdk/bus/index.ts +3979 -0
- package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
- package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
- package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
- package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
- package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
- package/src/sdk/bus/natives-augment.d.ts +38 -0
- package/src/sdk/bus/notification-orchestration.ts +535 -0
- package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
- package/src/sdk/bus/session-control.ts +333 -0
- package/src/sdk/bus/slack-conversation.ts +74 -0
- package/src/sdk/bus/slack-daemon.ts +2144 -0
- package/src/sdk/bus/slack-live-provider.ts +380 -0
- package/src/sdk/bus/slack-provider.ts +76 -0
- package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
- package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
- package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
- package/src/{notifications → sdk/bus}/telegram-daemon.ts +603 -63
- package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
- package/src/sdk/bus/telegram-setup.ts +663 -0
- package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
- package/src/sdk/cli/index.ts +1 -0
- package/src/sdk/cli/session-cli.ts +275 -0
- package/src/sdk/client/client.ts +1 -0
- package/src/sdk/client/discovery.ts +108 -0
- package/src/sdk/client/index.ts +2 -0
- package/src/sdk/host/control/dispatch.ts +367 -0
- package/src/sdk/host/control/index.ts +10 -0
- package/src/sdk/host/control/operations.ts +63 -0
- package/src/sdk/host/events.ts +91 -0
- package/src/sdk/host/host.ts +296 -0
- package/src/sdk/host/index.ts +4 -0
- package/src/sdk/host/query/cursor.ts +189 -0
- package/src/sdk/host/query/handlers.ts +533 -0
- package/src/sdk/host/query/index.ts +3 -0
- package/src/sdk/host/query/revision-store.ts +1126 -0
- package/src/sdk/host/reverse-leases.ts +325 -0
- package/src/sdk/host/types.ts +29 -0
- package/src/sdk/index.ts +13 -0
- package/src/sdk/lifecycle-session.ts +39 -0
- package/src/sdk/mcp/index.ts +1 -0
- package/src/sdk/mcp/server.ts +332 -0
- package/src/sdk/models.ts +168 -0
- package/src/sdk/protocol/adapter-validation.ts +48 -0
- package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
- package/src/sdk/protocol/operation-registry.ts +312 -0
- package/src/{sdk.ts → sdk/session.ts} +339 -212
- package/src/sdk/startup-capability.ts +189 -0
- package/src/session/agent-session.ts +2650 -944
- package/src/session/default-model-selection.ts +93 -0
- package/src/session/fallback-chain-controller.ts +136 -0
- package/src/session/session-manager.ts +438 -11
- package/src/session/session-storage.ts +8 -1
- package/src/setup/credential-auto-import.ts +290 -35
- package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
- package/src/slash-commands/builtin-registry.ts +2 -1
- package/src/task/executor.ts +62 -13
- package/src/task/index.ts +26 -16
- package/src/tools/ask-answer-registry.ts +1 -1
- package/src/tools/ask.ts +13 -8
- package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
- package/src/tools/browser/benchmark/detector-report.ts +157 -0
- package/src/tools/browser/benchmark/run-suite.ts +39 -0
- package/src/tools/browser/launch.ts +124 -19
- package/src/tools/browser/profile-discovery.ts +63 -0
- package/src/tools/browser/profile-posture.ts +59 -0
- package/src/tools/browser/profile-reuse.ts +102 -0
- package/src/tools/browser/profile-warmup.ts +109 -0
- package/src/tools/browser/registry.ts +87 -11
- package/src/tools/browser/tab-protocol.ts +1 -0
- package/src/tools/browser/tab-supervisor.ts +1 -0
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/browser.ts +6 -0
- package/src/tools/index.ts +8 -8
- package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
- package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
- package/src/tools/subagent-render.ts +19 -8
- package/src/tools/subagent.ts +84 -32
- package/src/tools/telegram-send.ts +2 -2
- package/vendor/insane-search/MANIFEST.json +2 -1
- package/vendor/insane-search/engine/bias_check.py +4 -1
- package/vendor/insane-search/engine/phase0.py +26 -1
- package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
- package/dist/types/modes/bridge/auth.d.ts +0 -12
- package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
- package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
- package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
- package/dist/types/modes/bridge/event-stream.d.ts +0 -8
- package/dist/types/modes/rpc/host-tools.d.ts +0 -1
- package/dist/types/modes/rpc/host-uris.d.ts +0 -1
- package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
- package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
- package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
- package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
- package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
- package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
- package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
- package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
- package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
- package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
- package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
- package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
- package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
- package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
- package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
- package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
- package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
- package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
- package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
- package/dist/types/notifications/config.d.ts +0 -132
- package/src/harness-control-plane/rpc-adapter.ts +0 -290
- package/src/modes/bridge/auth.ts +0 -41
- package/src/modes/bridge/bridge-client-bridge.ts +0 -47
- package/src/modes/bridge/bridge-mode.ts +0 -675
- package/src/modes/bridge/bridge-ui-context.ts +0 -200
- package/src/modes/bridge/event-stream.ts +0 -70
- package/src/modes/rpc/host-tools.ts +0 -1
- package/src/modes/rpc/host-uris.ts +0 -1
- package/src/modes/rpc/rpc-client.ts +0 -1166
- package/src/modes/rpc/rpc-mode.ts +0 -1029
- package/src/modes/rpc/rpc-socket-security.ts +0 -115
- package/src/modes/rpc/rpc-types.ts +0 -637
- package/src/modes/shared/agent-wire/command-contract.ts +0 -18
- package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
- package/src/modes/shared/agent-wire/command-validation.ts +0 -181
- package/src/modes/shared/agent-wire/handshake.ts +0 -157
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
- package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
- package/src/modes/shared/agent-wire/protocol.ts +0 -46
- package/src/modes/shared/agent-wire/responses.ts +0 -17
- package/src/modes/shared/agent-wire/scopes.ts +0 -94
- package/src/modes/shared/agent-wire/session-registry.ts +0 -109
- package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
- package/src/modes/shared/agent-wire/ui-result.ts +0 -48
- package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
- package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
- package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
- package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
- package/src/notifications/config.ts +0 -219
- package/src/notifications/index.ts +0 -1835
- package/src/notifications/telegram-daemon-cli.ts +0 -243
- package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
- /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
- /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
- /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
- /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
- /package/src/{notifications → sdk/bus}/engine.ts +0 -0
- /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
- /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
- /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
- /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
- /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
- /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
- /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
- /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
- /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
|
@@ -9,6 +9,7 @@ import { DEFAULT_ULTRAGOAL_OBJECTIVE } from "./goal-mode-request";
|
|
|
9
9
|
import {
|
|
10
10
|
computeUltragoalPlanGeneration,
|
|
11
11
|
findFreshBatchCloseReceipt,
|
|
12
|
+
findLedgerReceiptEvent,
|
|
12
13
|
requiredUltragoalGoals,
|
|
13
14
|
validateDeferredMemberReceiptFresh,
|
|
14
15
|
validateReceiptFreshBase,
|
|
@@ -572,16 +573,32 @@ async function writePlan(cwd: string, plan: UltragoalPlan, sessionId?: string |
|
|
|
572
573
|
|
|
573
574
|
function chooseReceiptKind(
|
|
574
575
|
plan: UltragoalPlan,
|
|
576
|
+
ledger: readonly UltragoalLedgerEvent[],
|
|
575
577
|
goal: UltragoalGoal,
|
|
576
578
|
status: UltragoalGoalStatus,
|
|
577
579
|
): UltragoalReceiptKind {
|
|
578
580
|
if (plan.gjcGoalMode === "per-story") return "per-goal";
|
|
579
581
|
if (status !== "complete") return "per-goal";
|
|
582
|
+
// A non-final validation-batch member must always carry a per-goal
|
|
583
|
+
// deferred receipt; only the batch's final goal may close the batch and
|
|
584
|
+
// (in aggregate mode) carry the final-aggregate receipt. Without this, a
|
|
585
|
+
// context-stale re-verification replay of a member could mint an invalid
|
|
586
|
+
// final-aggregate receipt with validationBatch.role "deferred-member".
|
|
587
|
+
if (goal.validationBatch && goal.validationBatch.finalGoalId !== goal.id) return "per-goal";
|
|
580
588
|
const requiredGoals = requiredUltragoalGoals(plan);
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
)
|
|
584
|
-
|
|
589
|
+
// Only a still-fresh final-aggregate receipt on another goal defers this
|
|
590
|
+
// checkpoint to per-goal. A stale one (e.g. staled by `steer add_subgoal`
|
|
591
|
+
// appending goals after a terminal run) must not suppress re-minting,
|
|
592
|
+
// otherwise the run can never regain a verifiable final-aggregate receipt:
|
|
593
|
+
// the completion guard demands a fresh final-aggregate receipt while this
|
|
594
|
+
// gate would keep answering per-goal forever.
|
|
595
|
+
const existingFreshFinalAggregateGoal = requiredGoals.find(item => {
|
|
596
|
+
if (item.id === goal.id) return false;
|
|
597
|
+
const receipt = item.completionVerification;
|
|
598
|
+
if (receipt?.receiptKind !== "final-aggregate") return false;
|
|
599
|
+
return validateReceiptFreshBase({ plan, ledger, goal: item, receipt, receiptKind: "final-aggregate" }) === null;
|
|
600
|
+
});
|
|
601
|
+
if (existingFreshFinalAggregateGoal) return "per-goal";
|
|
585
602
|
const unfinishedRequiredGoals = requiredGoals.filter(
|
|
586
603
|
item => item.id !== goal.id && !TERMINAL_OR_SKIPPED_STATUSES.has(item.status),
|
|
587
604
|
);
|
|
@@ -3451,7 +3468,12 @@ function canonicalChangeSetRows(value: unknown, fieldName: string): UltragoalCha
|
|
|
3451
3468
|
if ("goalId" in record) throw new Error(`${fieldName}[${index}] must not contain goalId attribution`);
|
|
3452
3469
|
const status = nonEmptyString(record.status);
|
|
3453
3470
|
if (!status) throw new Error(`${fieldName}[${index}].status is required`);
|
|
3454
|
-
|
|
3471
|
+
const oldPath = nonEmptyString(record.oldPath);
|
|
3472
|
+
return {
|
|
3473
|
+
path: normalizeRepoPath(pathValue),
|
|
3474
|
+
status: status as UltragoalChangeStatus,
|
|
3475
|
+
...(oldPath ? { oldPath: normalizeRepoPath(oldPath) } : {}),
|
|
3476
|
+
};
|
|
3455
3477
|
});
|
|
3456
3478
|
}
|
|
3457
3479
|
|
|
@@ -3711,6 +3733,140 @@ function validateBatchCloseQualityGate(
|
|
|
3711
3733
|
throw new Error("validationBatchClose.unionChangeSet.unionHash does not match declared union");
|
|
3712
3734
|
requireNonEmptyString(close.coverageEvidence, "validationBatchClose.coverageEvidence");
|
|
3713
3735
|
}
|
|
3736
|
+
|
|
3737
|
+
function hydrateReviewedBatchReplacementClose(input: {
|
|
3738
|
+
gate: JsonObject;
|
|
3739
|
+
plan: UltragoalPlan;
|
|
3740
|
+
goal: UltragoalGoal;
|
|
3741
|
+
metadata: UltragoalValidationBatchMetadata;
|
|
3742
|
+
ledger: readonly UltragoalLedgerEvent[];
|
|
3743
|
+
changeSet?: UltragoalChangeSet;
|
|
3744
|
+
}): JsonObject {
|
|
3745
|
+
const requested = qualityGateObject(input.gate.validationBatchClose);
|
|
3746
|
+
if (requested?.kind !== "review-blocker-replacement-close") return input.gate;
|
|
3747
|
+
const expectedKeys = new Set(["schemaVersion", "kind", "replacementGoalId", "coverageEvidence"]);
|
|
3748
|
+
if (Object.keys(requested).some(key => !expectedKeys.has(key)))
|
|
3749
|
+
throw new Error("review-blocker replacement close contains unsupported fields");
|
|
3750
|
+
const replacementGoalId = nonEmptyString(requested.replacementGoalId);
|
|
3751
|
+
const coverageEvidence = nonEmptyString(requested.coverageEvidence);
|
|
3752
|
+
if (requested.schemaVersion !== 1 || !replacementGoalId || !coverageEvidence)
|
|
3753
|
+
throw new Error("review-blocker replacement close is malformed");
|
|
3754
|
+
if (input.goal.status !== "active" || input.metadata.finalGoalId !== input.goal.id)
|
|
3755
|
+
throw new Error("review-blocker replacement close requires the active durable validation-batch final goal");
|
|
3756
|
+
if (!input.changeSet) throw new Error("review-blocker replacement close requires a current cumulative change set");
|
|
3757
|
+
|
|
3758
|
+
const replacements = input.plan.goals.filter(
|
|
3759
|
+
goal => goal.steering?.kind === "review_blocker" && goal.steering.blockedGoalId === input.goal.id,
|
|
3760
|
+
);
|
|
3761
|
+
if (replacements.length !== 1 || replacements[0]?.id !== replacementGoalId)
|
|
3762
|
+
throw new Error("review-blocker replacement close requires exactly the declared replacement");
|
|
3763
|
+
const replacement = replacements[0]!;
|
|
3764
|
+
const replacementReceipt = replacement.completionVerification;
|
|
3765
|
+
if (replacement.status !== "complete" || replacementReceipt?.receiptKind !== "per-goal")
|
|
3766
|
+
throw new Error("review-blocker replacement close requires a completed per-goal replacement receipt");
|
|
3767
|
+
const replacementDiagnostic = validateReceiptFreshBase({
|
|
3768
|
+
plan: input.plan,
|
|
3769
|
+
ledger: input.ledger,
|
|
3770
|
+
goal: replacement,
|
|
3771
|
+
receipt: replacementReceipt,
|
|
3772
|
+
receiptKind: "per-goal",
|
|
3773
|
+
});
|
|
3774
|
+
if (replacementDiagnostic) throw new Error(`review-blocker replacement close ${replacementDiagnostic.message}`);
|
|
3775
|
+
const replacementCheckpointIndex = input.ledger.findIndex(
|
|
3776
|
+
event => event.eventId === replacementReceipt.checkpointLedgerEventId,
|
|
3777
|
+
);
|
|
3778
|
+
const reviewRecordedIndex = input.ledger.findIndex(
|
|
3779
|
+
event =>
|
|
3780
|
+
event.event === "review_blockers_recorded" &&
|
|
3781
|
+
event.goalId === input.goal.id &&
|
|
3782
|
+
event.blockerGoalId === replacement.id,
|
|
3783
|
+
);
|
|
3784
|
+
const reactivatedIndex = input.ledger.findIndex(
|
|
3785
|
+
(event, index) =>
|
|
3786
|
+
index > replacementCheckpointIndex &&
|
|
3787
|
+
event.event === "goal_checkpointed" &&
|
|
3788
|
+
event.goalId === input.goal.id &&
|
|
3789
|
+
event.status === "active",
|
|
3790
|
+
);
|
|
3791
|
+
if (reviewRecordedIndex < 0 || reviewRecordedIndex >= replacementCheckpointIndex || reactivatedIndex < 0)
|
|
3792
|
+
throw new Error("review-blocker replacement close lacks durable supersession and reopening evidence");
|
|
3793
|
+
|
|
3794
|
+
const historicalRequiredGoalIds = input.plan.goals
|
|
3795
|
+
.filter(goal => goal.id !== input.goal.id && goal.status !== "superseded")
|
|
3796
|
+
.map(goal => goal.id);
|
|
3797
|
+
const aggregateGoals = input.plan.goals.filter(goal => {
|
|
3798
|
+
const receipt = goal.completionVerification;
|
|
3799
|
+
return goal.status === "complete" && receipt?.receiptKind === "final-aggregate";
|
|
3800
|
+
});
|
|
3801
|
+
const aggregateGoal = aggregateGoals.find(goal => {
|
|
3802
|
+
const receipt = goal.completionVerification!;
|
|
3803
|
+
const event = findLedgerReceiptEvent(input.ledger, receipt);
|
|
3804
|
+
return (
|
|
3805
|
+
event !== null &&
|
|
3806
|
+
hashStructuredValue(event.qualityGateJson) === receipt.qualityGateHash &&
|
|
3807
|
+
goal.updatedAt === receipt.verifiedAt &&
|
|
3808
|
+
receipt.basis.relevantGoalIdsBeforeCheckpoint.length === historicalRequiredGoalIds.length &&
|
|
3809
|
+
receipt.basis.relevantGoalIdsBeforeCheckpoint.every(
|
|
3810
|
+
(goalId, index) => goalId === historicalRequiredGoalIds[index],
|
|
3811
|
+
)
|
|
3812
|
+
);
|
|
3813
|
+
});
|
|
3814
|
+
if (!aggregateGoal)
|
|
3815
|
+
throw new Error(
|
|
3816
|
+
"review-blocker replacement close requires a fresh final-aggregate receipt covering required goals",
|
|
3817
|
+
);
|
|
3818
|
+
|
|
3819
|
+
const memberMetadataHashes: Record<string, string> = {};
|
|
3820
|
+
const memberChangeSetHashes: Record<string, string> = {};
|
|
3821
|
+
const memberReceipts: JsonObject[] = [];
|
|
3822
|
+
for (const memberId of input.metadata.memberIds) {
|
|
3823
|
+
const member = input.plan.goals.find(goal => goal.id === memberId);
|
|
3824
|
+
if (!member?.validationBatch)
|
|
3825
|
+
throw new Error(`review-blocker replacement close references missing batch member ${memberId}`);
|
|
3826
|
+
memberMetadataHashes[memberId] = member.validationBatch.metadataHash;
|
|
3827
|
+
if (memberId === input.goal.id) continue;
|
|
3828
|
+
const receipt = requireDeferredMemberReceiptFresh(
|
|
3829
|
+
input.plan,
|
|
3830
|
+
input.ledger,
|
|
3831
|
+
member,
|
|
3832
|
+
"review-blocker replacement close",
|
|
3833
|
+
);
|
|
3834
|
+
memberChangeSetHashes[memberId] = receipt.validationBatch.changeSetHash;
|
|
3835
|
+
memberReceipts.push({
|
|
3836
|
+
goalId: memberId,
|
|
3837
|
+
receiptId: receipt.receiptId,
|
|
3838
|
+
checkpointLedgerEventId: receipt.checkpointLedgerEventId,
|
|
3839
|
+
qualityGateHash: receipt.qualityGateHash,
|
|
3840
|
+
changeSetHash: receipt.validationBatch.changeSetHash,
|
|
3841
|
+
role: "deferred-member",
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3844
|
+
const paths = input.changeSet.paths.map(row => ({ ...row }));
|
|
3845
|
+
memberChangeSetHashes[input.goal.id] = changeSetHashForPaths(paths);
|
|
3846
|
+
const unionHash = hashStructuredValue({
|
|
3847
|
+
memberChangeSetHashes,
|
|
3848
|
+
paths: paths.map(row => ({ path: row.path, status: row.status, oldPath: row.oldPath })),
|
|
3849
|
+
});
|
|
3850
|
+
return {
|
|
3851
|
+
...input.gate,
|
|
3852
|
+
validationBatchClose: {
|
|
3853
|
+
schemaVersion: 1,
|
|
3854
|
+
kind: "validation-batch-close",
|
|
3855
|
+
batchId: input.metadata.batchId,
|
|
3856
|
+
finalGoalId: input.metadata.finalGoalId,
|
|
3857
|
+
memberIds: [...input.metadata.memberIds],
|
|
3858
|
+
memberMetadataHashes,
|
|
3859
|
+
memberReceipts,
|
|
3860
|
+
unionChangeSet: {
|
|
3861
|
+
source: "validation-batch",
|
|
3862
|
+
memberChangeSetHashes,
|
|
3863
|
+
paths,
|
|
3864
|
+
unionHash,
|
|
3865
|
+
},
|
|
3866
|
+
coverageEvidence,
|
|
3867
|
+
},
|
|
3868
|
+
};
|
|
3869
|
+
}
|
|
3714
3870
|
async function readRequiredCompletionQualityGate(
|
|
3715
3871
|
cwd: string,
|
|
3716
3872
|
value: string | undefined,
|
|
@@ -3729,13 +3885,25 @@ async function readRequiredCompletionQualityGate(
|
|
|
3729
3885
|
const gate = await readStructuredValue(cwd, value);
|
|
3730
3886
|
const gateObject = qualityGateObject(gate);
|
|
3731
3887
|
if (!gateObject) throw new Error("qualityGate must be a JSON object");
|
|
3732
|
-
|
|
3888
|
+
const validationBatch = options.goal ? requireFreshValidationBatchMetadata(options.goal) : undefined;
|
|
3889
|
+
const hydratedGate =
|
|
3890
|
+
validationBatch && options.plan && options.goal && options.ledger
|
|
3891
|
+
? hydrateReviewedBatchReplacementClose({
|
|
3892
|
+
gate: gateObject,
|
|
3893
|
+
plan: options.plan,
|
|
3894
|
+
goal: options.goal,
|
|
3895
|
+
metadata: validationBatch,
|
|
3896
|
+
ledger: options.ledger,
|
|
3897
|
+
changeSet: options.changeSet,
|
|
3898
|
+
})
|
|
3899
|
+
: gateObject;
|
|
3900
|
+
await validateCompletionQualityGate(cwd, hydratedGate, {
|
|
3733
3901
|
changeSet: options.changeSet,
|
|
3734
3902
|
plan: options.plan,
|
|
3735
3903
|
goal: options.goal,
|
|
3736
3904
|
ledger: options.ledger,
|
|
3737
3905
|
});
|
|
3738
|
-
return
|
|
3906
|
+
return hydratedGate;
|
|
3739
3907
|
}
|
|
3740
3908
|
|
|
3741
3909
|
function validatePipelineCheckpointSafety(
|
|
@@ -3812,13 +3980,21 @@ export async function checkpointUltragoalGoal(input: {
|
|
|
3812
3980
|
const evidence = input.evidence.trim();
|
|
3813
3981
|
if (!evidence) throw new Error("checkpoint evidence is required");
|
|
3814
3982
|
const ledgerBefore = await readUltragoalLedger(input.cwd);
|
|
3815
|
-
const
|
|
3983
|
+
const matchingIdempotentEvents = ledgerBefore.filter(
|
|
3816
3984
|
event =>
|
|
3817
3985
|
event.event === "goal_checkpointed" &&
|
|
3818
3986
|
event.goalId === goal.id &&
|
|
3819
3987
|
event.status === input.status &&
|
|
3820
3988
|
event.evidence === evidence,
|
|
3821
3989
|
);
|
|
3990
|
+
// Re-verification replays legitimately append repeated same-status,
|
|
3991
|
+
// same-evidence checkpoint events for one goal. The recorded receipt must
|
|
3992
|
+
// be compared against ITS OWN checkpoint event — resolved by the receipt's
|
|
3993
|
+
// checkpointLedgerEventId, falling back to the latest match — never the
|
|
3994
|
+
// oldest duplicate, which would wrongly report the current receipt stale.
|
|
3995
|
+
const matchingIdempotentEvent =
|
|
3996
|
+
matchingIdempotentEvents.find(event => event.eventId === goal.completionVerification?.checkpointLedgerEventId) ??
|
|
3997
|
+
matchingIdempotentEvents.at(-1);
|
|
3822
3998
|
const batchMetadata = input.status === "complete" ? requireFreshValidationBatchMetadata(goal) : undefined;
|
|
3823
3999
|
if (batchMetadata && goal.completionVerification?.validationBatch) {
|
|
3824
4000
|
const receiptBatch = goal.completionVerification.validationBatch;
|
|
@@ -3835,7 +4011,35 @@ export async function checkpointUltragoalGoal(input: {
|
|
|
3835
4011
|
if (input.status === "complete" && goal.completionVerification?.validationBatch && !batchMetadata) {
|
|
3836
4012
|
throw new Error(`Goal ${goal.id} has stale validation batch completion receipt`);
|
|
3837
4013
|
}
|
|
3838
|
-
|
|
4014
|
+
// An identical-evidence complete replay is only a no-op while the recorded
|
|
4015
|
+
// receipt still validates fresh. When the goal row itself is untouched
|
|
4016
|
+
// (updatedAt still matches the receipt's verifiedAt) but later goal-tagged
|
|
4017
|
+
// ledger events (e.g. blocker classifications) or plan growth staled the
|
|
4018
|
+
// receipt, the replay is a genuine re-verification: it must run the full
|
|
4019
|
+
// quality gate and mint a fresh receipt, otherwise a completed goal with a
|
|
4020
|
+
// context-staled receipt can never be repaired (different evidence is
|
|
4021
|
+
// rejected on complete goals by design). A mutated goal row keeps the
|
|
4022
|
+
// fail-loud tamper handling in the idempotent branch below.
|
|
4023
|
+
const staleCompleteReceiptReplay =
|
|
4024
|
+
input.status === "complete" &&
|
|
4025
|
+
goal.status === "complete" &&
|
|
4026
|
+
goal.evidence === evidence &&
|
|
4027
|
+
Boolean(matchingIdempotentEvent) &&
|
|
4028
|
+
(!goal.completionVerification ||
|
|
4029
|
+
(goal.completionVerification.verifiedAt === goal.updatedAt &&
|
|
4030
|
+
validateReceiptFreshBase({
|
|
4031
|
+
plan,
|
|
4032
|
+
ledger: ledgerBefore,
|
|
4033
|
+
goal,
|
|
4034
|
+
receipt: goal.completionVerification,
|
|
4035
|
+
receiptKind: goal.completionVerification.receiptKind,
|
|
4036
|
+
}) !== null));
|
|
4037
|
+
if (
|
|
4038
|
+
goal.status === input.status &&
|
|
4039
|
+
goal.evidence === evidence &&
|
|
4040
|
+
matchingIdempotentEvent &&
|
|
4041
|
+
!staleCompleteReceiptReplay
|
|
4042
|
+
) {
|
|
3839
4043
|
if (batchMetadata) {
|
|
3840
4044
|
const receipt = goal.completionVerification;
|
|
3841
4045
|
const receiptBatch = receipt?.validationBatch;
|
|
@@ -3857,6 +4061,18 @@ export async function checkpointUltragoalGoal(input: {
|
|
|
3857
4061
|
)
|
|
3858
4062
|
throw new Error(`Goal ${goal.id} has stale validation batch metadata hash in close receipt`);
|
|
3859
4063
|
}
|
|
4064
|
+
// A complete goal whose row changed after its receipt was verified is
|
|
4065
|
+
// neither a clean no-op nor a repairable context-stale replay: fail loud
|
|
4066
|
+
// instead of silently laundering a tampered/inconsistent durable row.
|
|
4067
|
+
if (
|
|
4068
|
+
input.status === "complete" &&
|
|
4069
|
+
goal.completionVerification &&
|
|
4070
|
+
goal.completionVerification.verifiedAt !== goal.updatedAt
|
|
4071
|
+
) {
|
|
4072
|
+
throw new Error(
|
|
4073
|
+
`Goal ${goal.id} changed after its completion receipt was verified; refusing idempotent replay. Investigate the durable goals.json row before re-checkpointing.`,
|
|
4074
|
+
);
|
|
4075
|
+
}
|
|
3860
4076
|
// Idempotent re-checkpoint: this goal is already recorded in the target status with the same
|
|
3861
4077
|
// evidence, so skip the plan rewrite and ledger append to avoid duplicate goal_checkpointed
|
|
3862
4078
|
// events. The ledger is the dedup source of truth because it is exactly what a duplicate write
|
|
@@ -3868,7 +4084,7 @@ export async function checkpointUltragoalGoal(input: {
|
|
|
3868
4084
|
const changeSet = input.status === "complete" ? await computeCheckpointChangeSet(input.cwd) : undefined;
|
|
3869
4085
|
if (input.status === "complete") {
|
|
3870
4086
|
validatePipelineCheckpointSafety(plan, goal, changeSet);
|
|
3871
|
-
validateCompleteCheckpointTargetGoal(goal);
|
|
4087
|
+
if (!staleCompleteReceiptReplay) validateCompleteCheckpointTargetGoal(goal);
|
|
3872
4088
|
}
|
|
3873
4089
|
const qualityGateJson =
|
|
3874
4090
|
input.status === "complete"
|
|
@@ -3895,7 +4111,7 @@ export async function checkpointUltragoalGoal(input: {
|
|
|
3895
4111
|
blockedGoal.updatedAt = now;
|
|
3896
4112
|
}
|
|
3897
4113
|
}
|
|
3898
|
-
const receiptKind = input.status === "complete" ? chooseReceiptKind(plan, goal, input.status) : null;
|
|
4114
|
+
const receiptKind = input.status === "complete" ? chooseReceiptKind(plan, ledgerBefore, goal, input.status) : null;
|
|
3899
4115
|
const pendingCheckpointEventId = crypto.randomUUID();
|
|
3900
4116
|
if (input.status === "complete" && receiptKind && qualityGateJson && !Array.isArray(qualityGateJson)) {
|
|
3901
4117
|
goal.completionVerification = buildCompletionReceipt({
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
|
|
4
|
+
export const GJC_TMUX_LAUNCHED_ENV = "GJC_TMUX_LAUNCHED";
|
|
5
|
+
|
|
6
|
+
export interface WindowsPowerShellInnerCommandOptions {
|
|
7
|
+
command: readonly string[];
|
|
8
|
+
args?: readonly string[];
|
|
9
|
+
environment?: Record<string, string>;
|
|
10
|
+
tmuxExitMarkerPath?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function powershellQuote(value: string): string {
|
|
14
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function buildPowerShellTmuxExitMarkerFinally(markerPath: string): string {
|
|
18
|
+
const markerDir = path.win32.dirname(markerPath);
|
|
19
|
+
return [
|
|
20
|
+
"} finally {",
|
|
21
|
+
"\ttry {",
|
|
22
|
+
`\t\tNew-Item -ItemType Directory -Force -Path ${powershellQuote(markerDir)} -ErrorAction Stop | Out-Null`,
|
|
23
|
+
"\t\t$__gjcTmuxExitMarker = @{ schema_version = 1; source = 'tmux_inner_shell'; ended_at = (Get-Date).ToUniversalTime().ToString('o'); exit_code = $__gjcTmuxExitCode } | ConvertTo-Json -Compress",
|
|
24
|
+
`\t\tSet-Content -LiteralPath ${powershellQuote(markerPath)} -Value $__gjcTmuxExitMarker -Encoding UTF8 -ErrorAction Stop`,
|
|
25
|
+
"\t} catch {",
|
|
26
|
+
"\t}",
|
|
27
|
+
"}",
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Builds the shared BOM-free UTF-16LE command for native Windows tmux-compatible panes. */
|
|
32
|
+
export function buildWindowsPowerShellInnerCommand({
|
|
33
|
+
command,
|
|
34
|
+
args = [],
|
|
35
|
+
environment,
|
|
36
|
+
tmuxExitMarkerPath,
|
|
37
|
+
}: WindowsPowerShellInnerCommandOptions): string {
|
|
38
|
+
const envLines = Object.entries({ [GJC_TMUX_LAUNCHED_ENV]: "1", ...(environment ?? {}) }).map(
|
|
39
|
+
([key, value]) => `$env:${key} = ${powershellQuote(value)}`,
|
|
40
|
+
);
|
|
41
|
+
const resolvedCommand = command.map(powershellQuote).join(" ");
|
|
42
|
+
const innerArgs = args.map(powershellQuote).join(" ");
|
|
43
|
+
const invocation = `& ${resolvedCommand} ${innerArgs}`;
|
|
44
|
+
const exitLine = "if ($null -ne $LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 }";
|
|
45
|
+
const script = tmuxExitMarkerPath
|
|
46
|
+
? [
|
|
47
|
+
...envLines,
|
|
48
|
+
"$__gjcTmuxExitCode = 1",
|
|
49
|
+
"try {",
|
|
50
|
+
`\t${invocation}`,
|
|
51
|
+
"\tif ($null -ne $LASTEXITCODE) { $__gjcTmuxExitCode = $LASTEXITCODE } else { $__gjcTmuxExitCode = 1 }",
|
|
52
|
+
buildPowerShellTmuxExitMarkerFinally(tmuxExitMarkerPath),
|
|
53
|
+
"exit $__gjcTmuxExitCode",
|
|
54
|
+
].join("\n")
|
|
55
|
+
: [...envLines, invocation, exitLine].join("\n");
|
|
56
|
+
const encodedCommand = Buffer.from(script, "utf16le").toString("base64");
|
|
57
|
+
return `pwsh -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${encodedCommand}`;
|
|
58
|
+
}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
type VanishEvidence,
|
|
20
20
|
validateReceipt,
|
|
21
21
|
} from "./receipts";
|
|
22
|
-
import { type
|
|
22
|
+
import { type HarnessSessionTransport, singleFlightAccept } from "./session-transport";
|
|
23
23
|
import { writeReceiptImmutable } from "./storage";
|
|
24
24
|
import {
|
|
25
25
|
DEFAULT_RETRY_BUDGET,
|
|
@@ -35,10 +35,10 @@ export interface OperateOptions {
|
|
|
35
35
|
sessionId: string;
|
|
36
36
|
workspace: string;
|
|
37
37
|
branch: string;
|
|
38
|
-
|
|
39
|
-
/** Factory used to
|
|
40
|
-
|
|
41
|
-
/** Bounded observation provider (scripted in tests; real = git +
|
|
38
|
+
transport: HarnessSessionTransport;
|
|
39
|
+
/** Factory used to recreate an SDK transport on restart recovery. Defaults to reusing `transport`. */
|
|
40
|
+
transportFactory?: () => HarnessSessionTransport;
|
|
41
|
+
/** Bounded observation provider (scripted in tests; real = git + SDK session state). */
|
|
42
42
|
observe: () => Promise<Observation>;
|
|
43
43
|
/** Real dirty-worktree preservation; injectable for tests. Defaults to git stash/diff capture. */
|
|
44
44
|
preserve?: (workspace: string) => PreserveResult;
|
|
@@ -71,7 +71,7 @@ export async function operate(goal: string, opts: OperateOptions): Promise<Opera
|
|
|
71
71
|
const vanishReceiptIds: string[] = [];
|
|
72
72
|
const blockers: string[] = [];
|
|
73
73
|
|
|
74
|
-
let
|
|
74
|
+
let transport = opts.transport;
|
|
75
75
|
|
|
76
76
|
const now = (): string => new Date(opts.clock ? opts.clock() : Date.now()).toISOString();
|
|
77
77
|
let lifecycle: HarnessLifecycle = "started";
|
|
@@ -118,7 +118,7 @@ export async function operate(goal: string, opts: OperateOptions): Promise<Opera
|
|
|
118
118
|
};
|
|
119
119
|
|
|
120
120
|
const submit = async (): Promise<boolean> => {
|
|
121
|
-
const acc = await singleFlightAccept(
|
|
121
|
+
const acc = await singleFlightAccept(transport, goal, acceptanceTimeoutMs);
|
|
122
122
|
await emit(acc.accepted ? "info" : "warn", acc.accepted ? "prompt_accepted" : "prompt_not_accepted", {
|
|
123
123
|
reason: acc.reason,
|
|
124
124
|
});
|
|
@@ -160,11 +160,11 @@ export async function operate(goal: string, opts: OperateOptions): Promise<Opera
|
|
|
160
160
|
accepted = await submit();
|
|
161
161
|
} else if (decision.classification === "restart-clean") {
|
|
162
162
|
budget.zeroDeltaVanish = Math.max(0, budget.zeroDeltaVanish - 1);
|
|
163
|
-
|
|
163
|
+
transport = opts.transportFactory ? opts.transportFactory() : transport;
|
|
164
164
|
accepted = await submit();
|
|
165
165
|
} else if (decision.classification === "restart-preserve-delta") {
|
|
166
166
|
budget.dirtyVanishPreserve = Math.max(0, budget.dirtyVanishPreserve - 1);
|
|
167
|
-
|
|
167
|
+
transport = opts.transportFactory ? opts.transportFactory() : transport;
|
|
168
168
|
accepted = await submit();
|
|
169
169
|
} else if (decision.classification === "fallback-codex-exec") {
|
|
170
170
|
lifecycle = "blocked";
|