@gajae-code/coding-agent 0.13.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +215 -8
- package/README.md +2 -0
- package/bin/gajaessi.js +4 -0
- package/dist/types/async/job-manager.d.ts +55 -2
- package/dist/types/async/support.d.ts +14 -0
- package/dist/types/capability/mcp.d.ts +6 -0
- package/dist/types/capability/types.d.ts +6 -0
- package/dist/types/cli/accounts-cli.d.ts +19 -0
- package/dist/types/cli/args.d.ts +3 -0
- package/dist/types/cli/config-cli.d.ts +6 -0
- package/dist/types/cli/crash-cli.d.ts +10 -0
- package/dist/types/cli/customize-doctor.d.ts +145 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/mcp-cli.d.ts +11 -0
- package/dist/types/cli/notify-cli.d.ts +1 -1
- package/dist/types/cli/root-flags.d.ts +12 -0
- package/dist/types/cli/setup-cli.d.ts +3 -1
- package/dist/types/cli/skills-cli.d.ts +2 -1
- package/dist/types/cli/update-cli.d.ts +19 -1
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/commands/accounts.d.ts +40 -0
- package/dist/types/commands/crash.d.ts +24 -0
- package/dist/types/commands/customize.d.ts +22 -0
- package/dist/types/commands/daemon.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +6 -0
- package/dist/types/commands/setup.d.ts +6 -0
- package/dist/types/commands/skills.d.ts +6 -1
- package/dist/types/commands/update.d.ts +7 -0
- package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
- package/dist/types/config/config-schema-version.d.ts +10 -0
- package/dist/types/config/file-lock.d.ts +18 -0
- package/dist/types/config/model-profile-activation.d.ts +3 -1
- package/dist/types/config/model-registry.d.ts +10 -1
- package/dist/types/config/models-config-schema.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +73 -9
- package/dist/types/config/settings.d.ts +63 -0
- package/dist/types/config/skill-settings-defaults.d.ts +26 -0
- package/dist/types/config/task-delegation.d.ts +39 -0
- package/dist/types/config/update-channel.d.ts +10 -0
- package/dist/types/coordinator-mcp/server.d.ts +5 -1
- package/dist/types/crash/index-store.d.ts +87 -0
- package/dist/types/crash/nudge.d.ts +50 -0
- package/dist/types/crash/record-loader.d.ts +17 -0
- package/dist/types/crash/report.d.ts +134 -0
- package/dist/types/crash/sanitize.d.ts +25 -0
- package/dist/types/cursor.d.ts +13 -2
- package/dist/types/customization/import.d.ts +37 -0
- package/dist/types/customization/index.d.ts +4 -0
- package/dist/types/customization/inventory.d.ts +25 -0
- package/dist/types/customization/mutations.d.ts +32 -0
- package/dist/types/customization/types.d.ts +115 -0
- package/dist/types/daemon/control-types.d.ts +8 -1
- package/dist/types/daemon/operator-contract.d.ts +4 -4
- package/dist/types/discovery/claude.d.ts +39 -1
- package/dist/types/discovery/codex.d.ts +39 -1
- package/dist/types/discovery/index.d.ts +2 -0
- package/dist/types/discovery/mcp-compat.d.ts +30 -0
- package/dist/types/edit/renderer.d.ts +23 -0
- package/dist/types/extensibility/extensions/runner.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +21 -4
- package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
- package/dist/types/extensibility/hooks/loader.d.ts +19 -5
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
- package/dist/types/extensibility/skill-management.d.ts +107 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
- package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
- package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
- package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
- package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
- package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
- package/dist/types/hooks/events.d.ts +60 -0
- package/dist/types/hooks/normalize.d.ts +83 -0
- package/dist/types/hooks/skill-state.d.ts +9 -2
- package/dist/types/main.d.ts +2 -1
- package/dist/types/modes/acp/abort-scope.d.ts +13 -0
- package/dist/types/modes/acp/acp-agent.d.ts +7 -4
- package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
- package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
- package/dist/types/modes/components/customization/index.d.ts +1 -0
- package/dist/types/modes/components/dynamic-theme-text.d.ts +9 -0
- package/dist/types/modes/components/gajae-pet-widget.d.ts +6 -28
- package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
- package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
- package/dist/types/modes/components/oauth-selector.d.ts +10 -4
- package/dist/types/modes/components/pet-capability.d.ts +7 -21
- package/dist/types/modes/components/settings-selector.d.ts +5 -0
- package/dist/types/modes/components/status-line/gh.d.ts +6 -2
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
- package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/theme/defaults/index.d.ts +118 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
- package/dist/types/runtime-mcp/config.d.ts +9 -0
- package/dist/types/runtime-mcp/manager.d.ts +26 -1
- package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
- package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
- package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
- package/dist/types/runtime-mcp/protocol.d.ts +278 -0
- package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
- package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
- package/dist/types/runtime-mcp/types.d.ts +102 -10
- package/dist/types/sdk/acp/adapter.d.ts +26 -5
- package/dist/types/sdk/broker/broker.d.ts +3 -55
- package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
- package/dist/types/sdk/broker/session-index.d.ts +14 -5
- package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
- package/dist/types/sdk/bus/config.d.ts +11 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
- package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
- package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
- package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
- package/dist/types/sdk/bus/index.d.ts +85 -99
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
- package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
- package/dist/types/sdk/bus/notification-service.d.ts +52 -0
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
- package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
- package/dist/types/sdk/bus/session-control.d.ts +25 -1
- package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
- package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
- package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
- package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
- package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
- package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
- package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
- package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
- package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
- package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
- package/dist/types/sdk/cli/rows.d.ts +2 -11
- package/dist/types/sdk/cli/session-cli.d.ts +15 -25
- package/dist/types/sdk/client/client.d.ts +97 -1
- package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
- package/dist/types/sdk/host/control/index.d.ts +1 -1
- package/dist/types/sdk/host/control/operations.d.ts +18 -5
- package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
- package/dist/types/sdk/host/host.d.ts +15 -1
- package/dist/types/sdk/host/query/handlers.d.ts +5 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
- package/dist/types/sdk/host/session-runtime.d.ts +127 -7
- package/dist/types/sdk/host/types.d.ts +1 -1
- package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
- package/dist/types/sdk/index.d.ts +2 -1
- package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
- package/dist/types/sdk/lifecycle/client.d.ts +59 -0
- package/dist/types/sdk/lifecycle/index.d.ts +3 -0
- package/dist/types/sdk/lifecycle/service.d.ts +232 -0
- package/dist/types/sdk/mcp/server.d.ts +9 -6
- package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
- package/dist/types/sdk/prompt-status.d.ts +10 -3
- package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
- package/dist/types/sdk/receipt-state.d.ts +17 -0
- package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
- package/dist/types/sdk/router/index.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +152 -0
- package/dist/types/sdk/session-list.d.ts +22 -0
- package/dist/types/sdk/session-reconnect.d.ts +43 -1
- package/dist/types/sdk/session.d.ts +34 -1
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
- package/dist/types/session/account-inventory.d.ts +86 -0
- package/dist/types/session/agent-session.d.ts +145 -6
- package/dist/types/session/agent-storage.d.ts +10 -0
- package/dist/types/session/coordinator-tool-label.d.ts +28 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
- package/dist/types/session/messages.d.ts +1 -1
- package/dist/types/session/secure-token-file.d.ts +3 -0
- package/dist/types/session/session-manager.d.ts +47 -1
- package/dist/types/session/startup-auth-config.d.ts +44 -0
- package/dist/types/session/terminal-abort.d.ts +378 -0
- package/dist/types/session/yield-queue.d.ts +7 -0
- package/dist/types/session-import/claude.d.ts +26 -0
- package/dist/types/session-import/codex.d.ts +88 -0
- package/dist/types/session-import/command.d.ts +35 -0
- package/dist/types/session-import/detect.d.ts +22 -0
- package/dist/types/session-import/index.d.ts +7 -0
- package/dist/types/session-import/provider-codex.d.ts +22 -0
- package/dist/types/session-import/provider-service.d.ts +38 -0
- package/dist/types/session-import/redact.d.ts +23 -0
- package/dist/types/session-import/service.d.ts +47 -0
- package/dist/types/session-import/types.d.ts +120 -0
- package/dist/types/setup/paseo/check.d.ts +16 -0
- package/dist/types/setup/paseo/install-saga.d.ts +115 -0
- package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
- package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
- package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
- package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
- package/dist/types/setup/paseo/provider-config.d.ts +35 -0
- package/dist/types/setup/paseo/remove.d.ts +14 -0
- package/dist/types/setup/paseo/result-types.d.ts +59 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
- package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
- package/dist/types/skill-state/active-state.d.ts +5 -1
- package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
- package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
- package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
- package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
- package/dist/types/slash-commands/types.d.ts +7 -1
- package/dist/types/task/executor.d.ts +10 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/tools/ask-answer-registry.d.ts +6 -3
- package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
- package/dist/types/tools/bash.d.ts +2 -6
- package/dist/types/tools/browser/attach.d.ts +11 -0
- package/dist/types/tools/browser/launch.d.ts +20 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
- package/dist/types/tools/browser/render.d.ts +1 -0
- package/dist/types/tools/browser.d.ts +3 -1
- package/dist/types/tools/image-gen.d.ts +10 -2
- package/dist/types/tools/index.d.ts +8 -0
- package/dist/types/tools/monitor.d.ts +1 -1
- package/dist/types/tools/skill-discovery.d.ts +8 -1
- package/dist/types/tools/subagent.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
- package/dist/types/utils/herdr-pane.d.ts +76 -0
- package/package.json +19 -9
- package/scripts/build-binary.ts +2 -1
- package/scripts/build-sdk-package-smoke.ts +2 -13
- package/scripts/capture-sticky-viewport-showcase.ts +0 -1
- package/scripts/compile-args.ts +2 -0
- package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
- package/scripts/generate-sdk-operation-inventory.ts +28 -0
- package/scripts/generate-telegram-baseline-manifest.ts +1 -0
- package/scripts/generate-tool-catalog.ts +6 -4
- package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
- package/src/async/job-manager.ts +352 -17
- package/src/async/support.ts +25 -0
- package/src/autoresearch/dashboard.ts +28 -13
- package/src/capability/index.ts +3 -1
- package/src/capability/mcp.ts +6 -0
- package/src/capability/types.ts +6 -0
- package/src/cli/accounts-cli.ts +395 -0
- package/src/cli/args.ts +23 -0
- package/src/cli/auth-broker-cli.ts +136 -66
- package/src/cli/auth-gateway-cli.ts +94 -70
- package/src/cli/config-cli.ts +27 -2
- package/src/cli/crash-cli.ts +78 -0
- package/src/cli/customize-doctor.ts +1605 -0
- package/src/cli/daemon-cli.ts +12 -3
- package/src/cli/fast-help.ts +1 -0
- package/src/cli/mcp-cli.ts +128 -60
- package/src/cli/notify-cli.ts +8 -14
- package/src/cli/root-flags.ts +8 -0
- package/src/cli/setup-cli.ts +145 -0
- package/src/cli/skills-cli.ts +38 -2
- package/src/cli/update-cli.ts +167 -12
- package/src/cli.ts +4 -0
- package/src/commands/accounts.ts +71 -0
- package/src/commands/crash.ts +35 -0
- package/src/commands/customize.ts +84 -0
- package/src/commands/daemon.ts +2 -2
- package/src/commands/deep-interview.ts +2 -0
- package/src/commands/launch.ts +1 -0
- package/src/commands/mcp.ts +12 -7
- package/src/commands/ralplan.ts +2 -0
- package/src/commands/sdk.ts +65 -32
- package/src/commands/setup.ts +5 -0
- package/src/commands/skills.ts +14 -4
- package/src/commands/ultragoal.ts +10 -1
- package/src/commands/update.ts +26 -15
- package/src/config/atomic-yaml-patch-worker.ts +57 -0
- package/src/config/atomic-yaml-patch.ts +769 -29
- package/src/config/config-schema-version.ts +10 -0
- package/src/config/file-lock.ts +70 -1
- package/src/config/mcp-schema.json +52 -14
- package/src/config/model-profile-activation.ts +23 -2
- package/src/config/model-profiles.ts +88 -21
- package/src/config/model-registry.ts +147 -21
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +77 -7
- package/src/config/settings.ts +4038 -199
- package/src/config/skill-settings-defaults.ts +41 -3
- package/src/config/task-delegation.ts +87 -0
- package/src/config/update-channel.ts +23 -0
- package/src/coordinator-mcp/server.ts +377 -308
- package/src/crash/index-store.ts +723 -0
- package/src/crash/nudge.ts +89 -0
- package/src/crash/record-loader.ts +149 -0
- package/src/crash/report.ts +551 -0
- package/src/crash/sanitize.ts +129 -0
- package/src/cursor.ts +36 -10
- package/src/customization/import.ts +946 -0
- package/src/customization/index.ts +4 -0
- package/src/customization/inventory.ts +335 -0
- package/src/customization/mutations.ts +141 -0
- package/src/customization/types.ts +223 -0
- package/src/daemon/control-types.ts +8 -1
- package/src/daemon/operator-contract.ts +6 -6
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +31 -6
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
- package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
- package/src/discovery/claude-hooks.ts +38 -0
- package/src/discovery/claude.ts +142 -209
- package/src/discovery/codex-hooks.ts +38 -0
- package/src/discovery/codex.ts +132 -198
- package/src/discovery/helpers.ts +8 -1
- package/src/discovery/index.ts +2 -0
- package/src/discovery/mcp-compat.ts +234 -0
- package/src/discovery/mcp-json.ts +6 -0
- package/src/edit/renderer.ts +40 -0
- package/src/edit/streaming.ts +4 -2
- package/src/exec/bash-executor.ts +24 -20
- package/src/export/html/index.ts +51 -2
- package/src/extensibility/extensions/loader.ts +9 -1
- package/src/extensibility/extensions/runner.ts +17 -4
- package/src/extensibility/extensions/types.ts +31 -6
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
- package/src/extensibility/gjc-plugins/installer.ts +9 -5
- package/src/extensibility/gjc-plugins/observability.ts +8 -2
- package/src/extensibility/gjc-plugins/registry.ts +13 -2
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
- package/src/extensibility/gjc-plugins/schema.ts +222 -39
- package/src/extensibility/hooks/loader.ts +154 -10
- package/src/extensibility/runtime-skill-discovery.ts +257 -60
- package/src/extensibility/skill-management.ts +368 -0
- package/src/extensibility/skills.ts +52 -16
- package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
- package/src/gjc-runtime/launch-worktree.ts +56 -2
- package/src/gjc-runtime/linux-proc.ts +7 -1
- package/src/gjc-runtime/ralplan-runtime.ts +100 -164
- package/src/gjc-runtime/session-state-lock.ts +992 -0
- package/src/gjc-runtime/session-state-sidecar.ts +644 -142
- package/src/gjc-runtime/state-writer.ts +39 -14
- package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
- package/src/gjc-runtime/ultragoal-guard.ts +11 -4
- package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
- package/src/gjc-runtime/workflow-settings.ts +596 -0
- package/src/goals/tools/goal-tool.ts +6 -1
- package/src/hooks/events.ts +291 -0
- package/src/hooks/native-skill-hook.ts +4 -0
- package/src/hooks/normalize.ts +369 -0
- package/src/hooks/skill-state.ts +165 -46
- package/src/internal-urls/docs-index.generated.ts +41 -32
- package/src/main.ts +36 -5
- package/src/migrate/mcp-mapper.ts +25 -2
- package/src/modes/acp/abort-scope.ts +29 -0
- package/src/modes/acp/acp-agent.ts +423 -98
- package/src/modes/components/assistant-message.ts +6 -1
- package/src/modes/components/chrome.ts +4 -3
- package/src/modes/components/customization/customization-dashboard.ts +443 -0
- package/src/modes/components/customization/import-wizard.ts +372 -0
- package/src/modes/components/customization/index.ts +1 -0
- package/src/modes/components/dynamic-theme-text.ts +22 -0
- package/src/modes/components/gajae-pet-widget.ts +607 -193
- package/src/modes/components/irc-sidebar.ts +11 -0
- package/src/modes/components/iterm-pet-transport.ts +585 -0
- package/src/modes/components/model-selector.ts +1 -6
- package/src/modes/components/oauth-selector.ts +277 -86
- package/src/modes/components/pet-capability.ts +35 -31
- package/src/modes/components/settings-selector.ts +29 -5
- package/src/modes/components/status-line/gh.ts +45 -1
- package/src/modes/components/status-line/segments.ts +19 -4
- package/src/modes/components/tool-status-header.ts +13 -3
- package/src/modes/controllers/command-controller.ts +20 -8
- package/src/modes/controllers/extension-ui-controller.ts +56 -257
- package/src/modes/controllers/input-controller.ts +10 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
- package/src/modes/controllers/selector-controller.ts +238 -77
- package/src/modes/controllers/stt-controller.ts +3 -3
- package/src/modes/interactive-mode.ts +88 -16
- package/src/modes/print-mode.ts +35 -6
- package/src/modes/runtime-init.ts +21 -68
- package/src/modes/theme/defaults/index.ts +2 -0
- package/src/modes/theme/defaults/ouroboros.json +118 -0
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/injected-user-submission.ts +25 -0
- package/src/modes/utils/terminal-bell.ts +15 -1
- package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/critic.md +1 -1
- package/src/prompts/system/rlm-research.md +1 -1
- package/src/prompts/system/system-prompt.md +0 -2
- package/src/prompts/tools/bash.md +7 -1
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/cron.md +6 -6
- package/src/prompts/tools/read.md +0 -2
- package/src/prompts/tools/skill-discovery.md +4 -2
- package/src/runtime-mcp/client.ts +427 -23
- package/src/runtime-mcp/config.ts +37 -5
- package/src/runtime-mcp/manager-pool.test.ts +56 -0
- package/src/runtime-mcp/manager.ts +52 -2
- package/src/runtime-mcp/oauth-discovery.ts +13 -0
- package/src/runtime-mcp/oauth-flow.ts +46 -1
- package/src/runtime-mcp/pool-key.ts +5 -1
- package/src/runtime-mcp/pool.test.ts +9 -0
- package/src/runtime-mcp/protocol.test.ts +353 -0
- package/src/runtime-mcp/protocol.ts +624 -0
- package/src/runtime-mcp/scope-config.ts +78 -0
- package/src/runtime-mcp/tool-bridge.ts +44 -10
- package/src/runtime-mcp/transports/http.ts +84 -13
- package/src/runtime-mcp/types.ts +123 -12
- package/src/sdk/acp/adapter.ts +328 -97
- package/src/sdk/broker/broker.ts +160 -741
- package/src/sdk/broker/ensure.ts +9 -1
- package/src/sdk/broker/lifecycle.ts +510 -116
- package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
- package/src/sdk/broker/process-incarnation.ts +19 -0
- package/src/sdk/broker/session-index.ts +516 -117
- package/src/sdk/broker/startup-failure.ts +28 -5
- package/src/sdk/broker/transport.ts +1 -13
- package/src/sdk/bus/chat-daemon-cli.ts +4 -2
- package/src/sdk/bus/chat-daemon-control.ts +67 -6
- package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
- package/src/sdk/bus/config.ts +13 -0
- package/src/sdk/bus/conversation-store.ts +59 -171
- package/src/sdk/bus/daemon-paths.ts +20 -0
- package/src/sdk/bus/discord-conversation.ts +2 -0
- package/src/sdk/bus/discord-daemon.ts +524 -126
- package/src/sdk/bus/discord-live-provider.ts +206 -79
- package/src/sdk/bus/existing-thread-readiness.ts +4 -97
- package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
- package/src/sdk/bus/index.ts +2480 -456
- package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
- package/src/sdk/bus/lifecycle-commands.ts +2 -2
- package/src/sdk/bus/managed-daemon.ts +2 -145
- package/src/sdk/bus/notification-service.ts +196 -0
- package/src/sdk/bus/operator-runtime.ts +1 -1
- package/src/sdk/bus/prompt-reconciliation.ts +24 -15
- package/src/sdk/bus/reconciliation-store.ts +553 -24
- package/src/sdk/bus/session-control.ts +49 -3
- package/src/sdk/bus/slack-conversation.ts +4 -0
- package/src/sdk/bus/slack-daemon.ts +733 -134
- package/src/sdk/bus/slack-live-provider.ts +65 -15
- package/src/sdk/bus/slack-provider.ts +4 -0
- package/src/sdk/bus/slack-thread-binding.ts +9 -104
- package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
- package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
- package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
- package/src/sdk/bus/telegram-daemon-control.ts +3 -13
- package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
- package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
- package/src/sdk/bus/telegram-daemon.ts +2552 -2280
- package/src/sdk/bus/telegram-reference.ts +1 -226
- package/src/sdk/bus/telegram-setup.ts +2 -2
- package/src/sdk/bus/threaded-render.ts +1 -0
- package/src/sdk/bus/topic-registry.ts +279 -146
- package/src/sdk/cli/rows.ts +2 -35
- package/src/sdk/cli/session-cli.ts +776 -700
- package/src/sdk/client/client.ts +892 -1
- package/src/sdk/host/control/dispatch.ts +93 -58
- package/src/sdk/host/control/index.ts +1 -1
- package/src/sdk/host/control/operations.ts +18 -10
- package/src/sdk/host/control/runtime-gate.ts +40 -0
- package/src/sdk/host/host.ts +63 -12
- package/src/sdk/host/query/handlers.ts +66 -7
- package/src/sdk/host/reverse-leases.ts +2 -2
- package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
- package/src/sdk/host/session-runtime.test.ts +2787 -34
- package/src/sdk/host/session-runtime.ts +1489 -101
- package/src/sdk/host/surface-policy.ts +12 -8
- package/src/sdk/host/types.ts +1 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
- package/src/sdk/host/websocket-transport.ts +85 -50
- package/src/sdk/index.ts +2 -1
- package/src/sdk/lifecycle/broker-client.ts +53 -0
- package/src/sdk/lifecycle/client.ts +234 -0
- package/src/sdk/lifecycle/index.ts +3 -0
- package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
- package/src/sdk/lifecycle/service.ts +720 -0
- package/src/sdk/mcp/server.ts +226 -188
- package/src/sdk/prompt-deadline-lease.ts +55 -0
- package/src/sdk/prompt-deadline-manager.ts +148 -0
- package/src/sdk/prompt-status.ts +11 -3
- package/src/sdk/protocol/operation-inventory.generated.json +272 -129
- package/src/sdk/protocol/operation-registry.ts +71 -8
- package/src/sdk/receipt-state.ts +43 -0
- package/src/sdk/reconciliation-extensions.ts +14 -0
- package/src/sdk/router/index.ts +1 -0
- package/src/sdk/router/session-router.ts +1658 -0
- package/src/sdk/session-list.ts +93 -0
- package/src/sdk/session-reconnect.ts +45 -1
- package/src/sdk/session.ts +716 -120
- package/src/sdk/transport/serve-cli.ts +18 -34
- package/src/session/account-inventory.ts +603 -0
- package/src/session/agent-session.ts +2873 -559
- package/src/session/agent-storage.ts +35 -0
- package/src/session/blob-store.ts +32 -1
- package/src/session/coordinator-tool-label.ts +40 -0
- package/src/session/internal/managed-session-scope.ts +4 -0
- package/src/session/internal/managed-session-storage.ts +199 -31
- package/src/session/messages.ts +1 -1
- package/src/session/secure-token-file.ts +80 -0
- package/src/session/session-manager.ts +757 -57
- package/src/session/session-storage.ts +25 -16
- package/src/session/startup-auth-config.ts +297 -0
- package/src/session/terminal-abort.ts +1253 -0
- package/src/session/yield-queue.ts +57 -15
- package/src/session-import/claude.ts +334 -0
- package/src/session-import/codex.ts +1033 -0
- package/src/session-import/command.ts +77 -0
- package/src/session-import/detect.ts +133 -0
- package/src/session-import/index.ts +7 -0
- package/src/session-import/provider-codex.ts +327 -0
- package/src/session-import/provider-service.ts +457 -0
- package/src/session-import/redact.ts +128 -0
- package/src/session-import/service.ts +1264 -0
- package/src/session-import/types.ts +148 -0
- package/src/setup/paseo/check.ts +213 -0
- package/src/setup/paseo/install-saga.ts +293 -0
- package/src/setup/paseo/json-publisher.ts +263 -0
- package/src/setup/paseo/orchestration-preferences.ts +86 -0
- package/src/setup/paseo/paseo-ownership.ts +224 -0
- package/src/setup/paseo/paseo-setup.ts +253 -0
- package/src/setup/paseo/provider-config.ts +139 -0
- package/src/setup/paseo/remove.ts +183 -0
- package/src/setup/paseo/result-types.ts +79 -0
- package/src/setup/paseo/setup-deps.ts +175 -0
- package/src/setup/paseo/skills-bridge.ts +260 -0
- package/src/skill-state/active-state.ts +21 -11
- package/src/slash-commands/acp-builtins.ts +9 -1
- package/src/slash-commands/builtin-registry.ts +117 -19
- package/src/slash-commands/helpers/credential-switch.ts +143 -0
- package/src/slash-commands/helpers/mcp.ts +9 -3
- package/src/slash-commands/helpers/usage-report.ts +61 -56
- package/src/slash-commands/types.ts +7 -2
- package/src/task/executor.ts +30 -11
- package/src/task/index.ts +66 -7
- package/src/task/render.ts +23 -9
- package/src/tools/ask-answer-registry.ts +23 -7
- package/src/tools/ask.ts +8 -4
- package/src/tools/bash-sleep-advisory.ts +115 -0
- package/src/tools/bash.ts +98 -18
- package/src/tools/browser/attach.ts +71 -3
- package/src/tools/browser/launch.ts +86 -13
- package/src/tools/browser/profile-discovery.ts +57 -7
- package/src/tools/browser/render.ts +8 -1
- package/src/tools/browser.ts +130 -21
- package/src/tools/computer.enforcement.test.ts +1 -1
- package/src/tools/computer.ts +3 -2
- package/src/tools/cron.ts +12 -1
- package/src/tools/image-gen.ts +349 -142
- package/src/tools/index.ts +8 -0
- package/src/tools/job.ts +33 -6
- package/src/tools/monitor.ts +41 -2
- package/src/tools/skill-discovery.ts +21 -29
- package/src/tools/subagent.ts +142 -24
- package/src/tools/todo-contract.ts +55 -3
- package/src/tools/todo-write.ts +4 -3
- package/src/tools/tool-catalog.generated.ts +6 -6
- package/src/tools/ultragoal-ask-guard.ts +10 -3
- package/src/utils/herdr-pane.ts +345 -0
- package/src/utils/title-generator.ts +2 -0
- package/src/web/scrapers/index.ts +6 -4
- package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
- package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
- package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
- package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
- package/dist/types/runtime/lazy-service.test.d.ts +0 -1
- package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
- package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
- package/dist/types/runtime-mcp/config.test.d.ts +0 -1
- package/dist/types/runtime-mcp/http.test.d.ts +0 -1
- package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
- package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
- package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
- package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
- package/dist/types/sdk/elevation/audit.d.ts +0 -93
- package/dist/types/sdk/elevation/capability.d.ts +0 -3
- package/dist/types/sdk/elevation/digest.d.ts +0 -72
- package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
- package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
- package/dist/types/sdk/elevation/owner.d.ts +0 -48
- package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
- package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
- package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
- package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
- package/dist/types/session/auth-broker-config.d.ts +0 -13
- package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
- package/dist/types/skills/skills.test.d.ts +0 -1
- package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
- package/dist/types/task/token-log.test.d.ts +0 -1
- package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
- package/dist/types/tools/descriptors.test.d.ts +0 -1
- package/scripts/g005-daemon-smoke.ts +0 -180
- package/scripts/g011-daemon-path-smoke.ts +0 -153
- package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
- package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
- package/src/sdk/bus/telegram-cli.ts +0 -212
- package/src/sdk/elevation/allowlist.ts +0 -54
- package/src/sdk/elevation/audit.ts +0 -208
- package/src/sdk/elevation/capability.ts +0 -41
- package/src/sdk/elevation/digest.ts +0 -129
- package/src/sdk/elevation/dispatch-receipt.ts +0 -184
- package/src/sdk/elevation/grant-ledger.ts +0 -1142
- package/src/sdk/elevation/owner.ts +0 -109
- package/src/session/auth-broker-config.ts +0 -109
- /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
- /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
- /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { findOperation } from "../protocol/operation-registry";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Exact elevation-gated allowlist, fully qualified and enumerative.
|
|
5
|
-
*
|
|
6
|
-
* The elevation allowlist is the exact set of registry operations below (the
|
|
7
|
-
* raw destructive lifecycle and workflow-approval operations). It is declared
|
|
8
|
-
* ONCE here as a `Set<string>` of `"kind:sdkId"` keys and mechanically pinned
|
|
9
|
-
* against `operation-registry.ts` by the allowlist unit test: every key must
|
|
10
|
-
* resolve via `findOperation(kind, sdkId)` and no elevatable operation may be
|
|
11
|
-
* silently missing. Any operation NOT in this set is rejected at issue with
|
|
12
|
-
* `elevation_not_allowlisted` before any ledger reservation. There is no
|
|
13
|
-
* generalized policy engine: this is the deterministic predicate.
|
|
14
|
-
*/
|
|
15
|
-
export const ELEVATION_ALLOWLIST_KEYS = [
|
|
16
|
-
"global:session.close",
|
|
17
|
-
"global:session.delete",
|
|
18
|
-
"control:session.delete",
|
|
19
|
-
"control:session.close",
|
|
20
|
-
"control:context.clear",
|
|
21
|
-
"control:session.cwd.move",
|
|
22
|
-
"control:compaction.run",
|
|
23
|
-
"control:bash.execute",
|
|
24
|
-
"control:bash.background",
|
|
25
|
-
"control:queue.message.remove",
|
|
26
|
-
"control:queue.message.update",
|
|
27
|
-
"control:retry.abort",
|
|
28
|
-
"control:retry.now",
|
|
29
|
-
"control:bash.abort",
|
|
30
|
-
"control:retry.auto.set",
|
|
31
|
-
"control:compaction.auto.set",
|
|
32
|
-
"control:extension.set_enabled",
|
|
33
|
-
"control:queue.interrupt_mode.set",
|
|
34
|
-
"control:queue.follow_up_mode.set",
|
|
35
|
-
"control:queue.steering_mode.set",
|
|
36
|
-
"control:tools.active.set",
|
|
37
|
-
"control:permission_mode.set",
|
|
38
|
-
"control:service_tier.set",
|
|
39
|
-
"control:workflow.gate_answer",
|
|
40
|
-
"control:workflow.plan_approve",
|
|
41
|
-
] as const;
|
|
42
|
-
const elevationAllowlistKeySet = new Set<string>(ELEVATION_ALLOWLIST_KEYS);
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Whether `(kind, sdkId)` is the fully qualified identity of an allowlisted
|
|
46
|
-
* elevation-gated operation. The pair is validated against the operation
|
|
47
|
-
* registry before any elevation is admitted, so a key can never name an
|
|
48
|
-
* operation that does not exist.
|
|
49
|
-
*/
|
|
50
|
-
export function isElevationAllowlisted(kind: unknown, sdkId: unknown): boolean {
|
|
51
|
-
if (typeof kind !== "string" || typeof sdkId !== "string") return false;
|
|
52
|
-
if (!elevationAllowlistKeySet.has(`${kind}:${sdkId}`)) return false;
|
|
53
|
-
return findOperation(kind as "control" | "global" | "query" | "reverse", sdkId) !== undefined;
|
|
54
|
-
}
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import * as fsSync from "node:fs";
|
|
2
|
-
import * as fs from "node:fs/promises";
|
|
3
|
-
import * as path from "node:path";
|
|
4
|
-
import { assertSupportedStateVersion, SDK_STATE_VERSION } from "../broker/state-version";
|
|
5
|
-
import { classifyProcessIncarnationLiveness } from "./owner";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Durable elevation audit trail.
|
|
9
|
-
*
|
|
10
|
-
* Append-only JSONL under the same elevation-local lock as the grant ledger,
|
|
11
|
-
* mode 0600. Every state transition of a grant — issue, operator answer,
|
|
12
|
-
* expiry, misuse, duplicate answer, claim, and dispatch outcome — is
|
|
13
|
-
* recorded with the exact identity evidence the transition consumed, so an
|
|
14
|
-
* auditor can reproduce why a grant reached its terminal state without
|
|
15
|
-
* trusting in-memory state.
|
|
16
|
-
*
|
|
17
|
-
* The audit stream is an evidence trail, never an authority: audit rows are
|
|
18
|
-
* append-only, are never re-read to drive decisions, and a corrupted row is
|
|
19
|
-
* quarantined (like ledger rows) instead of failing the ledger.
|
|
20
|
-
*/
|
|
21
|
-
export type ElevationAuditEvent =
|
|
22
|
-
| { kind: "issued" }
|
|
23
|
-
| {
|
|
24
|
-
kind: "answered";
|
|
25
|
-
outcome: "granted" | "denied" | "expired" | "misused" | "target_unavailable" | "duplicate_answer";
|
|
26
|
-
}
|
|
27
|
-
| { kind: "expired" }
|
|
28
|
-
| { kind: "misused" }
|
|
29
|
-
| { kind: "duplicate_answer" }
|
|
30
|
-
| { kind: "claimed"; claim: { ownerId: string; epoch: number; pid: number; incarnation: string } }
|
|
31
|
-
| {
|
|
32
|
-
kind: "dispatched";
|
|
33
|
-
dispatch: { ownerId: string; epoch: number; dispatchedAt: number };
|
|
34
|
-
outcome: { status: "ok" | "failed"; code?: string; message?: string; dispatchedAt: number };
|
|
35
|
-
}
|
|
36
|
-
| { kind: "consumed"; message: string }
|
|
37
|
-
| { kind: "unavailable"; reason: string };
|
|
38
|
-
|
|
39
|
-
export interface ElevationAuditEntry {
|
|
40
|
-
version: typeof SDK_STATE_VERSION;
|
|
41
|
-
ts: number;
|
|
42
|
-
elevationRequestId: string;
|
|
43
|
-
issueIndex: number;
|
|
44
|
-
event: ElevationAuditEvent;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export type ElevationAuditEventName = ElevationAuditEvent["kind"];
|
|
48
|
-
|
|
49
|
-
export function isElevationAuditEntry(value: unknown): value is ElevationAuditEntry {
|
|
50
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
51
|
-
const entry = value as {
|
|
52
|
-
version?: unknown;
|
|
53
|
-
ts?: unknown;
|
|
54
|
-
elevationRequestId?: unknown;
|
|
55
|
-
issueIndex?: unknown;
|
|
56
|
-
event?: unknown;
|
|
57
|
-
};
|
|
58
|
-
if (
|
|
59
|
-
entry.version !== SDK_STATE_VERSION ||
|
|
60
|
-
!Number.isSafeInteger(entry.ts) ||
|
|
61
|
-
(entry.ts as number) <= 0 ||
|
|
62
|
-
typeof entry.elevationRequestId !== "string" ||
|
|
63
|
-
entry.elevationRequestId.length === 0 ||
|
|
64
|
-
!Number.isSafeInteger(entry.issueIndex) ||
|
|
65
|
-
(entry.issueIndex as number) <= 0 ||
|
|
66
|
-
typeof entry.event !== "object" ||
|
|
67
|
-
entry.event === null ||
|
|
68
|
-
Array.isArray(entry.event)
|
|
69
|
-
)
|
|
70
|
-
return false;
|
|
71
|
-
const event = entry.event as { kind?: unknown };
|
|
72
|
-
return typeof event.kind === "string" && event.kind.length > 0;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const AUDIT_FILE_NAME = "audit.jsonl";
|
|
76
|
-
const MAX_AUDIT_FILE_BYTES = 64 * 1024 * 1024;
|
|
77
|
-
const MAX_AUDIT_LINE_BYTES = 8 * 1024 * 1024;
|
|
78
|
-
|
|
79
|
-
export interface ElevationAuditOptions {
|
|
80
|
-
/** Injectable clock. */
|
|
81
|
-
now?: () => number;
|
|
82
|
-
/**
|
|
83
|
-
* Injectable tri-state process-incarnation liveness classifier, defaulting
|
|
84
|
-
* to `classifyProcessIncarnationLiveness`. The audit trail records the
|
|
85
|
-
* liveness verdict behind `consumed`/`unavailable` settlements so the
|
|
86
|
-
* crash-truth settlement is reproducible; the verdict never drives the
|
|
87
|
-
* settlement itself (that lives in the ledger).
|
|
88
|
-
*/
|
|
89
|
-
classifyLiveness?: typeof classifyProcessIncarnationLiveness;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export class ElevationAudit {
|
|
93
|
-
readonly #dir: string;
|
|
94
|
-
readonly #file: string;
|
|
95
|
-
#now: () => number;
|
|
96
|
-
#classifyLiveness: typeof classifyProcessIncarnationLiveness;
|
|
97
|
-
#warnings: string[] = [];
|
|
98
|
-
|
|
99
|
-
constructor(agentDir: string, options: ElevationAuditOptions = {}) {
|
|
100
|
-
this.#dir = path.join(agentDir, "sdk", "elevation");
|
|
101
|
-
this.#file = path.join(this.#dir, AUDIT_FILE_NAME);
|
|
102
|
-
this.#now = options.now ?? Date.now;
|
|
103
|
-
this.#classifyLiveness = options.classifyLiveness ?? classifyProcessIncarnationLiveness;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
get warnings(): readonly string[] {
|
|
107
|
-
return this.#warnings;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Appends one audit row for an elevation grant transition. Callers MUST
|
|
112
|
-
* hold the same elevation-local lock that guards the grant ledger; the
|
|
113
|
-
* audit row and the grant row therefore commit together.
|
|
114
|
-
*/
|
|
115
|
-
async append(entry: Omit<ElevationAuditEntry, "version">): Promise<void> {
|
|
116
|
-
const record: ElevationAuditEntry = { version: SDK_STATE_VERSION, ...entry };
|
|
117
|
-
const line = Buffer.from(`${JSON.stringify(record)}\n`);
|
|
118
|
-
if (line.length - 1 > MAX_AUDIT_LINE_BYTES)
|
|
119
|
-
throw new Error("Elevation audit row exceeds the maximum byte length");
|
|
120
|
-
const handle = await fs.open(
|
|
121
|
-
this.#file,
|
|
122
|
-
fsSync.constants.O_WRONLY | fsSync.constants.O_APPEND | fsSync.constants.O_CREAT | fsSync.constants.O_NOFOLLOW,
|
|
123
|
-
0o600,
|
|
124
|
-
);
|
|
125
|
-
try {
|
|
126
|
-
if (!(await handle.stat()).isFile()) throw new Error("Elevation audit target is not a regular file.");
|
|
127
|
-
await handle.writeFile(line);
|
|
128
|
-
await handle.sync();
|
|
129
|
-
} finally {
|
|
130
|
-
await handle.close();
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Opens the audit stream: creates the 0600 directory/file if absent and
|
|
136
|
-
* quarantines any corrupt tail so subsequent appends are always readable.
|
|
137
|
-
* Called under the same lock as `ElevationLedger.open()`.
|
|
138
|
-
*/
|
|
139
|
-
async open(): Promise<this> {
|
|
140
|
-
await fs.mkdir(this.#dir, { recursive: true, mode: 0o700 });
|
|
141
|
-
let source: Buffer | undefined;
|
|
142
|
-
let handle: fs.FileHandle | undefined;
|
|
143
|
-
try {
|
|
144
|
-
handle = await fs.open(this.#file, fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW);
|
|
145
|
-
const stat = await handle.stat({ bigint: true });
|
|
146
|
-
if (!stat.isFile()) throw new Error(`Elevation audit target is not a regular file: ${this.#file}`);
|
|
147
|
-
if (stat.size > BigInt(MAX_AUDIT_FILE_BYTES))
|
|
148
|
-
throw new Error(`Elevation audit file exceeds the maximum byte length: ${this.#file}`);
|
|
149
|
-
const bytes = Buffer.alloc(Number(stat.size) + 1);
|
|
150
|
-
const { bytesRead } = await handle.read(bytes, 0, bytes.length, 0);
|
|
151
|
-
source = bytes.subarray(0, bytesRead);
|
|
152
|
-
} catch (error) {
|
|
153
|
-
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
154
|
-
} finally {
|
|
155
|
-
if (handle) await handle.close();
|
|
156
|
-
}
|
|
157
|
-
if (!source) return this;
|
|
158
|
-
const tornTail = source.length > 0 && source.at(-1) !== 0x0a;
|
|
159
|
-
let lineStart = 0;
|
|
160
|
-
for (let offset = 0; offset <= source.length; offset += 1) {
|
|
161
|
-
if (offset !== source.length && source[offset] !== 0x0a) continue;
|
|
162
|
-
const line = source.subarray(lineStart, offset);
|
|
163
|
-
lineStart = offset + 1;
|
|
164
|
-
if (line.length === 0) continue;
|
|
165
|
-
if (line.length > MAX_AUDIT_LINE_BYTES) throw new Error("Elevation audit row exceeds the maximum byte length");
|
|
166
|
-
try {
|
|
167
|
-
const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(line));
|
|
168
|
-
assertSupportedStateVersion(this.#file, value);
|
|
169
|
-
if (!isElevationAuditEntry(value)) throw new Error("invalid elevation audit entry");
|
|
170
|
-
} catch (error) {
|
|
171
|
-
if (error instanceof Error && "code" in error && error.code === "unsupported_state_version") throw error;
|
|
172
|
-
const quarantine = await fs.open(
|
|
173
|
-
`${this.#file}.corrupt`,
|
|
174
|
-
fsSync.constants.O_WRONLY |
|
|
175
|
-
fsSync.constants.O_APPEND |
|
|
176
|
-
fsSync.constants.O_CREAT |
|
|
177
|
-
fsSync.constants.O_NOFOLLOW,
|
|
178
|
-
0o600,
|
|
179
|
-
);
|
|
180
|
-
try {
|
|
181
|
-
await quarantine.writeFile(line);
|
|
182
|
-
await quarantine.writeFile("\n");
|
|
183
|
-
await quarantine.sync();
|
|
184
|
-
} finally {
|
|
185
|
-
await quarantine.close();
|
|
186
|
-
}
|
|
187
|
-
this.#warnings.push("Malformed elevation audit entry quarantined");
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (tornTail) {
|
|
191
|
-
const seal = await fs.open(
|
|
192
|
-
this.#file,
|
|
193
|
-
fsSync.constants.O_WRONLY |
|
|
194
|
-
fsSync.constants.O_APPEND |
|
|
195
|
-
fsSync.constants.O_CREAT |
|
|
196
|
-
fsSync.constants.O_NOFOLLOW,
|
|
197
|
-
0o600,
|
|
198
|
-
);
|
|
199
|
-
try {
|
|
200
|
-
await seal.writeFile("\n");
|
|
201
|
-
await seal.sync();
|
|
202
|
-
} finally {
|
|
203
|
-
await seal.close();
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return this;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { canonicalElevationJson } from "./digest";
|
|
4
|
-
|
|
5
|
-
const CAPABILITY_PATTERN = /^([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})\.([0-9a-f]{64})$/;
|
|
6
|
-
|
|
7
|
-
function payload(requestId: string, sdkId: string, input: Record<string, unknown>): string {
|
|
8
|
-
return canonicalElevationJson({ requestId, kind: "control", sdkId, input });
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function signElevationCapability(
|
|
12
|
-
authorityToken: string,
|
|
13
|
-
requestId: string,
|
|
14
|
-
sdkId: string,
|
|
15
|
-
input: Record<string, unknown>,
|
|
16
|
-
): string {
|
|
17
|
-
const signature = createHmac("sha256", authorityToken)
|
|
18
|
-
.update(payload(requestId, sdkId, input))
|
|
19
|
-
.digest("hex");
|
|
20
|
-
return `${requestId}.${signature}`;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function verifyElevationCapability(
|
|
24
|
-
authorityToken: string,
|
|
25
|
-
capability: string,
|
|
26
|
-
sdkId: string,
|
|
27
|
-
input: Record<string, unknown>,
|
|
28
|
-
): boolean {
|
|
29
|
-
const match = CAPABILITY_PATTERN.exec(capability);
|
|
30
|
-
if (!match) return false;
|
|
31
|
-
const requestId = match[1]!;
|
|
32
|
-
const supplied = Buffer.from(match[2]!, "hex");
|
|
33
|
-
const expected = createHmac("sha256", authorityToken)
|
|
34
|
-
.update(payload(requestId, sdkId, input))
|
|
35
|
-
.digest();
|
|
36
|
-
return supplied.length === expected.length && timingSafeEqual(supplied, expected);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function elevationAuthorityPath(stateRoot: string, sessionId: string): string {
|
|
40
|
-
return path.join(stateRoot, "sdk", ".authority", `${sessionId}.json`);
|
|
41
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { ELEVATION_ALLOWLIST_KEYS, isElevationAllowlisted } from "./allowlist";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Fully qualified elevation request digest.
|
|
6
|
-
*
|
|
7
|
-
* An elevation grant binds the exact operation the operator approved. The
|
|
8
|
-
* digest covers the complete `{kind, sdkId, input}` triple so substituting a
|
|
9
|
-
* different operation or different input bytes changes the digest and the
|
|
10
|
-
* gate presentation fails closed (`misused`). The top-level
|
|
11
|
-
* `elevationRequestId` correlation field is deliberately excluded: it is the
|
|
12
|
-
* durable correlation ID assigned to a request, not part of the approved
|
|
13
|
-
* content, and the same content re-issued under a new ID must produce the
|
|
14
|
-
* same digest.
|
|
15
|
-
*
|
|
16
|
-
* Only allowlisted operations can be elevated; anything else is refused so a
|
|
17
|
-
* caller cannot mint a grant for an operation outside the elevation policy.
|
|
18
|
-
*/
|
|
19
|
-
export const ELEVATION_OPERATION_KINDS = ["control", "query", "global"] as const;
|
|
20
|
-
export type ElevationOperationKind = (typeof ELEVATION_OPERATION_KINDS)[number];
|
|
21
|
-
|
|
22
|
-
export interface ElevationOperation {
|
|
23
|
-
kind: ElevationOperationKind;
|
|
24
|
-
sdkId: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Operations that require an elevation grant. Default SDK scope
|
|
29
|
-
* (list/query/send/tail) stays grant-free; destructive lifecycle operations
|
|
30
|
-
* and workflow approval operations are elevatable and therefore gated.
|
|
31
|
-
*/
|
|
32
|
-
export const ELEVATION_ALLOWLIST: readonly { kind: ElevationOperationKind; sdkId: string }[] =
|
|
33
|
-
ELEVATION_OPERATION_KINDS.flatMap(kind =>
|
|
34
|
-
[...ELEVATION_ALLOWLIST_KEYS]
|
|
35
|
-
.filter(key => key.startsWith(`${kind}:`))
|
|
36
|
-
.map(key => ({ kind, sdkId: key.slice(kind.length + 1) })),
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
export function isElevatableOperation(kind: unknown, sdkId: unknown): boolean {
|
|
40
|
-
return isElevationAllowlisted(kind, sdkId);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Whether the `(kind, sdkId)` pair names a registry operation that the
|
|
45
|
-
* elevation allowlist recognizes. Used by the ledger row validator so a
|
|
46
|
-
* persisted row can never bind an operation outside the allowlist.
|
|
47
|
-
*/
|
|
48
|
-
export function isKnownElevationOperation(kind: unknown, sdkId: unknown): boolean {
|
|
49
|
-
return isElevationAllowlisted(kind, sdkId);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Canonical JSON encoding for elevation digest leaves.
|
|
54
|
-
*
|
|
55
|
-
* Intentionally byte-compatible with the broker's identity canonicalization
|
|
56
|
-
* (`canonicalJson` in `sdk/broker/broker.ts`): object keys sorted, compact
|
|
57
|
-
* separators, `undefined` fields preserved verbatim, arrays joined without
|
|
58
|
-
* separators. The broker computes the request digest at issue time and the
|
|
59
|
-
* ledger recomputes/compares the same encoding, so digest verification is
|
|
60
|
-
* stable across issue, gate presentation, and answer.
|
|
61
|
-
*/
|
|
62
|
-
export function canonicalElevationJson(value: unknown): string {
|
|
63
|
-
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
64
|
-
if (Array.isArray(value)) return `[${value.map(canonicalElevationJson).join(",")}]`;
|
|
65
|
-
const record = value as Record<string, unknown>;
|
|
66
|
-
return `{${Object.keys(record)
|
|
67
|
-
.sort()
|
|
68
|
-
.map(key => `${JSON.stringify(key)}:${canonicalElevationJson(record[key])}`)
|
|
69
|
-
.join(",")}}`;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export type ElevationDigestResult =
|
|
73
|
-
| { ok: true; digest: string }
|
|
74
|
-
| { ok: false; error: { code: string; message: string } };
|
|
75
|
-
|
|
76
|
-
const MAX_SDK_ID_LENGTH = 128;
|
|
77
|
-
const MAX_INPUT_JSON_DEPTH = 64;
|
|
78
|
-
const MAX_INPUT_JSON_FIELDS = 1024;
|
|
79
|
-
|
|
80
|
-
function isBoundedInputJson(value: unknown, depth = 0, budget = { fields: 0 }): boolean {
|
|
81
|
-
if (depth > MAX_INPUT_JSON_DEPTH) return false;
|
|
82
|
-
if (value === null || typeof value !== "object") return true;
|
|
83
|
-
if (Array.isArray(value)) {
|
|
84
|
-
if (value.length > MAX_INPUT_JSON_FIELDS) return false;
|
|
85
|
-
return value.every(item => isBoundedInputJson(item, depth + 1, budget));
|
|
86
|
-
}
|
|
87
|
-
const record = value as Record<string, unknown>;
|
|
88
|
-
const keys = Object.keys(record);
|
|
89
|
-
budget.fields += keys.length;
|
|
90
|
-
return (
|
|
91
|
-
budget.fields <= MAX_INPUT_JSON_FIELDS && keys.every(key => isBoundedInputJson(record[key], depth + 1, budget))
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Computes the fully qualified digest for an elevation request.
|
|
97
|
-
*
|
|
98
|
-
* `input` is digested exactly as supplied except that a top-level
|
|
99
|
-
* `elevationRequestId` field is removed first (it is the correlation ID, not
|
|
100
|
-
* approved content). Operations outside `ELEVATION_ALLOWLIST` are refused
|
|
101
|
-
* with `elevation_not_required` so the broker never mints a grant for an
|
|
102
|
-
* operation that does not need one.
|
|
103
|
-
*/
|
|
104
|
-
export function elevationRequestDigest(request: {
|
|
105
|
-
kind: unknown;
|
|
106
|
-
sdkId: unknown;
|
|
107
|
-
input: unknown;
|
|
108
|
-
}): ElevationDigestResult {
|
|
109
|
-
const kind = request.kind;
|
|
110
|
-
if (!ELEVATION_OPERATION_KINDS.includes(kind as ElevationOperationKind))
|
|
111
|
-
return { ok: false, error: { code: "invalid_input", message: "kind must be control, query, or global" } };
|
|
112
|
-
if (typeof request.sdkId !== "string" || request.sdkId.length === 0 || request.sdkId.length > MAX_SDK_ID_LENGTH)
|
|
113
|
-
return { ok: false, error: { code: "invalid_input", message: "sdkId must be a non-empty bounded string" } };
|
|
114
|
-
if (!isElevatableOperation(kind, request.sdkId))
|
|
115
|
-
return {
|
|
116
|
-
ok: false,
|
|
117
|
-
error: { code: "elevation_not_required", message: `${request.sdkId} does not require elevation` },
|
|
118
|
-
};
|
|
119
|
-
if (typeof request.input !== "object" || request.input === null || Array.isArray(request.input))
|
|
120
|
-
return { ok: false, error: { code: "invalid_input", message: "input must be a JSON object" } };
|
|
121
|
-
if (!isBoundedInputJson(request.input))
|
|
122
|
-
return { ok: false, error: { code: "invalid_input", message: "input exceeds the bounded JSON limits" } };
|
|
123
|
-
const input = { ...(request.input as Record<string, unknown>) };
|
|
124
|
-
delete input.elevationRequestId;
|
|
125
|
-
const digest = createHash("sha256")
|
|
126
|
-
.update(canonicalElevationJson({ kind: kind as ElevationOperationKind, sdkId: request.sdkId, input }))
|
|
127
|
-
.digest("hex");
|
|
128
|
-
return { ok: true, digest };
|
|
129
|
-
}
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { isProcessIncarnation } from "../broker/process-incarnation";
|
|
2
|
-
|
|
3
|
-
export const ELEVATION_RECEIPT_VERSION = 1;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Identity of the broker tenure that claims a grant and dispatches it.
|
|
7
|
-
*
|
|
8
|
-
* `ownerId` is the broker instance owner id and `epoch` increments per broker
|
|
9
|
-
* start, so a restart (even of the same object) yields a new tenure. `pid` and
|
|
10
|
-
* `incarnation` are retained for truthful tri-state liveness replay.
|
|
11
|
-
*/
|
|
12
|
-
export interface ElevationClaimIdentity {
|
|
13
|
-
ownerId: string;
|
|
14
|
-
epoch: number;
|
|
15
|
-
pid: number;
|
|
16
|
-
incarnation: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type ElevationReceiptState = "claimed" | "dispatched" | "uncertain";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Durable dispatch outcome. `unknown` is the crash truth: the grant was
|
|
23
|
-
* consumed by a claim but the dispatch outcome is not knowable, so retry
|
|
24
|
-
* requires a new grant.
|
|
25
|
-
*/
|
|
26
|
-
export type ElevationDispatchOutcome =
|
|
27
|
-
| { status: "ok"; dispatchedAt: number }
|
|
28
|
-
| { status: "failed"; code: string; message: string; dispatchedAt: number }
|
|
29
|
-
| { status: "unknown"; message: string; dispatchedAt: number };
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Owner/epoch-bound dispatch receipt.
|
|
33
|
-
*
|
|
34
|
-
* State machine: `claimed` (grant spent, dispatch in flight, bound to the
|
|
35
|
-
* claiming broker tenure) -> `dispatched` (terminal, outcome recorded) or
|
|
36
|
-
* `uncertain` (terminal truth: the claim's outcome is unknowable after its
|
|
37
|
-
* broker tenure died). Replay never fabricates an outcome: a receipt left in
|
|
38
|
-
* `claimed` by a dead tenure is truthfully terminalized to `uncertain`.
|
|
39
|
-
*/
|
|
40
|
-
export interface ElevationDispatchReceipt {
|
|
41
|
-
version: typeof ELEVATION_RECEIPT_VERSION;
|
|
42
|
-
elevationRequestId: string;
|
|
43
|
-
issueIndex: number;
|
|
44
|
-
state: ElevationReceiptState;
|
|
45
|
-
claim: ElevationClaimIdentity & { claimedAt: number };
|
|
46
|
-
dispatch?: { ownerId: string; epoch: number; dispatchedAt: number };
|
|
47
|
-
outcome?: ElevationDispatchOutcome;
|
|
48
|
-
ts: number;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
52
|
-
|
|
53
|
-
export function isElevationRequestId(value: unknown): value is string {
|
|
54
|
-
return typeof value === "string" && UUID_V4.test(value);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function isElevationClaimIdentity(value: unknown): value is ElevationClaimIdentity {
|
|
58
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
59
|
-
const identity = value as { ownerId?: unknown; epoch?: unknown; pid?: unknown; incarnation?: unknown };
|
|
60
|
-
return (
|
|
61
|
-
typeof identity.ownerId === "string" &&
|
|
62
|
-
identity.ownerId.length > 0 &&
|
|
63
|
-
Number.isSafeInteger(identity.epoch) &&
|
|
64
|
-
(identity.epoch as number) > 0 &&
|
|
65
|
-
Number.isSafeInteger(identity.pid) &&
|
|
66
|
-
(identity.pid as number) > 0 &&
|
|
67
|
-
isProcessIncarnation(identity.incarnation)
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function isElevationDispatchOutcome(value: unknown): value is ElevationDispatchOutcome {
|
|
72
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
73
|
-
const outcome = value as { status?: unknown; code?: unknown; message?: unknown; dispatchedAt?: unknown };
|
|
74
|
-
if (!Number.isSafeInteger(outcome.dispatchedAt) || (outcome.dispatchedAt as number) <= 0) return false;
|
|
75
|
-
if (outcome.status === "ok") return true;
|
|
76
|
-
if (outcome.status === "unknown") return typeof outcome.message === "string";
|
|
77
|
-
if (outcome.status === "failed")
|
|
78
|
-
return typeof outcome.code === "string" && outcome.code.length > 0 && typeof outcome.message === "string";
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function isElevationDispatchReceipt(value: unknown): value is ElevationDispatchReceipt {
|
|
83
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
84
|
-
const receipt = value as Partial<ElevationDispatchReceipt>;
|
|
85
|
-
if (
|
|
86
|
-
receipt.version !== ELEVATION_RECEIPT_VERSION ||
|
|
87
|
-
!isElevationRequestId(receipt.elevationRequestId) ||
|
|
88
|
-
!Number.isSafeInteger(receipt.issueIndex) ||
|
|
89
|
-
(receipt.issueIndex as number) <= 0 ||
|
|
90
|
-
(receipt.state !== "claimed" && receipt.state !== "dispatched" && receipt.state !== "uncertain") ||
|
|
91
|
-
!isElevationClaimIdentity(receipt.claim) ||
|
|
92
|
-
!Number.isSafeInteger(receipt.claim.claimedAt) ||
|
|
93
|
-
(receipt.claim.claimedAt as number) <= 0 ||
|
|
94
|
-
!Number.isSafeInteger(receipt.ts) ||
|
|
95
|
-
(receipt.ts as number) <= 0
|
|
96
|
-
)
|
|
97
|
-
return false;
|
|
98
|
-
if (receipt.state === "claimed") return receipt.dispatch === undefined && receipt.outcome === undefined;
|
|
99
|
-
if (receipt.state === "uncertain") {
|
|
100
|
-
const outcome = receipt.outcome;
|
|
101
|
-
return receipt.dispatch === undefined && isElevationDispatchOutcome(outcome) && outcome.status === "unknown";
|
|
102
|
-
}
|
|
103
|
-
const dispatch = receipt.dispatch;
|
|
104
|
-
if (dispatch === undefined) return false;
|
|
105
|
-
return (
|
|
106
|
-
typeof dispatch.ownerId === "string" &&
|
|
107
|
-
dispatch.ownerId.length > 0 &&
|
|
108
|
-
Number.isSafeInteger(dispatch.epoch) &&
|
|
109
|
-
dispatch.epoch > 0 &&
|
|
110
|
-
Number.isSafeInteger(dispatch.dispatchedAt) &&
|
|
111
|
-
dispatch.dispatchedAt > 0 &&
|
|
112
|
-
isElevationDispatchOutcome(receipt.outcome) &&
|
|
113
|
-
receipt.outcome.status !== "unknown"
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function claimReceipt(
|
|
118
|
-
requestId: string,
|
|
119
|
-
issueIndex: number,
|
|
120
|
-
claim: ElevationClaimIdentity,
|
|
121
|
-
claimedAt: number,
|
|
122
|
-
): ElevationDispatchReceipt {
|
|
123
|
-
return {
|
|
124
|
-
version: ELEVATION_RECEIPT_VERSION,
|
|
125
|
-
elevationRequestId: requestId,
|
|
126
|
-
issueIndex,
|
|
127
|
-
state: "claimed",
|
|
128
|
-
claim: { ...claim, claimedAt },
|
|
129
|
-
ts: claimedAt,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export function dispatchReceipt(
|
|
134
|
-
receipt: ElevationDispatchReceipt,
|
|
135
|
-
dispatch: { ownerId: string; epoch: number; dispatchedAt: number },
|
|
136
|
-
outcome: ElevationDispatchOutcome,
|
|
137
|
-
): ElevationDispatchReceipt {
|
|
138
|
-
return {
|
|
139
|
-
...receipt,
|
|
140
|
-
state: "dispatched",
|
|
141
|
-
dispatch,
|
|
142
|
-
outcome,
|
|
143
|
-
ts: dispatch.dispatchedAt,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export function uncertainReceipt(receipt: ElevationDispatchReceipt, at: number): ElevationDispatchReceipt {
|
|
148
|
-
return {
|
|
149
|
-
...receipt,
|
|
150
|
-
state: "uncertain",
|
|
151
|
-
outcome: {
|
|
152
|
-
status: "unknown",
|
|
153
|
-
message: "Claiming broker tenure ended before dispatch outcome was recorded",
|
|
154
|
-
dispatchedAt: at,
|
|
155
|
-
},
|
|
156
|
-
ts: at,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export function receiptClaimMatches(receipt: ElevationDispatchReceipt, identity: ElevationClaimIdentity): boolean {
|
|
161
|
-
return receipt.claim.ownerId === identity.ownerId && receipt.claim.epoch === identity.epoch;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Who may answer an elevation gate.
|
|
166
|
-
*
|
|
167
|
-
* Internal operator-only: the answer boundary is the broker's internal
|
|
168
|
-
* operator attestation (`local_operator`), reached only through broker-owned
|
|
169
|
-
* surfaces. There is no public `elevation.answer` operation and no
|
|
170
|
-
* requester-correlation check: the answerer is structurally an operator
|
|
171
|
-
* attestation, so requester self-approval is impossible by construction.
|
|
172
|
-
*/
|
|
173
|
-
export type ElevationAnswerAuthority = { source: "local_operator"; attestedBy: string };
|
|
174
|
-
|
|
175
|
-
/** Structural guard for the internal operator attestation. */
|
|
176
|
-
export function isElevationAnswerAuthority(value: unknown): value is ElevationAnswerAuthority {
|
|
177
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
178
|
-
const authority = value as { source?: unknown; attestedBy?: unknown };
|
|
179
|
-
return (
|
|
180
|
-
authority.source === "local_operator" &&
|
|
181
|
-
typeof authority.attestedBy === "string" &&
|
|
182
|
-
authority.attestedBy.length > 0
|
|
183
|
-
);
|
|
184
|
-
}
|