@humwick/server 0.130.1 → 0.130.3
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/bundled/prompts/manifest.json +1 -0
- package/bundled/prompts/task.hydration.md +1 -1
- package/bundled/roles/builder.md +1 -1
- package/docs/guides/sub-coordinators.md +12 -5
- package/docs/guides/tools-administration.md +4 -0
- package/docs/guides/tools-coordination.md +2 -0
- package/docs/guides/tools-tasks.md +8 -0
- package/docs/guides/workflows.md +74 -0
- package/docs/openapi.json +486 -4
- package/package.json +10 -18
- package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-Bq9kr21N.js} +2 -2
- package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-Dqiroy06.js} +2 -2
- package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-DYU962-H.js} +2 -2
- package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-DhPfzioE.js} +2 -2
- package/public/assets/{activity-yLztXEBt.js → activity-DzCcQTee.js} +2 -2
- package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-SgDt9i3T.js} +2 -2
- package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
- package/public/assets/{agent-name-CTZBrSD9.js → agent-name-CcY3Aijy.js} +2 -2
- package/public/assets/agent-profiles-cxtRBn6O.js +2 -0
- package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-DGYbIhaI.js} +2 -2
- package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-DHbftV0N.js} +2 -2
- package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-CY113sp-.js} +2 -2
- package/public/assets/{agents-BYDslkJc.js → agents-BPzY7IlQ.js} +2 -2
- package/public/assets/{analytics-B-XSbEMC.js → analytics-DENFPv_a.js} +2 -2
- package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-KRvSc7sl.js} +2 -2
- package/public/assets/{artifacts-DPN1q4pA.js → artifacts-C9gSmL3s.js} +2 -2
- package/public/assets/{artifacts-oBOqks-2.js → artifacts-DT-HkI5O.js} +2 -2
- package/public/assets/{automation-4KcRFXEu.js → automation-BsmjQhKD.js} +2 -2
- package/public/assets/{backlog-Cw9xPTCF.js → backlog-8NYH_62t.js} +2 -2
- package/public/assets/{busy-health-CTu32MZt.js → busy-health-D3hwvYb4.js} +2 -2
- package/public/assets/{channels-BiXzg1G9.js → channels-DCJ5WL7O.js} +2 -2
- package/public/assets/{chat-Ctk2qwvA.js → chat-DAIl357U.js} +3 -3
- package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-CzrZfr9U.js} +2 -2
- package/public/assets/{connectors-C36ax4Vw.js → connectors-xTxtlyou.js} +2 -2
- package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BpebFLK2.js} +2 -2
- package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-BHvI5wXC.js} +2 -2
- package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-DGT0o3wJ.js} +2 -2
- package/public/assets/{deploys-Bwfq146q.js → deploys-hqWOHSHE.js} +2 -2
- package/public/assets/{display-CfO7rTuF.js → display-CDeH4I8T.js} +2 -2
- package/public/assets/{files-DhhZI2Ih.js → files-BTeGVmTg.js} +2 -2
- package/public/assets/{fleet-B_rFEbnL.js → fleet-DgXtNgCa.js} +2 -2
- package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BHEt5yc_.js} +2 -2
- package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-MLtodyPp.js} +3 -3
- package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-CAe664Z8.js} +2 -2
- package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-mapF4Fj9.js} +2 -2
- package/public/assets/index-CqqgOI5R.js +15 -0
- package/public/assets/index-MYAIwYTX.css +2 -0
- package/public/assets/{insights-fH1EL-qZ.js → insights-DNyf7IzF.js} +2 -2
- package/public/assets/{integrations-C5Oix6ng.js → integrations-DlYOHq7T.js} +2 -2
- package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-CeWBNWn7.js} +2 -2
- package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-Cib8nqdE.js} +2 -2
- package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-DSn1cPm7.js} +2 -2
- package/public/assets/{managed-agents-egllbpij.js → managed-agents-C3CkM81m.js} +2 -2
- package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-W4VQQPAv.js} +3 -3
- package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
- package/public/assets/{memory-C8WmXsyr.js → memory-BV17qtO4.js} +2 -2
- package/public/assets/{messages-BzQdqlO6.js → messages-Bm_1AqSA.js} +2 -2
- package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Dg-vfP09.js} +2 -2
- package/public/assets/{overview-DCUnI4Z7.js → overview-DcYCrvlr.js} +2 -2
- package/public/assets/{pairs-ftCd2XcD.js → pairs-8o9nuG3V.js} +2 -2
- package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-BsRyBMea.js} +2 -2
- package/public/assets/project-profile-instructions-DETKFn_E.js +2 -0
- package/public/assets/projects-M_m6AHws.js +2 -0
- package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-C_mNCgeL.js} +2 -2
- package/public/assets/provider-display-BEeLXC_D.js +2 -0
- package/public/assets/{registry-DWCU5c8q.js → registry-DDHHHE5N.js} +2 -2
- package/public/assets/run-card-Dt4I4jaP.js +2 -0
- package/public/assets/scroll-text-BKXS1ahr.js +2 -0
- package/public/assets/{secrets-C7GIUATz.js → secrets-BkVwxI5O.js} +2 -2
- package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-Crq-6a-B.js} +2 -2
- package/public/assets/{settings-C6sZ9eBa.js → settings-CYcavMFu.js} +2 -2
- package/public/assets/shipping-H6gzEeZB.js +2 -0
- package/public/assets/{stats-V9Z-GxUd.js → stats-BJVeWkpV.js} +2 -2
- package/public/assets/{status-dot-CVv0iGHL.js → status-dot-BcHyw1Vw.js} +2 -2
- package/public/assets/store-DKPDIZBe.js +9 -0
- package/public/assets/{tasks-CXU75HRF.js → tasks-qJjlQPpx.js} +2 -2
- package/public/assets/{teams-BPf976zb.js → teams-Cd5Sk1uX.js} +2 -2
- package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-CpY5_m7W.js} +3 -3
- package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
- package/public/assets/token-estimate-Co-Jdphh.js +2 -0
- package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-0yJA_buM.js} +2 -2
- package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-uJXHf34W.js} +2 -2
- package/public/assets/use-project-list-CpWl6eHQ.js +2 -0
- package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BdxBW8mL.js} +2 -2
- package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-3IndfpOc.js} +2 -2
- package/public/assets/versioned-prompt-editor-CIVg7XB1.js +8 -0
- package/public/assets/{work-queue-TCjJxeT-.js → work-queue-B9rnLwHZ.js} +2 -2
- package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-X8wxyhzC.js} +2 -2
- package/public/assets/{workflows-CXQX20Qj.js → workflows-o5YyMFW7.js} +2 -2
- package/public/assets/{workspaces-qSYzKYMA.js → workspaces-CzEGoAng.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/claude-headless.ts +1 -1
- package/runner/src/adapters/claude-launch-exit.ts +26 -0
- package/runner/src/adapters/claude-session-probe.ts +1 -1
- package/runner/src/adapters/claude-tmux.ts +38 -10
- package/runner/src/adapters/claude.ts +28 -75
- 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/adapters/provider-quota-harvest.ts +20 -71
- 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 +2 -4
- package/runner/src/agent-runner/liveness-exchange.ts +104 -0
- 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/claude-system-prompt.ts +49 -0
- package/runner/src/index.ts +5 -2
- package/runner/src/launch-assembly.ts +14 -10
- package/runner/src/profile-home.ts +1 -1
- package/runner/src/project-instructions.ts +2 -2
- package/runner/src/provider-command.ts +18 -0
- package/runner/src/provider-setup.ts +35 -0
- package/runner/src/providers.ts +2 -1
- package/runner/src/runner-core.ts +32 -38
- package/runner/src/runner-helpers.ts +0 -8
- package/runner/src/session-scratch.ts +6 -2
- package/runner/src/spawn-input.ts +2 -1
- package/runner/src/test-run-dedup.ts +59 -56
- package/runner/test-support/provisioning-context.ts +4 -2
- package/runner/test-support/runner-harness.ts +2 -1
- package/scripts/cd-config.ts +8 -0
- package/scripts/gate-run-lease.ts +10 -7
- package/scripts/gate.sh +5 -1
- package/scripts/steward-policy-cleanup.ts +2 -2
- package/src/agent-authz.ts +2 -2
- package/src/agent-drive-arbiter.ts +3 -8
- package/src/agent-exit-cleanup-async.ts +2 -2
- package/src/agent-exit-cleanup.ts +23 -19
- package/src/agent-lifecycle-events.ts +112 -85
- package/src/agent-ref.ts +3 -2
- package/src/agent-status-events.ts +43 -14
- package/src/auth/password.ts +4 -3
- package/src/auth/session-refresh.ts +1 -1
- package/src/auth/session.test-fixture.ts +2 -2
- package/src/auth/session.ts +7 -7
- package/src/automations/crud.ts +8 -81
- package/src/automations/dispatch.ts +33 -58
- package/src/automations/index.ts +1 -1
- package/src/automations/persistence.ts +65 -0
- package/src/automations/precheck.ts +18 -16
- package/src/automations/read-async.ts +11 -0
- package/src/automations/reconcile.ts +30 -39
- package/src/automations/storage.ts +33 -10
- package/src/automations/write-async.ts +33 -0
- package/src/branch-land-notice.ts +93 -0
- package/src/branch-landed.ts +31 -98
- package/src/bus.ts +40 -39
- package/src/cd-deploy-notify.ts +32 -4
- 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/notifications.ts +4 -4
- package/src/ci/root-missing.ts +4 -9
- package/src/ci/transition-notify.ts +12 -44
- package/src/claude-app/oauth-http.ts +3 -3
- 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 +19 -4
- package/src/commands-db.ts +7 -7
- package/src/commands-write.ts +8 -0
- package/src/compaction-watch.ts +10 -8
- package/src/config-store-write.ts +13 -1
- package/src/config-store.ts +25 -14
- package/src/config.ts +4 -11
- package/src/connectors.ts +10 -8
- package/src/context-advisory.ts +22 -21
- 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-action-write.ts +36 -0
- package/src/db/agent-control-async.ts +9 -0
- package/src/db/agent-control-write.ts +49 -0
- package/src/db/agent-effort-observe.ts +22 -0
- package/src/db/agent-meta.ts +14 -3
- package/src/db/agent-search.ts +1 -15
- package/src/db/agents-async.ts +59 -9
- package/src/db/agents-write-ops.ts +12 -3
- package/src/db/agents.ts +95 -65
- package/src/db/auth-identities.ts +2 -2
- package/src/db/automation-read-ops.ts +11 -0
- package/src/db/automation-write-ops.ts +46 -0
- package/src/db/blackboard.ts +2 -2
- package/src/db/browser-session-write.ts +32 -0
- package/src/db/bus-outbox-write-ops.ts +3 -1
- package/src/db/checkout-refresh-schema.ts +47 -0
- package/src/db/checkout-refresh.ts +5 -5
- package/src/db/ci-incidents-async.ts +5 -5
- package/src/db/ci-incidents-write-ops.ts +2 -2
- package/src/db/command-agent-profile-backfill.ts +39 -0
- package/src/db/command-agent-profiles.ts +5 -1
- package/src/db/command-retention.ts +126 -0
- package/src/db/command-row.ts +10 -2
- package/src/db/commands-list-query.ts +2 -0
- package/src/db/commands-planner-stats.test-fixture.ts +8 -0
- package/src/db/commands-read-ops.ts +16 -0
- package/src/db/commands-spawn-read.ts +1 -1
- package/src/db/config-store-write-ops.ts +7 -2
- package/src/db/connection.ts +1 -182
- package/src/db/context-carry-write.ts +74 -0
- package/src/db/continuation-archives-async.ts +5 -0
- package/src/db/continuation-archives-write-ops.ts +7 -0
- package/src/db/continuations.ts +6 -6
- package/src/db/db-error-registry.ts +12 -0
- 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/gateway.ts +26 -133
- package/src/db/history-retention-ops.ts +13 -0
- package/src/db/hosts-registration.ts +10 -2
- package/src/db/hosts.ts +9 -6
- package/src/db/inbox-async.ts +2 -2
- package/src/db/inbox-read-ops.ts +1 -1
- package/src/db/inbox.ts +9 -17
- 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-associations.ts +2 -2
- package/src/db/issue-lifecycle.ts +3 -4
- package/src/db/issue-refs-async.ts +23 -0
- package/src/db/issue-refs-read-ops.ts +6 -0
- package/src/db/issue-refs-write-ops.ts +29 -0
- package/src/db/issue-refs.ts +15 -16
- package/src/db/kernel-event-log-schema.ts +2 -0
- package/src/db/land-boundaries.ts +51 -5
- package/src/db/land-gate-attestations.ts +2 -2
- package/src/db/landing-receipts.ts +2 -2
- package/src/db/lifecycle-context-write.ts +5 -0
- package/src/db/lifecycle-tail-async.ts +76 -0
- package/src/db/lifecycle-tail-write-ops.ts +62 -0
- package/src/db/lifecycle-write-window.ts +2 -1
- package/src/db/lineage-pair-dedupe-sql.ts +3 -3
- package/src/db/long-running-work.ts +2 -2
- package/src/db/main-connection-mode.ts +11 -0
- package/src/db/main-connection-writes.ts +41 -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/maintenance-pauses.ts +2 -2
- package/src/db/mappers.ts +2 -14
- package/src/db/merge-lease.ts +1 -15
- package/src/db/message-send.ts +4 -0
- package/src/db/messages.ts +31 -25
- package/src/db/migrations.ts +25 -16
- package/src/db/notification-write-ops.ts +19 -0
- package/src/db/operator-answer-write.ts +19 -0
- package/src/db/orchestrators.ts +14 -76
- package/src/db/pairs-async.ts +22 -1
- package/src/db/pairs-write-ops.ts +8 -3
- package/src/db/pairs.ts +42 -61
- package/src/db/plan-dispatch-schema.ts +5 -1
- package/src/db/plan-ready-notices.ts +43 -0
- package/src/db/plan-tools-include-migration.ts +36 -0
- package/src/db/plans-write-ops.ts +2 -0
- package/src/db/presence-buffer.ts +5 -0
- package/src/db/presence-loop.ts +18 -23
- package/src/db/presence-write.ts +0 -6
- package/src/db/project-entries-async.ts +14 -0
- package/src/db/project-entries-read-ops.ts +5 -1
- package/src/db/project-entries-write-ops.ts +8 -0
- package/src/db/project-entries.ts +15 -12
- package/src/db/project-journal.ts +2 -2
- package/src/db/project-profile-instructions.ts +50 -0
- package/src/db/project-trust-approvals.ts +2 -2
- package/src/db/prompt-templates.ts +4 -4
- 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 +23 -0
- package/src/db/read-ops.ts +8 -0
- package/src/db/retention.ts +13 -2
- package/src/db/review-publish-write.ts +8 -0
- package/src/db/routing-policy.ts +2 -3
- package/src/db/runtime-admin-async.ts +19 -0
- package/src/db/runtime-admin-write-ops.ts +36 -0
- package/src/db/runtime-tail-async.ts +288 -0
- package/src/db/runtime-tail-write-ops.ts +97 -0
- package/src/db/schema.ts +13 -4
- package/src/db/spawn-budget.ts +5 -0
- package/src/db/spawn-delegation-state.ts +11 -4
- package/src/db/spawn-delegation.ts +1 -11
- package/src/db/sql-audit-indexes.ts +3 -0
- package/src/db/stats-async.ts +9 -6
- package/src/db/task-entity.ts +28 -6
- package/src/db/task-list.ts +3 -1
- package/src/db/tasks.ts +1 -17
- package/src/db/team-claim-policy.ts +60 -0
- package/src/db/teams-async.ts +4 -0
- package/src/db/teams-write-ops.ts +4 -0
- package/src/db/terminal-events.ts +15 -0
- package/src/db/timer-cutover-bodies.ts +292 -0
- package/src/db/timer-cutover-core.ts +37 -278
- package/src/db/timer-cutover-state.ts +40 -0
- package/src/db/timer-cutover-write-ops.ts +1 -40
- package/src/db/timer-ingress.ts +7 -1
- package/src/db/token-db-write-ops.ts +19 -0
- package/src/db/token-standing-async.ts +12 -0
- package/src/db/token-standing.ts +21 -20
- package/src/db/token-usage-retention.ts +33 -0
- package/src/db/token-usage-write-ops.ts +1 -1
- package/src/db/token-usage.ts +4 -1
- package/src/db/user-invites-async.ts +13 -0
- package/src/db/user-invites.ts +3 -3
- package/src/db/users.ts +14 -6
- package/src/db/workflow-contact.ts +1 -1
- package/src/db/workflow-task-read-ops.ts +30 -0
- package/src/db/workspaces.ts +8 -5
- package/src/db/write-ops.ts +37 -12
- package/src/db/writer-fault-seam.ts +2 -9
- package/src/db/writer-fault-test-ops.ts +18 -0
- package/src/db/writer-gateway.ts +58 -56
- package/src/dev.ts +8 -3
- 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/event-loop-lag.ts +4 -2
- package/src/event-loop-yield.ts +2 -2
- package/src/events.ts +10 -8
- package/src/host/disk-alert.ts +121 -0
- package/src/host-provider-store.ts +5 -4
- package/src/hub-metrics-report.ts +5 -1
- package/src/hub-metrics.ts +38 -18
- package/src/injection-sweep-pacing.ts +6 -8
- package/src/land-gate-notifications.ts +11 -10
- package/src/land-gate-queue-progress.ts +3 -3
- package/src/land-settle-dispatch.ts +52 -92
- package/src/lifecycle-context-pressure.ts +11 -10
- package/src/lifecycle-manager.ts +107 -100
- package/src/maintenance/breaker.ts +18 -16
- package/src/maintenance/cd-watcher.ts +3 -3
- package/src/maintenance/checkout-refresh.ts +18 -1
- package/src/maintenance/critical-job-watchdog.ts +19 -20
- package/src/maintenance/events.ts +3 -3
- package/src/maintenance/history-retention-job.ts +30 -0
- package/src/maintenance/index.ts +1 -0
- package/src/maintenance/jobs.ts +32 -69
- package/src/maintenance/long-running-work.ts +3 -1
- package/src/maintenance/offline-agent-prune-job.ts +28 -0
- package/src/maintenance/orphaned-sessions.ts +5 -4
- package/src/maintenance/pauses.ts +4 -10
- package/src/maintenance/plan-ready-notice-job.ts +71 -0
- package/src/maintenance/scheduler.ts +98 -137
- package/src/maintenance/stalled-delivery-pager.ts +10 -9
- package/src/maintenance/teams.ts +19 -30
- package/src/maintenance/workspaces.ts +18 -28
- package/src/managed-policy-escalation.ts +7 -7
- package/src/managed-policy.ts +32 -28
- package/src/managed-provider-gate.ts +5 -4
- package/src/managed-spawn-reservation.ts +5 -4
- package/src/mcp/index.ts +12 -9
- package/src/mcp/output-descriptions.ts +8 -8
- package/src/mcp/presentation.ts +6 -5
- package/src/mcp/project-profile-instructions.ts +32 -0
- package/src/mcp/runtime-output.ts +6 -1
- package/src/mcp/self-care-visibility.ts +2 -2
- package/src/mcp/spawn-targets-matrix.ts +10 -1
- package/src/mcp/tool-groups.ts +4 -3
- package/src/mcp/tool-roles.ts +81 -0
- package/src/mcp/tools-spawn.ts +4 -3
- package/src/mcp/tools-workspace.ts +1 -1
- package/src/mcp-agent-action.ts +1 -2
- package/src/mcp-blackboard-tools.ts +6 -5
- package/src/mcp-decision-tools.ts +7 -7
- package/src/mcp-egress-tools.ts +10 -9
- package/src/mcp-issue-activity-tools.ts +2 -2
- package/src/mcp-issue-association-tools.ts +4 -4
- package/src/mcp-issue-ref-tools.ts +13 -12
- package/src/mcp-maintenance-tools.ts +2 -2
- package/src/mcp-merge-tools.ts +5 -5
- package/src/mcp-notification-subscription-tools.ts +14 -15
- package/src/mcp-output-levels.test-fixture.ts +1 -1
- package/src/mcp-profile-trust-tools.ts +5 -5
- package/src/mcp-project-journal-tools.ts +4 -12
- package/src/mcp-project-tools.ts +17 -18
- package/src/mcp-provider-catalog.ts +2 -2
- package/src/mcp-routing-policy-tools.ts +3 -2
- package/src/mcp-task-tools.ts +11 -5
- package/src/mcp-team-template-tools.ts +3 -3
- package/src/mcp-team-tools.ts +6 -6
- package/src/mcp-workflow-tools.ts +13 -4
- package/src/memory-area-injection.ts +13 -12
- package/src/memory-boundary-capture.ts +6 -6
- package/src/memory-injection.ts +45 -43
- package/src/merge-pause-maintenance.ts +5 -4
- package/src/notification-router.ts +44 -17
- package/src/notification-types.ts +2 -1
- package/src/notify.ts +5 -5
- package/src/observed-reset-refresh.ts +4 -4
- package/src/operator-alarm.ts +23 -11
- package/src/project-ingest.ts +6 -6
- package/src/project-instructions.ts +12 -1
- package/src/project-profile-instruction-text.ts +6 -0
- package/src/project-profile-instructions.ts +20 -0
- package/src/project-trust.ts +12 -11
- package/src/prompt-resolver.ts +3 -3
- 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-async.ts +5 -7
- package/src/provider-quota-config-store.ts +5 -4
- package/src/provider-secrets.test-fixture.ts +3 -3
- package/src/provider-timeline-event.ts +4 -7
- package/src/quota-band-delivery.ts +2 -2
- package/src/recipe-runner.ts +6 -5
- package/src/repo-config-source.ts +10 -4
- package/src/retention-config-store.ts +4 -3
- package/src/reviewer-pipeline.ts +11 -10
- package/src/routes/_route.ts +4 -4
- package/src/routes/_shared.ts +13 -12
- package/src/routes/agent-effort.ts +5 -5
- package/src/routes/agent-heartbeat-quota.ts +23 -0
- package/src/routes/agent-keep.ts +1 -1
- package/src/routes/agent-profiles.ts +6 -6
- package/src/routes/agent-reporting.ts +1 -1
- package/src/routes/agent-self-effort.ts +5 -5
- package/src/routes/agent-sessions.ts +24 -24
- package/src/routes/agents-spawn.ts +2 -2
- package/src/routes/agents.ts +19 -121
- package/src/routes/auth.ts +14 -15
- package/src/routes/authority-audit.ts +2 -2
- package/src/routes/automations.ts +6 -5
- package/src/routes/channel-binding-delete.ts +1 -1
- package/src/routes/channel-output.ts +3 -3
- package/src/routes/claude-api-budget.ts +5 -5
- package/src/routes/commands-listing.ts +5 -1
- package/src/routes/commands.ts +31 -29
- package/src/routes/context-resets.ts +2 -2
- package/src/routes/continuation-archives.ts +2 -2
- package/src/routes/coordinator-teams.ts +1 -1
- package/src/routes/decisions.ts +2 -2
- package/src/routes/host-secret-files.ts +1 -1
- package/src/routes/hosts.ts +11 -11
- package/src/routes/inbox.ts +3 -2
- package/src/routes/index.ts +12 -2
- package/src/routes/integrations.ts +32 -56
- package/src/routes/issue-activity.ts +2 -2
- package/src/routes/issue-associations.ts +4 -4
- package/src/routes/issue-refs.ts +9 -9
- package/src/routes/kernel-timers-operator.ts +1 -1
- package/src/routes/memory.ts +1 -1
- package/src/routes/merges.ts +11 -11
- package/src/routes/messages.ts +23 -17
- package/src/routes/orchestrator-bootstrap.ts +2 -2
- package/src/routes/orchestrator-host-registration.ts +4 -2
- package/src/routes/orchestrator-host-utilization.ts +5 -3
- package/src/routes/orchestrator-proxy.ts +4 -4
- package/src/routes/orchestrator.ts +28 -19
- package/src/routes/pairs.ts +8 -8
- package/src/routes/project-profile-instructions.ts +27 -0
- package/src/routes/project-trust.ts +3 -3
- package/src/routes/projects.ts +16 -16
- package/src/routes/prompt-templates.ts +12 -12
- package/src/routes/provider-config.ts +6 -6
- package/src/routes/provider-quota-config.ts +2 -2
- package/src/routes/provider-quotas.ts +10 -10
- package/src/routes/run-command.ts +1 -1
- package/src/routes/secrets-backup.ts +2 -2
- package/src/routes/secrets-import.ts +1 -1
- package/src/routes/secrets-vault.ts +7 -7
- package/src/routes/settings.ts +6 -6
- package/src/routes/shipping.ts +9 -1
- package/src/routes/spawn-policy.ts +8 -7
- package/src/routes/sse.ts +2 -2
- 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 +12 -12
- package/src/routes/teams-config.ts +2 -2
- package/src/routes/teams.ts +10 -10
- package/src/routes/tokens.ts +30 -22
- package/src/routes/users.ts +24 -24
- package/src/routes/viewer-read.ts +3 -3
- package/src/routes/web-tool-calls.ts +4 -4
- package/src/routes/workflows.ts +22 -7
- package/src/routes/workspaces.ts +17 -16
- package/src/routing-policy-normalize.ts +1 -2
- package/src/routing-policy-push.ts +6 -6
- package/src/routing-step-defaults.ts +0 -2
- package/src/runner-token-mint-limit.ts +63 -0
- package/src/runtime-grant.ts +21 -13
- package/src/runtime-tokens.ts +59 -35
- package/src/secrets-broker/config.ts +1 -1
- package/src/secrets-broker/service.ts +2 -2
- package/src/security.ts +16 -21
- package/src/self-resume-carry.ts +21 -110
- package/src/self-resume-supersede.ts +4 -3
- package/src/self-resume.ts +54 -66
- package/src/server-background.ts +2 -2
- package/src/server.ts +26 -24
- package/src/services/agent-action.ts +12 -31
- package/src/services/agent-effort.ts +7 -32
- package/src/services/agent-hang-watchdog-job.ts +2 -2
- package/src/services/agent-heartbeat.ts +166 -0
- package/src/services/agent-reporting.ts +1 -1
- package/src/services/browser-inventory.ts +3 -3
- package/src/services/browser-session-state.ts +3 -2
- package/src/services/browser-session.ts +21 -27
- package/src/services/bus-command-update.ts +9 -9
- package/src/services/checkout-refresh-state.ts +1 -0
- package/src/services/checkout-refresh.test-fixture.ts +3 -2
- package/src/services/command-host.ts +7 -2
- package/src/services/coordinator-digest.ts +3 -2
- package/src/services/dispatch-command.ts +12 -13
- package/src/services/effective-launch-driver.ts +14 -9
- package/src/services/host-changed-paths.test-fixture.ts +5 -6
- package/src/services/host-project-readiness.ts +2 -2
- package/src/services/host-providers.ts +1 -1
- package/src/services/host-utilization.ts +27 -4
- package/src/services/idle-agent-digest.ts +17 -12
- package/src/services/idle-epics.ts +9 -10
- package/src/services/interrupt-agent.ts +12 -9
- package/src/services/issue-activity.ts +3 -3
- package/src/services/issue-associations.ts +15 -18
- package/src/services/issue-lifecycle-comments.ts +3 -2
- package/src/services/issue-lifecycle.ts +69 -72
- package/src/services/issue-refs.ts +10 -15
- package/src/services/kernel-timers-cutover-chaos-worker.ts +11 -8
- package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
- package/src/services/kernel-timers-ingress.ts +4 -4
- package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
- package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
- package/src/services/kernel-timers-outbox.ts +1 -1
- package/src/services/kernel-timers-stage10-operator.ts +1 -1
- package/src/services/kernel-timers.ts +4 -3
- package/src/services/land-gate-placement.ts +11 -2
- package/src/services/land-issue-relations.ts +5 -4
- package/src/services/land-restart-retry.ts +7 -6
- package/src/services/landed-ancestry.ts +25 -8
- package/src/services/legacy-landing-host.ts +4 -1
- package/src/services/legacy-landing-recovery.ts +8 -6
- package/src/services/managed-running.ts +17 -17
- package/src/services/memory-areas.ts +17 -53
- package/src/services/merge-pause.ts +9 -15
- package/src/services/operator-decisions.ts +37 -41
- package/src/services/orchestrator-registration-recovery.ts +6 -2
- package/src/services/orchestrator-upgrade.ts +14 -12
- package/src/services/permission-decision.ts +4 -3
- package/src/services/plan-ci-notice.ts +57 -0
- package/src/services/plan-ci-recovery.ts +2 -55
- package/src/services/plan-conformance.ts +4 -4
- package/src/services/plan-dispatch-policy.ts +10 -3
- package/src/services/plan-dispatch.ts +35 -14
- package/src/services/plan-graph.ts +39 -261
- package/src/services/plan-import.ts +1 -1
- package/src/services/plan-live-bindings.ts +8 -37
- package/src/services/plan-task-create.ts +1 -1
- package/src/services/plan-terminal-refs.ts +2 -12
- package/src/services/plan-wake-digest.ts +9 -3
- package/src/services/profile-trust.ts +6 -5
- package/src/services/project-config-read.ts +70 -0
- package/src/services/project-profile-instructions.ts +54 -0
- package/src/services/project.ts +11 -10
- package/src/services/prompt-templates.ts +6 -5
- package/src/services/provider-hold-nudge.ts +9 -9
- package/src/services/provider-hold-record.ts +13 -12
- package/src/services/provider-state-audit.ts +19 -18
- package/src/services/provisioning-harness/budget-baseline.json +4 -4
- package/src/services/provisioning-harness/driver.ts +1 -1
- package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
- package/src/services/provisioning-harness/lifecycle.ts +24 -22
- package/src/services/provisioning-harness/prepare.ts +16 -17
- package/src/services/rate-limit-resume.ts +10 -9
- package/src/services/red-main-auto-revert.ts +7 -5
- package/src/services/red-main-controller-deps.ts +20 -3
- package/src/services/red-main-incident.ts +3 -1
- package/src/services/red-main-quarantine.ts +2 -3
- package/src/services/register-agent.ts +22 -22
- package/src/services/restart-project-role.ts +1 -1
- package/src/services/restart-spawn.ts +74 -61
- package/src/services/review-publish.ts +7 -24
- package/src/services/review-ref-reconcile.ts +29 -38
- package/src/services/runtime-dependency-alert.ts +27 -0
- package/src/services/scheduler-command.ts +11 -9
- package/src/services/scheduler.ts +5 -5
- package/src/services/self-care-state.ts +2 -1
- package/src/services/self-effort-grant.ts +5 -25
- package/src/services/self-effort.ts +5 -5
- package/src/services/send-message.ts +21 -34
- package/src/services/shutdown-agent.ts +17 -14
- package/src/services/spawn-agent.ts +25 -43
- package/src/services/spawn-chain-inspector.ts +7 -14
- package/src/services/spawn-cwd-placement.ts +21 -5
- package/src/services/spawn-issue-activity.ts +8 -6
- package/src/services/spawn-launch.ts +17 -1
- package/src/services/spawn-loss-escalation.ts +1 -1
- package/src/services/spawn-policy.ts +68 -0
- package/src/services/spawn-registration-watchdog.ts +2 -2
- package/src/services/spawn-repo-probe.ts +7 -5
- package/src/services/spawn-tree-cleanup.ts +8 -9
- package/src/services/steward-reaper.ts +4 -4
- package/src/services/task-context-hydration.ts +25 -1
- package/src/services/task-delivery.ts +20 -34
- package/src/services/task-dispatch.ts +3 -0
- package/src/services/task-entity.ts +40 -203
- package/src/services/task-issue-link.ts +13 -20
- package/src/services/task-issue-weave.ts +12 -11
- package/src/services/task-lifecycle.ts +27 -31
- package/src/services/task-repo-cwd.ts +37 -0
- package/src/services/task-review-hold.ts +4 -17
- package/src/services/task-semantic-events.ts +13 -11
- package/src/services/task-state-reconcile.ts +8 -17
- package/src/services/task-validation.ts +2 -2
- package/src/services/team-templates.ts +12 -11
- package/src/services/team.ts +31 -98
- package/src/services/terminal-provider-exit.ts +6 -5
- package/src/services/timer-message-fire-chaos-worker.ts +7 -3
- package/src/services/timer-message-fire-outbox.ts +1 -1
- package/src/services/transient-agent-reaper.ts +25 -20
- package/src/services/turn-reconcile-audit.ts +9 -9
- package/src/services/user-onboarding.ts +8 -6
- package/src/services/user-profile.ts +6 -9
- package/src/services/work-finality.ts +16 -4
- package/src/services/workflow-auto-start.ts +26 -13
- package/src/services/workflow-caller.ts +61 -4
- package/src/services/workflow-child-proof-worker.ts +1 -1
- package/src/services/workflow-ci-main.ts +1 -1
- package/src/services/workflow-control-proof-worker.ts +1 -1
- package/src/services/workflow-coordinator.ts +8 -2
- package/src/services/workflow-decisions.ts +5 -5
- package/src/services/workflow-deferred-cleanup.ts +5 -3
- package/src/services/workflow-effect-driver.ts +42 -17
- package/src/services/workflow-effects.ts +58 -37
- package/src/services/workflow-land-notice.ts +10 -0
- package/src/services/workflow-pause-text.ts +43 -0
- package/src/services/workflow-pins.ts +7 -4
- package/src/services/workflow-reconcile.ts +14 -11
- package/src/services/workflow-resume-pins.ts +3 -3
- package/src/services/workflow-routing-defaults.ts +18 -0
- package/src/services/workflow-run-view.ts +6 -3
- package/src/services/workflow-run.test-fixture.ts +1 -1
- package/src/services/workflow-runs.ts +61 -33
- package/src/services/workflow-supervisor-state.ts +26 -1
- package/src/services/workflow-supervisor.ts +11 -6
- package/src/services/workspace-recovery.ts +4 -3
- package/src/settings/registry.ts +1 -2
- package/src/spawn-admission.ts +10 -2
- package/src/spawn-command.ts +4 -4
- package/src/spawn-models.ts +10 -12
- package/src/spawn-placement.ts +28 -10
- package/src/spawn-targets.ts +9 -9
- package/src/sse-agent-status.ts +15 -6
- package/src/sse.ts +49 -24
- package/src/startup-context-injection.ts +62 -57
- 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-handoff.ts +4 -3
- package/src/steward-policy-cleanup.ts +9 -8
- package/src/steward.ts +9 -8
- package/src/task-dispatch-live.ts +6 -3
- package/src/task-dispatcher.ts +3 -3
- package/src/teams-config-store.ts +4 -3
- package/src/token-db-write.ts +10 -0
- package/src/token-db.ts +2 -2
- package/src/token-usage-async.ts +2 -4
- package/src/user-awaiting-reply.ts +5 -5
- package/src/workspace-actions.ts +24 -29
- package/src/workspace-auto-merge.ts +14 -12
- package/src/workspace-changed-paths-client.ts +16 -5
- package/src/workspace-cleanup-stale.ts +30 -7
- package/src/workspace-command-settle.ts +26 -17
- package/src/workspace-config.ts +1 -1
- package/src/workspace-conflict-resolver.ts +9 -7
- package/src/workspace-dead-owner-recovery.ts +5 -4
- package/src/workspace-escalation.ts +12 -11
- package/src/workspace-human-escalation.ts +3 -3
- package/src/workspace-land-gate-watchdog.ts +3 -3
- package/src/workspace-land-refusal.ts +20 -0
- package/src/workspace-land-stopped.ts +1 -0
- package/src/workspace-merge.ts +10 -26
- package/src/workspace-nothing-to-land-notice.ts +2 -2
- package/src/workspace-orphans.ts +18 -37
- package/src/workspace-pr-completion.ts +10 -8
- package/src/workspace-rekey.ts +3 -3
- package/src/workspace-steward-failure.ts +2 -2
- package/src/workspace-steward-wake.ts +4 -4
- 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/shipping-Bu8p1gEw.js +0 -2
- package/public/assets/store-BvtFdlGX.js +0 -9
- package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
- package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
- package/runner/src/agent-runner/http-liveness.ts +0 -85
- package/runner/src/gate-run-lease-probe.ts +0 -38
- package/src/db/claude-catalog-reconcile.ts +0 -27
- package/src/db/on-loop-write-transaction.ts +0 -34
- package/src/routing-model-aliases.ts +0 -21
package/src/db/token-standing.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { participatesInSpawnDelegation, spawnDelegationState, spawnTreeStopped }
|
|
|
3
3
|
import { getDb } from "./connection.ts";
|
|
4
4
|
import type { TokenRevokeReason } from "../security.ts";
|
|
5
5
|
|
|
6
|
-
export function isTokenRevoked(jti: string): boolean {
|
|
6
|
+
export function isTokenRevoked(jti: string, retire?: (predecessor: string) => void): boolean {
|
|
7
7
|
let row: { revoked_at: number | null; retire_jti: string | null; agent_id: string | null } | null;
|
|
8
8
|
try {
|
|
9
9
|
// #1245 — the same lookup names a handed-off predecessor this token has not retired yet.
|
|
@@ -24,19 +24,16 @@ export function isTokenRevoked(jti: string): boolean {
|
|
|
24
24
|
const state = spawnDelegationState(row.agent_id);
|
|
25
25
|
if (state.participating && (state.displaced || spawnTreeStopped(row.agent_id))) return true;
|
|
26
26
|
}
|
|
27
|
-
if (row.retire_jti)
|
|
27
|
+
if (row.retire_jti) retire?.(row.retire_jti);
|
|
28
28
|
return false;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// A successor's first authentication proves its holder has it, so the predecessor it replaced (token-db.ts
|
|
32
32
|
// handoffTokenInternal) is retired as a rotation. A failed write is retried by the successor's next request.
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} catch {
|
|
38
|
-
// The successor stays valid; its next authentication retries.
|
|
39
|
-
}
|
|
33
|
+
export function retireHandedOffPredecessorBody(jti: string, now: number): null {
|
|
34
|
+
getDb().query("UPDATE tokens SET revoked_at = COALESCE(revoked_at, ?), revoked_reason = 'rotation' WHERE jti = ? AND (revoked_at IS NULL OR revoked_reason = 'stale')")
|
|
35
|
+
.run(Math.floor(now / 1000), jti);
|
|
36
|
+
return null;
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
// Returns undefined if the token is not revoked, otherwise its reason string
|
|
@@ -61,24 +58,28 @@ export function tokenRevocationReason(jti: string): string | null | undefined {
|
|
|
61
58
|
/** A rotation retires one token for its successor, so it is never a lineage revocation. */
|
|
62
59
|
export type LineageRevokeReason = Exclude<TokenRevokeReason, "rotation">;
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* stale walk stops at stale members: what follows them is an orchestrator recovery. It never enters a `keep` token. */
|
|
68
|
-
export function revokeTokenLineage(seeds: readonly string[], reason: LineageRevokeReason | null, nowSeconds: number, keep: readonly string[] = []): string[] {
|
|
69
|
-
if (seeds.length === 0) return [];
|
|
70
|
-
const rows = getDb().query(`
|
|
61
|
+
// #3776 — each step must be a key lookup whatever sqlite_stat1 says: CROSS JOIN pins the join order and the unary
|
|
62
|
+
// `+` keeps the predecessor index off the backward step, so stale stats cannot make the walk scan per member.
|
|
63
|
+
export const TOKEN_LINEAGE_REVOKE_SQL = `
|
|
71
64
|
WITH RECURSIVE kept(jti) AS (SELECT value FROM json_each(?1)),
|
|
72
65
|
lineage(jti) AS (
|
|
73
66
|
SELECT value FROM json_each(?2) WHERE value NOT IN kept
|
|
74
|
-
UNION SELECT t.jti FROM lineage l JOIN tokens p ON p.jti = l.jti JOIN tokens t ON t.predecessor_jti = p.jti
|
|
67
|
+
UNION SELECT t.jti FROM lineage l CROSS JOIN tokens p ON p.jti = l.jti CROSS JOIN tokens t ON t.predecessor_jti = p.jti
|
|
75
68
|
WHERE t.jti NOT IN kept AND (?4 IS NOT 'stale' OR p.revoked_reason IS NOT 'stale')
|
|
76
|
-
UNION SELECT p.predecessor_jti FROM lineage l JOIN tokens p ON p.jti = l.jti
|
|
77
|
-
WHERE p.predecessor_jti IS NOT NULL AND p.predecessor_jti NOT IN kept AND (?4 IS NOT 'stale' OR p.revoked_reason IS NOT 'stale')
|
|
69
|
+
UNION SELECT p.predecessor_jti FROM lineage l CROSS JOIN tokens p ON p.jti = l.jti
|
|
70
|
+
WHERE +p.predecessor_jti IS NOT NULL AND +p.predecessor_jti NOT IN kept AND (?4 IS NOT 'stale' OR p.revoked_reason IS NOT 'stale')
|
|
78
71
|
)
|
|
79
72
|
UPDATE tokens SET revoked_at = COALESCE(revoked_at, ?3), revoked_reason = ?4
|
|
80
73
|
WHERE jti IN lineage AND (revoked_at IS NULL OR (?4 IS NOT 'stale' AND revoked_reason = 'stale'))
|
|
81
74
|
RETURNING jti
|
|
82
|
-
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
/** #1245 — a token and every token handed off from it (token-db.ts handoffTokenInternal) are one credential, so
|
|
78
|
+
* revoking any of them revokes the whole lineage: unretired predecessors, pending successors and their renewals.
|
|
79
|
+
* A hard reason also hardens stale members, so no auth, renewal or orchestrator recovery reaches the lineage. A
|
|
80
|
+
* stale walk stops at stale members: what follows them is an orchestrator recovery. It never enters a `keep` token. */
|
|
81
|
+
export function revokeTokenLineage(seeds: readonly string[], reason: LineageRevokeReason | null, nowSeconds: number, keep: readonly string[] = []): string[] {
|
|
82
|
+
if (seeds.length === 0) return [];
|
|
83
|
+
const rows = getDb().query(TOKEN_LINEAGE_REVOKE_SQL).all(JSON.stringify(keep), JSON.stringify(seeds), nowSeconds, reason) as Array<{ jti: string }>;
|
|
83
84
|
return rows.map((row) => row.jti);
|
|
84
85
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getDb } from "./connection";
|
|
2
|
+
|
|
3
|
+
export const TOKEN_USAGE_RETENTION_SCHEMA = `
|
|
4
|
+
CREATE TABLE IF NOT EXISTS retired_token_usage_totals (
|
|
5
|
+
agent_id TEXT PRIMARY KEY, tokens INTEGER NOT NULL, unknown_reports INTEGER NOT NULL);
|
|
6
|
+
CREATE TABLE IF NOT EXISTS token_usage_retention_state (
|
|
7
|
+
id INTEGER PRIMARY KEY CHECK (id = 1), expired_before INTEGER NOT NULL);
|
|
8
|
+
`;
|
|
9
|
+
|
|
10
|
+
/** #3619 — old retries must not resurrect reports already folded into permanent budget totals. */
|
|
11
|
+
export function isTokenUsageExpired(createdAt: number): boolean {
|
|
12
|
+
const state = getDb().query("SELECT expired_before FROM token_usage_retention_state WHERE id = 1")
|
|
13
|
+
.get() as { expired_before: number } | null;
|
|
14
|
+
return state !== null && createdAt < state.expired_before;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Writer-op body: fold each deleted report into its agent's permanent spend in the SAME commit. */
|
|
18
|
+
export function pruneTokenUsage(cutoff: number, limit: number): { pruned: number; moreWork: boolean } {
|
|
19
|
+
const db = getDb();
|
|
20
|
+
db.query(`INSERT INTO token_usage_retention_state VALUES (1, ?)
|
|
21
|
+
ON CONFLICT(id) DO UPDATE SET expired_before = max(expired_before, excluded.expired_before)`).run(cutoff);
|
|
22
|
+
const rows = db.query(`SELECT id, agent_id, input_tokens + output_tokens + cache_read_tokens + cache_write_tokens
|
|
23
|
+
+ COALESCE(reasoning_output_tokens, 0) AS tokens, usage_status IS NOT NULL AS unknown_reports
|
|
24
|
+
FROM session_token_usage WHERE created_at < ? ORDER BY created_at, id LIMIT ?`)
|
|
25
|
+
.all(cutoff, limit) as { id: number; agent_id: string; tokens: number; unknown_reports: number }[];
|
|
26
|
+
for (const row of rows) {
|
|
27
|
+
db.query(`INSERT INTO retired_token_usage_totals VALUES (?, ?, ?)
|
|
28
|
+
ON CONFLICT(agent_id) DO UPDATE SET tokens = tokens + excluded.tokens,
|
|
29
|
+
unknown_reports = unknown_reports + excluded.unknown_reports`).run(row.agent_id, row.tokens, row.unknown_reports);
|
|
30
|
+
db.query("DELETE FROM session_token_usage WHERE id = ?").run(row.id);
|
|
31
|
+
}
|
|
32
|
+
return { pruned: rows.length, moreWork: rows.length === limit };
|
|
33
|
+
}
|
|
@@ -13,7 +13,7 @@ export const TOKEN_USAGE_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Obj
|
|
|
13
13
|
idempotent: true,
|
|
14
14
|
fn: (args: { input: SessionTokenUsageInput }, ctx: WriterOpContext) => {
|
|
15
15
|
const result = recordSessionTokenUsage(args.input);
|
|
16
|
-
const budgetNotices = recordExhaustedSpawnBudgets(result.record.agentId, ctx.now);
|
|
16
|
+
const budgetNotices = result.record ? recordExhaustedSpawnBudgets(result.record.agentId, ctx.now) : [];
|
|
17
17
|
return { ...result, budgetNotices };
|
|
18
18
|
},
|
|
19
19
|
},
|
package/src/db/token-usage.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isTokenUsageExpired } from "./token-usage-retention";
|
|
1
2
|
// #2485 — the durable, provider-agnostic token-usage ledger ("the spine" of epic #2481). The three
|
|
2
3
|
// capture seams write per-turn provider usage here through `tokenUsage.record`; the Analytics box
|
|
3
4
|
// reads period/provider aggregates through `tokenUsage.aggregate`.
|
|
@@ -144,7 +145,7 @@ export function getSessionTokenUsageByDedupeKey(dedupeKey: string): SessionToken
|
|
|
144
145
|
* the writer boundary as well as at the HTTP boundary, and never minted from the receipt clock,
|
|
145
146
|
* so a genuine retry deterministically reuses the same key.
|
|
146
147
|
*/
|
|
147
|
-
export function recordSessionTokenUsage(input: SessionTokenUsageInput): { record: SessionTokenUsageRecord; inserted: boolean } {
|
|
148
|
+
export function recordSessionTokenUsage(input: SessionTokenUsageInput): { record: SessionTokenUsageRecord | null; inserted: boolean } {
|
|
148
149
|
const { createdAt } = input;
|
|
149
150
|
if (!Number.isSafeInteger(createdAt) || createdAt <= 0) {
|
|
150
151
|
throw new ValidationError("createdAt required (positive epoch-milliseconds of the provider's observed usage time)");
|
|
@@ -160,6 +161,8 @@ export function recordSessionTokenUsage(input: SessionTokenUsageInput): { record
|
|
|
160
161
|
const prior = getDb().query("SELECT * FROM session_token_usage WHERE dedupe_key = ?").get(dedupeKey) as
|
|
161
162
|
| SessionTokenUsageRow
|
|
162
163
|
| undefined;
|
|
164
|
+
// Transcript capture replays from byte zero after restart; acknowledge folded history without recreating it (#3619).
|
|
165
|
+
if (!prior && isTokenUsageExpired(createdAt)) return { record: null, inserted: false };
|
|
163
166
|
// Bound once, at first attribution: a replacement reuses the row's Task, never the agent's current one.
|
|
164
167
|
const taskId = prior ? (prior.task_id ?? undefined) : deliverableTaskIdForAgent(input.agentId);
|
|
165
168
|
getDb().query(`
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { getGateway } from "./gateway";
|
|
3
|
+
import type { createUserInvite, acceptUserInvite } from "./user-invites";
|
|
4
|
+
import { invalidateUserCount } from "./users";
|
|
5
|
+
|
|
6
|
+
export function createUserInviteAsync(input: Parameters<typeof createUserInvite>[0]): Promise<ReturnType<typeof createUserInvite>> {
|
|
7
|
+
return getGateway().write("userInvites.create", input, { idempotencyKey: randomUUID() }) as unknown as Promise<ReturnType<typeof createUserInvite>>;
|
|
8
|
+
}
|
|
9
|
+
export async function acceptUserInviteAsync(input: Parameters<typeof acceptUserInvite>[0]): Promise<ReturnType<typeof acceptUserInvite>> {
|
|
10
|
+
const user = await getGateway().write("userInvites.accept", input, { idempotencyKey: randomUUID() }) as unknown as ReturnType<typeof acceptUserInvite>;
|
|
11
|
+
invalidateUserCount();
|
|
12
|
+
return user;
|
|
13
|
+
}
|
package/src/db/user-invites.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// the password identity, so a replayed or raced code can never create a second account.
|
|
5
5
|
import { createHash, randomBytes } from "node:crypto";
|
|
6
6
|
import { ValidationError, getDb, writeTransaction } from "./connection.ts";
|
|
7
|
-
import {
|
|
7
|
+
import { createUserRow } from "./users.ts";
|
|
8
8
|
import { createAuthIdentity } from "./auth-identities.ts";
|
|
9
9
|
import type { User, UserRole } from "../types";
|
|
10
10
|
|
|
@@ -99,8 +99,8 @@ export function acceptUserInvite(input: { code: string; userId: string; handle:
|
|
|
99
99
|
}
|
|
100
100
|
const claimed = getDb().query("UPDATE user_invites SET used_at = ? WHERE id = ? AND used_at IS NULL").run(now, row.id);
|
|
101
101
|
if (claimed.changes !== 1) throw new InviteUnavailableError("invite is invalid, expired or already used");
|
|
102
|
-
const user =
|
|
103
|
-
createAuthIdentity({ userId: user.id, provider: input.provider, providerSubject: input.handle, secretHash: input.secretHash });
|
|
102
|
+
const user = createUserRow({ id: input.userId, handle: input.handle, displayName: input.displayName || row.display_name || input.handle, role: row.role as UserRole }, now);
|
|
103
|
+
createAuthIdentity({ userId: user.id, provider: input.provider, providerSubject: input.handle, secretHash: input.secretHash }, now);
|
|
104
104
|
getDb().query("UPDATE user_invites SET used_by = ? WHERE id = ?").run(user.id, row.id);
|
|
105
105
|
return user;
|
|
106
106
|
});
|
package/src/db/users.ts
CHANGED
|
@@ -91,10 +91,19 @@ export function userCount(now: number = Date.now()): number {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export function createUser(input: CreateUserInput): User {
|
|
94
|
+
const user = createUserRow(input);
|
|
95
|
+
invalidateUserCount();
|
|
96
|
+
return user;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function invalidateUserCount(): void {
|
|
94
100
|
assertMainThreadState("users.ts");
|
|
101
|
+
userCountCache = undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function createUserRow(input: CreateUserInput, now = Date.now()): User {
|
|
95
105
|
if (!input.id) throw new ValidationError("user id is required");
|
|
96
106
|
if (!input.handle) throw new ValidationError("user handle is required");
|
|
97
|
-
const now = Date.now();
|
|
98
107
|
getDb()
|
|
99
108
|
.query(
|
|
100
109
|
`INSERT INTO users (id, handle, display_name, role, status, tenant_id, avatar_artifact_id, created_at, updated_at)
|
|
@@ -111,7 +120,6 @@ export function createUser(input: CreateUserInput): User {
|
|
|
111
120
|
now,
|
|
112
121
|
now,
|
|
113
122
|
);
|
|
114
|
-
userCountCache = undefined;
|
|
115
123
|
const created = getUser(input.id);
|
|
116
124
|
if (!created) throw new ValidationError(`failed to create user ${input.id}`);
|
|
117
125
|
return created;
|
|
@@ -121,7 +129,7 @@ export function updateUserProfile(input: {
|
|
|
121
129
|
id: string;
|
|
122
130
|
displayName?: string;
|
|
123
131
|
avatarArtifactId?: string | null;
|
|
124
|
-
}): User {
|
|
132
|
+
}, submittedAt: number = Date.now()): User {
|
|
125
133
|
const current = getUser(input.id);
|
|
126
134
|
if (!current) throw new ValidationError("user not found");
|
|
127
135
|
const updates: string[] = [];
|
|
@@ -137,17 +145,17 @@ export function updateUserProfile(input: {
|
|
|
137
145
|
}
|
|
138
146
|
if (!updates.length) return current;
|
|
139
147
|
updates.push("updated_at = ?");
|
|
140
|
-
params.push(
|
|
148
|
+
params.push(submittedAt, input.id);
|
|
141
149
|
getDb().query(`UPDATE users SET ${updates.join(", ")} WHERE id = ?`).run(...params);
|
|
142
150
|
return getUser(input.id)!;
|
|
143
151
|
}
|
|
144
152
|
|
|
145
153
|
/** Change a user's role or account status (#3567 admin user list). */
|
|
146
|
-
export function updateUserAccess(input: { id: string; role?: UserRole; status?: UserStatus }): User {
|
|
154
|
+
export function updateUserAccess(input: { id: string; role?: UserRole; status?: UserStatus }, submittedAt: number = Date.now()): User {
|
|
147
155
|
const current = getUser(input.id);
|
|
148
156
|
if (!current) throw new ValidationError("user not found");
|
|
149
157
|
getDb().query("UPDATE users SET role = ?, status = ?, updated_at = ? WHERE id = ?")
|
|
150
|
-
.run(input.role ?? current.role, input.status ?? current.status,
|
|
158
|
+
.run(input.role ?? current.role, input.status ?? current.status, submittedAt, input.id);
|
|
151
159
|
return getUser(input.id)!;
|
|
152
160
|
}
|
|
153
161
|
|
|
@@ -20,7 +20,7 @@ export interface WorkflowHeldContact { runId: string; reason: WorkflowContactRea
|
|
|
20
20
|
|
|
21
21
|
/** Notices that bypass the step-contact hold: the run's own coordinator notices (including GO awaiting an external
|
|
22
22
|
* hold's release), and a step agent held on a provider block, which waits until someone acts (#3647). */
|
|
23
|
-
const COORDINATOR_NOTICE_KINDS = new Set(["workflow.started", "workflow.landed", "workflow.escalated", "workflow.result", "workflow.review-passed", "agent.spawn_failed", "agent.spawn_recovered", "delegation.budget_exhausted", "agent.provider_blocked", "agent.provider_still_held"]);
|
|
23
|
+
const COORDINATOR_NOTICE_KINDS = new Set(["workflow.started", "workflow.landed", "workflow.escalated", "workflow.result", "workflow.review-passed", "workflow.paused", "workflow.unpaused", "agent.spawn_failed", "agent.spawn_recovered", "delegation.budget_exhausted", "agent.provider_blocked", "agent.provider_still_held"]);
|
|
24
24
|
export const WORKFLOW_SCOPE = "local";
|
|
25
25
|
export const WORKFLOW_RUN_TABLE = "kernel_entity__workflow__run";
|
|
26
26
|
const LINK_TABLE = "kernel_entity__workflow__link";
|
|
@@ -185,3 +185,33 @@ export function openWorkflowRunHolders(): { teamIds: Set<string>; coordinatorIds
|
|
|
185
185
|
}
|
|
186
186
|
return holders;
|
|
187
187
|
}
|
|
188
|
+
|
|
189
|
+
/** #3757 — a running run a coordinator paused, with its input Task's team; `pause` is the stored JSON. */
|
|
190
|
+
export interface PausedWorkflowRunRow {
|
|
191
|
+
runId: string; taskId: number; taskTitle: string | null; coordinator: string; callerAgentId: string | null;
|
|
192
|
+
teamId: string | null; owner: string | null; pause: string;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let pauseColumnOn: unknown;
|
|
196
|
+
/** The column appears when the workflow module first registers after #3757; until then nothing is paused. */
|
|
197
|
+
function pauseColumnReady(): boolean {
|
|
198
|
+
const db = getDb();
|
|
199
|
+
if (pauseColumnOn === db) return true;
|
|
200
|
+
const ready = (db.query(`PRAGMA table_info(${WORKFLOW_RUN_TABLE})`).all() as Array<{ name: string }>).some((column) => column.name === "pause");
|
|
201
|
+
if (ready) pauseColumnOn = db;
|
|
202
|
+
return ready;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function pausedWorkflowRuns(): PausedWorkflowRunRow[] {
|
|
206
|
+
if (!workflowTablesReady() || !pauseColumnReady()) return [];
|
|
207
|
+
return getDb().query(`SELECT run.id AS runId, run.taskId AS taskId, task.title AS taskTitle, run.coordinator AS coordinator, run.callerAgentId AS callerAgentId,
|
|
208
|
+
task.team_id AS teamId, task.owner AS owner, run.pause AS pause
|
|
209
|
+
FROM ${WORKFLOW_RUN_TABLE} run LEFT JOIN tasks task ON task.id = run.taskId
|
|
210
|
+
WHERE run.scope = ? AND run.status = 'running' AND run.pause IS NOT NULL ORDER BY run.id`).all(WORKFLOW_SCOPE) as PausedWorkflowRunRow[];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** #3757 — a paused run keeps its idle step agents: the idle reapers leave them alone until it is unpaused. */
|
|
214
|
+
export function workflowRunPaused(runId: string): boolean {
|
|
215
|
+
if (!workflowTablesReady() || !pauseColumnReady()) return false;
|
|
216
|
+
return Boolean(getDb().query(`SELECT 1 FROM ${WORKFLOW_RUN_TABLE} WHERE scope = ? AND id = ? AND status = 'running' AND pause IS NOT NULL`).get(WORKFLOW_SCOPE, runId));
|
|
217
|
+
}
|
package/src/db/workspaces.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { trackRelayEvent } from "../relay-event-drain";
|
|
1
2
|
import { mainThreadRegistry } from "./main-thread-state";
|
|
2
3
|
import { persistWorkspace, type WorkspaceUpsertInput } from "./workspace-persistence";
|
|
3
4
|
import { Database } from "bun:sqlite";
|
|
@@ -438,7 +439,7 @@ export function pruneOrphanedSharedWorkspaces(): string[] {
|
|
|
438
439
|
// owner's branch-state badge" (#236). A hook, not a direct emit, because getDb().ts is
|
|
439
440
|
// the lowest layer — sse.ts imports db, so db can't import sse without a cycle. sse
|
|
440
441
|
// registers a listener at startup that re-emits the owner agent's status over SSE.
|
|
441
|
-
type WorkspaceChangeListener = (workspace: WorkspaceRecord) =>
|
|
442
|
+
type WorkspaceChangeListener = (workspace: WorkspaceRecord) => unknown;
|
|
442
443
|
export const workspaceChangeListeners = mainThreadRegistry("workspaces.ts:workspaceChangeListeners", new Set<WorkspaceChangeListener>());
|
|
443
444
|
export function onWorkspaceChange(listener: WorkspaceChangeListener): void {
|
|
444
445
|
workspaceChangeListeners.add(listener);
|
|
@@ -447,7 +448,8 @@ export function emitWorkspaceChange(workspace: WorkspaceRecord | null | undefine
|
|
|
447
448
|
if (!workspace) return;
|
|
448
449
|
for (const listener of workspaceChangeListeners) {
|
|
449
450
|
try {
|
|
450
|
-
listener(workspace);
|
|
451
|
+
const result = listener(workspace);
|
|
452
|
+
if (result instanceof Promise) trackRelayEvent(result, "workspace.changed");
|
|
451
453
|
} catch {
|
|
452
454
|
// A badge-refresh listener must never break a workspace write.
|
|
453
455
|
}
|
|
@@ -455,15 +457,16 @@ export function emitWorkspaceChange(workspace: WorkspaceRecord | null | undefine
|
|
|
455
457
|
}
|
|
456
458
|
|
|
457
459
|
// #1870 — workspace-create effects stay on main; index.ts registers the issue activity handler.
|
|
458
|
-
type WorkspaceCreateListener = (workspace: WorkspaceRecord) => void
|
|
460
|
+
type WorkspaceCreateListener = (workspace: WorkspaceRecord) => void | Promise<void>;
|
|
459
461
|
const workspaceCreateListeners = mainThreadRegistry("workspaces.ts:workspaceCreateListeners", new Set<WorkspaceCreateListener>());
|
|
460
462
|
export function onWorkspaceCreate(listener: WorkspaceCreateListener): void {
|
|
461
463
|
workspaceCreateListeners.add(listener);
|
|
462
464
|
}
|
|
463
|
-
function emitWorkspaceCreate(workspace: WorkspaceRecord): void {
|
|
465
|
+
export function emitWorkspaceCreate(workspace: WorkspaceRecord): void {
|
|
464
466
|
for (const listener of workspaceCreateListeners) {
|
|
465
467
|
try {
|
|
466
|
-
listener(workspace);
|
|
468
|
+
const result = listener(workspace);
|
|
469
|
+
if (result) trackRelayEvent(result, "workspace.created");
|
|
467
470
|
} catch {
|
|
468
471
|
// A create listener must never break a workspace write.
|
|
469
472
|
}
|
package/src/db/write-ops.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import { TIMER_CUTOVER_COORDINATOR_WRITE_OPS } from "./timer-cutover-bodies";
|
|
2
|
+
import { RUNTIME_ADMIN_WRITE_OPS } from "./runtime-admin-write-ops";
|
|
3
|
+
import { AUTOMATION_WRITE_OPS } from "./automation-write-ops";
|
|
4
|
+
import { RUNTIME_TAIL_WRITE_OPS } from "./runtime-tail-write-ops";
|
|
5
|
+
import { LIFECYCLE_TAIL_WRITE_OPS } from "./lifecycle-tail-write-ops";
|
|
6
|
+
import { NOTIFICATION_WRITE_OPS } from "./notification-write-ops";
|
|
7
|
+
import { HISTORY_RETENTION_WRITE_OPS } from "./history-retention-ops";
|
|
8
|
+
import { INTEGRATIONS_WRITE_OPS } from "./integrations-ops.ts";
|
|
1
9
|
import { bufferedLastSeen, type PresenceSnapshot } from "./presence-buffer";
|
|
2
10
|
import { ensureDurablePayloadSchema, readRetryReceipt, storeDurablePayload } from "./durable-payloads";
|
|
3
11
|
import { ledgerSlotPredicate, ledgerSlots, WRITER_IDEMPOTENCY_RETENTION_MS } from "./writer-ledger";
|
|
@@ -5,6 +13,7 @@ import { workspaceChangeListeners } from "./workspaces";
|
|
|
5
13
|
import { withWriterOpState } from "./main-thread-state";
|
|
6
14
|
import { importVaultRows } from "./secrets-vault-import";
|
|
7
15
|
import { PROMPT_VERSION_WRITE_OPS } from "./prompt-versions-ops";
|
|
16
|
+
import { PROJECT_PROFILE_INSTRUCTION_WRITE_OPS } from "./project-profile-instructions";
|
|
8
17
|
import { VAULT_WRITE_OPS } from "./secrets-vault-write";
|
|
9
18
|
import { VAULT_EXPIRY_WRITE_OPS } from "./vault-expiry";
|
|
10
19
|
import { VAULT_BACKUP_WRITE_OPS } from "./vault-backup";
|
|
@@ -40,6 +49,7 @@ import { CLAUDE_API_BUDGET_WRITE_OPS } from "./claude-api-budget-ops";
|
|
|
40
49
|
// file is the seam they plug into, not the final op set.
|
|
41
50
|
|
|
42
51
|
import type { Database } from "bun:sqlite";
|
|
52
|
+
import { WRITER_FAULT_TEST_OPS } from "./writer-fault-test-ops";
|
|
43
53
|
import { ValidationError } from "@humwick/sdk";
|
|
44
54
|
import { getDb, inWriteTransaction } from "./connection.ts";
|
|
45
55
|
import type { SerializedDbError } from "./db-error-registry.ts";
|
|
@@ -91,6 +101,7 @@ import { PLANS_WRITE_OPS } from "./plans-write-ops.ts";
|
|
|
91
101
|
import { CONTINUATION_ARCHIVES_WRITE_OPS } from "./continuation-archives-write-ops.ts";
|
|
92
102
|
import { WORKFLOW_JOURNAL_WRITE_OPS } from "./workflow-journal-write-ops.ts";
|
|
93
103
|
import { WORKFLOW_STEP_TASK_WRITE_OPS } from "./workflow-step-tasks.ts";
|
|
104
|
+
import { PROJECT_ENTRIES_WRITE_OPS } from "./project-entries-write-ops";
|
|
94
105
|
import { PROJECTS_WRITE_OPS } from "./projects-write-ops.ts";
|
|
95
106
|
import { CHANNELS_WRITE_OPS } from "./channels-write-ops.ts";
|
|
96
107
|
import { CI_INCIDENTS_WRITE_OPS } from "./ci-incidents-write-ops.ts";
|
|
@@ -117,6 +128,7 @@ import { RESTART_EPOCH_WRITE_OPS } from "./restart-epoch-write-ops.ts";
|
|
|
117
128
|
import { TOKEN_USAGE_WRITE_OPS } from "./token-usage-write-ops.ts";
|
|
118
129
|
// #1870 S3 — the 1 s raw writers: maintenance leases/runs, pending issue closes, workspace lifecycle.
|
|
119
130
|
import { MAINTENANCE_JOB_WRITE_OPS } from "./maintenance-job-write-ops.ts";
|
|
131
|
+
import { ISSUE_REFS_WRITE_OPS } from "./issue-refs-write-ops.ts";
|
|
120
132
|
import { LONG_RUNNING_WORK_WRITE_OPS } from "./long-running-work-write-ops.ts";
|
|
121
133
|
import { WORKSPACE_WRITE_OPS } from "./workspace-write-ops.ts";
|
|
122
134
|
|
|
@@ -196,6 +208,10 @@ export interface WriterOpSpec {
|
|
|
196
208
|
/** This complete operation has no main-thread effects and may use the file-backed writer. */
|
|
197
209
|
readonly offLoop?: boolean;
|
|
198
210
|
readonly idempotent: boolean;
|
|
211
|
+
/** #3614 — a non-idempotent op whose keyless callers never resubmit: it runs without a key and
|
|
212
|
+
* writes no ledger row, and a lost acknowledgement stays indeterminate for that caller. A caller
|
|
213
|
+
* that does retry still passes a key and gets the ledger's exactly-once dedup. */
|
|
214
|
+
readonly atMostOnce?: true;
|
|
199
215
|
readonly fn: WriterOp;
|
|
200
216
|
/** Sanitizes a result before it enters the durable retry ledger. Results can include a newly-created
|
|
201
217
|
* command's caller-visible plaintext env, while the ledger is readable as raw DB state. */
|
|
@@ -231,14 +247,7 @@ const PROBE_DDL = `
|
|
|
231
247
|
// durable across a worker death (the phantom-failure case), because it lives in the DB, not in memory.
|
|
232
248
|
export { WRITER_IDEMPOTENCY_RETENTION_MS };
|
|
233
249
|
|
|
234
|
-
|
|
235
|
-
* Create the seam-probe + dedup schema. This models real schema bootstrap (§4, the allowlisted
|
|
236
|
-
* bootstrap layer): DDL runs ONCE at startup as its own committed statement, NOT lazily inside an op —
|
|
237
|
-
* a rolled back op must never undo the schema it ran against. Ops below therefore assume the tables
|
|
238
|
-
* exist, just as relocated real ops assume the migrated catalog exists (H6/§3.1). Idempotent
|
|
239
|
-
* (`IF NOT EXISTS`), so it is safe to call on both the in-process connection and, at bootstrap, on the
|
|
240
|
-
* file that the worker later opens (WAL makes the committed tables visible cross-connection, §3.5).
|
|
241
|
-
*/
|
|
250
|
+
// Probe tables are installed at bootstrap, outside writer transactions.
|
|
242
251
|
export function ensureSeamProbeSchema(db: Database = getDb()): void {
|
|
243
252
|
if (db.inTransaction) throw new Error("ensureSeamProbeSchema must run at bootstrap, not inside a transaction");
|
|
244
253
|
db.run(PROBE_DDL);
|
|
@@ -274,6 +283,7 @@ export const WRITER_OPS: Readonly<Record<string, WriterOpSpec>> = Object.freeze(
|
|
|
274
283
|
// call inserts a NEW row — NON-idempotent: a retry without dedup would double-apply, so the gateway
|
|
275
284
|
// requires an idempotencyKey and the executor dedups on it.
|
|
276
285
|
"seam.append": {
|
|
286
|
+
offLoop: true,
|
|
277
287
|
idempotent: false,
|
|
278
288
|
fn: (args: { tag: string; value?: string }, ctx) => {
|
|
279
289
|
const row = getDb()
|
|
@@ -393,11 +403,17 @@ export function allWriterOps(): Readonly<Record<string, WriterOpSpec>> {
|
|
|
393
403
|
if (!mergedWriterOps) {
|
|
394
404
|
mergedWriterOps = Object.freeze({
|
|
395
405
|
...WRITER_OPS,
|
|
406
|
+
...WRITER_FAULT_TEST_OPS,
|
|
396
407
|
...VAULT_TOKEN_WRITE_OPS,
|
|
397
408
|
...VAULT_HEALTH_WRITE_OPS,
|
|
398
409
|
...WORKSPACE_REKEY_WRITE_OPS,
|
|
399
410
|
...PAIRS_WRITE_OPS,
|
|
400
411
|
...MESSAGE_WRITE_OPS,
|
|
412
|
+
...NOTIFICATION_WRITE_OPS,
|
|
413
|
+
...LIFECYCLE_TAIL_WRITE_OPS,
|
|
414
|
+
...RUNTIME_TAIL_WRITE_OPS,
|
|
415
|
+
...AUTOMATION_WRITE_OPS,
|
|
416
|
+
...RUNTIME_ADMIN_WRITE_OPS,
|
|
401
417
|
...COMMANDS_WRITE_OPS,
|
|
402
418
|
...RESTART_EPOCH_WRITE_OPS,
|
|
403
419
|
...BUS_OUTBOX_WRITE_OPS,
|
|
@@ -406,12 +422,14 @@ export function allWriterOps(): Readonly<Record<string, WriterOpSpec>> {
|
|
|
406
422
|
...ROUTING_POLICY_WRITE_OPS,
|
|
407
423
|
...USER_SETTINGS_WRITE_OPS,
|
|
408
424
|
...PROMPT_VERSION_WRITE_OPS,
|
|
425
|
+
...PROJECT_PROFILE_INSTRUCTION_WRITE_OPS,
|
|
409
426
|
...TOKEN_DB_WRITE_OPS,
|
|
410
427
|
...DELIVERY_WRITE_OPS,
|
|
411
428
|
...TIMER_WRITE_OPS,
|
|
412
429
|
...TIMER_INGRESS_WRITE_OPS,
|
|
413
430
|
...TIMER_TRANSFER_WRITE_OPS,
|
|
414
431
|
...TIMER_CUTOVER_WRITE_OPS,
|
|
432
|
+
...TIMER_CUTOVER_COORDINATOR_WRITE_OPS,
|
|
415
433
|
...TASK_WRITE_OPS,
|
|
416
434
|
...AGENTS_WRITE_OPS,
|
|
417
435
|
...AGENT_LIFECYCLE_WRITE_OPS,
|
|
@@ -439,7 +457,9 @@ export function allWriterOps(): Readonly<Record<string, WriterOpSpec>> {
|
|
|
439
457
|
...WORKFLOW_STEP_TASK_WRITE_OPS,
|
|
440
458
|
...SPAWN_TREE_CLEANUP_WRITE_OPS,
|
|
441
459
|
...PROJECTS_WRITE_OPS,
|
|
460
|
+
...PROJECT_ENTRIES_WRITE_OPS,
|
|
442
461
|
...CHANNELS_WRITE_OPS,
|
|
462
|
+
...INTEGRATIONS_WRITE_OPS,
|
|
443
463
|
...CI_INCIDENTS_WRITE_OPS,
|
|
444
464
|
...TEAMS_WRITE_OPS,
|
|
445
465
|
...TEAM_SPAWN_DELEGATION_WRITE_OPS,
|
|
@@ -468,8 +488,10 @@ export function allWriterOps(): Readonly<Record<string, WriterOpSpec>> {
|
|
|
468
488
|
...TOKEN_USAGE_WRITE_OPS,
|
|
469
489
|
...MAINTENANCE_JOB_WRITE_OPS,
|
|
470
490
|
...LONG_RUNNING_WORK_WRITE_OPS,
|
|
491
|
+
...ISSUE_REFS_WRITE_OPS,
|
|
471
492
|
...WORKSPACE_WRITE_OPS,
|
|
472
493
|
...WEB_TOOL_CALL_WRITE_OPS,
|
|
494
|
+
...HISTORY_RETENTION_WRITE_OPS,
|
|
473
495
|
...CLAUDE_API_BUDGET_WRITE_OPS,
|
|
474
496
|
...CLAUDE_APP_OAUTH_WRITE_OPS,
|
|
475
497
|
});
|
|
@@ -481,10 +503,12 @@ export function isKnownWriterOp(op: string): boolean {
|
|
|
481
503
|
return Object.prototype.hasOwnProperty.call(allWriterOps(), op);
|
|
482
504
|
}
|
|
483
505
|
|
|
484
|
-
/** Whether a registered op
|
|
485
|
-
* unknown op so a typo cannot silently pass the
|
|
486
|
-
|
|
487
|
-
|
|
506
|
+
/** Whether a registered op may be submitted without an idempotency key (H5 §3.7.1): it is safe to
|
|
507
|
+
* re-apply, or it is at-most-once. Throws for an unknown op so a typo cannot silently pass the
|
|
508
|
+
* gateway's keyless-write gate. */
|
|
509
|
+
export function writerOpAllowsKeyless(op: string): boolean {
|
|
510
|
+
const spec = resolveOp(op);
|
|
511
|
+
return spec.idempotent || spec.atMostOnce === true;
|
|
488
512
|
}
|
|
489
513
|
|
|
490
514
|
export function isOffLoopWriterOp(op: string): boolean {
|
|
@@ -506,6 +530,7 @@ function resolveOp(op: string): WriterOpSpec {
|
|
|
506
530
|
*/
|
|
507
531
|
function applyOnce(op: string, spec: WriterOpSpec, args: unknown, ctx: WriterOpContext, key: string | undefined): unknown {
|
|
508
532
|
if (spec.idempotent) return spec.fn(args, ctx); // safe to re-apply, no key needed
|
|
533
|
+
if (key === undefined && spec.atMostOnce) return spec.fn(args, ctx); // no retry, so nothing to dedup
|
|
509
534
|
// STRUCTURAL enforcement at the executor (H5 §3.7.1): a non-idempotent op MUST carry a key here, so
|
|
510
535
|
// the invariant holds even for a direct executor caller that bypassed the gateway guard. Rejecting
|
|
511
536
|
// BEFORE spec.fn means zero rows are written, so a keyless non-idempotent write can never duplicate.
|
|
@@ -24,10 +24,6 @@
|
|
|
24
24
|
// `threadId` is still recorded and checked as belt-and-braces for an exotic case where a fault is
|
|
25
25
|
// armed on a thread that later dispatches ops elsewhere.
|
|
26
26
|
//
|
|
27
|
-
// This is deliverable under the IN-PROCESS backend, which is the gateway default (`initGateway`
|
|
28
|
-
// chooses in-process even for a file DB) and therefore what the whole default suite and every
|
|
29
|
-
// existing chaos-worker subprocess run — so no existing crash seam loses its injection.
|
|
30
|
-
|
|
31
27
|
import { threadId } from "node:worker_threads";
|
|
32
28
|
|
|
33
29
|
interface ArmedWriterFault {
|
|
@@ -36,10 +32,7 @@ interface ArmedWriterFault {
|
|
|
36
32
|
readonly threadId: number;
|
|
37
33
|
}
|
|
38
34
|
|
|
39
|
-
//
|
|
40
|
-
// writer thread this map is empty, so the lookup is a harmless no-op there. Delivery is kept honest at
|
|
41
|
-
// dispatch: while a fault is armed the in-process backend runs off-loop ops on the arming thread
|
|
42
|
-
// (writer-gateway `dispatchEntry`), and arming refuses under the worker backend.
|
|
35
|
+
// Each writer thread owns its fault registry. File-backed tests arm named actions on that thread.
|
|
43
36
|
const armed = new Map<string, ArmedWriterFault>();
|
|
44
37
|
|
|
45
38
|
/**
|
|
@@ -67,7 +60,7 @@ export function armWriterFault(name: string, fn: () => void): () => void {
|
|
|
67
60
|
throw new Error(
|
|
68
61
|
`writer fault '${name}' cannot be armed: the gateway writer backend is 'worker', so this ` +
|
|
69
62
|
`main-thread closure can never run inside the writer op's transaction and the crash would ` +
|
|
70
|
-
`not be injected at all.
|
|
63
|
+
`not be injected at all. Use :memory: for closure faults, arm a named seam.armFault action on the writer, ` +
|
|
71
64
|
`or assert the behaviour without an in-transaction crash seam.`,
|
|
72
65
|
);
|
|
73
66
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { armWriterFault } from "./writer-fault-seam";
|
|
2
|
+
import type { WriterOpSpec } from "./write-ops";
|
|
3
|
+
|
|
4
|
+
// Named actions cross the worker seam; main-thread closures cannot (#1870 S8).
|
|
5
|
+
export const WRITER_FAULT_TEST_OPS = {
|
|
6
|
+
"seam.armFault": {
|
|
7
|
+
offLoop: true,
|
|
8
|
+
idempotent: true,
|
|
9
|
+
fn: (args: { name: string; action: "kill" | "throw" }) => {
|
|
10
|
+
if (args.action !== "kill" && args.action !== "throw") throw new Error("unknown writer test fault");
|
|
11
|
+
armWriterFault(args.name, () => {
|
|
12
|
+
if (args.action === "kill") process.kill(process.pid, "SIGKILL");
|
|
13
|
+
throw new Error(`injected writer fault: ${args.name}`);
|
|
14
|
+
});
|
|
15
|
+
return null;
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
} satisfies Record<string, WriterOpSpec>;
|