@humwick/server 0.130.0 → 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 +6 -1
- 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-C7jQWbw2.js +2 -0
- 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 +24 -3
- 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 +10 -6
- package/src/commands-write.ts +8 -0
- 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 +13 -1
- package/src/db/activity.ts +1 -14
- package/src/db/agent-lifecycle-write-ops.ts +1 -0
- package/src/db/agent-meta.ts +2 -2
- package/src/db/agent-ownership-write-ops.ts +4 -0
- package/src/db/agent-search.ts +1 -15
- package/src/db/agents-async.ts +58 -7
- package/src/db/agents-write-ops.ts +28 -5
- package/src/db/agents.ts +81 -54
- package/src/db/artifacts-write-ops.ts +8 -3
- package/src/db/bus-outbox-write-ops.ts +1 -0
- package/src/db/channels-write-ops.ts +4 -0
- package/src/db/ci-incidents-async.ts +5 -5
- package/src/db/ci-incidents-write-ops.ts +2 -2
- package/src/db/claude-api-budget-ops.ts +5 -5
- package/src/db/claude-app-oauth.ts +4 -4
- package/src/db/codex-reset-consumes-write-ops.ts +3 -0
- 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/commands-write-ops.ts +21 -0
- package/src/db/config-store-write-ops.ts +9 -2
- package/src/db/continuation-archives-async.ts +5 -0
- package/src/db/continuation-archives-write-ops.ts +9 -0
- package/src/db/continuations.ts +2 -2
- package/src/db/db-writer-worker.ts +8 -1
- package/src/db/delivery-write-ops.ts +5 -0
- 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-write-ops.ts +14 -0
- package/src/db/hosts.ts +9 -6
- package/src/db/inbox-write-ops.ts +4 -0
- package/src/db/inbox.ts +0 -14
- package/src/db/index.ts +2 -0
- package/src/db/insights-write-ops.ts +1 -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/macos-privacy.ts +1 -1
- 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/message-reads-write-ops.ts +3 -0
- package/src/db/message-write-ops.ts +4 -0
- package/src/db/migrations.ts +7 -15
- package/src/db/orchestrators-async.ts +7 -3
- package/src/db/orchestrators-write-ops.ts +7 -1
- package/src/db/orchestrators.ts +21 -77
- package/src/db/pairs.ts +1 -13
- package/src/db/project-profile-instructions.ts +50 -0
- package/src/db/prompt-versions-ops.ts +1 -0
- package/src/db/prompt-versions.ts +9 -2
- package/src/db/provider-catalog-write-ops.ts +4 -4
- package/src/db/provider-config-history.ts +8 -3
- package/src/db/provider-flap-messages-write-ops.ts +1 -0
- package/src/db/provider-model-seed.ts +34 -0
- package/src/db/provider-quota-lease-write-ops.ts +1 -0
- package/src/db/provider-quota-write-ops.ts +2 -0
- package/src/db/provisioning-write-ops.ts +9 -8
- package/src/db/read-op-marshaling-fixtures.ts +5 -0
- package/src/db/read-ops.ts +4 -0
- package/src/db/routing-policy.ts +3 -4
- package/src/db/schema.ts +9 -3
- package/src/db/secrets-broker-write-ops.ts +5 -5
- package/src/db/secrets-vault-write.ts +7 -7
- package/src/db/services-write-ops.ts +3 -0
- package/src/db/spawn-delegation-state.ts +11 -4
- package/src/db/spawn-tree-cleanup.ts +3 -0
- 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/team-spawn-delegation.ts +1 -1
- package/src/db/teams-write-ops.ts +4 -4
- package/src/db/timer-cutover-write-ops.ts +7 -0
- package/src/db/timer-ingress-write-ops.ts +9 -0
- package/src/db/timer-ingress.ts +7 -1
- package/src/db/timer-operator-write-ops.ts +14 -0
- package/src/db/timer-transfer-write-ops.ts +4 -0
- package/src/db/timer-write-ops.ts +14 -0
- package/src/db/token-db-write-ops.ts +21 -0
- package/src/db/token-standing.ts +15 -11
- package/src/db/user-settings-write-ops.ts +1 -0
- package/src/db/vault-backup.ts +2 -2
- package/src/db/vault-expiry.ts +2 -2
- package/src/db/vault-health.ts +3 -3
- package/src/db/vault-token-ops.ts +8 -8
- package/src/db/web-tool-call-ops.ts +3 -3
- package/src/db/workflow-contact.ts +1 -1
- package/src/db/workflow-task-read-ops.ts +30 -0
- package/src/db/write-ops.ts +15 -1
- package/src/db/writer-fault-seam.ts +5 -2
- package/src/db/writer-gateway.ts +21 -12
- 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-host-tools.ts +1 -1
- 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/package-pack.ts +42 -39
- 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/host-resource-control.ts +4 -1
- 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 +3 -3
- 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 +4 -4
- package/src/routes/project-profile-instructions.ts +27 -0
- package/src/routes/project-trust.ts +2 -2
- package/src/routes/provider-config.ts +9 -8
- 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 +50 -9
- 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 +12 -7
- package/src/services/kernel-timers-ingress.ts +1 -1
- package/src/services/kernel-timers-request-key-migration-chaos-worker.ts +4 -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 -47
- 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 -46
- 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/fleet-BL4UXS_k.js +0 -2
- package/public/assets/index-B7ZerHLY.css +0 -2
- package/public/assets/index-BK0WV6hF.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,200 +0,0 @@
|
|
|
1
|
-
import { relayEnv } from "@humwick/sdk/env";
|
|
2
|
-
/**
|
|
3
|
-
* Real-process Stage-0 MESSAGE-authority crash fixture. This is intentionally a fake store: it
|
|
4
|
-
* gives the dormant participant one CAS-shaped SQL statement without installing any production
|
|
5
|
-
* timer table or call site.
|
|
6
|
-
*/
|
|
7
|
-
import { existsSync, writeFileSync } from "node:fs";
|
|
8
|
-
import { Database } from "bun:sqlite";
|
|
9
|
-
import { z } from "zod";
|
|
10
|
-
import {
|
|
11
|
-
createSqliteModuleHost,
|
|
12
|
-
createRealClock,
|
|
13
|
-
defineModule,
|
|
14
|
-
type MessageAuthorityOperation,
|
|
15
|
-
type MessageAuthorityStore,
|
|
16
|
-
type ModuleCtx,
|
|
17
|
-
type OpCommitFaults,
|
|
18
|
-
type WorkflowStepCommitFaults,
|
|
19
|
-
} from "./index";
|
|
20
|
-
|
|
21
|
-
const DB_PATH = required("AUTHORITY_CHAOS_DB");
|
|
22
|
-
const COMMAND = required("AUTHORITY_CHAOS_COMMAND");
|
|
23
|
-
const ID = process.env.AUTHORITY_CHAOS_ID ?? "sentinel";
|
|
24
|
-
const TIMER_ID = process.env.AUTHORITY_CHAOS_TIMER_ID ?? "timer";
|
|
25
|
-
const BOUNDARY = process.env.AUTHORITY_CHAOS_BOUNDARY ?? "none";
|
|
26
|
-
const ROLE = process.env.AUTHORITY_CHAOS_ROLE ?? "winner";
|
|
27
|
-
const READY_FILE = process.env.AUTHORITY_CHAOS_READY_FILE;
|
|
28
|
-
const RELEASE_FILE = process.env.AUTHORITY_CHAOS_RELEASE_FILE;
|
|
29
|
-
|
|
30
|
-
function required(name: string): string {
|
|
31
|
-
const value = relayEnv(process.env, name);
|
|
32
|
-
if (!value) throw new Error(`missing ${name}`);
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function selfKill(): never {
|
|
37
|
-
process.kill(process.pid, "SIGKILL");
|
|
38
|
-
throw new Error("unreachable");
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function pausePreFlush(): void {
|
|
42
|
-
if (!READY_FILE || !RELEASE_FILE) throw new Error("race loser needs marker paths");
|
|
43
|
-
writeFileSync(READY_FILE, "ready");
|
|
44
|
-
const deadline = Date.now() + 10_000;
|
|
45
|
-
while (!existsSync(RELEASE_FILE)) {
|
|
46
|
-
if (Date.now() >= deadline) throw new Error("race release timed out");
|
|
47
|
-
Bun.sleepSync(5);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function workflowFaults(): WorkflowStepCommitFaults | undefined {
|
|
52
|
-
switch (BOUNDARY) {
|
|
53
|
-
case "pre-tx": return { beforeCommit: selfKill };
|
|
54
|
-
case "after-lease-fence": return { afterFenceBeforeParticipant: selfKill };
|
|
55
|
-
case "after-participant-sql": return { afterParticipantBeforeEntities: selfKill };
|
|
56
|
-
case "between-entity-event": return { betweenEntitiesAndEvents: selfKill };
|
|
57
|
-
case "after-event-flush": return { insideTxBeforeJournal: selfKill };
|
|
58
|
-
case "after-journal-sql": return { afterJournalBeforeCommit: selfKill };
|
|
59
|
-
case "after-commit": return { afterCommit: selfKill };
|
|
60
|
-
default: return undefined;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function openDb(): Database {
|
|
65
|
-
const db = new Database(DB_PATH);
|
|
66
|
-
db.run("PRAGMA busy_timeout = 5000");
|
|
67
|
-
db.run("PRAGMA journal_mode = WAL");
|
|
68
|
-
db.run(`CREATE TABLE IF NOT EXISTS fake_message_authority (
|
|
69
|
-
timer_id TEXT PRIMARY KEY,
|
|
70
|
-
fence INTEGER NOT NULL,
|
|
71
|
-
winner TEXT NOT NULL
|
|
72
|
-
)`);
|
|
73
|
-
return db;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
class FakeStore implements MessageAuthorityStore {
|
|
77
|
-
constructor(readonly winner: string) {}
|
|
78
|
-
|
|
79
|
-
executeInTransaction(db: Database, operation: MessageAuthorityOperation) {
|
|
80
|
-
if (!db.inTransaction) throw new Error("fake authority SQL escaped the caller transaction");
|
|
81
|
-
const changes = db.query(`INSERT INTO fake_message_authority (timer_id, fence, winner)
|
|
82
|
-
VALUES (?, ?, ?) ON CONFLICT(timer_id) DO UPDATE SET fence = excluded.fence, winner = excluded.winner
|
|
83
|
-
WHERE fake_message_authority.fence < excluded.fence`)
|
|
84
|
-
.run(operation.timer.timerId, operation.fence, this.winner).changes;
|
|
85
|
-
return changes === 1
|
|
86
|
-
? { ok: true as const }
|
|
87
|
-
: { ok: false as const, code: "contended" as const, reason: "participant CAS lost" };
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const inputSchema = z.object({ id: z.string(), timerId: z.string() });
|
|
92
|
-
const stateSchema = z.object({ id: z.string(), timerId: z.string() });
|
|
93
|
-
|
|
94
|
-
function stageSentinels(ctx: ModuleCtx, id: string, timerId: string): Promise<void> {
|
|
95
|
-
ctx.messageAuthority.applyFence({ timer: { timerId, message: { body: id } }, fence: 1 });
|
|
96
|
-
return Promise.all([
|
|
97
|
-
(ctx.entities as unknown as { mark: { create(row: { id: string; owner: string }): Promise<unknown> } })
|
|
98
|
-
.mark.create({ id, owner: id }),
|
|
99
|
-
ctx.events.emit("authority-chaos.wrote", { id }),
|
|
100
|
-
]).then(() => undefined);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const module = defineModule({
|
|
104
|
-
id: "authority-chaos",
|
|
105
|
-
title: "MESSAGE authority chaos fixture",
|
|
106
|
-
description: "Fake-store transaction-enlistment proof.",
|
|
107
|
-
entities: { mark: { schema: z.object({ id: z.string(), owner: z.string() }) } },
|
|
108
|
-
events: { "authority-chaos.wrote": z.object({ id: z.string() }) },
|
|
109
|
-
workflows: {
|
|
110
|
-
execute: {
|
|
111
|
-
input: inputSchema,
|
|
112
|
-
state: stateSchema,
|
|
113
|
-
init: (input) => input,
|
|
114
|
-
start: "commit",
|
|
115
|
-
steps: {
|
|
116
|
-
commit: {
|
|
117
|
-
run: async (ctx, state) => {
|
|
118
|
-
await stageSentinels(ctx, state.id, state.timerId);
|
|
119
|
-
return { state, next: "done" as const };
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
seed: {
|
|
125
|
-
input: z.object({ id: z.string() }),
|
|
126
|
-
state: z.object({ id: z.string() }),
|
|
127
|
-
init: (input) => input,
|
|
128
|
-
start: "park",
|
|
129
|
-
steps: {
|
|
130
|
-
// Park rather than finish so the seed itself remains easy to distinguish from an op's rows.
|
|
131
|
-
park: { run: async (ctx, state) => ({ state, next: "park", sleepUntil: ctx.clock.now() + 60_000 }) },
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
ops: {
|
|
136
|
-
write: {
|
|
137
|
-
kind: "mutation",
|
|
138
|
-
grant: "authority-chaos:write",
|
|
139
|
-
summary: "Stage authority/entity/event/workflow-seed sentinels.",
|
|
140
|
-
idempotent: false,
|
|
141
|
-
emits: ["authority-chaos.wrote"],
|
|
142
|
-
input: inputSchema,
|
|
143
|
-
output: z.object({ ok: z.boolean() }),
|
|
144
|
-
handler: async (ctx, input) => {
|
|
145
|
-
await stageSentinels(ctx, input.id, input.timerId);
|
|
146
|
-
await ctx.workflows.start("seed", { id: input.id }, {
|
|
147
|
-
idempotencyKey: `seed-${input.id}`,
|
|
148
|
-
enlist: "op-commit",
|
|
149
|
-
});
|
|
150
|
-
return { ok: true };
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
function build(db: Database) {
|
|
157
|
-
const opFaults: OpCommitFaults | undefined = ROLE === "loser" ? { beforeCommit: pausePreFlush } : undefined;
|
|
158
|
-
const host = createSqliteModuleHost({
|
|
159
|
-
db,
|
|
160
|
-
clock: createRealClock(),
|
|
161
|
-
leaseTtlMs: 100,
|
|
162
|
-
busyTimeoutMs: 5_000,
|
|
163
|
-
messageAuthority: new FakeStore(ID),
|
|
164
|
-
workflowCommitFaults: () => ROLE === "loser" && COMMAND === "workflow"
|
|
165
|
-
? { beforeCommit: pausePreFlush }
|
|
166
|
-
: workflowFaults(),
|
|
167
|
-
...(opFaults ? { opCommitFaults: () => opFaults } : {}),
|
|
168
|
-
});
|
|
169
|
-
host.register(module);
|
|
170
|
-
return host;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async function recover(host: ReturnType<typeof build>, db: Database): Promise<void> {
|
|
174
|
-
const driver = host.workflowDriver(module, { actor: "chaos", grants: [] });
|
|
175
|
-
const deadline = Date.now() + 5_000;
|
|
176
|
-
while (Date.now() < deadline) {
|
|
177
|
-
await driver.recover();
|
|
178
|
-
const open = (db.query(`SELECT COUNT(*) AS n FROM workflow_instances
|
|
179
|
-
WHERE status NOT IN ('done','failed','canceled','sleeping','waiting')`).get() as { n: number }).n;
|
|
180
|
-
if (open === 0) return;
|
|
181
|
-
await Bun.sleep(10);
|
|
182
|
-
}
|
|
183
|
-
throw new Error("recovery timed out");
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const db = openDb();
|
|
187
|
-
const host = build(db);
|
|
188
|
-
|
|
189
|
-
if (COMMAND === "workflow") {
|
|
190
|
-
await host.workflowDriver(module, { actor: "chaos", grants: [] })
|
|
191
|
-
.start("execute", { id: ID, timerId: TIMER_ID }, { idempotencyKey: `workflow-${ID}` });
|
|
192
|
-
} else if (COMMAND === "op") {
|
|
193
|
-
await host.invoke(module, "write", { actor: "chaos", grants: ["authority-chaos:write"] }, { id: ID, timerId: TIMER_ID });
|
|
194
|
-
} else if (COMMAND === "recover") {
|
|
195
|
-
await recover(host, db);
|
|
196
|
-
} else {
|
|
197
|
-
throw new Error(`unknown command ${COMMAND}`);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
db.close();
|
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
import type { Database } from "bun:sqlite";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The timer projection carried by every MESSAGE-authority operation. The host participant accepts
|
|
5
|
-
* only pure-message timers: a message must be present and `command` must be absent/null. Keeping
|
|
6
|
-
* this check at the participant boundary means a future caller cannot accidentally enlist a shell
|
|
7
|
-
* timer in the MESSAGE authority protocol even if it bypasses a module-level schema.
|
|
8
|
-
*/
|
|
9
|
-
export interface MessageAuthorityTimer {
|
|
10
|
-
readonly timerId: string;
|
|
11
|
-
readonly message: unknown;
|
|
12
|
-
readonly command?: never;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type MessageAuthorityEngine = "legacy" | "kernel";
|
|
16
|
-
export type MessageAuthorityDecision = "dispatch" | "expired" | "terminal";
|
|
17
|
-
|
|
18
|
-
export interface ApplyMessageAuthorityFence {
|
|
19
|
-
readonly kind: "applyFence";
|
|
20
|
-
readonly timer: MessageAuthorityTimer;
|
|
21
|
-
readonly fence: number;
|
|
22
|
-
readonly updatedAt?: number;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface DecideMessageAuthorityFire {
|
|
26
|
-
readonly kind: "decideFire";
|
|
27
|
-
readonly timer: MessageAuthorityTimer;
|
|
28
|
-
readonly fence: number;
|
|
29
|
-
readonly generation: number;
|
|
30
|
-
readonly run: number;
|
|
31
|
-
readonly engine: MessageAuthorityEngine;
|
|
32
|
-
readonly decision: MessageAuthorityDecision;
|
|
33
|
-
/** The deadline this exact generation/run woke for. It is part of the ownership predicate. */
|
|
34
|
-
readonly fireAt: number;
|
|
35
|
-
/** Authority lifecycle after this decision commits. */
|
|
36
|
-
readonly lifecycle: "scheduled" | "fired" | "disabled";
|
|
37
|
-
/** Immutable fire-row recurrence projection; null for a terminal decision. */
|
|
38
|
-
readonly nextRun: number | null;
|
|
39
|
-
readonly nextRunAt: number | null;
|
|
40
|
-
readonly decidedAt: number;
|
|
41
|
-
readonly sendPayload: unknown | null;
|
|
42
|
-
readonly idempotencyKey: string | null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface CommitMessageAuthorityTransfer {
|
|
46
|
-
readonly kind: "commitTransfer";
|
|
47
|
-
readonly timer: MessageAuthorityTimer;
|
|
48
|
-
readonly fence: number;
|
|
49
|
-
readonly cutoverEpoch: number;
|
|
50
|
-
readonly generation: number;
|
|
51
|
-
readonly nextRun: number;
|
|
52
|
-
readonly from: "legacy";
|
|
53
|
-
readonly to: "kernel";
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface CommitMessageAuthorityReverseTransfer {
|
|
57
|
-
readonly kind: "commitReverseTransfer";
|
|
58
|
-
readonly timer: MessageAuthorityTimer;
|
|
59
|
-
readonly fence: number;
|
|
60
|
-
readonly cutoverEpoch: number;
|
|
61
|
-
readonly generation: number;
|
|
62
|
-
readonly nextRun: number;
|
|
63
|
-
readonly from: "kernel";
|
|
64
|
-
readonly to: "legacy";
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** The deliberately closed set of host-owned authority mutations available to a module attempt. */
|
|
68
|
-
export type MessageAuthorityOperation =
|
|
69
|
-
| ApplyMessageAuthorityFence
|
|
70
|
-
| DecideMessageAuthorityFire
|
|
71
|
-
| CommitMessageAuthorityTransfer
|
|
72
|
-
| CommitMessageAuthorityReverseTransfer;
|
|
73
|
-
|
|
74
|
-
export type MessageAuthorityRefusal = {
|
|
75
|
-
readonly ok: false;
|
|
76
|
-
/** `superseded` is terminal for the exact workflow generation that proposed the operation;
|
|
77
|
-
* ordinary authority refusal/contention remains retryable. */
|
|
78
|
-
readonly code: "contended" | "authority_refused" | "superseded";
|
|
79
|
-
readonly reason: string;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export type MessageAuthorityStoreResult = { readonly ok: true } | MessageAuthorityRefusal;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Host-owned implementation boundary. Stage 0 intentionally provides no production store: tests
|
|
86
|
-
* inject a fake SQL store. Implementations must execute on the same Database connection passed to
|
|
87
|
-
* the participant and must not open a transaction of their own.
|
|
88
|
-
*/
|
|
89
|
-
export interface MessageAuthorityStore {
|
|
90
|
-
executeInTransaction(db: Database, operation: MessageAuthorityOperation): MessageAuthorityStoreResult;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** The narrow module-visible staging surface. It exposes no SQL and no generic callback escape. */
|
|
94
|
-
export interface MessageAuthorityParticipant {
|
|
95
|
-
applyFence(input: Omit<ApplyMessageAuthorityFence, "kind">): void;
|
|
96
|
-
decideFire(input: Omit<DecideMessageAuthorityFire, "kind">): void;
|
|
97
|
-
commitTransfer(input: Omit<CommitMessageAuthorityTransfer, "kind">): void;
|
|
98
|
-
commitReverseTransfer(input: Omit<CommitMessageAuthorityReverseTransfer, "kind">): void;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export class MessageAuthorityUnavailableError extends Error {
|
|
102
|
-
constructor() {
|
|
103
|
-
super("MESSAGE authority participation is not configured on this host");
|
|
104
|
-
this.name = "MessageAuthorityUnavailableError";
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export class MessageAuthoritySessionClosedError extends Error {
|
|
109
|
-
constructor() {
|
|
110
|
-
super("MESSAGE authority participant session is closed");
|
|
111
|
-
this.name = "MessageAuthoritySessionClosedError";
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export class MessageAuthorityShapeError extends TypeError {
|
|
116
|
-
constructor(message: string) {
|
|
117
|
-
super(message);
|
|
118
|
-
this.name = "MessageAuthorityShapeError";
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/** A failed store predicate. Throwing this aborts the caller-owned transaction as one unit. */
|
|
123
|
-
export class MessageAuthorityCommitRefusedError extends Error {
|
|
124
|
-
constructor(readonly refusal: MessageAuthorityRefusal, readonly operation: MessageAuthorityOperation) {
|
|
125
|
-
super(`MESSAGE authority ${refusal.code}: ${refusal.reason}`);
|
|
126
|
-
this.name = "MessageAuthorityCommitRefusedError";
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export interface MessageAuthoritySession {
|
|
131
|
-
readonly participant: MessageAuthorityParticipant;
|
|
132
|
-
readonly pendingOperations: number;
|
|
133
|
-
seal(): void;
|
|
134
|
-
flush(): void;
|
|
135
|
-
/** Consume the clone-safe participant operations for an async persistence envelope. */
|
|
136
|
-
operations(): readonly MessageAuthorityOperation[];
|
|
137
|
-
discard(): void;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function assertInteger(value: number, name: string, minimum: number): void {
|
|
141
|
-
if (!Number.isSafeInteger(value) || value < minimum) {
|
|
142
|
-
throw new MessageAuthorityShapeError(`${name} must be a safe integer >= ${minimum}`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function assertPureMessageTimer(timer: MessageAuthorityTimer): void {
|
|
147
|
-
if (typeof timer !== "object" || timer === null) {
|
|
148
|
-
throw new MessageAuthorityShapeError("MESSAGE authority requires a timer projection");
|
|
149
|
-
}
|
|
150
|
-
if (typeof timer.timerId !== "string" || timer.timerId.length === 0) {
|
|
151
|
-
throw new MessageAuthorityShapeError("MESSAGE authority requires a non-empty timerId");
|
|
152
|
-
}
|
|
153
|
-
if (timer.message === undefined || timer.message === null) {
|
|
154
|
-
throw new MessageAuthorityShapeError(`timer '${timer.timerId}' has no message payload`);
|
|
155
|
-
}
|
|
156
|
-
const command = (timer as unknown as { command?: unknown }).command;
|
|
157
|
-
if (command !== undefined && command !== null) {
|
|
158
|
-
throw new MessageAuthorityShapeError(`timer '${timer.timerId}' is command-shaped and cannot join MESSAGE authority`);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function validateOperation(operation: MessageAuthorityOperation): void {
|
|
163
|
-
assertPureMessageTimer(operation.timer);
|
|
164
|
-
assertInteger(operation.fence, "fence", 0);
|
|
165
|
-
if (operation.kind === "applyFence") {
|
|
166
|
-
if (operation.updatedAt !== undefined) assertInteger(operation.updatedAt, "updatedAt", 0);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
assertInteger(operation.generation, "generation", 0);
|
|
170
|
-
if (operation.kind === "decideFire") {
|
|
171
|
-
assertInteger(operation.run, "run", 1);
|
|
172
|
-
if (operation.run === Number.MAX_SAFE_INTEGER) {
|
|
173
|
-
throw new MessageAuthorityShapeError("run must leave room for the authority advance");
|
|
174
|
-
}
|
|
175
|
-
assertInteger(operation.fireAt, "fireAt", 0);
|
|
176
|
-
assertInteger(operation.decidedAt, "decidedAt", 0);
|
|
177
|
-
if (operation.nextRun !== null) assertInteger(operation.nextRun, "nextRun", 1);
|
|
178
|
-
if (operation.nextRunAt !== null) assertInteger(operation.nextRunAt, "nextRunAt", 0);
|
|
179
|
-
if ((operation.nextRun === null) !== (operation.nextRunAt === null)) {
|
|
180
|
-
throw new MessageAuthorityShapeError("nextRun and nextRunAt must both be null or both be present");
|
|
181
|
-
}
|
|
182
|
-
if ((operation.lifecycle === "scheduled") !== (operation.nextRun !== null)) {
|
|
183
|
-
throw new MessageAuthorityShapeError("scheduled lifecycle requires a next run/deadline");
|
|
184
|
-
}
|
|
185
|
-
if (operation.decision === "expired" && operation.lifecycle !== "disabled") {
|
|
186
|
-
throw new MessageAuthorityShapeError("expired decisions must disable authority");
|
|
187
|
-
}
|
|
188
|
-
const dispatch = operation.decision === "dispatch";
|
|
189
|
-
if (dispatch !== (operation.sendPayload !== null && operation.idempotencyKey !== null)) {
|
|
190
|
-
throw new MessageAuthorityShapeError("dispatch decisions require sendPayload and idempotencyKey only");
|
|
191
|
-
}
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
assertInteger(operation.cutoverEpoch, "cutoverEpoch", 0);
|
|
195
|
-
assertInteger(operation.nextRun, "nextRun", 0);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
class MessageAuthoritySessionRuntime implements MessageAuthoritySession {
|
|
199
|
-
readonly participant: MessageAuthorityParticipant;
|
|
200
|
-
readonly #operations: MessageAuthorityOperation[] = [];
|
|
201
|
-
#closed = false;
|
|
202
|
-
#finished = false;
|
|
203
|
-
|
|
204
|
-
constructor(
|
|
205
|
-
readonly available: boolean,
|
|
206
|
-
readonly flushOperations?: (operations: readonly MessageAuthorityOperation[]) => void,
|
|
207
|
-
) {
|
|
208
|
-
this.participant = Object.freeze({
|
|
209
|
-
applyFence: (input: Omit<ApplyMessageAuthorityFence, "kind">) => this.#stage({ kind: "applyFence", ...input }),
|
|
210
|
-
decideFire: (input: Omit<DecideMessageAuthorityFire, "kind">) => this.#stage({ kind: "decideFire", ...input }),
|
|
211
|
-
commitTransfer: (input: Omit<CommitMessageAuthorityTransfer, "kind">) => this.#stage({ kind: "commitTransfer", ...input }),
|
|
212
|
-
commitReverseTransfer: (input: Omit<CommitMessageAuthorityReverseTransfer, "kind">) =>
|
|
213
|
-
this.#stage({ kind: "commitReverseTransfer", ...input }),
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
get pendingOperations(): number {
|
|
218
|
-
return this.#operations.length;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
#stage(operation: MessageAuthorityOperation): void {
|
|
222
|
-
if (this.#closed) throw new MessageAuthoritySessionClosedError();
|
|
223
|
-
if (!this.available) throw new MessageAuthorityUnavailableError();
|
|
224
|
-
validateOperation(operation);
|
|
225
|
-
// Snapshot the validated projection. Holding the caller's mutable object would let detached
|
|
226
|
-
// code add `command` after validation but before commit and smuggle a command-shaped timer to
|
|
227
|
-
// the store. The participant needs only these two fields, so discard every other property.
|
|
228
|
-
const timer = Object.freeze({ timerId: operation.timer.timerId, message: operation.timer.message });
|
|
229
|
-
this.#operations.push(Object.freeze({ ...operation, timer }) as MessageAuthorityOperation);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
seal(): void {
|
|
233
|
-
if (this.#finished) throw new MessageAuthoritySessionClosedError();
|
|
234
|
-
this.#closed = true;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
flush(): void {
|
|
238
|
-
if (!this.#closed || this.#finished) throw new MessageAuthoritySessionClosedError();
|
|
239
|
-
try {
|
|
240
|
-
if (!this.flushOperations) throw new Error("async MESSAGE authority operations must commit through KernelPersistence");
|
|
241
|
-
this.flushOperations(this.#operations);
|
|
242
|
-
this.#finished = true;
|
|
243
|
-
} catch (error) {
|
|
244
|
-
this.#finished = true;
|
|
245
|
-
throw error;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
operations(): readonly MessageAuthorityOperation[] {
|
|
250
|
-
if (!this.#closed || this.#finished) throw new MessageAuthoritySessionClosedError();
|
|
251
|
-
this.#finished = true;
|
|
252
|
-
return Object.freeze(this.#operations.map((operation) => structuredClone(operation)));
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
discard(): void {
|
|
256
|
-
if (this.#finished) throw new MessageAuthoritySessionClosedError();
|
|
257
|
-
this.#closed = true;
|
|
258
|
-
this.#operations.length = 0;
|
|
259
|
-
this.#finished = true;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/** Begin one participant session, scoped to exactly one op or workflow-step attempt. */
|
|
264
|
-
export function beginMessageAuthoritySession(db: Database, store?: MessageAuthorityStore): MessageAuthoritySession;
|
|
265
|
-
export function beginMessageAuthoritySession(available: boolean): MessageAuthoritySession;
|
|
266
|
-
export function beginMessageAuthoritySession(dbOrAvailable: Database | boolean, store?: MessageAuthorityStore): MessageAuthoritySession {
|
|
267
|
-
return typeof dbOrAvailable === "boolean"
|
|
268
|
-
? new MessageAuthoritySessionRuntime(dbOrAvailable)
|
|
269
|
-
: new MessageAuthoritySessionRuntime(store !== undefined, (operations) => {
|
|
270
|
-
if (!dbOrAvailable.inTransaction) {
|
|
271
|
-
throw new Error("MESSAGE authority operations must flush inside a caller-owned SQLite transaction");
|
|
272
|
-
}
|
|
273
|
-
for (const operation of operations) {
|
|
274
|
-
// The caller-owned handle is passed explicitly. A store that tries to wrap this in another
|
|
275
|
-
// BEGIN/COMMIT fails as a nested transaction instead of silently escaping the atomic commit.
|
|
276
|
-
const result = store?.executeInTransaction(dbOrAvailable, operation);
|
|
277
|
-
if (!result) throw new MessageAuthorityUnavailableError();
|
|
278
|
-
if (!result.ok) throw new MessageAuthorityCommitRefusedError(result, operation);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
}
|