@humwick/server 0.130.1 → 0.130.2
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 +5 -0
- package/docs/guides/tools-administration.md +4 -0
- package/docs/guides/tools-coordination.md +1 -0
- package/docs/guides/tools-tasks.md +8 -0
- package/docs/guides/workflows.md +58 -0
- package/docs/openapi.json +414 -1
- package/package.json +8 -17
- package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-BWLqMGKG.js} +2 -2
- package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-3TlIQpjk.js} +2 -2
- package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-Wimm0Czv.js} +2 -2
- package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-Bau_vNax.js} +2 -2
- package/public/assets/{activity-yLztXEBt.js → activity-CrSurn-r.js} +2 -2
- package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-CknAJKcb.js} +2 -2
- package/public/assets/agent-liveness-CaNwK0Zf.js +2 -0
- package/public/assets/{agent-name-CTZBrSD9.js → agent-name-DKbiIhBo.js} +2 -2
- package/public/assets/agent-profiles-DwF6EQ4R.js +2 -0
- package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-Diz4Sjjb.js} +2 -2
- package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-CRhpRQza.js} +2 -2
- package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-LrUEU3lB.js} +2 -2
- package/public/assets/{agents-BYDslkJc.js → agents-B-v66C-4.js} +2 -2
- package/public/assets/{analytics-B-XSbEMC.js → analytics-BqCb-LKi.js} +2 -2
- package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-kf4pGuAR.js} +2 -2
- package/public/assets/{artifacts-oBOqks-2.js → artifacts-D32zyw4Y.js} +2 -2
- package/public/assets/{artifacts-DPN1q4pA.js → artifacts-DJevXcvg.js} +2 -2
- package/public/assets/{automation-4KcRFXEu.js → automation-BpRajx_5.js} +2 -2
- package/public/assets/{backlog-Cw9xPTCF.js → backlog-D_UjTdzX.js} +2 -2
- package/public/assets/{busy-health-CTu32MZt.js → busy-health-N3VEh4ao.js} +2 -2
- package/public/assets/{channels-BiXzg1G9.js → channels-9jopungq.js} +2 -2
- package/public/assets/{chat-Ctk2qwvA.js → chat-CSXrTB3C.js} +2 -2
- package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-p1NnmqK0.js} +2 -2
- package/public/assets/{connectors-C36ax4Vw.js → connectors-CZdqlDNL.js} +2 -2
- package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BgdsE4dG.js} +2 -2
- package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-30aXTKva.js} +2 -2
- package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-B_jvw2GE.js} +2 -2
- package/public/assets/{deploys-Bwfq146q.js → deploys-DoN6bAb5.js} +2 -2
- package/public/assets/{display-CfO7rTuF.js → display-BrKWFGJz.js} +2 -2
- package/public/assets/{files-DhhZI2Ih.js → files-D6XEu8Ng.js} +2 -2
- package/public/assets/{fleet-B_rFEbnL.js → fleet-C7jQWbw2.js} +2 -2
- package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BiDs3MLx.js} +2 -2
- package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-CQBwc1fb.js} +3 -3
- package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-DyG0WsQS.js} +2 -2
- package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-DKaW31dN.js} +2 -2
- package/public/assets/index-CRHep3M9.js +15 -0
- package/public/assets/index-MYAIwYTX.css +2 -0
- package/public/assets/{insights-fH1EL-qZ.js → insights-CzrtkpOE.js} +2 -2
- package/public/assets/{integrations-C5Oix6ng.js → integrations-aVsUmigt.js} +2 -2
- package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-BnSlM_95.js} +2 -2
- package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-qe7Ee47Z.js} +2 -2
- package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-NfjqFZAk.js} +2 -2
- package/public/assets/{managed-agents-egllbpij.js → managed-agents-BiH0HgaE.js} +2 -2
- package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-BixaT3Xr.js} +3 -3
- package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-DNGlWIS3.js} +2 -2
- package/public/assets/{memory-C8WmXsyr.js → memory-DNsCl6UX.js} +2 -2
- package/public/assets/{messages-BzQdqlO6.js → messages-DopU1L1X.js} +2 -2
- package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Cq7ckLQT.js} +2 -2
- package/public/assets/{overview-DCUnI4Z7.js → overview-C1DCTzzV.js} +2 -2
- package/public/assets/{pairs-ftCd2XcD.js → pairs-DE_m6rrE.js} +2 -2
- package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-B3rfh77F.js} +2 -2
- package/public/assets/project-profile-instructions-DQWZE0kA.js +2 -0
- package/public/assets/projects-Br2Bd2h1.js +2 -0
- package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-BKvFsvGD.js} +2 -2
- package/public/assets/provider-display-DsuWMvVL.js +2 -0
- package/public/assets/{registry-DWCU5c8q.js → registry-Cw38_6gW.js} +2 -2
- package/public/assets/run-card-CpKqRbhg.js +2 -0
- package/public/assets/scroll-text-BKXS1ahr.js +2 -0
- package/public/assets/{secrets-C7GIUATz.js → secrets-DxI-vzSq.js} +2 -2
- package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-D9s_VJbd.js} +2 -2
- package/public/assets/{settings-C6sZ9eBa.js → settings-CKZTVGIx.js} +2 -2
- package/public/assets/{shipping-Bu8p1gEw.js → shipping-B9YtnwtG.js} +2 -2
- package/public/assets/{stats-V9Z-GxUd.js → stats-DyUBKyWI.js} +2 -2
- package/public/assets/{status-dot-CVv0iGHL.js → status-dot-DYqlEUhJ.js} +2 -2
- package/public/assets/{store-BvtFdlGX.js → store-DcClXLH0.js} +3 -3
- package/public/assets/{tasks-CXU75HRF.js → tasks-Bh7Chr4-.js} +2 -2
- package/public/assets/{teams-BPf976zb.js → teams-bowI7qVY.js} +2 -2
- package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-BgVLHdsU.js} +3 -3
- package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-Dz22UPy6.js} +2 -2
- package/public/assets/token-estimate-Co-Jdphh.js +2 -0
- package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-DSQQ-iY7.js} +2 -2
- package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-samMQhQf.js} +2 -2
- package/public/assets/use-project-list-59LheVP7.js +2 -0
- package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BZa25xEB.js} +2 -2
- package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-DHxlvUvV.js} +2 -2
- package/public/assets/versioned-prompt-editor-BmED5DnJ.js +8 -0
- package/public/assets/{work-queue-TCjJxeT-.js → work-queue-CSvpuNLz.js} +2 -2
- package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-DAZcj5qt.js} +2 -2
- package/public/assets/{workflows-CXQX20Qj.js → workflows-DdmxRSyg.js} +2 -2
- package/public/assets/{workspaces-qSYzKYMA.js → workspaces-BxeKfVuF.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +31 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
- package/runner/src/adapters/claude-effort.ts +2 -4
- package/runner/src/adapters/codex-launch-config.ts +4 -5
- package/runner/src/adapters/codex.ts +1 -1
- package/runner/src/adapters/opencode-provider.ts +7 -22
- package/runner/src/adapters/opencode.ts +4 -4
- package/runner/src/agent-runner/credentials.ts +42 -12
- package/runner/src/agent-runner/inbox.ts +27 -0
- package/runner/src/agent-runner/lifecycle-milestones.ts +0 -2
- package/runner/src/bin/claude.ts +4 -0
- package/runner/src/bin/codex.ts +4 -0
- package/runner/src/bin/opencode.ts +4 -0
- package/runner/src/index.ts +5 -2
- package/runner/src/provider-setup.ts +34 -0
- package/runner/src/providers.ts +2 -1
- package/runner/src/runner-core.ts +18 -23
- package/runner/src/spawn-input.ts +2 -1
- package/runner/src/test-run-dedup.ts +59 -56
- package/scripts/cd-config.ts +8 -0
- package/scripts/gate-run-lease.ts +10 -7
- package/scripts/gate.sh +5 -1
- package/src/branch-land-notice.ts +93 -0
- package/src/branch-landed.ts +7 -76
- package/src/bus.ts +19 -20
- package/src/cd-deploy-notify.ts +30 -2
- package/src/cd-host-lag-notify.ts +7 -6
- package/src/ci/incidents.ts +2 -2
- package/src/ci/monitor.ts +5 -8
- package/src/ci/root-missing.ts +2 -7
- package/src/ci/transition-notify.ts +7 -39
- package/src/cli/cd-pauses.ts +19 -0
- package/src/cli/orchestrator.ts +1 -1
- package/src/cli/state.ts +2 -19
- package/src/cli/task-edit.ts +22 -0
- package/src/cli/task.ts +3 -1
- package/src/cli/workflow.ts +8 -2
- package/src/commands-db.ts +3 -3
- package/src/config-store-write.ts +13 -1
- package/src/config-store.ts +25 -14
- package/src/db/activity-async.ts +6 -1
- package/src/db/activity-write-ops.ts +12 -1
- package/src/db/activity.ts +1 -14
- package/src/db/agent-search.ts +1 -15
- package/src/db/agents-async.ts +52 -5
- package/src/db/agents-write-ops.ts +12 -3
- package/src/db/agents.ts +81 -54
- package/src/db/ci-incidents-async.ts +5 -5
- package/src/db/ci-incidents-write-ops.ts +2 -2
- package/src/db/command-row.ts +10 -2
- package/src/db/commands-list-query.ts +2 -0
- package/src/db/commands-spawn-read.ts +1 -1
- package/src/db/config-store-write-ops.ts +7 -2
- package/src/db/continuation-archives-async.ts +5 -0
- package/src/db/continuation-archives-write-ops.ts +7 -0
- package/src/db/continuations.ts +2 -2
- package/src/db/db-writer-worker.ts +8 -1
- package/src/db/deploy-events-async.ts +1 -0
- package/src/db/deploy-events-read-ops.ts +2 -1
- package/src/db/deploy-events.ts +35 -4
- package/src/db/hosts-registration.ts +10 -2
- package/src/db/hosts.ts +9 -6
- package/src/db/inbox.ts +0 -14
- package/src/db/index.ts +2 -0
- package/src/db/integrations-async.ts +8 -0
- package/src/db/integrations-ops.ts +15 -0
- package/src/db/integrations.ts +15 -21
- package/src/db/issue-lifecycle.ts +3 -4
- package/src/db/issue-refs-async.ts +20 -0
- package/src/db/issue-refs-write-ops.ts +29 -0
- package/src/db/issue-refs.ts +7 -8
- package/src/db/long-running-work.ts +2 -2
- package/src/db/main-connection-writes.ts +23 -2
- package/src/db/maintenance-job-reconcile.ts +61 -0
- package/src/db/maintenance-job-runs-async.ts +14 -0
- package/src/db/maintenance-job-write-ops.ts +9 -0
- package/src/db/mappers.ts +2 -14
- package/src/db/merge-lease.ts +1 -15
- package/src/db/migrations.ts +7 -15
- package/src/db/orchestrators.ts +4 -72
- package/src/db/pairs.ts +1 -13
- package/src/db/project-profile-instructions.ts +50 -0
- package/src/db/prompt-versions.ts +9 -2
- package/src/db/provider-config-history.ts +8 -3
- package/src/db/provider-model-seed.ts +34 -0
- package/src/db/read-op-marshaling-fixtures.ts +5 -0
- package/src/db/read-ops.ts +4 -0
- package/src/db/routing-policy.ts +2 -3
- package/src/db/schema.ts +9 -3
- package/src/db/spawn-delegation-state.ts +11 -4
- package/src/db/stats-async.ts +4 -3
- package/src/db/task-entity.ts +23 -2
- package/src/db/task-list.ts +3 -1
- package/src/db/tasks.ts +1 -17
- package/src/db/timer-ingress.ts +7 -1
- package/src/db/token-db-write-ops.ts +17 -0
- package/src/db/token-standing.ts +15 -11
- package/src/db/workflow-contact.ts +1 -1
- package/src/db/workflow-task-read-ops.ts +30 -0
- package/src/db/write-ops.ts +6 -0
- package/src/db/writer-gateway.ts +17 -11
- package/src/dispatch-availability.ts +10 -6
- package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
- package/src/host/disk-alert.ts +121 -0
- package/src/lifecycle-manager.ts +3 -2
- package/src/maintenance/cd-watcher.ts +3 -3
- package/src/maintenance/critical-job-watchdog.ts +16 -17
- package/src/maintenance/index.ts +1 -0
- package/src/maintenance/jobs.ts +3 -2
- package/src/maintenance/scheduler.ts +84 -128
- package/src/maintenance/stalled-delivery-pager.ts +6 -5
- package/src/maintenance/workspaces.ts +1 -1
- package/src/managed-policy.ts +31 -27
- package/src/mcp/index.ts +5 -2
- package/src/mcp/output-descriptions.ts +8 -8
- package/src/mcp/presentation.ts +4 -4
- package/src/mcp/project-profile-instructions.ts +32 -0
- package/src/mcp/tool-groups.ts +1 -1
- package/src/mcp/tools-spawn.ts +4 -3
- package/src/mcp-agent-action.ts +1 -2
- package/src/mcp-issue-ref-tools.ts +12 -11
- package/src/mcp-maintenance-tools.ts +2 -2
- package/src/mcp-profile-trust-tools.ts +4 -4
- package/src/mcp-provider-catalog.ts +2 -2
- package/src/mcp-task-tools.ts +11 -5
- package/src/mcp-team-template-tools.ts +3 -3
- package/src/mcp-workflow-tools.ts +10 -3
- package/src/notification-types.ts +2 -1
- package/src/operator-alarm.ts +26 -11
- package/src/project-instructions.ts +4 -0
- package/src/project-profile-instruction-text.ts +6 -0
- package/src/project-profile-instructions.ts +20 -0
- package/src/provider-catalog-store.ts +3 -49
- package/src/provider-config-store.ts +12 -11
- package/src/provider-model-seed.ts +1 -18
- package/src/provider-quota-config-store.ts +5 -4
- package/src/provider-secrets.test-fixture.ts +3 -3
- package/src/recipe-runner.ts +2 -2
- package/src/repo-config-source.ts +10 -4
- package/src/routes/agent-profiles.ts +6 -6
- package/src/routes/agents-spawn.ts +1 -1
- package/src/routes/agents.ts +6 -6
- package/src/routes/commands-listing.ts +4 -0
- package/src/routes/commands.ts +2 -2
- package/src/routes/continuation-archives.ts +2 -2
- package/src/routes/index.ts +10 -1
- package/src/routes/integrations.ts +24 -50
- package/src/routes/issue-refs.ts +7 -7
- package/src/routes/orchestrator-bootstrap.ts +1 -1
- package/src/routes/orchestrator-host-registration.ts +2 -2
- package/src/routes/orchestrator-host-utilization.ts +3 -1
- package/src/routes/orchestrator-proxy.ts +2 -2
- package/src/routes/orchestrator.ts +2 -2
- package/src/routes/project-profile-instructions.ts +27 -0
- package/src/routes/project-trust.ts +2 -2
- package/src/routes/provider-config.ts +6 -6
- package/src/routes/provider-quota-config.ts +2 -2
- package/src/routes/settings.ts +5 -5
- package/src/routes/stats.ts +6 -6
- package/src/routes/task-http.ts +15 -1
- package/src/routes/task-issues.ts +11 -26
- package/src/routes/tasks.ts +22 -53
- package/src/routes/team-templates.ts +5 -5
- package/src/routes/teams-config.ts +2 -2
- package/src/routes/tokens.ts +12 -5
- package/src/routes/workflows.ts +20 -5
- package/src/routing-policy-normalize.ts +1 -2
- package/src/routing-step-defaults.ts +0 -2
- package/src/runner-token-mint-limit.ts +63 -0
- package/src/runtime-grant.ts +4 -2
- package/src/runtime-tokens.ts +39 -7
- package/src/security.ts +13 -20
- package/src/server-background.ts +1 -1
- package/src/server.ts +5 -2
- package/src/services/host-utilization.ts +23 -0
- package/src/services/idle-epics.ts +5 -6
- package/src/services/issue-lifecycle.ts +57 -61
- package/src/services/issue-refs.ts +9 -13
- package/src/services/kernel-timers-cutover-chaos-worker.ts +10 -7
- package/src/services/kernel-timers-ingress.ts +1 -1
- package/src/services/landed-ancestry.ts +19 -3
- package/src/services/memory-areas.ts +15 -51
- package/src/services/plan-ci-notice.ts +57 -0
- package/src/services/plan-ci-recovery.ts +2 -55
- package/src/services/plan-wake-digest.ts +1 -0
- package/src/services/profile-trust.ts +4 -3
- package/src/services/project-config-read.ts +70 -0
- package/src/services/project-profile-instructions.ts +54 -0
- package/src/services/provisioning-harness/budget-baseline.json +4 -4
- package/src/services/restart-spawn.ts +61 -49
- package/src/services/self-care-state.ts +2 -1
- package/src/services/self-effort.ts +5 -5
- package/src/services/send-message.ts +5 -1
- package/src/services/spawn-agent.ts +13 -2
- package/src/services/spawn-chain-inspector.ts +6 -13
- package/src/services/spawn-policy.ts +68 -0
- package/src/services/spawn-tree-cleanup.ts +2 -2
- package/src/services/task-dispatch.ts +3 -0
- package/src/services/task-state-reconcile.ts +6 -14
- package/src/services/team-templates.ts +9 -8
- package/src/services/transient-agent-reaper.ts +3 -1
- package/src/services/workflow-auto-start.ts +25 -13
- package/src/services/workflow-ci-main.ts +1 -1
- package/src/services/workflow-deferred-cleanup.ts +4 -2
- package/src/services/workflow-effect-driver.ts +2 -0
- package/src/services/workflow-effects.ts +18 -11
- package/src/services/workflow-land-notice.ts +10 -0
- package/src/services/workflow-pause-text.ts +43 -0
- package/src/services/workflow-reconcile.ts +13 -11
- package/src/services/workflow-run-view.ts +2 -0
- package/src/services/workflow-runs.ts +29 -13
- package/src/services/workflow-supervisor-state.ts +5 -0
- package/src/services/workflow-supervisor.ts +7 -3
- package/src/settings/registry.ts +1 -2
- package/src/spawn-command.ts +4 -4
- package/src/spawn-models.ts +10 -12
- package/src/spawn-placement.ts +1 -1
- package/src/spawn-targets.ts +1 -1
- package/src/startup-context-injection.ts +1 -0
- package/src/state-adoption/cd-cutover.ts +53 -7
- package/src/state-adoption/fleet-cutover.ts +35 -0
- package/src/state-adoption/fleet-plan.ts +36 -0
- package/src/state-adoption/index.ts +2 -2
- package/src/state-adoption/linux-plan.ts +2 -2
- package/src/state-adoption/linux.ts +2 -2
- package/src/state-adoption/macos-plan.ts +2 -2
- package/src/state-adoption/macos.ts +1 -1
- package/src/steward.ts +7 -6
- package/src/task-dispatch-live.ts +1 -1
- package/src/task-dispatcher.ts +1 -1
- package/src/teams-config-store.ts +4 -3
- package/src/token-db-write.ts +10 -0
- package/src/workspace-command-settle.ts +2 -1
- package/src/workspace-steward-wake.ts +2 -2
- package/node_modules/@humwick/kernel/LICENSE +0 -167
- package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
- package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
- package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
- package/node_modules/@humwick/kernel/config.ts +0 -111
- package/node_modules/@humwick/kernel/contract.ts +0 -572
- package/node_modules/@humwick/kernel/control-authz.ts +0 -281
- package/node_modules/@humwick/kernel/control.ts +0 -645
- package/node_modules/@humwick/kernel/effects.ts +0 -493
- package/node_modules/@humwick/kernel/event-log.ts +0 -319
- package/node_modules/@humwick/kernel/http-transport.ts +0 -384
- package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
- package/node_modules/@humwick/kernel/identity.ts +0 -248
- package/node_modules/@humwick/kernel/index.ts +0 -28
- package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
- package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
- package/node_modules/@humwick/kernel/landing.ts +0 -953
- package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
- package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
- package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
- package/node_modules/@humwick/kernel/message-authority.ts +0 -281
- package/node_modules/@humwick/kernel/module-host.ts +0 -722
- package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
- package/node_modules/@humwick/kernel/package.json +0 -39
- package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
- package/node_modules/@humwick/kernel/persistence.ts +0 -510
- package/node_modules/@humwick/kernel/registry.ts +0 -60
- package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
- package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
- package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
- package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
- package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
- package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
- package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
- package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
- package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
- package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
- package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
- package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
- package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
- package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
- package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
- package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
- package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
- package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
- package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
- package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
- package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
- package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
- package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
- package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
- package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
- package/node_modules/@humwick/offload/LICENSE +0 -167
- package/node_modules/@humwick/offload/README.md +0 -57
- package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
- package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
- package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
- package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.js +0 -80
- package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
- package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/index.js +0 -5
- package/node_modules/@humwick/offload/dist/index.js.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
- package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
- package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/types.js +0 -176
- package/node_modules/@humwick/offload/dist/types.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
- package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
- package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.js +0 -1
- package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
- package/node_modules/@humwick/offload/package.json +0 -42
- package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
- package/node_modules/@humwick/offload/src/envelope.ts +0 -92
- package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
- package/node_modules/@humwick/offload/src/index.ts +0 -4
- package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
- package/node_modules/@humwick/offload/src/types.ts +0 -235
- package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
- package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
- package/node_modules/@humwick/offload/src/worker.ts +0 -5
- package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
- package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
- package/public/assets/index-B7ZerHLY.css +0 -2
- package/public/assets/index-BU3uWo2t.js +0 -15
- package/public/assets/projects-B_lmcqfO.js +0 -2
- package/public/assets/provider-display-DbLWpP3j.js +0 -2
- package/public/assets/run-card-CO_bguQf.js +0 -2
- package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
- package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
- package/runner/src/gate-run-lease-probe.ts +0 -38
- package/src/db/claude-catalog-reconcile.ts +0 -27
- package/src/routing-model-aliases.ts +0 -21
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
import type { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
|
-
import type { Context } from "hono";
|
|
3
|
-
import type { Grant, ResolvedIdentity } from "./contract";
|
|
4
|
-
import type { InvocationIdentity, ModuleHost } from "./module-host";
|
|
5
|
-
import { type HttpTransportOptions, type IdentityResolver, createHttpApp } from "./http-transport";
|
|
6
|
-
import {
|
|
7
|
-
type ControlModule,
|
|
8
|
-
CONTROL_ADMIN_GRANT,
|
|
9
|
-
CONTROL_READ_GRANT,
|
|
10
|
-
CONTROL_WRITE_GRANT,
|
|
11
|
-
SYSTEM_ADMIN_GRANT,
|
|
12
|
-
} from "./control";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* K1-6 — the control-module scope→grant bridge + fail-closed edge identity for the `/api/kernel`
|
|
16
|
-
* transport. The kernel invoker is default-deny over FLAT, EXACT grants (`admin` does NOT imply
|
|
17
|
-
* `read`/`write` — see `identity.ts:isAuthorized`) and carries no cwd constraints, so the transport
|
|
18
|
-
* edge must translate the caller's authenticated scopes into the exact grants the control ops declare
|
|
19
|
-
* before an op is invoked — exactly as the timers pilot does at its MCP boundary
|
|
20
|
-
* (`src/services/kernel-timers-authz.ts:timerInvocationIdentity`).
|
|
21
|
-
*
|
|
22
|
-
* ── O2 — the admin-token expansion (why a bare admin scope is not enough) ───────────────────────────
|
|
23
|
-
* Under the exact-grant model an identity holding ONLY `control:admin` (or `system:admin`) 403s on
|
|
24
|
-
* every exposed op: `listInstances` requires `control:read`, `cancel` requires `control:write`, and
|
|
25
|
-
* neither is implied by an admin grant. So an admin token MUST expand to `control:read + control:write`
|
|
26
|
-
* PLUS the admin grant — mirroring the timers bridge's `admin ⇒ timers:write + timers:read`. Only then
|
|
27
|
-
* can an admin identity actually invoke the read + control surface (not merely the `*System` twins).
|
|
28
|
-
*
|
|
29
|
-
* ── G-M2 / O4 — fail-closed, per-user, no blanket admin (#389 avoidance) ────────────────────────────
|
|
30
|
-
* {@link controlHttpIdentity} resolves a PER-USER identity from the request and returns a NO-GRANT
|
|
31
|
-
* identity when the request carries no control-scoped credential — so an anonymous/unauthenticated
|
|
32
|
-
* request yields `{grants: []}` and the invoker 403s it (G-M2). It deliberately does NOT reuse the src
|
|
33
|
-
* `authContextFromRequest` fallback, which maps a credential-less request to a full-reach `*` system
|
|
34
|
-
* principal (the #389 route fail-open): mounting the derived app must resolve real caller scopes, never
|
|
35
|
-
* a server-side superuser (O4). The token-reading step is injected (the src mount supplies it), keeping
|
|
36
|
-
* this mapping transport-scope-driven and testable in isolation.
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
/** The authenticated caller facts the bridge maps to grants: WHO (actor) and WHAT scopes the token
|
|
40
|
-
* carries. `resolvedIdentity` is the opaque server-resolved creator blob carried through verbatim for
|
|
41
|
-
* durable-effect identity freezing (P2-7), never interpreted here. */
|
|
42
|
-
export interface ControlAuthClaims {
|
|
43
|
-
readonly actor: string;
|
|
44
|
-
readonly scopes: readonly string[];
|
|
45
|
-
readonly resolvedIdentity?: ResolvedIdentity;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** A module-private brand. It is a real runtime symbol (so the mint can stamp it) but is NEVER
|
|
49
|
-
* exported, so no code outside this file can reference it — which is exactly what makes
|
|
50
|
-
* {@link VerifiedControlClaims} unforgeable from a raw object literal. */
|
|
51
|
-
const VERIFIED_BRAND: unique symbol = Symbol("kernel.control.verifiedClaims");
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* {@link ControlAuthClaims} that have been minted from a verified token — the ONLY value type the control
|
|
55
|
-
* mount's claims-resolver ({@link VerifiedClaimsResolver}) may return, and the ONLY shape
|
|
56
|
-
* {@link createControlHttpApp} accepts. The brand cannot be produced from an object literal
|
|
57
|
-
* (`VERIFIED_BRAND` is module-private), and the low-level mint is itself un-exported (W4d), so the ONLY
|
|
58
|
-
* mint out-of-kernel code can reach is {@link controlClaimsFromComponentToken}. A future `/api/kernel`
|
|
59
|
-
* mount therefore physically cannot hand the mount a bag of fields it scraped off a request header: it
|
|
60
|
-
* must present a verified {@link VerifiedComponentToken}, whose derivation is the explicit, reviewable
|
|
61
|
-
* "these are VERIFIED, server-resolved facts — from `getComponentAuth`, not a spoofable `actor` header"
|
|
62
|
-
* assertion (§4.1/§4.2, #389 avoidance). */
|
|
63
|
-
export interface VerifiedControlClaims extends ControlAuthClaims {
|
|
64
|
-
readonly [VERIFIED_BRAND]: true;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The low-level mint for {@link VerifiedControlClaims}. MODULE-PRIVATE by design (W4d, W4b-http finding 1):
|
|
69
|
-
* it is deliberately NOT exported, so the only mint reachable from out-of-kernel code is
|
|
70
|
-
* {@link controlClaimsFromComponentToken}, which forces the caller to present a token-shaped
|
|
71
|
-
* {@link VerifiedComponentToken} rather than an arbitrary `{actor, scopes}` bag. That closes the footgun
|
|
72
|
-
* where a future mount could hand-mint a `control:admin` grant from client-controlled `actor`/`scopes`
|
|
73
|
-
* fields it scraped off a request. This function does NOT itself verify anything — verification is the
|
|
74
|
-
* caller's earlier step; the brand only guarantees a resolver can reach {@link createControlHttpApp} ONLY
|
|
75
|
-
* by passing through the explicit token-derivation gate, so the misuse is never silent. The scopes still
|
|
76
|
-
* flow through the fail-closed {@link controlGrantsForScopes} allowlist downstream, so even an over-broad
|
|
77
|
-
* claim can only earn the exact grants that map. */
|
|
78
|
-
function verifiedControlClaims(claims: ControlAuthClaims): VerifiedControlClaims {
|
|
79
|
-
return {
|
|
80
|
-
actor: claims.actor,
|
|
81
|
-
scopes: claims.scopes,
|
|
82
|
-
...(claims.resolvedIdentity ? { resolvedIdentity: claims.resolvedIdentity } : {}),
|
|
83
|
-
[VERIFIED_BRAND]: true,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* The minimal shape of a VERIFIED component token the control mount derives its claims from (sol
|
|
89
|
-
* finding 1). A `/api/kernel` mount must produce this ONLY from a signature+revocation-verified
|
|
90
|
-
* component token (the src edge reads it from `getComponentAuth(req)`); a missing/invalid/non-component
|
|
91
|
-
* credential yields no token at all and the resolver denies. The kernel treats `constraints` as an
|
|
92
|
-
* opaque blob — it never interprets it (the src edge derives the caller-agent from it).
|
|
93
|
-
*/
|
|
94
|
-
export interface VerifiedComponentToken {
|
|
95
|
-
/** The token subject (`sub`) — the default actor when no finer caller-agent resolves. */
|
|
96
|
-
readonly sub: string;
|
|
97
|
-
/** The token's authenticated transport scopes. These become the claims' scopes VERBATIM — the only
|
|
98
|
-
* source of scope authority, so a client can never inject a scope through a header/body/query. */
|
|
99
|
-
readonly scope?: readonly string[];
|
|
100
|
-
/** The token's opaque signed constraint blob (agent/cwd axes). Server-resolved; never client-named. */
|
|
101
|
-
readonly constraints?: Readonly<Record<string, unknown>>;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Derive branded {@link VerifiedControlClaims} STRICTLY from a verified {@link VerifiedComponentToken}
|
|
106
|
-
* — the sol-finding-1 strengthening of the guard. The point: `actor`, `scopes`, and `resolvedIdentity`
|
|
107
|
-
* all originate in the verified token, NEVER in arbitrary caller-supplied fields:
|
|
108
|
-
*
|
|
109
|
-
* • `scopes` ← `token.scope` verbatim (a client cannot name its own scope).
|
|
110
|
-
* • `resolvedIdentity` ← the token's own kind/scopes/constraints (server-resolved; frozen for P2-7).
|
|
111
|
-
* • `actor` ← `resolveActor(token)`, which receives ONLY the token (not the request), so a
|
|
112
|
-
* mount cannot read a spoofable `x-actor` header here. The src mount passes
|
|
113
|
-
* `resolveCallerAgentId(token.constraints, …) ?? token.sub` (the resolver
|
|
114
|
-
* contract), deriving the caller-agent solely from the token's signed
|
|
115
|
-
* constraints.
|
|
116
|
-
*
|
|
117
|
-
* Because `resolveActor` is handed the token and nothing else, and scopes/resolvedIdentity are read off
|
|
118
|
-
* the token directly, there is no path from a header/body/query value into the resulting claims — the
|
|
119
|
-
* spoof surface #389 warns about is closed at the mint, not merely at the branding gate. The scopes
|
|
120
|
-
* still flow through the fail-closed {@link controlGrantsForScopes} allowlist downstream, so an
|
|
121
|
-
* over-broad token still only earns the exact grants that map.
|
|
122
|
-
*/
|
|
123
|
-
export function controlClaimsFromComponentToken(
|
|
124
|
-
token: VerifiedComponentToken,
|
|
125
|
-
resolveActor: (token: VerifiedComponentToken) => string,
|
|
126
|
-
): VerifiedControlClaims {
|
|
127
|
-
return verifiedControlClaims({
|
|
128
|
-
actor: resolveActor(token),
|
|
129
|
-
scopes: token.scope ?? [],
|
|
130
|
-
resolvedIdentity: {
|
|
131
|
-
kind: "component",
|
|
132
|
-
...(token.scope ? { scopes: token.scope } : {}),
|
|
133
|
-
...(token.constraints ? { constraints: token.constraints } : {}),
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** The per-request claims producer {@link createControlHttpApp} requires: it returns VERIFIED claims or
|
|
139
|
-
* `null` (⇒ anonymous default-deny). Typed to a {@link VerifiedControlClaims} producer, NOT a raw
|
|
140
|
-
* {@link IdentityResolver} — the mount cannot supply an arbitrary `(c)=>InvocationIdentity` and thereby
|
|
141
|
-
* hand-pick grants (e.g. mapping an anonymous caller straight to `control:admin`); every identity is
|
|
142
|
-
* forced through the branded-claims → {@link controlGrantsForScopes} allowlist path. */
|
|
143
|
-
export type VerifiedClaimsResolver = (c: Context) => VerifiedControlClaims | null;
|
|
144
|
-
|
|
145
|
-
/** The deny identity an anonymous/credential-less edge request resolves to: a valid actor label with
|
|
146
|
-
* ZERO grants, so the invoker's default-deny 403s it before any handler runs (G-M2). */
|
|
147
|
-
const ANONYMOUS_DENY: InvocationIdentity = Object.freeze({ actor: "anonymous", grants: [] as readonly Grant[] });
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Map a caller's authenticated transport scopes to the exact kernel grants the control ops declare
|
|
151
|
-
* (O2). Fail-closed: an unrecognized scope contributes nothing, and an empty/absent scope set yields
|
|
152
|
-
* NO grants (⇒ default-deny 403). The two admin scopes expand to the full read+control grant set so an
|
|
153
|
-
* admin identity can actually invoke the exposed surface, not just cross-creator-reach it:
|
|
154
|
-
*
|
|
155
|
-
* `control:read` ⇒ control:read
|
|
156
|
-
* `control:write` ⇒ control:write
|
|
157
|
-
* `control:admin` ⇒ control:admin + control:read + control:write (module-matched admin; reaches all)
|
|
158
|
-
* `system:admin` ⇒ system:admin + control:read + control:write (global admin; crosses creators)
|
|
159
|
-
*
|
|
160
|
-
* The `*System` twins are NOT reachable via any grant here — they carry `expose.mcp/http/cli:false`
|
|
161
|
-
* and so are excluded from every transport derivation (K-C2 / O1); grants alone never surface them.
|
|
162
|
-
*/
|
|
163
|
-
export function controlGrantsForScopes(scopes: Iterable<string>): Grant[] {
|
|
164
|
-
const held = new Set<string>(scopes);
|
|
165
|
-
const grants = new Set<Grant>();
|
|
166
|
-
const isAdmin = held.has(CONTROL_ADMIN_GRANT) || held.has(SYSTEM_ADMIN_GRANT);
|
|
167
|
-
if (held.has(CONTROL_READ_GRANT)) grants.add(CONTROL_READ_GRANT);
|
|
168
|
-
if (held.has(CONTROL_WRITE_GRANT)) grants.add(CONTROL_WRITE_GRANT);
|
|
169
|
-
if (isAdmin) {
|
|
170
|
-
// O2: an admin token must hold the entry grants the exposed ops gate on, or it 403s on every one.
|
|
171
|
-
grants.add(CONTROL_READ_GRANT);
|
|
172
|
-
grants.add(CONTROL_WRITE_GRANT);
|
|
173
|
-
}
|
|
174
|
-
if (held.has(CONTROL_ADMIN_GRANT)) grants.add(CONTROL_ADMIN_GRANT);
|
|
175
|
-
if (held.has(SYSTEM_ADMIN_GRANT)) grants.add(SYSTEM_ADMIN_GRANT);
|
|
176
|
-
return [...grants];
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Build the per-request {@link InvocationIdentity} for the control transport from authenticated claims:
|
|
181
|
-
* the actor becomes the kernel owner key (the per-creator ownership basis, exactly the timers
|
|
182
|
-
* `callerAgentId ?? actor.id` precedent) and the scopes map to grants via {@link controlGrantsForScopes}.
|
|
183
|
-
* A caller with no control scopes gets an empty grant set (default-deny). The trusted server-resolved
|
|
184
|
-
* `resolvedIdentity` rides through verbatim — never anything the client named.
|
|
185
|
-
*/
|
|
186
|
-
export function controlInvocationIdentity(claims: ControlAuthClaims): InvocationIdentity {
|
|
187
|
-
return {
|
|
188
|
-
actor: claims.actor,
|
|
189
|
-
grants: controlGrantsForScopes(claims.scopes),
|
|
190
|
-
...(claims.resolvedIdentity ? { resolvedIdentity: claims.resolvedIdentity } : {}),
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* The fail-closed {@link IdentityResolver} the control transport runs. `resolveClaims` reads the REAL
|
|
196
|
-
* caller from the request as VERIFIED claims (the src mount injects a reader over the component token —
|
|
197
|
-
* NOT `authContextFromRequest`, whose credential-less `*` fallback is the #389 fail-open); returning
|
|
198
|
-
* `null` means "no authenticated control caller", which resolves to the zero-grant {@link ANONYMOUS_DENY}
|
|
199
|
-
* identity ⇒ the invoker 403s (G-M2). It requires a {@link VerifiedClaimsResolver}, so there is no path
|
|
200
|
-
* that hand-picks grants or mints a blanket-admin identity for the app (O4): every non-anonymous
|
|
201
|
-
* identity is the caller's own, scoped to exactly the grants {@link controlGrantsForScopes} maps.
|
|
202
|
-
* Prefer {@link createControlHttpApp}, which wires this internally and never exposes a raw `identify`.
|
|
203
|
-
*/
|
|
204
|
-
export function controlHttpIdentity(resolveClaims: VerifiedClaimsResolver): IdentityResolver {
|
|
205
|
-
return (c: Context): InvocationIdentity => {
|
|
206
|
-
const claims = resolveClaims(c);
|
|
207
|
-
if (claims === null) return ANONYMOUS_DENY;
|
|
208
|
-
return controlInvocationIdentity(claims);
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* The SAFE-by-construction way to mount the control module over HTTP (the export the `/api/kernel` src
|
|
214
|
-
* mount must consume). It wraps {@link createHttpApp} and wires {@link controlHttpIdentity} internally,
|
|
215
|
-
* so the control app's `identify` is not caller-supplied: a mount CANNOT pass a raw
|
|
216
|
-
* `(c)=>InvocationIdentity` and thereby (a) map an unauthenticated/`system` principal directly to a
|
|
217
|
-
* recognized admin grant, nor (b) fabricate grants from a spoofable header — the only knob it exposes is
|
|
218
|
-
* `resolveClaims`, a {@link VerifiedClaimsResolver} that must return branded {@link VerifiedControlClaims}
|
|
219
|
-
* (mintable only via the explicit {@link verifiedControlClaims} gate) whose scopes then flow through the
|
|
220
|
-
* fail-closed {@link controlGrantsForScopes} allowlist. `options` intentionally omits `identify`; the
|
|
221
|
-
* remaining {@link HttpTransportOptions} (docPath / serveOpenApiDoc / info) pass through unchanged.
|
|
222
|
-
*
|
|
223
|
-
* ── §2.4 — the OpenAPI doc is scope-gated, not served to any authenticated caller ──────────────────────
|
|
224
|
-
* The generic {@link createHttpApp} serves its OpenAPI document from an UNAUTHENTICATED route
|
|
225
|
-
* (`app.doc(...)`), which is route + schema disclosure. On the control mount that is too open: the outer
|
|
226
|
-
* coarse gate treats a bare `*` (wildcard) token as universal, so it clears that gate — yet `*` maps to
|
|
227
|
-
* ZERO control grants through {@link controlGrantsForScopes} (which does NOT expand `*`), so it could
|
|
228
|
-
* still read the full spec while being 403'd on every op. So this wrapper WITHHOLDS the built-in doc route
|
|
229
|
-
* (`serveOpenApiDoc:false` to `createHttpApp`) and re-serves the document behind
|
|
230
|
-
* {@link mountGatedControlDoc}, which runs the SAME {@link VerifiedClaimsResolver} the op routes do: only a
|
|
231
|
-
* caller whose verified claims earn at least one control grant receives the document; anonymous /
|
|
232
|
-
* no-control-grant callers get 403 — the identical fail-closed floor the op surface enforces.
|
|
233
|
-
*/
|
|
234
|
-
export function createControlHttpApp(
|
|
235
|
-
host: ModuleHost,
|
|
236
|
-
control: ControlModule,
|
|
237
|
-
resolveClaims: VerifiedClaimsResolver,
|
|
238
|
-
options: Omit<HttpTransportOptions, "identify"> = {},
|
|
239
|
-
): OpenAPIHono {
|
|
240
|
-
const serveDoc = options.serveOpenApiDoc !== false;
|
|
241
|
-
const docPath = options.docPath ?? "/openapi.json";
|
|
242
|
-
const app = createHttpApp(host, control, {
|
|
243
|
-
...options,
|
|
244
|
-
identify: controlHttpIdentity(resolveClaims),
|
|
245
|
-
// Withhold the built-in UNAUTHENTICATED doc route; the scope-gated route below replaces it (§2.4).
|
|
246
|
-
serveOpenApiDoc: false,
|
|
247
|
-
});
|
|
248
|
-
if (serveDoc) mountGatedControlDoc(app, control, resolveClaims, docPath, options.info);
|
|
249
|
-
return app;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Serve the control OpenAPI document ONLY to a caller whose VERIFIED claims earn at least one control
|
|
254
|
-
* grant (§2.4). This closes the last unauthenticated read on the control mount: a null (anonymous)
|
|
255
|
-
* resolver result OR a scope set that maps — through the fail-closed {@link controlGrantsForScopes}
|
|
256
|
-
* allowlist — to ZERO control grants (e.g. a bare `*` token that cleared the outer coarse gate but which
|
|
257
|
-
* `*` does not expand into any control grant) is 403'd, exactly as the op routes 403 a zero-grant identity.
|
|
258
|
-
* A real control scope — including `control:admin`/`system:admin`, which the allowlist expands — IS served.
|
|
259
|
-
* The document is byte-identical to the served surface (`getOpenAPIDocument` walks the same registered
|
|
260
|
-
* routes). The doc route itself is not OpenAPI-registered, so it never appears in the spec.
|
|
261
|
-
*/
|
|
262
|
-
function mountGatedControlDoc(
|
|
263
|
-
app: OpenAPIHono,
|
|
264
|
-
control: ControlModule,
|
|
265
|
-
resolveClaims: VerifiedClaimsResolver,
|
|
266
|
-
docPath: string,
|
|
267
|
-
info: HttpTransportOptions["info"],
|
|
268
|
-
): void {
|
|
269
|
-
let cachedDoc: unknown;
|
|
270
|
-
app.get(docPath, (c: Context) => {
|
|
271
|
-
const claims = resolveClaims(c);
|
|
272
|
-
if (claims === null || controlGrantsForScopes(claims.scopes).length === 0) {
|
|
273
|
-
return c.json({ error: { code: "unauthorized", message: "kernel control document requires a control scope" } }, 403);
|
|
274
|
-
}
|
|
275
|
-
cachedDoc ??= app.getOpenAPIDocument({
|
|
276
|
-
openapi: "3.0.0",
|
|
277
|
-
info: { title: info?.title ?? control.title, version: info?.version ?? "0.0.0" },
|
|
278
|
-
});
|
|
279
|
-
return c.json(cachedDoc as never);
|
|
280
|
-
});
|
|
281
|
-
}
|