@zergai/ztc 0.4.0-beta.1 → 0.5.0-beta.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/README.md +398 -45
- package/RUST_THIRD_PARTY_LICENSES.txt +1080 -822
- package/THIRD_PARTY_NOTICES.md +273 -12
- package/bin/zmux-darwin-arm64 +0 -0
- package/bin/ztc-audio-darwin-arm64 +0 -0
- package/bin/ztc-capture-darwin-arm64 +0 -0
- package/bin/ztc-computer-darwin-arm64 +0 -0
- package/bin/ztc-llm-darwin-arm64 +0 -0
- package/bin/ztc-tts-darwin-arm64 +0 -0
- package/bin/ztc-tui-darwin-arm64 +0 -0
- package/bin/ztc-zlicky-overlay-darwin-arm64 +0 -0
- package/bin/zterm-darwin-arm64 +0 -0
- package/dist/App.js +1206 -209
- package/dist/agent/agent.d.ts +74 -8
- package/dist/agent/agent.js +1073 -184
- package/dist/agent/backends/account_rotation.d.ts +4 -0
- package/dist/agent/backends/account_rotation.js +8 -2
- package/dist/agent/backends/anthropic.d.ts +13 -0
- package/dist/agent/backends/anthropic.js +169 -28
- package/dist/agent/backends/claude_cli.js +18 -8
- package/dist/agent/backends/codex_app_server.d.ts +1 -0
- package/dist/agent/backends/codex_app_server.js +55 -3
- package/dist/agent/backends/codex_auth.d.ts +1 -0
- package/dist/agent/backends/codex_auth.js +67 -13
- package/dist/agent/backends/codex_buffered_recovery.d.ts +27 -0
- package/dist/agent/backends/codex_buffered_recovery.js +293 -0
- package/dist/agent/backends/gemini.js +3 -1
- package/dist/agent/backends/http_error.d.ts +26 -0
- package/dist/agent/backends/http_error.js +221 -0
- package/dist/agent/backends/index.d.ts +9 -2
- package/dist/agent/backends/index.js +22 -2
- package/dist/agent/backends/openai.d.ts +0 -6
- package/dist/agent/backends/openai.js +5 -2
- package/dist/agent/backends/openai_compatible.d.ts +5 -4
- package/dist/agent/backends/openai_compatible.js +26 -19
- package/dist/agent/backends/openai_responses.d.ts +8 -3
- package/dist/agent/backends/openai_responses.js +77 -33
- package/dist/agent/backends/provider_ids.d.ts +1 -0
- package/dist/agent/backends/provider_ids.js +4 -0
- package/dist/agent/backends/request_metrics.js +12 -2
- package/dist/agent/backends/types.d.ts +109 -6
- package/dist/agent/backends/types.js +5 -1
- package/dist/agent/backends/zrouter_stream.d.ts +6 -1
- package/dist/agent/backends/zrouter_stream.js +160 -42
- package/dist/agent/background_registry.d.ts +2 -0
- package/dist/agent/background_registry.js +1 -0
- package/dist/agent/claim_observation.d.ts +6 -0
- package/dist/agent/claim_observation.js +54 -0
- package/dist/agent/commands/accounts.js +46 -177
- package/dist/agent/commands/attention.d.ts +2 -0
- package/dist/agent/commands/attention.js +67 -0
- package/dist/agent/commands/auth.js +18 -2
- package/dist/agent/commands/board.d.ts +2 -0
- package/dist/agent/commands/board.js +169 -0
- package/dist/agent/commands/clipboard.js +50 -1
- package/dist/agent/commands/compact.js +21 -13
- package/dist/agent/commands/config.js +4 -1
- package/dist/agent/commands/context.js +6 -1
- package/dist/agent/commands/desktop.d.ts +2 -0
- package/dist/agent/commands/desktop.js +29 -0
- package/dist/agent/commands/effort.js +14 -6
- package/dist/agent/commands/environment.d.ts +3 -0
- package/dist/agent/commands/environment.js +109 -0
- package/dist/agent/commands/evidence.d.ts +2 -0
- package/dist/agent/commands/evidence.js +9 -0
- package/dist/agent/commands/fork.js +4 -3
- package/dist/agent/commands/goal.d.ts +33 -1
- package/dist/agent/commands/goal.js +174 -14
- package/dist/agent/commands/goal_exit.d.ts +36 -0
- package/dist/agent/commands/goal_exit.js +120 -0
- package/dist/agent/commands/help.js +3 -1
- package/dist/agent/commands/history.js +3 -1
- package/dist/agent/commands/inbox.d.ts +2 -0
- package/dist/agent/commands/inbox.js +148 -0
- package/dist/agent/commands/index.js +16 -1
- package/dist/agent/commands/input_mode.js +8 -6
- package/dist/agent/commands/job.d.ts +2 -0
- package/dist/agent/commands/job.js +93 -0
- package/dist/agent/commands/keybindings.js +4 -1
- package/dist/agent/commands/label.d.ts +2 -0
- package/dist/agent/commands/label.js +77 -0
- package/dist/agent/commands/layout.d.ts +2 -0
- package/dist/agent/commands/layout.js +20 -0
- package/dist/agent/commands/mirror.js +16 -1
- package/dist/agent/commands/model.js +12 -2
- package/dist/agent/commands/permissions.d.ts +3 -1
- package/dist/agent/commands/permissions.js +79 -89
- package/dist/agent/commands/plan.js +5 -15
- package/dist/agent/commands/profile.js +21 -2
- package/dist/agent/commands/provider_selection.js +20 -1
- package/dist/agent/commands/rename.js +1 -1
- package/dist/agent/commands/resources.d.ts +2 -0
- package/dist/agent/commands/resources.js +67 -0
- package/dist/agent/commands/rewind.d.ts +3 -0
- package/dist/agent/commands/rewind.js +16 -0
- package/dist/agent/commands/runbooks.d.ts +2 -0
- package/dist/agent/commands/runbooks.js +73 -0
- package/dist/agent/commands/runbooks_lazy.d.ts +2 -0
- package/dist/agent/commands/runbooks_lazy.js +8 -0
- package/dist/agent/commands/sessions.d.ts +1 -1
- package/dist/agent/commands/sessions.js +33 -5
- package/dist/agent/commands/settings.js +185 -39
- package/dist/agent/commands/setup.d.ts +2 -0
- package/dist/agent/commands/setup.js +78 -0
- package/dist/agent/commands/share.d.ts +2 -0
- package/dist/agent/commands/share.js +64 -0
- package/dist/agent/commands/status.js +14 -2
- package/dist/agent/commands/types.d.ts +99 -6
- package/dist/agent/commands/update.js +8 -0
- package/dist/agent/commands/usage.d.ts +2 -0
- package/dist/agent/commands/usage.js +8 -0
- package/dist/agent/factory.d.ts +11 -0
- package/dist/agent/factory.js +113 -88
- package/dist/agent/loop_policy.d.ts +6 -3
- package/dist/agent/loop_policy.js +12 -3
- package/dist/agent/measurement_guidance.d.ts +2 -0
- package/dist/agent/measurement_guidance.js +5 -0
- package/dist/agent/request_encoder.d.ts +8 -1
- package/dist/agent/request_encoder.js +95 -23
- package/dist/agent/runtime/benchmark_comparison.d.ts +30 -0
- package/dist/agent/runtime/benchmark_comparison.js +94 -0
- package/dist/agent/runtime/benchmark_contract.d.ts +48 -0
- package/dist/agent/runtime/benchmark_contract.js +90 -0
- package/dist/agent/runtime/checked_commands.d.ts +32 -0
- package/dist/agent/runtime/checked_commands.js +119 -0
- package/dist/agent/runtime/command_execution_policy.d.ts +26 -0
- package/dist/agent/runtime/command_execution_policy.js +91 -0
- package/dist/agent/runtime/command_jobs.d.ts +36 -18
- package/dist/agent/runtime/command_jobs.js +151 -13
- package/dist/agent/runtime/command_panes.d.ts +59 -0
- package/dist/agent/runtime/command_panes.js +398 -0
- package/dist/agent/runtime/command_wait.d.ts +19 -0
- package/dist/agent/runtime/command_wait.js +167 -0
- package/dist/agent/runtime/cpu_benchmark.d.ts +30 -0
- package/dist/agent/runtime/cpu_benchmark.js +126 -0
- package/dist/agent/runtime/delegated_evidence.d.ts +26 -0
- package/dist/agent/runtime/delegated_evidence.js +80 -0
- package/dist/agent/runtime/evidence.d.ts +127 -0
- package/dist/agent/runtime/evidence.js +468 -0
- package/dist/agent/runtime/execution_context.d.ts +7 -0
- package/dist/agent/runtime/execution_context.js +39 -3
- package/dist/agent/runtime/json_verifier_recipe.d.ts +8 -0
- package/dist/agent/runtime/json_verifier_recipe.js +66 -0
- package/dist/agent/runtime/measurements.d.ts +110 -0
- package/dist/agent/runtime/measurements.js +317 -0
- package/dist/agent/runtime/policy.d.ts +4 -0
- package/dist/agent/runtime/policy.js +31 -20
- package/dist/agent/runtime/provider_native_evidence.d.ts +20 -0
- package/dist/agent/runtime/provider_native_evidence.js +86 -0
- package/dist/agent/runtime/recovery.d.ts +2 -0
- package/dist/agent/runtime/recovery.js +45 -2
- package/dist/agent/runtime/remote_broker_transport.d.ts +10 -0
- package/dist/agent/runtime/remote_broker_transport.js +84 -0
- package/dist/agent/runtime/remote_deletion_receipts.d.ts +3 -0
- package/dist/agent/runtime/remote_deletion_receipts.js +43 -0
- package/dist/agent/runtime/remote_journal_replay.d.ts +13 -0
- package/dist/agent/runtime/remote_journal_replay.js +233 -0
- package/dist/agent/runtime/remote_mutation_journal.d.ts +25 -0
- package/dist/agent/runtime/remote_mutation_journal.js +208 -0
- package/dist/agent/runtime/remote_resource_endpoint.d.ts +7 -0
- package/dist/agent/runtime/remote_resource_endpoint.js +6 -0
- package/dist/agent/runtime/remote_resource_errors.d.ts +5 -0
- package/dist/agent/runtime/remote_resource_errors.js +9 -0
- package/dist/agent/runtime/remote_resource_script.d.ts +2 -0
- package/dist/agent/runtime/remote_resource_script.js +1009 -0
- package/dist/agent/runtime/remote_resources.d.ts +29 -0
- package/dist/agent/runtime/remote_resources.js +160 -0
- package/dist/agent/runtime/source_verification.d.ts +12 -0
- package/dist/agent/runtime/source_verification.js +210 -0
- package/dist/agent/runtime/source_verification_contract.d.ts +75 -0
- package/dist/agent/runtime/source_verification_contract.js +203 -0
- package/dist/agent/runtime/tool_checkpoints.d.ts +11 -0
- package/dist/agent/runtime/tool_checkpoints.js +26 -0
- package/dist/agent/runtime/tool_effects.d.ts +5 -0
- package/dist/agent/runtime/tool_progress.d.ts +12 -0
- package/dist/agent/runtime/tool_progress.js +76 -0
- package/dist/agent/runtime/tool_runtime.d.ts +16 -1
- package/dist/agent/runtime/tool_runtime.js +204 -10
- package/dist/agent/runtime/tracing.d.ts +1 -1
- package/dist/agent/runtime/verifier_capture.d.ts +9 -0
- package/dist/agent/runtime/verifier_capture.js +100 -0
- package/dist/agent/runtime/verifier_contract.d.ts +24 -0
- package/dist/agent/runtime/verifier_contract.js +41 -0
- package/dist/agent/subagent.d.ts +20 -10
- package/dist/agent/subagent.js +266 -29
- package/dist/agent/tool_response_directory.d.ts +24 -0
- package/dist/agent/tool_response_directory.js +61 -0
- package/dist/agent/tool_response_source.d.ts +8 -0
- package/dist/agent/tool_response_source.js +49 -0
- package/dist/agent/tool_response_store.d.ts +75 -4
- package/dist/agent/tool_response_store.js +583 -64
- package/dist/agent/tools/ask_user.d.ts +3 -1
- package/dist/agent/tools/ask_user.js +30 -11
- package/dist/agent/tools/background.js +1 -0
- package/dist/agent/tools/benchmark_cpu.d.ts +2 -0
- package/dist/agent/tools/benchmark_cpu.js +102 -0
- package/dist/agent/tools/compare_benchmarks.d.ts +2 -0
- package/dist/agent/tools/compare_benchmarks.js +53 -0
- package/dist/agent/tools/deferred.js +1 -0
- package/dist/agent/tools/delegate.js +18 -2
- package/dist/agent/tools/helper_requirements.d.ts +7 -0
- package/dist/agent/tools/helper_requirements.js +19 -0
- package/dist/agent/tools/index.d.ts +1 -0
- package/dist/agent/tools/index.js +3 -0
- package/dist/agent/tools/measurement_report.d.ts +22 -0
- package/dist/agent/tools/measurement_report.js +190 -0
- package/dist/agent/tools/pane.d.ts +0 -7
- package/dist/agent/tools/pane.js +5 -4
- package/dist/agent/tools/project_context.d.ts +3 -0
- package/dist/agent/tools/project_context.js +45 -0
- package/dist/agent/tools/recall_tool_response.d.ts +3 -5
- package/dist/agent/tools/recall_tool_response.js +19 -29
- package/dist/agent/tools/registry.d.ts +1 -0
- package/dist/agent/tools/registry.js +23 -0
- package/dist/agent/tools/related_sessions.d.ts +2 -0
- package/dist/agent/tools/related_sessions.js +156 -0
- package/dist/agent/tools/routine.js +13 -3
- package/dist/agent/tools/session_evidence.d.ts +3 -0
- package/dist/agent/tools/session_evidence.js +72 -0
- package/dist/agent/tools/shell.d.ts +4 -3
- package/dist/agent/tools/shell.js +174 -47
- package/dist/agent/tools/tool_search.js +3 -2
- package/dist/agent/tools/types.d.ts +28 -0
- package/dist/agent/tools/verify_artifact.d.ts +2 -0
- package/dist/agent/tools/verify_artifact.js +60 -0
- package/dist/agent/tools/workflow.js +1 -0
- package/dist/app/activity.d.ts +6 -1
- package/dist/app/activity.js +81 -12
- package/dist/app/agent_runner.d.ts +6 -1
- package/dist/app/agent_runner.js +34 -19
- package/dist/app/command_context.js +106 -10
- package/dist/app/controller.d.ts +15 -4
- package/dist/app/controller.js +29 -3
- package/dist/app/escape_stop.d.ts +11 -0
- package/dist/app/escape_stop.js +15 -0
- package/dist/app/liveness.d.ts +6 -4
- package/dist/app/liveness.js +13 -3
- package/dist/app/model_catalog_cache.d.ts +5 -0
- package/dist/app/model_catalog_cache.js +138 -0
- package/dist/app/ordered_transcript.js +43 -4
- package/dist/app/prompt_turn.d.ts +14 -0
- package/dist/app/prompt_turn.js +53 -0
- package/dist/app/recap.d.ts +3 -0
- package/dist/app/recap.js +9 -3
- package/dist/app/restart.d.ts +3 -2
- package/dist/app/restart.js +22 -7
- package/dist/app/rewind.d.ts +3 -3
- package/dist/app/rewind.js +3 -3
- package/dist/app/selection_completion.d.ts +17 -2
- package/dist/app/selection_completion.js +84 -9
- package/dist/app/session_manager.d.ts +38 -6
- package/dist/app/session_manager.js +263 -60
- package/dist/app/session_messages.d.ts +3 -0
- package/dist/app/session_messages.js +60 -0
- package/dist/app/task_scope_router.d.ts +20 -0
- package/dist/app/task_scope_router.js +173 -0
- package/dist/app/transcript_window.d.ts +2 -0
- package/dist/app/transcript_window.js +4 -0
- package/dist/app/workspace_admission_details.d.ts +3 -0
- package/dist/app/workspace_admission_details.js +26 -0
- package/dist/app/workspace_layout_controller.d.ts +11 -0
- package/dist/app/workspace_layout_controller.js +88 -0
- package/dist/app/workspace_monitor.d.ts +1 -0
- package/dist/app/workspace_monitor.js +216 -0
- package/dist/app/workspace_presets.d.ts +29 -0
- package/dist/app/workspace_presets.js +192 -0
- package/dist/attention/queue.d.ts +37 -0
- package/dist/attention/queue.js +183 -0
- package/dist/bench/rf_shared.d.ts +2 -0
- package/dist/board/binding.d.ts +42 -0
- package/dist/board/binding.js +38 -0
- package/dist/board/client.d.ts +42 -0
- package/dist/board/client.js +60 -0
- package/dist/cli.js +1 -1
- package/dist/cli_args.js +19 -17
- package/dist/cli_main.js +110 -13
- package/dist/cli_ratatui.d.ts +183 -16
- package/dist/cli_ratatui.js +3989 -1255
- package/dist/components/ActivityLine.d.ts +3 -2
- package/dist/components/ActivityLine.js +2 -2
- package/dist/components/InputArea.d.ts +19 -1
- package/dist/components/InputArea.js +264 -190
- package/dist/components/MessageList.d.ts +2 -0
- package/dist/components/MessageList.js +3 -1
- package/dist/components/SingleMessage.d.ts +2 -0
- package/dist/components/SingleMessage.js +4 -2
- package/dist/components/StatusBar.d.ts +4 -2
- package/dist/components/StatusBar.js +3 -1
- package/dist/conductor_branch.js +3 -0
- package/dist/config/api_retry.d.ts +6 -1
- package/dist/config/api_retry.js +19 -1
- package/dist/config/defaults.d.ts +2 -1
- package/dist/config/defaults.js +9 -2
- package/dist/config/message_display.d.ts +1 -0
- package/dist/config/message_display.js +17 -2
- package/dist/config/permissions.d.ts +21 -0
- package/dist/config/permissions.js +89 -0
- package/dist/config/resolved.d.ts +2 -2
- package/dist/config/types.d.ts +32 -5
- package/dist/config.d.ts +38 -4
- package/dist/config.js +290 -42
- package/dist/context/project_intelligence.d.ts +44 -0
- package/dist/context/project_intelligence.js +246 -0
- package/dist/desktop/cli_launch.d.ts +8 -0
- package/dist/desktop/cli_launch.js +6 -0
- package/dist/desktop/cli_shim.d.ts +8 -0
- package/dist/desktop/cli_shim.js +120 -0
- package/dist/desktop/runtime.d.ts +16 -0
- package/dist/desktop/runtime.js +161 -0
- package/dist/desktop/worker_launch.d.ts +7 -0
- package/dist/desktop/worker_launch.js +7 -0
- package/dist/diagnostics/cargo_mutants_selection.d.ts +27 -0
- package/dist/diagnostics/cargo_mutants_selection.js +48 -0
- package/dist/diagnostics/native_terminal_benchmark.d.ts +58 -0
- package/dist/diagnostics/native_terminal_benchmark.js +1247 -0
- package/dist/diagnostics/session_evidence_package.d.ts +40 -0
- package/dist/diagnostics/session_evidence_package.js +234 -0
- package/dist/diagnostics/session_export.d.ts +93 -0
- package/dist/diagnostics/session_export.js +634 -0
- package/dist/emulation/tool_adapters.js +48 -18
- package/dist/emulation/ztc_addendum.d.ts +1 -0
- package/dist/emulation/ztc_addendum.js +13 -12
- package/dist/environment/service_runner.d.ts +1 -0
- package/dist/environment/service_runner.js +68 -0
- package/dist/environment/store.d.ts +120 -0
- package/dist/environment/store.js +387 -0
- package/dist/events.d.ts +40 -1
- package/dist/events.js +10 -17
- package/dist/goal_contract.d.ts +25 -0
- package/dist/goal_contract.js +44 -0
- package/dist/headless.d.ts +31 -0
- package/dist/headless.js +578 -70
- package/dist/headless_cli.js +8 -0
- package/dist/headless_cli_args.d.ts +1 -0
- package/dist/headless_cli_args.js +1 -0
- package/dist/intake/cli.d.ts +1 -0
- package/dist/intake/cli.js +33 -0
- package/dist/intake/format.d.ts +2 -0
- package/dist/intake/format.js +14 -0
- package/dist/intake/notifications.d.ts +16 -0
- package/dist/intake/notifications.js +132 -0
- package/dist/intake/store.d.ts +56 -0
- package/dist/intake/store.js +238 -0
- package/dist/library.d.ts +8 -0
- package/dist/library.js +19 -10
- package/dist/mcp/client.d.ts +1 -0
- package/dist/mcp/client.js +20 -0
- package/dist/modes/builtin/plan.yaml +2 -2
- package/dist/modes/handlers.js +1 -1
- package/dist/onboarding/first_run.d.ts +3 -0
- package/dist/onboarding/first_run.js +33 -25
- package/dist/onboarding/setup.d.ts +32 -0
- package/dist/onboarding/setup.js +133 -0
- package/dist/onboarding/setup_agent_health.d.ts +17 -0
- package/dist/onboarding/setup_agent_health.js +79 -0
- package/dist/onboarding/setup_environment.d.ts +66 -0
- package/dist/onboarding/setup_environment.js +219 -0
- package/dist/onboarding/setup_workspace.d.ts +17 -0
- package/dist/onboarding/setup_workspace.js +129 -0
- package/dist/optimize/adapters/index.d.ts +4 -1
- package/dist/optimize/adapters/index.js +7 -0
- package/dist/optimize/adapters/kernelbench.js +14 -5
- package/dist/optimize/adapters/popcorn.js +3 -2
- package/dist/optimize/adapters/profile_benchmark.js +13 -7
- package/dist/optimize/adapters/rfbench.js +25 -14
- package/dist/optimize/adapters/types.d.ts +3 -0
- package/dist/optimize/adapters/zergpod.js +5 -2
- package/dist/optimize/baseline.js +10 -21
- package/dist/optimize/branch.js +9 -12
- package/dist/optimize/combine.js +2 -3
- package/dist/optimize/executor.js +34 -48
- package/dist/optimize/measurements.d.ts +55 -0
- package/dist/optimize/measurements.js +173 -0
- package/dist/optimize/results.d.ts +1 -0
- package/dist/optimize/results.js +11 -33
- package/dist/optimize/tge.js +2 -1
- package/dist/panes/initial_input.d.ts +19 -0
- package/dist/panes/initial_input.js +206 -0
- package/dist/panes/labels.d.ts +16 -0
- package/dist/panes/labels.js +42 -0
- package/dist/panes/model_catalog.d.ts +3 -3
- package/dist/panes/model_catalog.js +28 -4
- package/dist/panes/pane_registry.js +6 -2
- package/dist/panes/types.d.ts +3 -0
- package/dist/panes/ztc_launch.js +19 -0
- package/dist/plugin/optimization.d.ts +2 -0
- package/dist/plugin/optimization.js +1 -0
- package/dist/plugin/runtime.d.ts +2 -0
- package/dist/plugin/simulation.d.ts +6 -1
- package/dist/plugin/simulation_contract.d.ts +836 -1
- package/dist/plugin/simulation_documents.d.ts +22 -0
- package/dist/plugin/simulation_documents.js +1 -0
- package/dist/plugin/simulation_interventions.d.ts +103 -0
- package/dist/plugin/simulation_interventions.js +1 -0
- package/dist/plugin/simulation_living.d.ts +1 -0
- package/dist/plugin/simulation_living.js +3 -0
- package/dist/plugin/simulation_meetings.d.ts +121 -0
- package/dist/plugin/simulation_meetings.js +1 -0
- package/dist/plugin/simulation_story_review.d.ts +111 -0
- package/dist/plugin/simulation_story_review.js +1 -0
- package/dist/plugin/simulation_storyteller.d.ts +91 -0
- package/dist/plugin/simulation_storyteller.js +1 -0
- package/dist/plugin/simulation_structured.d.ts +2 -0
- package/dist/plugin/simulation_structured.js +2 -0
- package/dist/plugin/simulation_toolkit.d.ts +21 -0
- package/dist/plugin/simulation_toolkit.js +24 -0
- package/dist/prompts/tool_delegate_task.j2 +1 -1
- package/dist/remote-broker/Dockerfile +10 -0
- package/dist/remote-broker/archive.py +1227 -0
- package/dist/remote-broker/cutover.py +761 -0
- package/dist/remote-broker/requirements.txt +5 -0
- package/dist/remote-broker/resources.json +6 -0
- package/dist/remote-broker/resources.write-staging.example.json +18 -0
- package/dist/remote-broker/retained.py +686 -0
- package/dist/remote-broker/retained_cleanup.py +550 -0
- package/dist/remote-broker/server.py +648 -0
- package/dist/remote-broker/worker.py +1007 -0
- package/dist/router_auth.d.ts +31 -0
- package/dist/router_auth.js +155 -9
- package/dist/runbooks/catalog.d.ts +3 -0
- package/dist/runbooks/catalog.js +26 -0
- package/dist/runbooks/library.d.ts +11 -0
- package/dist/runbooks/library.js +95 -0
- package/dist/runbooks/package.d.ts +43 -0
- package/dist/runbooks/package.js +102 -0
- package/dist/session.d.ts +65 -13
- package/dist/session.js +548 -43
- package/dist/session_handoff.d.ts +25 -0
- package/dist/session_handoff.js +322 -0
- package/dist/session_handoff_contract.d.ts +89 -0
- package/dist/session_handoff_contract.js +179 -0
- package/dist/session_media.d.ts +41 -0
- package/dist/session_media.js +357 -0
- package/dist/session_ownership.d.ts +16 -0
- package/dist/session_ownership.js +221 -0
- package/dist/session_public.d.ts +10 -2
- package/dist/session_public.js +6 -1
- package/dist/simulation/dynamic_history.d.ts +42 -0
- package/dist/simulation/dynamic_history.js +173 -0
- package/dist/simulation/engines/swarm/pane_manager.js +7 -6
- package/dist/simulation/inference.d.ts +3 -1
- package/dist/simulation/inference.js +19 -1
- package/dist/simulation/intervention_generation.d.ts +27 -0
- package/dist/simulation/intervention_generation.js +246 -0
- package/dist/simulation/intervention_material.d.ts +4 -0
- package/dist/simulation/intervention_material.js +81 -0
- package/dist/simulation/living/context.d.ts +3130 -0
- package/dist/simulation/living/context.js +944 -0
- package/dist/simulation/living/definer.d.ts +12 -0
- package/dist/simulation/living/definer.js +223 -0
- package/dist/simulation/living/definition.d.ts +257 -0
- package/dist/simulation/living/definition.js +341 -0
- package/dist/simulation/living/frame.d.ts +259 -0
- package/dist/simulation/living/frame.js +223 -0
- package/dist/simulation/living/identifiers.d.ts +2 -0
- package/dist/simulation/living/identifiers.js +12 -0
- package/dist/simulation/living/index.d.ts +15 -0
- package/dist/simulation/living/index.js +15 -0
- package/dist/simulation/living/inference.d.ts +219 -0
- package/dist/simulation/living/inference.js +576 -0
- package/dist/simulation/living/mechanics.d.ts +54 -0
- package/dist/simulation/living/mechanics.js +588 -0
- package/dist/simulation/living/model-input.d.ts +25 -0
- package/dist/simulation/living/model-input.js +215 -0
- package/dist/simulation/living/open-world.d.ts +257 -0
- package/dist/simulation/living/open-world.js +102 -0
- package/dist/simulation/living/projection.d.ts +7 -0
- package/dist/simulation/living/projection.js +31 -0
- package/dist/simulation/living/recall.d.ts +17 -0
- package/dist/simulation/living/recall.js +25 -0
- package/dist/simulation/living/reduce.d.ts +15 -0
- package/dist/simulation/living/reduce.js +1853 -0
- package/dist/simulation/living/replay.d.ts +6 -0
- package/dist/simulation/living/replay.js +22 -0
- package/dist/simulation/living/runtime.d.ts +140 -0
- package/dist/simulation/living/runtime.js +3020 -0
- package/dist/simulation/living/shared-kinds.d.ts +24 -0
- package/dist/simulation/living/shared-kinds.js +96 -0
- package/dist/simulation/living/types.d.ts +2785 -0
- package/dist/simulation/living/types.js +669 -0
- package/dist/simulation/llm.d.ts +3 -1
- package/dist/simulation/llm.js +90 -30
- package/dist/simulation/memory/embedding.d.ts +1 -1
- package/dist/simulation/memory/embedding.js +9 -3
- package/dist/simulation/memory/filesystem.d.ts +2 -0
- package/dist/simulation/memory/filesystem.js +5 -1
- package/dist/simulation/memory/filesystem_file_tree.d.ts +4 -1
- package/dist/simulation/memory/filesystem_file_tree.js +41 -10
- package/dist/simulation/memory/filesystem_invariants.js +1 -2
- package/dist/simulation/memory/filesystem_types.d.ts +1 -0
- package/dist/simulation/memory/memory.d.ts +2 -0
- package/dist/simulation/memory/memory.js +5 -1
- package/dist/simulation/orchestration/intent.js +0 -2
- package/dist/simulation/orchestration/lifecycle.js +0 -2
- package/dist/simulation/plugin_host.d.ts +25 -1
- package/dist/simulation/plugin_host.js +334 -17
- package/dist/simulation/session_documents.d.ts +20 -0
- package/dist/simulation/session_documents.js +62 -0
- package/dist/simulation/session_input_validation.d.ts +43 -0
- package/dist/simulation/session_input_validation.js +364 -0
- package/dist/simulation/session_inputs.d.ts +32 -0
- package/dist/simulation/session_inputs.js +154 -0
- package/dist/simulation/telemetry.d.ts +11 -14
- package/dist/simulation/telemetry.js +177 -54
- package/dist/simulation/toolkit/bounded_turns.d.ts +13 -0
- package/dist/simulation/toolkit/bounded_turns.js +80 -0
- package/dist/simulation/toolkit/dynamic_agents.d.ts +25 -0
- package/dist/simulation/toolkit/dynamic_agents.js +218 -0
- package/dist/simulation/toolkit/dynamic_digest.d.ts +1 -0
- package/dist/simulation/toolkit/dynamic_digest.js +8 -0
- package/dist/simulation/toolkit/dynamic_documents.d.ts +7 -0
- package/dist/simulation/toolkit/dynamic_documents.js +71 -0
- package/dist/simulation/toolkit/dynamic_driver.d.ts +8 -0
- package/dist/simulation/toolkit/dynamic_driver.js +269 -0
- package/dist/simulation/toolkit/dynamic_game.d.ts +53 -0
- package/dist/simulation/toolkit/dynamic_game.js +805 -0
- package/dist/simulation/toolkit/dynamic_knowledge.d.ts +15 -0
- package/dist/simulation/toolkit/dynamic_knowledge.js +91 -0
- package/dist/simulation/toolkit/dynamic_mechanics.d.ts +22 -0
- package/dist/simulation/toolkit/dynamic_mechanics.js +910 -0
- package/dist/simulation/toolkit/dynamic_meetings.d.ts +239 -0
- package/dist/simulation/toolkit/dynamic_meetings.js +350 -0
- package/dist/simulation/toolkit/dynamic_progress.d.ts +131 -0
- package/dist/simulation/toolkit/dynamic_progress.js +214 -0
- package/dist/simulation/toolkit/dynamic_projection.d.ts +9 -0
- package/dist/simulation/toolkit/dynamic_projection.js +219 -0
- package/dist/simulation/toolkit/dynamic_runtime.d.ts +412 -0
- package/dist/simulation/toolkit/dynamic_runtime.js +6536 -0
- package/dist/simulation/toolkit/dynamic_state.d.ts +111 -0
- package/dist/simulation/toolkit/dynamic_state.js +1967 -0
- package/dist/simulation/toolkit/dynamic_story_review.d.ts +508 -0
- package/dist/simulation/toolkit/dynamic_story_review.js +333 -0
- package/dist/simulation/toolkit/dynamic_storyteller.d.ts +77 -0
- package/dist/simulation/toolkit/dynamic_storyteller.js +114 -0
- package/dist/simulation/toolkit/dynamic_storyteller_runtime.d.ts +26 -0
- package/dist/simulation/toolkit/dynamic_storyteller_runtime.js +126 -0
- package/dist/simulation/toolkit/dynamic_world.d.ts +22 -0
- package/dist/simulation/toolkit/dynamic_world.js +377 -0
- package/dist/simulation/toolkit/structured_output.d.ts +5 -0
- package/dist/simulation/toolkit/structured_output.js +321 -0
- package/dist/simulation/types/world.d.ts +2 -0
- package/dist/simulation/world/artifact_store.js +1 -1
- package/dist/simulation/world/memory_manager.d.ts +5 -0
- package/dist/simulation/world/memory_manager.js +17 -2
- package/dist/simulation/world/state.d.ts +3 -2
- package/dist/simulation/world/state.js +15 -5
- package/dist/skills/bundled/measurement-validation/SKILL.md +144 -0
- package/dist/terminal_attach.d.ts +1 -0
- package/dist/terminal_attach.js +113 -0
- package/dist/tool_progress.d.ts +3 -0
- package/dist/tool_progress.js +27 -0
- package/dist/types.d.ts +145 -10
- package/dist/types.js +3 -0
- package/dist/ui/core/input.d.ts +3 -0
- package/dist/ui/core/input_segments.d.ts +18 -1
- package/dist/ui/core/input_segments.js +131 -47
- package/dist/ui/core/input_state.d.ts +12 -0
- package/dist/ui/core/layout_yoga.d.ts +1 -1
- package/dist/ui/core/turn_metadata.d.ts +5 -0
- package/dist/ui/core/turn_metadata.js +22 -0
- package/dist/ui/ink/render.d.ts +2 -1
- package/dist/ui/ink/render.js +6 -5
- package/dist/ui/ratatui/headless_pane_manager.d.ts +14 -1
- package/dist/ui/ratatui/headless_pane_manager.js +293 -104
- package/dist/ui/ratatui/index.d.ts +1 -0
- package/dist/ui/ratatui/input.d.ts +4 -0
- package/dist/ui/ratatui/input.js +15 -0
- package/dist/ui/ratatui/ipc_path.d.ts +2 -0
- package/dist/ui/ratatui/ipc_path.js +29 -1
- package/dist/ui/ratatui/mux_persistence.d.ts +3 -1
- package/dist/ui/ratatui/mux_persistence.js +139 -1
- package/dist/ui/ratatui/pane_relay.d.ts +1 -1
- package/dist/ui/ratatui/pane_relay.js +55 -27
- package/dist/ui/ratatui/process.d.ts +17 -1
- package/dist/ui/ratatui/process.js +80 -7
- package/dist/ui/ratatui/protocol.d.ts +236 -1
- package/dist/ui/ratatui/protocol.js +90 -0
- package/dist/ui/scrollback.d.ts +2 -1
- package/dist/ui/scrollback.js +9 -4
- package/dist/ui/stream_typewriter.d.ts +8 -3
- package/dist/ui/stream_typewriter.js +30 -1
- package/dist/ui/streaming_scrollback.d.ts +1 -0
- package/dist/ui/streaming_scrollback.js +1 -1
- package/dist/ui/transcript_render_cache.js +10 -0
- package/dist/ui/views/activity_line.d.ts +5 -3
- package/dist/ui/views/activity_line.js +65 -7
- package/dist/ui/views/app.d.ts +6 -3
- package/dist/ui/views/app.js +17 -6
- package/dist/ui/views/completion_menu.js +10 -5
- package/dist/ui/views/input_area.d.ts +7 -3
- package/dist/ui/views/input_area.js +15 -9
- package/dist/ui/views/message_list.d.ts +4 -1
- package/dist/ui/views/message_list.js +89 -19
- package/dist/ui/views/queue_panel.d.ts +3 -1
- package/dist/ui/views/queue_panel.js +9 -2
- package/dist/ui/views/status_bar.d.ts +4 -2
- package/dist/ui/views/status_bar.js +28 -13
- package/dist/ui/views/theme.d.ts +2 -0
- package/dist/ui/views/theme.js +2 -0
- package/dist/ui/widgets/color_panel.js +18 -0
- package/dist/ui/widgets/form.js +8 -0
- package/dist/ui/widgets/log_view.js +7 -0
- package/dist/ui/widgets/navigator_panel.js +8 -0
- package/dist/ui/widgets/prompt_viewer.js +2 -0
- package/dist/ui/widgets/questionnaire.d.ts +2 -0
- package/dist/ui/widgets/questionnaire.js +79 -16
- package/dist/ui/widgets/resume_panel.d.ts +2 -0
- package/dist/ui/widgets/resume_panel.js +26 -15
- package/dist/ui/widgets/rewind_panel.d.ts +2 -2
- package/dist/ui/widgets/rewind_panel.js +4 -2
- package/dist/ui/widgets/select.js +16 -27
- package/dist/ui/widgets/settings_panel.js +16 -0
- package/dist/ui/widgets/status_line_panel.d.ts +1 -0
- package/dist/ui/widgets/status_line_panel.js +30 -4
- package/dist/ui/widgets/text_input.d.ts +2 -0
- package/dist/ui/widgets/text_input.js +15 -1
- package/dist/ui/widgets/types.d.ts +2 -0
- package/dist/usage_projection.d.ts +24 -0
- package/dist/usage_projection.js +130 -0
- package/dist/usage_snapshot.d.ts +36 -0
- package/dist/usage_snapshot.js +131 -0
- package/dist/utils/assistant_message.d.ts +2 -0
- package/dist/utils/assistant_message.js +5 -0
- package/dist/utils/atomic_write.d.ts +6 -2
- package/dist/utils/atomic_write.js +29 -4
- package/dist/utils/checked_shell.d.ts +25 -0
- package/dist/utils/checked_shell.js +107 -0
- package/dist/utils/compaction.d.ts +4 -1
- package/dist/utils/compaction.js +31 -7
- package/dist/utils/context.d.ts +4 -4
- package/dist/utils/context.js +14 -12
- package/dist/utils/deepseek.d.ts +2 -2
- package/dist/utils/deepseek.js +13 -5
- package/dist/utils/ephemeral.js +4 -0
- package/dist/utils/ephemeral_tools.d.ts +18 -0
- package/dist/utils/ephemeral_tools.js +97 -0
- package/dist/utils/jev_client.d.ts +4 -0
- package/dist/utils/jev_client.js +15 -0
- package/dist/utils/model_cache.d.ts +15 -0
- package/dist/utils/model_cache.js +143 -0
- package/dist/utils/models.d.ts +4 -2
- package/dist/utils/models.js +12 -16
- package/dist/utils/reasoning.d.ts +8 -1
- package/dist/utils/reasoning.js +31 -11
- package/dist/utils/router_catalog.d.ts +49 -0
- package/dist/utils/router_catalog.js +271 -0
- package/dist/utils/sandbox.d.ts +9 -0
- package/dist/utils/sandbox.js +118 -15
- package/dist/utils/shell.d.ts +7 -0
- package/dist/utils/shell.js +98 -34
- package/dist/utils/subprocess_env.d.ts +3 -0
- package/dist/utils/subprocess_env.js +27 -1
- package/dist/web/accounts_mirror.d.ts +3 -1
- package/dist/web/accounts_mirror.js +13 -9
- package/dist/web/child_publication.d.ts +17 -0
- package/dist/web/child_publication.js +45 -0
- package/dist/web/mirror_authenticator.d.ts +31 -11
- package/dist/web/mirror_authenticator.js +67 -17
- package/dist/web/mirror_client.d.ts +31 -4
- package/dist/web/mirror_client.js +189 -23
- package/dist/web/mirror_stream.d.ts +84 -22
- package/dist/web/mirror_stream.js +676 -95
- package/dist/web/observer_query_redaction.d.ts +6 -0
- package/dist/web/observer_query_redaction.js +58 -0
- package/dist/web/pane_registry.d.ts +2 -0
- package/dist/web/pane_registry.js +86 -22
- package/dist/web/tool_image.d.ts +6 -0
- package/dist/web/tool_image.js +17 -0
- package/dist/web/view_plugin.d.ts +14 -0
- package/dist/web/view_plugin.js +23 -1
- package/dist/worker/executor.js +31 -12
- package/dist/worker/index.d.ts +1 -0
- package/dist/worker/toolsets.js +3 -1
- package/dist/worker/types.d.ts +12 -1
- package/dist/workflows/registry.js +1 -0
- package/dist/workflows/registry_handle.d.ts +2 -0
- package/dist/workflows/runtime.d.ts +2 -0
- package/dist/workflows/runtime.js +1 -0
- package/dist/workspace_agent.d.ts +7 -0
- package/dist/workspace_agent.js +36 -0
- package/dist/workspace_collision.d.ts +76 -0
- package/dist/workspace_collision.js +688 -0
- package/dist/workspace_layout.d.ts +18 -0
- package/dist/workspace_layout.js +121 -0
- package/dist/workspace_runtime.d.ts +44 -0
- package/dist/workspace_runtime.js +82 -0
- package/dist/workspace_session_context.d.ts +62 -0
- package/dist/workspace_session_context.js +160 -0
- package/dist/zlm-embed.mjs +32518 -9615
- package/dist/zlm.js +1 -0
- package/node_modules/@zerg/model-contracts/LICENSE.md +375 -0
- package/node_modules/@zerg/model-contracts/README.md +90 -0
- package/node_modules/@zerg/model-contracts/index.d.ts +20 -0
- package/node_modules/@zerg/model-contracts/index.js +223 -0
- package/node_modules/@zerg/model-contracts/package.json +8 -0
- package/node_modules/glob/node_modules/brace-expansion/index.js +78 -22
- package/node_modules/glob/node_modules/brace-expansion/package.json +1 -1
- package/node_modules/readdir-glob/node_modules/brace-expansion/index.js +78 -22
- package/node_modules/readdir-glob/node_modules/brace-expansion/package.json +1 -1
- package/package.json +45 -24
- package/packages/model-contracts/LICENSE.md +375 -0
- package/packages/model-contracts/README.md +90 -0
- package/packages/model-contracts/index.d.ts +20 -0
- package/packages/model-contracts/index.js +223 -0
- package/packages/model-contracts/package.json +8 -0
- package/remote-broker/Dockerfile +10 -0
- package/remote-broker/README.md +308 -0
- package/remote-broker/archive.py +1227 -0
- package/remote-broker/cutover.py +761 -0
- package/remote-broker/requirements.txt +5 -0
- package/remote-broker/resources.example.json +6 -0
- package/remote-broker/resources.write-staging.example.json +18 -0
- package/remote-broker/retained.py +686 -0
- package/remote-broker/retained_cleanup.py +550 -0
- package/remote-broker/server.py +648 -0
- package/scripts/build-remote-broker.mjs +13 -0
- package/scripts/ensure-local-packages.mjs +6 -0
- package/scripts/node-pty-helpers.mjs +103 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Tool } from '../tools/types.js';
|
|
2
|
+
import { type RemoteBrokerConfiguration } from './remote_broker_transport.js';
|
|
3
|
+
export { RemoteResourceRejectedError } from './remote_resource_errors.js';
|
|
4
|
+
export interface RemoteResource {
|
|
5
|
+
id: string;
|
|
6
|
+
host: string;
|
|
7
|
+
user: string;
|
|
8
|
+
port?: number;
|
|
9
|
+
root: string;
|
|
10
|
+
broker?: RemoteBrokerConfiguration;
|
|
11
|
+
}
|
|
12
|
+
/** Host-only process boundary. Model arguments cannot replace the transport. */
|
|
13
|
+
export type RemoteResourceTransport = (resource: Readonly<RemoteResource>, request: Readonly<Record<string, unknown>>, signal?: AbortSignal) => Promise<unknown>;
|
|
14
|
+
export interface RemoteResourceSession {
|
|
15
|
+
ownerId: string;
|
|
16
|
+
resources: readonly RemoteResource[];
|
|
17
|
+
transport?: RemoteResourceTransport;
|
|
18
|
+
/** Host-only durable journal location; never accepted from model arguments. */
|
|
19
|
+
journalDirectory?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function remoteResourceOwnerId(sessionId: string): string;
|
|
22
|
+
/** A session's guard remains active through agent reloads and queued messages. */
|
|
23
|
+
export declare function guardedRemoteSession(sessionId: string, resources?: readonly RemoteResource[], transport?: RemoteResourceTransport, journalDirectory?: string): RemoteResourceSession | undefined;
|
|
24
|
+
/** Legacy entry point retained to refuse unsafe callers explicitly. */
|
|
25
|
+
export declare const sshRemoteResourceTransport: RemoteResourceTransport;
|
|
26
|
+
export declare function requestRemoteResource(session: RemoteResourceSession, resourceId: string, operation: string, args?: Record<string, unknown>, signal?: AbortSignal): Promise<unknown>;
|
|
27
|
+
export declare function createRemoteResourceTool(session: RemoteResourceSession): Tool;
|
|
28
|
+
/** Object identity prevents a plugin or alias from spoofing the broker's name. */
|
|
29
|
+
export declare function isManagedRemoteResourceTool(tool: Tool, session: RemoteResourceSession): boolean;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { isIP } from 'node:net';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { posix } from 'node:path';
|
|
4
|
+
import { ToolCapability } from './capabilities.js';
|
|
5
|
+
import { remoteResourceEndpoint } from './remote_resource_endpoint.js';
|
|
6
|
+
import { makeRemoteBrokerTransport } from './remote_broker_transport.js';
|
|
7
|
+
import { RemoteResourceRejectedError } from './remote_resource_errors.js';
|
|
8
|
+
import { reserveUserSubprocessCredentials } from '../../utils/subprocess_env.js';
|
|
9
|
+
export { RemoteResourceRejectedError } from './remote_resource_errors.js';
|
|
10
|
+
import { admitRemoteMutation, findRemoteMutation, pendingRemoteMutations, remoteMutationJournalDirectory, resolveRemoteMutation } from './remote_mutation_journal.js';
|
|
11
|
+
const identities = new Map();
|
|
12
|
+
const sessions = new Map();
|
|
13
|
+
const managedTools = new WeakMap();
|
|
14
|
+
export function remoteResourceOwnerId(sessionId) {
|
|
15
|
+
let id = identities.get(sessionId);
|
|
16
|
+
if (!id) {
|
|
17
|
+
id = randomUUID();
|
|
18
|
+
identities.set(sessionId, id);
|
|
19
|
+
}
|
|
20
|
+
return id;
|
|
21
|
+
}
|
|
22
|
+
/** A session's guard remains active through agent reloads and queued messages. */
|
|
23
|
+
export function guardedRemoteSession(sessionId, resources, transport, journalDirectory) {
|
|
24
|
+
const existing = sessions.get(sessionId);
|
|
25
|
+
if (existing)
|
|
26
|
+
return existing;
|
|
27
|
+
if (resources === undefined)
|
|
28
|
+
return undefined;
|
|
29
|
+
if (!Array.isArray(resources))
|
|
30
|
+
throw new Error('Guarded remote resources must be an array');
|
|
31
|
+
if (resources.length > 100)
|
|
32
|
+
throw new Error('At most 100 guarded remote resources may be configured');
|
|
33
|
+
const copy = resources.map(resource => Object.freeze({ ...resource, ...(resource.broker ? { broker: Object.freeze({ ...resource.broker }) } : {}) }));
|
|
34
|
+
for (const resource of copy)
|
|
35
|
+
validateResource(resource);
|
|
36
|
+
if (new Set(copy.map(resource => resource.id)).size !== copy.length)
|
|
37
|
+
throw new Error('Remote resource IDs must be unique');
|
|
38
|
+
reserveUserSubprocessCredentials(copy.flatMap(resource => resource.broker ? [resource.broker.tokenEnv] : []));
|
|
39
|
+
const ownerId = remoteResourceOwnerId(sessionId);
|
|
40
|
+
const directory = remoteMutationJournalDirectory({ ownerId, resources: copy, journalDirectory });
|
|
41
|
+
const session = Object.freeze({ ownerId, resources: Object.freeze(copy), transport, journalDirectory: directory });
|
|
42
|
+
sessions.set(sessionId, session);
|
|
43
|
+
return session;
|
|
44
|
+
}
|
|
45
|
+
function validateResource(resource) {
|
|
46
|
+
if (typeof resource.id !== 'string' || typeof resource.host !== 'string' || typeof resource.user !== 'string' || typeof resource.root !== 'string'
|
|
47
|
+
|| !resource.id || resource.id.length > 100 || !/^[a-zA-Z0-9._:-]+$/.test(resource.id)
|
|
48
|
+
|| (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(resource.host) && isIP(resource.host) !== 6)
|
|
49
|
+
|| !/^[a-zA-Z0-9_][a-zA-Z0-9._-]*$/.test(resource.user)
|
|
50
|
+
|| !resource.root.startsWith('/') || resource.root.includes('\0')
|
|
51
|
+
|| (resource.port !== undefined && (!Number.isSafeInteger(resource.port) || resource.port < 1 || resource.port > 65535))) {
|
|
52
|
+
throw new Error('Invalid host-managed remote resource configuration');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Legacy entry point retained to refuse unsafe callers explicitly. */
|
|
56
|
+
export const sshRemoteResourceTransport = async () => {
|
|
57
|
+
throw new Error('Legacy SSH execution is unavailable in guarded sessions; configure an immutable RPC broker');
|
|
58
|
+
};
|
|
59
|
+
export async function requestRemoteResource(session, resourceId, operation, args = {}, signal) {
|
|
60
|
+
const resource = session.resources.find(candidate => candidate.id === resourceId);
|
|
61
|
+
if (!resource)
|
|
62
|
+
throw new Error(`Unknown host-managed resource: ${resourceId}`);
|
|
63
|
+
validateResource(resource);
|
|
64
|
+
const transport = session.transport ?? makeRemoteBrokerTransport(resource);
|
|
65
|
+
// Authority, IDs and durable linkage come from the host, after model arguments.
|
|
66
|
+
const mutation = (operation === 'delete' || operation === 'write') && args.dry_run !== true
|
|
67
|
+
? admitRemoteMutation(session, resource, operation, args) : undefined;
|
|
68
|
+
const operationId = mutation?.id ?? (operation === 'delete' ? randomUUID() : undefined);
|
|
69
|
+
const bound = { client_journal: remoteMutationJournalDirectory(session), root: resource.root, owner_id: session.ownerId, resource_id: resource.id,
|
|
70
|
+
endpoint: remoteResourceEndpoint(resource) };
|
|
71
|
+
const local = ['reconcile', 'resolve', 'receipt'].includes(operation) && typeof args.receipt_id === 'string'
|
|
72
|
+
? findRemoteMutation(session, args.receipt_id) : undefined;
|
|
73
|
+
if (local && operation !== 'receipt' && (local.endpoint.host !== resource.host || local.endpoint.user !== resource.user || local.endpoint.port !== remoteResourceEndpoint(resource).port
|
|
74
|
+
|| local.resource_id !== resource.id || local.target !== posix.resolve(resource.root, local.requested_path)))
|
|
75
|
+
throw new Error('Operation does not belong to this configured endpoint and root');
|
|
76
|
+
let dispatchReturned = false;
|
|
77
|
+
try {
|
|
78
|
+
const result = await transport(resource, { ...args, ...(local ? { path: local.requested_path, original_operation: local.operation, original_owner_id: local.owner_id, original_tool_call_id: local.tool_call_id } : {}), ...bound, operation,
|
|
79
|
+
...(operationId ? { operation_id: operationId } : {}) }, signal);
|
|
80
|
+
dispatchReturned = true;
|
|
81
|
+
if (operationId || operation === 'receipt') {
|
|
82
|
+
const receipt = result?.receipt;
|
|
83
|
+
const endpoint = receipt?.endpoint;
|
|
84
|
+
if (!receipt || receipt.version !== 1 || !['delete', 'write'].includes(String(receipt.operation))
|
|
85
|
+
|| (local && receipt.operation !== local.operation)
|
|
86
|
+
|| receipt.id !== (operationId ?? args.receipt_id) || receipt.owner_id !== session.ownerId
|
|
87
|
+
|| receipt.resource_id !== resource.id || receipt.configured_root !== resource.root
|
|
88
|
+
|| endpoint?.host !== resource.host || endpoint?.user !== resource.user || endpoint?.port !== remoteResourceEndpoint(resource).port
|
|
89
|
+
|| (operationId && (receipt.operation !== operation || receipt.requested_path !== (args.path ?? '.') || receipt.tool_call_id !== (args.tool_call_id ?? null)))) {
|
|
90
|
+
throw new Error('Remote deletion receipt does not match the exact host request');
|
|
91
|
+
}
|
|
92
|
+
if (mutation && ['verified', 'failed'].includes(String(receipt.status))) {
|
|
93
|
+
const acknowledged = await transport(resource, { ...bound, operation: 'ack', receipt_id: operationId }, signal);
|
|
94
|
+
if (acknowledged.receipt?.id !== mutation.id || acknowledged.receipt.admission_resolved !== true)
|
|
95
|
+
throw new Error('Remote acknowledgement does not match the mutation');
|
|
96
|
+
receipt.admission_resolved = true;
|
|
97
|
+
resolveRemoteMutation(session, mutation.id);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (operation === 'status') {
|
|
101
|
+
const status = result;
|
|
102
|
+
try {
|
|
103
|
+
const pending = pendingRemoteMutations(session, resource);
|
|
104
|
+
status.local_pending_operations = pending.operations;
|
|
105
|
+
status.local_pending_operation_count = pending.count;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
status.local_mutation_journal_error = error.message;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (operation === 'resolve') {
|
|
112
|
+
const resolved = result;
|
|
113
|
+
if (!resolved || !resolved.receipt || resolved.receipt.id !== args.receipt_id || resolved.receipt.admission_resolved !== true
|
|
114
|
+
|| resolved.observation?.receipt_id !== args.receipt_id || resolved.observation_token !== args.observation_token
|
|
115
|
+
|| resolved.decision !== 'accept_current_state')
|
|
116
|
+
throw new Error('Remote reconciliation does not match the confirmed operation and observation');
|
|
117
|
+
resolveRemoteMutation(session, String(args.receipt_id));
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (mutation && !dispatchReturned && error instanceof RemoteResourceRejectedError && error.operationId === mutation.id) {
|
|
123
|
+
resolveRemoteMutation(session, mutation.id, 'not_dispatched');
|
|
124
|
+
throw new Error(`Remote mutation rejected before effect; operation ${mutation.id}. ${error.message}`);
|
|
125
|
+
}
|
|
126
|
+
if (operationId)
|
|
127
|
+
throw new Error(`Remote ${operation === 'delete' ? 'deletion' : 'mutation'} outcome unresolved; operation ${operationId}. Inspect its receipt and reconcile through /resources before retrying. ${error.message}`);
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export function createRemoteResourceTool(session) {
|
|
132
|
+
reserveUserSubprocessCredentials(session.resources.flatMap(resource => resource.broker ? [resource.broker.tokenEnv] : []));
|
|
133
|
+
const tool = {
|
|
134
|
+
capabilities: [ToolCapability.NETWORK, ToolCapability.FILE_READ, ToolCapability.FILE_WRITE],
|
|
135
|
+
effect: 'external',
|
|
136
|
+
definition: {
|
|
137
|
+
name: 'remote_resource',
|
|
138
|
+
description: 'Operate on a host-configured remote resource under its required lease. Status shows your host-assigned owner label and the current owner. Labels identify cooperative host sessions; the bearer credential authenticates the host, not individual owners. Ask the user to claim or transfer through /resources. Arbitrary remote commands are unavailable. Use dry_run before mutation; deletion removes a file or empty directory only. Deletion returns a durable receipt with verified target state. Removed logical bytes do not establish reclaimed quota or free space; attribution is unknown without measurement. Unresolved writes and deletions fence overlapping targets. Inspect receipt after any unresolved result; ask the user to reconcile through /resources. Never retry mutations automatically.',
|
|
139
|
+
parameters: { type: 'object', properties: {
|
|
140
|
+
resource: { type: 'string', description: 'Host-configured resource ID', enum: session.resources.map(resource => resource.id) },
|
|
141
|
+
operation: { type: 'string', description: 'Bounded filesystem operation', enum: ['status', 'read', 'list', 'stat', 'write', 'delete', 'receipt'] },
|
|
142
|
+
path: { type: 'string', description: 'Path relative to the configured remote root' },
|
|
143
|
+
receipt_id: { type: 'string', description: 'Exact operation UUID to inspect after an interrupted or uncertain deletion' },
|
|
144
|
+
content: { type: 'string', description: 'UTF-8 text for a write' }, dry_run: { type: 'boolean', description: 'Validate ownership and target without changing the target' },
|
|
145
|
+
}, required: ['resource', 'operation'] },
|
|
146
|
+
},
|
|
147
|
+
execute: async (args, context) => {
|
|
148
|
+
const operation = String(args.operation);
|
|
149
|
+
if (!['status', 'read', 'list', 'stat', 'write', 'delete', 'receipt'].includes(operation))
|
|
150
|
+
throw new Error('Lease control requires a confirmed user /resources command');
|
|
151
|
+
const result = await requestRemoteResource(session, String(args.resource), operation, { path: args.path ?? '.', content: args.content, dry_run: args.dry_run ?? false,
|
|
152
|
+
receipt_id: args.receipt_id, tool_call_id: context?.toolCallId }, context?.signal);
|
|
153
|
+
return JSON.stringify({ resource: args.resource, requesting_owner_id: session.ownerId, result });
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
managedTools.set(tool, session);
|
|
157
|
+
return tool;
|
|
158
|
+
}
|
|
159
|
+
/** Object identity prevents a plugin or alias from spoofing the broker's name. */
|
|
160
|
+
export function isManagedRemoteResourceTool(tool, session) { return managedTools.get(tool) === session; }
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CommandVerificationReceipt, type CurrentVerificationProjection, type SourceSnapshot, type VerificationRequest } from './source_verification_contract.js';
|
|
2
|
+
export type SourceInspectionGate = (source: SourceSnapshot) => boolean | Promise<boolean>;
|
|
3
|
+
export declare const SOURCE_FILE_MAX_BYTES: number;
|
|
4
|
+
export declare const SOURCE_CAPTURE_MAX_BYTES: number;
|
|
5
|
+
/** Capture only declared files. This is a sequence of bounded observations, not an atomic input snapshot. */
|
|
6
|
+
export declare function captureSourceSnapshot(cwd: string, sourcePaths: readonly string[], options?: {
|
|
7
|
+
includeGit?: boolean;
|
|
8
|
+
}): Promise<SourceSnapshot>;
|
|
9
|
+
export declare function createCommandVerification(request: VerificationRequest, cwd: string, command: string, kind: CommandVerificationReceipt['command_kind']): Promise<CommandVerificationReceipt>;
|
|
10
|
+
export declare function finishCommandVerification(receipt: CommandVerificationReceipt, outcome: CommandVerificationReceipt['process_outcome'], canInspectSource?: SourceInspectionGate): Promise<CommandVerificationReceipt>;
|
|
11
|
+
/** Current applicability is a fresh projection; never replace the original or terminal source capture. */
|
|
12
|
+
export declare function projectCurrentVerification(receipt: CommandVerificationReceipt, canInspectSource?: SourceInspectionGate): Promise<CurrentVerificationProjection>;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
3
|
+
import { constants } from 'node:fs';
|
|
4
|
+
import { lstat, open, realpath } from 'node:fs/promises';
|
|
5
|
+
import { dirname, isAbsolute, relative, resolve } from 'node:path';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { canonicalSourceContent, canonicalSourceIdentity, parseCommandVerificationReceipt, parseSourceSnapshot, SOURCE_SNAPSHOT_MAX_BYTES } from './source_verification_contract.js';
|
|
8
|
+
export const SOURCE_FILE_MAX_BYTES = 2 * 1024 * 1024;
|
|
9
|
+
export const SOURCE_CAPTURE_MAX_BYTES = 8 * 1024 * 1024;
|
|
10
|
+
const exec = promisify(execFile);
|
|
11
|
+
const digest = (text) => createHash('sha256').update(text).digest('hex');
|
|
12
|
+
const within = (root, path) => {
|
|
13
|
+
const suffix = relative(root, path);
|
|
14
|
+
return !isAbsolute(suffix) && suffix !== '..' && !suffix.startsWith(`..${process.platform === 'win32' ? '\\' : '/'}`);
|
|
15
|
+
};
|
|
16
|
+
/** Resolve the nearest existing ancestor too: a missing leaf cannot hide an escaped parent. */
|
|
17
|
+
async function assertScopedLocation(root, path) {
|
|
18
|
+
let probe = path;
|
|
19
|
+
while (true) {
|
|
20
|
+
try {
|
|
21
|
+
const resolved = await realpath(probe);
|
|
22
|
+
if (!within(root, resolved))
|
|
23
|
+
throw new Error('Source verification path escapes its working directory');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const code = error.code;
|
|
28
|
+
if (code === 'ELOOP' || code === 'EACCES' || code === 'EPERM')
|
|
29
|
+
return;
|
|
30
|
+
if (code !== 'ENOENT' && code !== 'ENOTDIR')
|
|
31
|
+
throw error;
|
|
32
|
+
const parent = dirname(probe);
|
|
33
|
+
if (parent === probe)
|
|
34
|
+
throw new Error('Source verification working directory is unavailable');
|
|
35
|
+
probe = parent;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function gitIdentity(cwd) {
|
|
40
|
+
// Read-only Git probes are bounded process-boundary observations, never shell text.
|
|
41
|
+
try {
|
|
42
|
+
const env = { ...process.env, GIT_OPTIONAL_LOCKS: '0' };
|
|
43
|
+
for (const key of ['GIT_DIR', 'GIT_WORK_TREE', 'GIT_INDEX_FILE', 'GIT_OBJECT_DIRECTORY', 'GIT_ALTERNATE_OBJECT_DIRECTORIES'])
|
|
44
|
+
delete env[key];
|
|
45
|
+
const options = { cwd, timeout: 2000, maxBuffer: 256 * 1024, encoding: 'utf8',
|
|
46
|
+
env };
|
|
47
|
+
const [head, status] = await Promise.all([
|
|
48
|
+
exec('git', ['rev-parse', '--verify', 'HEAD'], options),
|
|
49
|
+
exec('git', ['-c', 'core.fsmonitor=false', 'status', '--porcelain=v1', '--untracked-files=normal'], options),
|
|
50
|
+
]);
|
|
51
|
+
const commit = head.stdout.trim();
|
|
52
|
+
return { commit: /^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(commit) ? commit : null, dirty: status.stdout.length > 0 };
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return { commit: null, dirty: null };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function sealSnapshot(snapshot) {
|
|
59
|
+
const content = canonicalSourceContent(snapshot);
|
|
60
|
+
if (content === null)
|
|
61
|
+
throw new Error('Source verification snapshot is invalid');
|
|
62
|
+
snapshot.content_sha256 = digest(content);
|
|
63
|
+
const identity = canonicalSourceIdentity(snapshot);
|
|
64
|
+
if (identity === null)
|
|
65
|
+
throw new Error('Source verification identity is invalid');
|
|
66
|
+
snapshot.source_id = digest(identity);
|
|
67
|
+
const parsed = parseSourceSnapshot(snapshot);
|
|
68
|
+
if (parsed === null)
|
|
69
|
+
throw new Error('Source verification snapshot exceeds its metadata bound');
|
|
70
|
+
return parsed;
|
|
71
|
+
}
|
|
72
|
+
/** Capture only declared files. This is a sequence of bounded observations, not an atomic input snapshot. */
|
|
73
|
+
export async function captureSourceSnapshot(cwd, sourcePaths, options = {}) {
|
|
74
|
+
const root = await realpath(resolve(cwd));
|
|
75
|
+
const paths = [...sourcePaths].sort();
|
|
76
|
+
if (paths.length < 1 || paths.length > 64 || new Set(paths).size !== paths.length
|
|
77
|
+
|| paths.some(path => !path || Buffer.byteLength(path) > 512 || /[\\\u0000-\u001f\u007f]/u.test(path) || /^[A-Za-z]:/.test(path)
|
|
78
|
+
|| path.split('/').some(part => !part || part === '.' || part === '..'))) {
|
|
79
|
+
throw new Error('Source verification requires 1–64 unique relative scoped file paths');
|
|
80
|
+
}
|
|
81
|
+
// Admit worst-case endpoint metadata before execution; later file changes cannot grow an unrepresentable receipt.
|
|
82
|
+
const worst = { schema_version: 1, source_id: 'f'.repeat(64), content_sha256: 'f'.repeat(64), cwd: root,
|
|
83
|
+
origin: 'local', captured_at: new Date().toISOString(), git: { commit: 'f'.repeat(64), dirty: false },
|
|
84
|
+
coverage: 'incomplete', files: paths.map(path => ({ path, kind: 'unavailable', sha256: 'f'.repeat(64),
|
|
85
|
+
bytes: Number.MAX_SAFE_INTEGER, mode: 4095 })), reason: 'x'.repeat(512) };
|
|
86
|
+
if (Buffer.byteLength(JSON.stringify(worst)) > SOURCE_SNAPSHOT_MAX_BYTES) {
|
|
87
|
+
throw new Error('Source verification snapshot metadata exceeds 16KiB; narrow source_paths');
|
|
88
|
+
}
|
|
89
|
+
for (const path of paths)
|
|
90
|
+
await assertScopedLocation(root, resolve(root, path));
|
|
91
|
+
const files = [];
|
|
92
|
+
let remaining = SOURCE_CAPTURE_MAX_BYTES;
|
|
93
|
+
for (const path of paths) {
|
|
94
|
+
const absolute = resolve(root, path);
|
|
95
|
+
let row = { path, kind: 'unavailable', sha256: null, bytes: 0, mode: 0 };
|
|
96
|
+
try {
|
|
97
|
+
await assertScopedLocation(root, absolute);
|
|
98
|
+
const stat = await lstat(absolute);
|
|
99
|
+
row.bytes = Number.isSafeInteger(stat.size) && stat.size >= 0 ? stat.size : 0;
|
|
100
|
+
row.mode = stat.mode & 0o7777;
|
|
101
|
+
// Symlink leaves are explicitly incomplete even when their target is inside the root.
|
|
102
|
+
if (stat.isFile() && stat.size <= SOURCE_FILE_MAX_BYTES && stat.size <= remaining) {
|
|
103
|
+
const handle = await open(absolute, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
104
|
+
try {
|
|
105
|
+
const before = await handle.stat();
|
|
106
|
+
if (before.isFile() && before.size === stat.size && before.dev === stat.dev && before.ino === stat.ino) {
|
|
107
|
+
const hash = createHash('sha256');
|
|
108
|
+
const buffer = Buffer.alloc(Math.min(65536, Math.max(1, before.size)));
|
|
109
|
+
let count = 0;
|
|
110
|
+
while (count < before.size) {
|
|
111
|
+
const read = await handle.read(buffer, 0, Math.min(buffer.length, before.size - count), count);
|
|
112
|
+
if (read.bytesRead === 0)
|
|
113
|
+
break;
|
|
114
|
+
hash.update(buffer.subarray(0, read.bytesRead));
|
|
115
|
+
count += read.bytesRead;
|
|
116
|
+
remaining -= read.bytesRead;
|
|
117
|
+
}
|
|
118
|
+
const after = await handle.stat();
|
|
119
|
+
if (count === before.size && after.size === before.size && after.mtimeMs === before.mtimeMs
|
|
120
|
+
&& after.ctimeMs === before.ctimeMs)
|
|
121
|
+
row = { ...row, kind: 'file', sha256: hash.digest('hex') };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
await handle.close();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (error.message.includes('escapes its working directory'))
|
|
131
|
+
throw error;
|
|
132
|
+
if (error.code === 'ENOENT')
|
|
133
|
+
row = { path, kind: 'missing', sha256: null, bytes: 0, mode: 0 };
|
|
134
|
+
}
|
|
135
|
+
files.push(row);
|
|
136
|
+
}
|
|
137
|
+
const incomplete = files.some(file => file.kind !== 'file');
|
|
138
|
+
return sealSnapshot({ schema_version: 1, source_id: '0'.repeat(64), content_sha256: '0'.repeat(64), cwd: root,
|
|
139
|
+
origin: 'local', captured_at: new Date().toISOString(),
|
|
140
|
+
git: options.includeGit === false ? { commit: null, dirty: null } : await gitIdentity(root),
|
|
141
|
+
coverage: incomplete ? 'incomplete' : 'complete', files,
|
|
142
|
+
...(incomplete ? { reason: 'Some scoped inputs were missing, unavailable, changed while read, or exceeded the capture budget.' } : {}) });
|
|
143
|
+
}
|
|
144
|
+
export async function createCommandVerification(request, cwd, command, kind) {
|
|
145
|
+
const source = await captureSourceSnapshot(cwd, request.source_paths);
|
|
146
|
+
const receipt = { schema_version: 1, receipt_id: randomUUID(), source, end_source: null,
|
|
147
|
+
purpose: request.purpose, scope: request.scope, command_sha256: digest(command), command_kind: kind,
|
|
148
|
+
environment: { platform: process.platform, arch: process.arch, node_version: process.version, declared_id: request.environment_id ?? null },
|
|
149
|
+
build_identity: request.build_identity ?? null, instrumentation: request.instrumentation,
|
|
150
|
+
process_outcome: 'running', source_binding: 'unknown', qualification: 'unverified', artifact_refs: [] };
|
|
151
|
+
const parsed = parseCommandVerificationReceipt(receipt);
|
|
152
|
+
if (parsed === null)
|
|
153
|
+
throw new Error('Source verification receipt exceeds its metadata bound');
|
|
154
|
+
return parsed;
|
|
155
|
+
}
|
|
156
|
+
export async function finishCommandVerification(receipt, outcome, canInspectSource) {
|
|
157
|
+
let end;
|
|
158
|
+
try {
|
|
159
|
+
if (canInspectSource && !await canInspectSource(receipt.source))
|
|
160
|
+
throw new Error('Source inspection permission denied');
|
|
161
|
+
end = await captureSourceSnapshot(receipt.source.cwd, receipt.source.files.map(file => file.path));
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
end = sealSnapshot({ ...structuredClone(receipt.source), captured_at: new Date().toISOString(),
|
|
165
|
+
coverage: 'incomplete', git: { commit: null, dirty: null },
|
|
166
|
+
files: receipt.source.files.map(file => ({ path: file.path, kind: 'unavailable', sha256: null, bytes: 0, mode: 0 })),
|
|
167
|
+
reason: 'The terminal scoped source capture was unavailable or source read permission was denied.' });
|
|
168
|
+
}
|
|
169
|
+
const value = { ...structuredClone(receipt), end_source: end, process_outcome: outcome,
|
|
170
|
+
source_binding: receipt.source.origin === 'local' && receipt.source.coverage === 'complete' && end.coverage === 'complete'
|
|
171
|
+
&& end.source_id === receipt.source.source_id && outcome !== 'running' ? 'observed_endpoints' : 'unknown' };
|
|
172
|
+
const parsed = parseCommandVerificationReceipt(value);
|
|
173
|
+
if (parsed === null)
|
|
174
|
+
throw new Error('The terminal source verification receipt is invalid');
|
|
175
|
+
return parsed;
|
|
176
|
+
}
|
|
177
|
+
/** Current applicability is a fresh projection; never replace the original or terminal source capture. */
|
|
178
|
+
export async function projectCurrentVerification(receipt, canInspectSource) {
|
|
179
|
+
const base = { receipt_id: receipt.receipt_id, checked_at: new Date().toISOString() };
|
|
180
|
+
if (receipt.source.origin !== 'local')
|
|
181
|
+
return { ...base, source_id: null, applicability: 'unknown',
|
|
182
|
+
reason: 'External reported source and artifacts cannot establish current local source applicability.' };
|
|
183
|
+
if (canInspectSource) {
|
|
184
|
+
let admitted = false;
|
|
185
|
+
try {
|
|
186
|
+
admitted = await canInspectSource(receipt.source);
|
|
187
|
+
}
|
|
188
|
+
catch { /* A failed admission cannot authorize a file read. */ }
|
|
189
|
+
if (!admitted)
|
|
190
|
+
return { ...base, source_id: null, applicability: 'unknown', reason: 'Current scoped source read permission was denied.' };
|
|
191
|
+
}
|
|
192
|
+
let current;
|
|
193
|
+
try {
|
|
194
|
+
current = await captureSourceSnapshot(receipt.source.cwd, receipt.source.files.map(file => file.path), { includeGit: false });
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
return { ...base, source_id: null, applicability: 'unknown', reason: 'Current scoped source is unavailable.' };
|
|
198
|
+
}
|
|
199
|
+
if (receipt.source.coverage !== 'complete' || current.coverage !== 'complete')
|
|
200
|
+
return { ...base,
|
|
201
|
+
source_id: current.source_id, applicability: 'unknown', reason: 'The original or current scoped capture is incomplete.' };
|
|
202
|
+
if (current.content_sha256 !== receipt.source.content_sha256)
|
|
203
|
+
return { ...base, source_id: current.source_id,
|
|
204
|
+
applicability: 'stale', reason: 'Current scoped source differs from the original command source observation; it is unverified by this result.' };
|
|
205
|
+
if (receipt.process_outcome !== 'running' && receipt.source_binding !== 'observed_endpoints')
|
|
206
|
+
return { ...base,
|
|
207
|
+
source_id: current.source_id, applicability: 'unknown', reason: 'Scoped bytes now match, but terminal input binding was not established.' };
|
|
208
|
+
return { ...base, source_id: current.source_id, applicability: 'current',
|
|
209
|
+
reason: 'Scoped bytes match the captured observation. Endpoint samples do not prove immutable execution or semantic qualification.' };
|
|
210
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** Scoped byte observations and process outcomes never establish semantic qualification. */
|
|
2
|
+
export interface VerificationRequest {
|
|
3
|
+
purpose: 'compile' | 'test' | 'benchmark' | 'qualification';
|
|
4
|
+
scope: string;
|
|
5
|
+
source_paths: string[];
|
|
6
|
+
environment_id?: string;
|
|
7
|
+
build_identity?: string;
|
|
8
|
+
instrumentation: 'production' | 'diagnostic' | 'unknown';
|
|
9
|
+
}
|
|
10
|
+
export interface SourceSnapshot {
|
|
11
|
+
schema_version: 1;
|
|
12
|
+
source_id: string;
|
|
13
|
+
content_sha256: string;
|
|
14
|
+
cwd: string;
|
|
15
|
+
origin: 'local' | 'external';
|
|
16
|
+
captured_at: string;
|
|
17
|
+
git: {
|
|
18
|
+
commit: string | null;
|
|
19
|
+
dirty: boolean | null;
|
|
20
|
+
};
|
|
21
|
+
coverage: 'complete' | 'incomplete';
|
|
22
|
+
files: {
|
|
23
|
+
path: string;
|
|
24
|
+
kind: 'file' | 'missing' | 'unavailable';
|
|
25
|
+
sha256: string | null;
|
|
26
|
+
bytes: number;
|
|
27
|
+
mode: number;
|
|
28
|
+
}[];
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface VerificationArtifactReference {
|
|
32
|
+
origin: 'local' | 'external';
|
|
33
|
+
path: string;
|
|
34
|
+
sha256: string;
|
|
35
|
+
source_observation_id?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface CommandVerificationReceipt {
|
|
38
|
+
schema_version: 1;
|
|
39
|
+
receipt_id: string;
|
|
40
|
+
source: SourceSnapshot;
|
|
41
|
+
end_source: SourceSnapshot | null;
|
|
42
|
+
purpose: VerificationRequest['purpose'];
|
|
43
|
+
scope: string;
|
|
44
|
+
command_sha256: string;
|
|
45
|
+
command_kind: 'shell' | 'checked' | 'host_verifier';
|
|
46
|
+
environment: {
|
|
47
|
+
platform: string;
|
|
48
|
+
arch: string;
|
|
49
|
+
node_version: string;
|
|
50
|
+
declared_id: string | null;
|
|
51
|
+
};
|
|
52
|
+
build_identity: string | null;
|
|
53
|
+
instrumentation: VerificationRequest['instrumentation'];
|
|
54
|
+
process_outcome: 'running' | 'passed' | 'failed' | 'timed_out' | 'cancelled' | 'interrupted' | 'unknown';
|
|
55
|
+
source_binding: 'observed_endpoints' | 'unknown';
|
|
56
|
+
qualification: 'unverified';
|
|
57
|
+
artifact_refs: VerificationArtifactReference[];
|
|
58
|
+
}
|
|
59
|
+
export interface CurrentVerificationProjection {
|
|
60
|
+
receipt_id: string;
|
|
61
|
+
checked_at: string;
|
|
62
|
+
source_id: string | null;
|
|
63
|
+
applicability: 'current' | 'stale' | 'unknown';
|
|
64
|
+
reason: string;
|
|
65
|
+
}
|
|
66
|
+
export declare const VERIFICATION_REQUEST_MAX_BYTES: number;
|
|
67
|
+
export declare const SOURCE_SNAPSHOT_MAX_BYTES: number;
|
|
68
|
+
export declare const VERIFICATION_RECEIPT_MAX_BYTES: number;
|
|
69
|
+
export declare function parseVerificationRequest(value: unknown): VerificationRequest | null;
|
|
70
|
+
export declare function parseSourceSnapshot(value: unknown): SourceSnapshot | null;
|
|
71
|
+
export declare function parseCommandVerificationReceipt(value: unknown): CommandVerificationReceipt | null;
|
|
72
|
+
export declare function parseCurrentVerificationProjection(value: unknown): CurrentVerificationProjection | null;
|
|
73
|
+
/** Canonical preimages, not digest verification. The host scanner hashes these observed fields. */
|
|
74
|
+
export declare function canonicalSourceContent(value: unknown): string | null;
|
|
75
|
+
export declare function canonicalSourceIdentity(value: unknown): string | null;
|