@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/routes/agents.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Auto-split from routes.ts (#299). Domain: agents.
|
|
2
2
|
import { messageViewerForRequest, visibleMessages } from "./message-viewer";
|
|
3
3
|
import { attachPrincipal, attachPrincipals } from "../agent-principal";
|
|
4
|
-
import {
|
|
5
|
-
import { ValidationError, deleteAgentAsync, getAgent, getAgentAsync, getAgentIdentityAsync, getAgentQuotaSnapshotsAsync, getAgentTimelineAsync, getCrashReport,
|
|
4
|
+
import { agentSessionStatus, auditEvent, authorizeRoute, canViewAgentRoute, error, json, normalizeAgentSessionGuard, parseBody, parseId, parseQueryInt, visibleAgentIdsForRequest, type Handler } from "./_shared";
|
|
5
|
+
import { ValidationError, deleteAgentAsync, getAgent, getAgentAsync, getAgentIdentityAsync, getAgentQuotaSnapshotsAsync, getAgentTimelineAsync, getCrashReport, listAgentChatHistoryAsync, listAgents, listAgentsAsync, listArtifactsForEntityAsync, listContextSnapshotsAsync, listPendingReplyObligationsAsync, searchAgentsAsync, setLabelAsync, setTagsAsync, validateAgentSession } from "../db";
|
|
6
6
|
import { attachBranchState, attachBranchStates } from "../agent-branch-state";
|
|
7
7
|
import { redactAgentCardLaunchShape } from "../agent-launch-shape-redaction";
|
|
8
8
|
import { attachChannelBinding, attachChannelBindings } from "../agent-channel-binding";
|
|
@@ -10,47 +10,16 @@ import { attachCommandActivities, attachCommandActivity } from "../agent-command
|
|
|
10
10
|
import { attachIssueRepo, attachIssueRepos } from "../agent-issue-repo";
|
|
11
11
|
import { cleanStringArray } from "../validation";
|
|
12
12
|
import { emitAgentRemoved, emitAgentStatus } from "../sse";
|
|
13
|
-
import { announceSpawnedAgentReady } from "../services/register-agent";
|
|
14
|
-
import { flushQueuedDirectMessages } from "../services/managed-running";
|
|
15
|
-
import { acquireTeamOnReady } from "../services/team";
|
|
16
13
|
import { artifactReadScopeForRequest } from "../services/artifact-access";
|
|
17
|
-
import { isAgentUnavailable } from "../db/agent-predicates";
|
|
18
14
|
import { getCompactionWatch } from "../compaction-watch";
|
|
19
15
|
import { isRecord } from "@humwick/sdk";
|
|
20
16
|
import { getComponentAuth, hasComponentScope } from "../security";
|
|
21
|
-
import { type AgentCard
|
|
17
|
+
import { type AgentCard } from "../types";
|
|
22
18
|
import { attachToolchain } from "../project-toolchain";
|
|
23
19
|
import { listEffortChangesAsync } from "../commands-write";
|
|
24
20
|
import { markAgentWorkFinal } from "../services/work-finality";
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
key: "available" | "busy" | "not-ready" | "offline";
|
|
28
|
-
title: string;
|
|
29
|
-
icon: string;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
function agentActivityState(agent?: Pick<AgentCard, "ready" | "status"> | null): AgentActivityState | null {
|
|
33
|
-
if (!agent) return null;
|
|
34
|
-
if (agent.status === "offline") return { key: "offline", title: "Agent offline", icon: "ti-plug-off" };
|
|
35
|
-
if (!agent.ready) return { key: "not-ready", title: "Agent not ready", icon: "ti-loader" };
|
|
36
|
-
if (agent.status === "busy") return { key: "busy", title: "Agent busy", icon: "ti-activity" };
|
|
37
|
-
return { key: "available", title: "Agent available", icon: "ti-circle-check" };
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function auditAgentStateTransition(agentId: string, before: AgentCard | null | undefined, after: AgentCard | null | undefined): Promise<void> {
|
|
41
|
-
const previous = agentActivityState(before);
|
|
42
|
-
const next = agentActivityState(after);
|
|
43
|
-
if (!next || previous?.key === next.key) return;
|
|
44
|
-
await auditEvent({
|
|
45
|
-
clientId: "server-agent-" + agentId + "-state-" + next.key + "-" + Date.now(),
|
|
46
|
-
kind: "state",
|
|
47
|
-
title: next.title,
|
|
48
|
-
meta: agentId,
|
|
49
|
-
icon: next.icon,
|
|
50
|
-
view: "agents",
|
|
51
|
-
agentId,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
21
|
+
import { authorizeProviderQuotaWrite } from "./provider-quotas";
|
|
22
|
+
import { applyAgentHeartbeat, applyAgentReady, applyAgentStatus, cleanAgentStatus, cleanHeartbeatReport, noteUnchangedLifecycle } from "../services/agent-heartbeat";
|
|
54
23
|
|
|
55
24
|
// #1797 round 2 (F1b) — the agent roster carried `meta.policyName` + `meta.spawnRequestId` in the
|
|
56
25
|
// clear to any `agent:read` holder. Those two strings are the ADDRESSING for every managed-agent
|
|
@@ -248,56 +217,6 @@ export const getTaskArtifactsRoute: Handler = async (req, params) => {
|
|
|
248
217
|
return json(await listArtifactsForEntityAsync("task", id, artifactReadScopeForRequest(req)));
|
|
249
218
|
};
|
|
250
219
|
|
|
251
|
-
type AgentStatusValue = (typeof VALID_AGENT_STATUSES)[number];
|
|
252
|
-
|
|
253
|
-
function cleanAgentStatus(value: unknown): AgentStatusValue {
|
|
254
|
-
if (!VALID_AGENT_STATUSES.includes(value as AgentStatusValue)) throw new ValidationError(`status must be one of: ${VALID_AGENT_STATUSES.join(", ")}`);
|
|
255
|
-
return value as AgentStatusValue;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// #3606 — a reported status/readiness equal to the live card is a liveness tick, not a transition: no
|
|
259
|
-
// row write, no agent.status event. Presence still advances through the coalescing heartbeat buffer,
|
|
260
|
-
// except for a terminal row, which a beat would resurrect.
|
|
261
|
-
function noteUnchangedLifecycle(agentId: string, current: AgentCard, guard: AgentSessionGuard | undefined): void {
|
|
262
|
-
if (current.status !== "offline" && current.status !== "stale") recordHeartbeat(agentId, { guard });
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
async function applyAgentStatus(agentId: string, status: AgentStatusValue, guard: AgentSessionGuard | undefined, before: AgentCard | null): Promise<boolean> {
|
|
266
|
-
// #1895 (S3.2 L10, review finding 3) — routed through the async gateway facade.
|
|
267
|
-
if (!(await setStatusAsync(agentId, status, guard))) return false;
|
|
268
|
-
await auditAgentStateTransition(agentId, before, getAgent(agentId));
|
|
269
|
-
await emitAgentStatus(agentId);
|
|
270
|
-
return true;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
async function applyAgentReady(agentId: string, ready: boolean, guard: AgentSessionGuard | undefined, before: AgentCard | null): Promise<boolean> {
|
|
274
|
-
// #1895 (S3.2 L10, review finding 3) — routed through the async gateway facade.
|
|
275
|
-
if (!(await markReadyAsync(agentId, ready, guard))) return false;
|
|
276
|
-
await auditAgentStateTransition(agentId, before, getAgent(agentId));
|
|
277
|
-
// #308 — a spawned child flipping false→true ready is "genuinely ready" (past onboarding):
|
|
278
|
-
// wake its parent so it can stop block-polling and stamp the durable readiness. #2432 —
|
|
279
|
-
// announceSpawnedAgentReady is the shared seam; it no-ops for non-spawned agents and dedups
|
|
280
|
-
// repeat readies (e.g. a later bus status frame or PATCH for an already-announced child).
|
|
281
|
-
// #1927 review round 2 (HIGH 1) — the audit above now awaits the async gateway, widening the
|
|
282
|
-
// window for a concurrent same-instance PATCH to flip ready back to false before we get here.
|
|
283
|
-
// Re-read the LIVE card (and re-check the session guard) right before firing these effects
|
|
284
|
-
// instead of trusting the pre-audit snapshot, so a superseded transition never fires a false
|
|
285
|
-
// durable agent.ready.
|
|
286
|
-
if (ready && !before?.ready) {
|
|
287
|
-
const live = getAgent(agentId);
|
|
288
|
-
const stillCurrentInstance = validateAgentSession(agentId, guard).ok;
|
|
289
|
-
if (live?.ready === true && stillCurrentInstance) {
|
|
290
|
-
announceSpawnedAgentReady(agentId, "agent-ready");
|
|
291
|
-
acquireTeamOnReady(agentId); // #3107 — before the flush, so seat mail reaches a new holder
|
|
292
|
-
// #416 — also flush queued direct messages: a not-ready agent that becomes ready
|
|
293
|
-
// may have queued messages waiting (e.g. starting up, clearing context).
|
|
294
|
-
flushQueuedDirectMessages(agentId);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
await emitAgentStatus(agentId);
|
|
298
|
-
return true;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
220
|
export const patchAgentStatus: Handler = async (req, params) => {
|
|
302
221
|
const parsed = await parseBody<{ status: string }>(req);
|
|
303
222
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -309,7 +228,7 @@ export const patchAgentStatus: Handler = async (req, params) => {
|
|
|
309
228
|
const session = validateAgentSession(params.id!, guard);
|
|
310
229
|
if (!session.ok) return error(session.error!, agentSessionStatus(session.error));
|
|
311
230
|
const before = getAgent(params.id!);
|
|
312
|
-
if (before?.status === status) noteUnchangedLifecycle(params.id!, before, guard);
|
|
231
|
+
if (before?.status === status) await noteUnchangedLifecycle(params.id!, before, guard);
|
|
313
232
|
else if (!(await applyAgentStatus(params.id!, status, guard, before))) return error("agent not found", 404);
|
|
314
233
|
} catch (e) {
|
|
315
234
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
@@ -322,40 +241,19 @@ export const postHeartbeat: Handler = async (req, params) => {
|
|
|
322
241
|
const parsed = await parseBody<unknown>(req);
|
|
323
242
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
324
243
|
try {
|
|
325
|
-
// #3606 — the runner's liveness tick reports status and readiness on this one call
|
|
326
|
-
//
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const ready = body.ready as boolean | undefined;
|
|
332
|
-
const guard = normalizeAgentSessionGuard(req, parsed.body);
|
|
333
|
-
const session = validateAgentSession(params.id!, guard);
|
|
334
|
-
if (!session.ok) return error(session.error!, agentSessionStatus(session.error));
|
|
335
|
-
// #416 — capture unavailability before heartbeat to detect the transition.
|
|
336
|
-
const beforeHeartbeat = getAgent(params.id!);
|
|
337
|
-
if (beforeHeartbeat?.kind === "channel" && !beforeHeartbeat.ready) {
|
|
338
|
-
return error("channel agent not ready; re-register required", 409);
|
|
339
|
-
}
|
|
340
|
-
const wasUnavailable = beforeHeartbeat ? isAgentUnavailable(beforeHeartbeat) : false;
|
|
341
|
-
let current = beforeHeartbeat;
|
|
342
|
-
if (status !== undefined && status !== current?.status) {
|
|
343
|
-
if (!(await applyAgentStatus(params.id!, status, guard, current))) return error("agent not found", 404);
|
|
344
|
-
current = getAgent(params.id!);
|
|
345
|
-
}
|
|
346
|
-
if (ready !== undefined && ready !== current?.ready) {
|
|
347
|
-
if (!(await applyAgentReady(params.id!, ready, guard, current))) return error("agent not found", 404);
|
|
348
|
-
}
|
|
349
|
-
// A reported terminal status must not be undone by the beat's offline/stale resurrection.
|
|
350
|
-
if (status !== "offline" && status !== "stale") {
|
|
351
|
-
// #1468 — route the API heartbeat through the same coalescing buffer as the bus path.
|
|
352
|
-
if (!recordHeartbeat(params.id!, { guard })) return error("agent not found", 404);
|
|
244
|
+
// #3606 — the runner's liveness tick reports status and readiness on this one call; the bus
|
|
245
|
+
// `agent.heartbeat` frame (#3618) is the same exchange through the same service.
|
|
246
|
+
const report = cleanHeartbeatReport(params.id!, parsed.body);
|
|
247
|
+
if (report.unread) {
|
|
248
|
+
const denied = await authorizeRoute(req, { scope: "message:read", resource: { agentId: params.id!, target: params.id! } });
|
|
249
|
+
if (denied) return denied;
|
|
353
250
|
}
|
|
354
|
-
if (
|
|
355
|
-
const
|
|
356
|
-
if (
|
|
251
|
+
if (report.providerQuota) {
|
|
252
|
+
const denied = (await authorizeRoute(req, { scope: "quota:write", resource: { agentId: params.id! } })) ?? await authorizeProviderQuotaWrite(req, report.providerQuota);
|
|
253
|
+
if (denied) return denied;
|
|
357
254
|
}
|
|
358
|
-
|
|
255
|
+
const outcome = await applyAgentHeartbeat(params.id!, report, normalizeAgentSessionGuard(req, parsed.body), messageViewerForRequest(req));
|
|
256
|
+
return outcome.ok ? json(outcome.result) : error(outcome.error, outcome.status);
|
|
359
257
|
} catch (e) {
|
|
360
258
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
361
259
|
throw e;
|
|
@@ -429,7 +327,7 @@ export const patchAgentReady: Handler = async (req, params) => {
|
|
|
429
327
|
const session = validateAgentSession(params.id!, guard);
|
|
430
328
|
if (!session.ok) return error(session.error!, agentSessionStatus(session.error));
|
|
431
329
|
const before = getAgent(params.id!);
|
|
432
|
-
if (before?.ready === body.ready) noteUnchangedLifecycle(params.id!, before, guard);
|
|
330
|
+
if (before?.ready === body.ready) await noteUnchangedLifecycle(params.id!, before, guard);
|
|
433
331
|
else if (!(await applyAgentReady(params.id!, body.ready, guard, before))) return error("agent not found", 404);
|
|
434
332
|
} catch (e) {
|
|
435
333
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
@@ -439,7 +337,7 @@ export const patchAgentReady: Handler = async (req, params) => {
|
|
|
439
337
|
};
|
|
440
338
|
|
|
441
339
|
export const deleteAgentById: Handler = async (_req, params) => {
|
|
442
|
-
markAgentWorkFinal(params.id!, "edge-fallback");
|
|
340
|
+
(await markAgentWorkFinal(params.id!, "edge-fallback"));
|
|
443
341
|
// #1895 (S3.2 L10, review finding 3) — routed through the async gateway facade.
|
|
444
342
|
const result = await deleteAgentAsync(params.id!);
|
|
445
343
|
if (!result.ok) {
|
package/src/routes/auth.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { authorityDenied, recordUserManagement } from "../authority-audit";
|
|
|
6
6
|
import { isRecord, type User } from "@humwick/sdk";
|
|
7
7
|
import { error, json, parseBody, type Handler } from "./_shared";
|
|
8
8
|
import { getAuthProvider, listAuthProviders, mintUserSession, type MintedSession } from "../auth";
|
|
9
|
-
import { getAuthIdentity, getUser } from "../db";
|
|
9
|
+
import { getAuthIdentity, getUser, InviteUnavailableError, ValidationError } from "../db";
|
|
10
10
|
import { revokeTokenAsync } from "../token-db-write.ts";
|
|
11
11
|
import { refreshUserSession } from "../auth/session-refresh";
|
|
12
12
|
import { revokeUserSession } from "../auth/session";
|
|
@@ -14,7 +14,6 @@ import { readSessionCookie, sessionOriginAllowed, withSessionCookie } from "../a
|
|
|
14
14
|
import { getComponentAuth } from "../security";
|
|
15
15
|
import { acceptInvite, userInvitesEnabled } from "../services/user-onboarding";
|
|
16
16
|
import { invitesDisabled } from "./users";
|
|
17
|
-
import { InviteUnavailableError, ValidationError } from "../db";
|
|
18
17
|
|
|
19
18
|
/** Public projection of a user for login/refresh responses — never leaks internal-only columns. */
|
|
20
19
|
function userView(user: User): Record<string, unknown> {
|
|
@@ -60,7 +59,7 @@ export const getAuthProvidersRoute: Handler = () =>
|
|
|
60
59
|
* session. Every failure returns the same generic 401 (no provider/user/credential enumeration).
|
|
61
60
|
*/
|
|
62
61
|
export const postAuthLoginRoute: Handler = async (req) => {
|
|
63
|
-
if (!sessionOriginAllowed(req, false)) return authorityDenied(req, "origin not allowed", 403);
|
|
62
|
+
if (!sessionOriginAllowed(req, false)) return (await authorityDenied(req, "origin not allowed", 403));
|
|
64
63
|
const parsed = await parseBody<unknown>(req);
|
|
65
64
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
66
65
|
if (!isRecord(parsed.body)) return error("login body required", 400);
|
|
@@ -68,33 +67,33 @@ export const postAuthLoginRoute: Handler = async (req) => {
|
|
|
68
67
|
if (typeof providerId !== "string" || !providerId) return error("provider required", 400);
|
|
69
68
|
|
|
70
69
|
const provider = getAuthProvider(providerId);
|
|
71
|
-
if (!provider) return authorityDenied(req, "invalid credentials", 401);
|
|
70
|
+
if (!provider) return (await authorityDenied(req, "invalid credentials", 401));
|
|
72
71
|
|
|
73
72
|
const result = await provider.verify(parsed.body);
|
|
74
|
-
if (!result) return authorityDenied(req, "invalid credentials", 401);
|
|
73
|
+
if (!result) return (await authorityDenied(req, "invalid credentials", 401));
|
|
75
74
|
|
|
76
75
|
const identity = getAuthIdentity(provider.id, result.providerSubject);
|
|
77
|
-
if (!identity) return authorityDenied(req, "invalid credentials", 401);
|
|
76
|
+
if (!identity) return (await authorityDenied(req, "invalid credentials", 401));
|
|
78
77
|
|
|
79
78
|
const user = getUser(identity.userId);
|
|
80
|
-
if (!user || user.status !== "active") return authorityDenied(req, "invalid credentials", 401);
|
|
79
|
+
if (!user || user.status !== "active") return (await authorityDenied(req, "invalid credentials", 401));
|
|
81
80
|
|
|
82
|
-
return sessionResponse(req, user, mintUserSession(user));
|
|
81
|
+
return sessionResponse(req, user, (await mintUserSession(user)));
|
|
83
82
|
};
|
|
84
83
|
|
|
85
84
|
/** POST /api/auth/refresh — cookie only, same-origin, with a short concurrent-request grace. */
|
|
86
85
|
export const postAuthRefreshRoute: Handler = async (req) => {
|
|
87
|
-
if (!sessionOriginAllowed(req)) return authorityDenied(req, "origin not allowed", 403);
|
|
86
|
+
if (!sessionOriginAllowed(req)) return (await authorityDenied(req, "origin not allowed", 403));
|
|
88
87
|
const refreshToken = readSessionCookie(req);
|
|
89
88
|
const result = refreshToken ? await refreshUserSession(refreshToken) : null;
|
|
90
89
|
// A stale response must never delete the cookie just rotated by another tab (#3567).
|
|
91
|
-
if (!result) return authorityDenied(req, "invalid refresh token", 401);
|
|
90
|
+
if (!result) return (await authorityDenied(req, "invalid refresh token", 401));
|
|
92
91
|
return sessionResponse(req, result.user, result.session);
|
|
93
92
|
};
|
|
94
93
|
|
|
95
94
|
/** POST /api/auth/logout — bearer authenticates the session; the refresh-only cookie is cleared. */
|
|
96
95
|
export const postAuthLogoutRoute: Handler = async (req) => {
|
|
97
|
-
if (!sessionOriginAllowed(req, false)) return authorityDenied(req, "origin not allowed", 403);
|
|
96
|
+
if (!sessionOriginAllowed(req, false)) return (await authorityDenied(req, "origin not allowed", 403));
|
|
98
97
|
const component = getComponentAuth(req);
|
|
99
98
|
if (component?.jti && !(await revokeUserSession(component))) await revokeTokenAsync(component.jti, "admin");
|
|
100
99
|
return withSessionCookie(req, new Response(null, { status: 204 }));
|
|
@@ -105,7 +104,7 @@ export const postAuthLogoutRoute: Handler = async (req) => {
|
|
|
105
104
|
* the single-use code is the credential. Creates the user and returns their first session.
|
|
106
105
|
*/
|
|
107
106
|
export const postAcceptInviteRoute: Handler = async (req) => {
|
|
108
|
-
if (!sessionOriginAllowed(req, false)) return authorityDenied(req, "origin not allowed", 403);
|
|
107
|
+
if (!sessionOriginAllowed(req, false)) return (await authorityDenied(req, "origin not allowed", 403));
|
|
109
108
|
if (!userInvitesEnabled()) return invitesDisabled();
|
|
110
109
|
const parsed = await parseBody<unknown>(req);
|
|
111
110
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -113,10 +112,10 @@ export const postAcceptInviteRoute: Handler = async (req) => {
|
|
|
113
112
|
const body = parsed.body;
|
|
114
113
|
try {
|
|
115
114
|
const user = await acceptInvite({ code: body.code, handle: body.handle, password: body.password, displayName: typeof body.displayName === "string" ? body.displayName.trim().slice(0, 120) || undefined : undefined });
|
|
116
|
-
recordUserManagement(req, user.id, "accept invite", { role: user.role }, user.id);
|
|
117
|
-
return sessionResponse(req, user, mintUserSession(user), 201);
|
|
115
|
+
(await recordUserManagement(req, user.id, "accept invite", { role: user.role }, user.id));
|
|
116
|
+
return sessionResponse(req, user, (await mintUserSession(user)), 201);
|
|
118
117
|
} catch (e) {
|
|
119
|
-
if (e instanceof InviteUnavailableError) return authorityDenied(req, e.message, 410);
|
|
118
|
+
if (e instanceof InviteUnavailableError) return (await authorityDenied(req, e.message, 410));
|
|
120
119
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
121
120
|
throw e;
|
|
122
121
|
}
|
|
@@ -5,9 +5,9 @@ import { isAdminRequest } from "./users";
|
|
|
5
5
|
|
|
6
6
|
/** GET /api/users/authority-denials — private, bounded admin audit list. */
|
|
7
7
|
export const getAuthorityDenials: Handler = async (req) => {
|
|
8
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
8
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
9
9
|
if (denied) return denied;
|
|
10
|
-
if (!isAdminRequest(req)) return authorityDenied(req, "only admins can read authority denials");
|
|
10
|
+
if (!isAdminRequest(req)) return (await authorityDenied(req, "only admins can read authority denials"));
|
|
11
11
|
const limit = parseQueryInt(new URL(req.url).searchParams.get("limit"), { min: 1, max: 500 });
|
|
12
12
|
if (Number.isNaN(limit)) return error("limit must be an integer between 1 and 500");
|
|
13
13
|
return json(await listActivityEventsAsync({ title: AUTHORITY_DENIED, limit: limit ?? 100 }));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Auto-split from routes.ts (#299). Domain: automations.
|
|
2
2
|
import { ValidationError } from "../db";
|
|
3
|
-
import {
|
|
3
|
+
import { listAutomationRunsAsync } from "../automations/read-async";
|
|
4
|
+
import { createAutomationAsync, deleteAutomationAsync, getAutomation, listAutomations, runAutomationNowAsync, updateAutomationAsync, type AutomationDispatchResult } from "../automations";
|
|
4
5
|
import { emitCommand, error, json, parseBody, parseQueryInt, type Handler } from "./_shared";
|
|
5
6
|
import { emitNewMessage, emitTaskChanged } from "../sse";
|
|
6
7
|
import { emitRelayEvent } from "../events";
|
|
@@ -53,8 +54,8 @@ export const patchAutomation: Handler = async (req, params) => {
|
|
|
53
54
|
}
|
|
54
55
|
};
|
|
55
56
|
|
|
56
|
-
export const deleteAutomationById: Handler = (_req, params) => {
|
|
57
|
-
if (!
|
|
57
|
+
export const deleteAutomationById: Handler = async (_req, params) => {
|
|
58
|
+
if (!(await deleteAutomationAsync(params.id!))) return error("automation not found", 404);
|
|
58
59
|
emitRelayEvent({ type: "automation.deleted", source: "server", subject: params.id!, data: { automationId: params.id! } });
|
|
59
60
|
return json({ ok: true });
|
|
60
61
|
};
|
|
@@ -71,11 +72,11 @@ export const postAutomationRun: Handler = async (_req, params) => {
|
|
|
71
72
|
}
|
|
72
73
|
};
|
|
73
74
|
|
|
74
|
-
export const getAutomationRuns: Handler = (req) => {
|
|
75
|
+
export const getAutomationRuns: Handler = async (req) => {
|
|
75
76
|
const url = new URL(req.url);
|
|
76
77
|
const limitRaw = parseQueryInt(url.searchParams.get("limit"), { min: 1, max: 500 });
|
|
77
78
|
if (Number.isNaN(limitRaw)) return error("limit must be an integer between 1 and 500");
|
|
78
|
-
return json(
|
|
79
|
+
return json(await listAutomationRunsAsync({
|
|
79
80
|
automationId: url.searchParams.get("automationId") ?? undefined,
|
|
80
81
|
status: url.searchParams.get("status") ?? undefined,
|
|
81
82
|
limit: limitRaw ?? 100,
|
|
@@ -5,7 +5,7 @@ import { ValidationError } from "../db/connection";
|
|
|
5
5
|
import { authorizeRoute, error, json, normalizeAgentSessionGuard, parseBody, type Handler } from "./_shared";
|
|
6
6
|
|
|
7
7
|
export const deleteChannelBinding: Handler = async (req, params) => {
|
|
8
|
-
const denied = authorizeRoute(req, { scope: "channel:write" });
|
|
8
|
+
const denied = (await authorizeRoute(req, { scope: "channel:write" }));
|
|
9
9
|
if (denied) return denied;
|
|
10
10
|
const parsed = await parseBody<unknown>(req);
|
|
11
11
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -3,12 +3,12 @@ import { authContextFromRequest } from "../services/auth-context";
|
|
|
3
3
|
import { ValidationError } from "../db/connection";
|
|
4
4
|
import { authorizeRoute, error, json, parseBody, type Handler } from "./_shared";
|
|
5
5
|
|
|
6
|
-
export const getChannelOutput: Handler = (req, params) => {
|
|
7
|
-
const denied = authorizeRoute(req, { scope: "channel:read", resource: { channel: params.id } });
|
|
6
|
+
export const getChannelOutput: Handler = async (req, params) => {
|
|
7
|
+
const denied = (await authorizeRoute(req, { scope: "channel:read", resource: { channel: params.id } }));
|
|
8
8
|
return denied ?? json(channelOutputControl(params.id!));
|
|
9
9
|
};
|
|
10
10
|
export const postChannelOutput: Handler = async (req, params) => {
|
|
11
|
-
const denied = authorizeRoute(req, { scope: "channel:egress", resource: { channel: params.id } });
|
|
11
|
+
const denied = (await authorizeRoute(req, { scope: "channel:egress", resource: { channel: params.id } }));
|
|
12
12
|
if (denied) return denied;
|
|
13
13
|
const parsed = await parseBody<unknown>(req);
|
|
14
14
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -5,7 +5,7 @@ import { authorizeRoute, error, json, parseBody, type Handler } from "./_shared"
|
|
|
5
5
|
import { apiBudgetId, isRecord } from "@humwick/sdk";
|
|
6
6
|
|
|
7
7
|
export const apiBudgetStatusRoute: Handler = async (req, params) => {
|
|
8
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
8
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
9
9
|
if (denied) return denied;
|
|
10
10
|
try { return json(await apiBudgetStatusAsync(apiBudgetId(params.budgetId))); }
|
|
11
11
|
catch { return error("Unknown API budget", 404); }
|
|
@@ -16,7 +16,7 @@ export const apiBudgetStatusRoute: Handler = async (req, params) => {
|
|
|
16
16
|
* it returns the status snapshot only and exposes no mutation.
|
|
17
17
|
*/
|
|
18
18
|
export const apiBudgetSummaryRoute: Handler = async (req, params) => {
|
|
19
|
-
const denied = authorizeRoute(req, { scope: "agent:read" });
|
|
19
|
+
const denied = (await authorizeRoute(req, { scope: "agent:read" }));
|
|
20
20
|
if (denied) return denied;
|
|
21
21
|
try {
|
|
22
22
|
const summary: ApiBudgetSummary = await apiBudgetStatusAsync(apiBudgetId(params.budgetId));
|
|
@@ -24,7 +24,7 @@ export const apiBudgetSummaryRoute: Handler = async (req, params) => {
|
|
|
24
24
|
} catch { return error("Unknown API budget", 404); }
|
|
25
25
|
};
|
|
26
26
|
export const apiBudgetConfigureRoute: Handler = async (req, params) => {
|
|
27
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
27
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
28
28
|
if (denied) return denied;
|
|
29
29
|
const body = await parseBody<unknown>(req);
|
|
30
30
|
if (!body.ok) return error(body.error, body.status);
|
|
@@ -37,7 +37,7 @@ export const apiBudgetConfigureRoute: Handler = async (req, params) => {
|
|
|
37
37
|
export const apiBudgetSessionRoute: Handler = async (req, params) => {
|
|
38
38
|
if (params.action !== "reserve" && params.action !== "report") return error("Unknown budget operation", 404);
|
|
39
39
|
const agentId = params.id!;
|
|
40
|
-
const denied = authorizeRoute(req, { scope: "agent:write", resource: { agentId } });
|
|
40
|
+
const denied = (await authorizeRoute(req, { scope: "agent:write", resource: { agentId } }));
|
|
41
41
|
if (denied) return denied;
|
|
42
42
|
const body = await parseBody<unknown>(req);
|
|
43
43
|
if (!body.ok) return error(body.error, body.status);
|
|
@@ -55,7 +55,7 @@ export const apiBudgetSessionRoute: Handler = async (req, params) => {
|
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
export const apiBudgetAgentRoute: Handler = async (req, params) => {
|
|
58
|
-
const denied = authorizeRoute(req, { scope: "agent:read", resource: { agentId: params.id! } });
|
|
58
|
+
const denied = (await authorizeRoute(req, { scope: "agent:read", resource: { agentId: params.id! } }));
|
|
59
59
|
if (denied) return denied;
|
|
60
60
|
try {
|
|
61
61
|
const budgetId = apiBudgetId(new URL(req.url).searchParams.get("budgetId") ?? "openai-api");
|
|
@@ -32,13 +32,17 @@ export const getCommands: Handler = async (req) => {
|
|
|
32
32
|
limit: limitRaw ?? undefined,
|
|
33
33
|
dispatchableOnly,
|
|
34
34
|
oldestFirst: dispatchableOnly && status === "pending",
|
|
35
|
+
// #3391 — a listing omits each spawn's inline agentProfile (13.9 MB per 30 rows blocked the hub
|
|
36
|
+
// loop); `GET /api/commands/:id` returns the full row. The executor dispatch feed runs the rows it
|
|
37
|
+
// polls, so it keeps the profile.
|
|
38
|
+
slim: !dispatchableOnly,
|
|
35
39
|
});
|
|
36
40
|
return json(commands.map((command) => serializeCommandForRead(command, ctx)));
|
|
37
41
|
};
|
|
38
42
|
|
|
39
43
|
// The host only needs existence, not historical command params/results (#3063).
|
|
40
44
|
export const getActiveCleanup: Handler = async (req) => {
|
|
41
|
-
const denied = authorizeRoute(req, { scope: "command:read" });
|
|
45
|
+
const denied = (await authorizeRoute(req, { scope: "command:read" }));
|
|
42
46
|
if (denied) return denied;
|
|
43
47
|
try {
|
|
44
48
|
const target = cleanString(new URL(req.url).searchParams.get("target"), "target", { required: true, max: 240 });
|
package/src/routes/commands.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { fencePublishForPushAsync, setReviewRefFenceTokenAsync } from "../db/runtime-tail-async";
|
|
2
|
+
import { updateCommandAsync, claimPendingCommandAsync } from "../commands-write";
|
|
3
|
+
import { setOrchestratorUpgradeStateAsync } from "../db/orchestrators-async";
|
|
4
|
+
import { deleteWorkspaceAsync } from "../db/lifecycle-tail-async";
|
|
1
5
|
import { VaultError } from "../secrets-vault/keys";
|
|
2
6
|
import { settleProjectRepoCreation } from "../services/project-repo-create";
|
|
3
7
|
import { settleAgentExitCleanupAsync } from "../agent-exit-cleanup-async";
|
|
4
8
|
// Auto-split from routes.ts (#299). Domain: commands.
|
|
5
9
|
import { randomUUID } from "node:crypto";
|
|
6
10
|
import { VALID_AGENT_ACTIONS, agentControlActionIcon, auditEvent, authorizeRoute, emitCommand, error, json, parseBody, type AgentControlAction, type Handler } from "./_shared";
|
|
7
|
-
import { getReviewRefFenceToken,
|
|
11
|
+
import { getReviewRefFenceToken, ValidationError, getOrchestrator, getWorkspace, listOrchestrators, patchWorkspaceMetadataAsync, updateWorkspaceStatus } from "../db";
|
|
8
12
|
import { cleanCommandReport, cleanParams, cleanString, optionalEnum } from "../validation";
|
|
9
|
-
import { ValidationError, deleteWorkspace, getOrchestrator, getWorkspace, listOrchestrators, patchWorkspaceMetadataAsync, setOrchestratorUpgradeState, updateWorkspaceStatus } from "../db";
|
|
10
13
|
import { applyCommandToRecipe } from "../recipe-runner";
|
|
11
|
-
import {
|
|
12
|
-
import { claimPendingCommandAsync, updateCommandAsync } from "../commands-write";
|
|
14
|
+
import { getCommand, listAcceptedCommandsByOwner } from "../commands-db";
|
|
13
15
|
import {
|
|
14
16
|
acceptLandingProgressAsync,
|
|
15
17
|
acquireKernelPublishFenceAsync,
|
|
@@ -29,7 +31,7 @@ import { KERNEL_CORRELATION_PREFIX, isReservedKernelCorrelationId } from "../ser
|
|
|
29
31
|
import { prepareScheduledCommandResultForStorage, settleScheduledCommandTimer } from "../services/scheduler-command";
|
|
30
32
|
import { ServiceAuthError } from "../services/errors";
|
|
31
33
|
import { applyIdleRefreshResult } from "../maintenance/workspaces";
|
|
32
|
-
import {
|
|
34
|
+
import { seedMigratedProviderConfigsAsync } from "../provider-config-store";
|
|
33
35
|
import { notifyAgentSpawnFailed } from "../agent-lifecycle-events";
|
|
34
36
|
import { scheduleRepoMerge } from "../workspace-auto-merge";
|
|
35
37
|
import { settleMemoryInjectionAfterContextCommand } from "../memory-injection";
|
|
@@ -103,7 +105,7 @@ async function settleFailedOrchestratorUpgrade(command: Command): Promise<void>
|
|
|
103
105
|
const up = orch?.upgrade;
|
|
104
106
|
if (!orch || !up || up.status !== "pending" || up.commandId !== command.id) return;
|
|
105
107
|
const errMsg = command.error ?? "orchestrator upgrade failed";
|
|
106
|
-
|
|
108
|
+
(await setOrchestratorUpgradeStateAsync(orch.id, { ...up, status: "failed", settledAt: Date.now(), error: errMsg }));
|
|
107
109
|
await auditEvent({
|
|
108
110
|
clientId: `server-orchestrator-upgrade-command-failed-${orch.id}-${command.id}`,
|
|
109
111
|
kind: "state",
|
|
@@ -170,7 +172,7 @@ export const getCommandById: Handler = async (req, params) => {
|
|
|
170
172
|
// token it minted before claiming; this returns only rows that token accepted and that have not begun
|
|
171
173
|
// running. It is intentionally separate from the normal pending poll, where accepted rows are hidden.
|
|
172
174
|
export const postOwnedAcceptedCommands: Handler = async (req) => {
|
|
173
|
-
const denied = authorizeRoute(req, { scope: "command:write" });
|
|
175
|
+
const denied = (await authorizeRoute(req, { scope: "command:write" }));
|
|
174
176
|
if (denied) return denied;
|
|
175
177
|
const parsed = await parseBody<unknown>(req);
|
|
176
178
|
if (!parsed.ok || !isRecord(parsed.body)) return error("command body must be an object", 400);
|
|
@@ -188,7 +190,7 @@ export const postOwnedAcceptedCommands: Handler = async (req) => {
|
|
|
188
190
|
export const claimCommandById: Handler = async (req, params) => {
|
|
189
191
|
const current = getCommand(params.id!);
|
|
190
192
|
if (!current) return error("command not found", 404);
|
|
191
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) });
|
|
193
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) }));
|
|
192
194
|
if (denied) return denied;
|
|
193
195
|
const parsed = await parseBody<unknown>(req);
|
|
194
196
|
const expectedType = parsed.ok && isRecord(parsed.body) ? cleanString(parsed.body.type, "type", { max: 100 }) : undefined;
|
|
@@ -223,12 +225,12 @@ export const claimCommandById: Handler = async (req, params) => {
|
|
|
223
225
|
// persist it in the durable ledger. It is the ONLY credential that authorizes this command's terminal
|
|
224
226
|
// settlement (POST /commands/:id/settle-review-publish), so no other command:write holder — including an
|
|
225
227
|
// admin/`*` token — can spoof succeeded/failed/canceled on the claimed publish (generic PATCH + WS bus
|
|
226
|
-
// are refused at the
|
|
228
|
+
// are refused at the updateCommandAsync choke point). Returned to the executor only; never serialized to reads.
|
|
227
229
|
let reviewFenceToken: string | undefined;
|
|
228
230
|
if (claimed && claimed.type === "workspace.publish-review") {
|
|
229
231
|
const storedFenceToken = getReviewRefFenceToken(claimed.id);
|
|
230
232
|
reviewFenceToken = storedFenceToken ?? randomUUID();
|
|
231
|
-
if (!storedFenceToken)
|
|
233
|
+
if (!storedFenceToken) (await setReviewRefFenceTokenAsync(claimed.id, reviewFenceToken));
|
|
232
234
|
}
|
|
233
235
|
// #2663 — a land that lost its CAS because an OLDER land on the same target's lane is still
|
|
234
236
|
// pending is QUEUED, not out-raced, so name the head. Only a genuine CAS loss opens that: every
|
|
@@ -253,14 +255,14 @@ export const claimCommandById: Handler = async (req, params) => {
|
|
|
253
255
|
};
|
|
254
256
|
|
|
255
257
|
// #1452 round-13 HIGH#2 — token-gated settlement endpoint: the ONLY external path that may terminalize a
|
|
256
|
-
// CLAIMED review publish (generic PATCH + WS bus are refused at the
|
|
258
|
+
// CLAIMED review publish (generic PATCH + WS bus are refused at the updateCommandAsync choke point). The caller
|
|
257
259
|
// must present the exact fence token minted at claim; a missing/mismatched token fails closed (409). Only
|
|
258
|
-
// then does
|
|
260
|
+
// then does updateCommandAsync run with executor authority. Confines settlement to the actual executor.
|
|
259
261
|
export const settleReviewPublishCommandById: Handler = async (req, params) => {
|
|
260
262
|
const current = getCommand(params.id!);
|
|
261
263
|
if (!current) return error("command not found", 404);
|
|
262
264
|
if (current.type !== "workspace.publish-review") return error("not a review publish command", 400);
|
|
263
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) });
|
|
265
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) }));
|
|
264
266
|
if (denied) return denied;
|
|
265
267
|
const parsed = await parseBody<unknown>(req);
|
|
266
268
|
if (!parsed.ok || !isRecord(parsed.body)) return error("command body must be an object", 400);
|
|
@@ -271,7 +273,7 @@ export const settleReviewPublishCommandById: Handler = async (req, params) => {
|
|
|
271
273
|
if (!status) return error("status must be succeeded or failed", 400);
|
|
272
274
|
const result = cleanParams(parsed.body.result, "result");
|
|
273
275
|
const err = cleanString(parsed.body.error, "error", { max: 4000 });
|
|
274
|
-
const command =
|
|
276
|
+
const command = (await updateCommandAsync(params.id!, { status: status as CommandStatus, result, error: err }, { executor: true }));
|
|
275
277
|
if (!command) return error("command not found", 404);
|
|
276
278
|
emitCommand(command);
|
|
277
279
|
return json(serializeCommandForRead(command, authContextFromRequest(req)));
|
|
@@ -285,7 +287,7 @@ export const settleReviewPublishCommandById: Handler = async (req, params) => {
|
|
|
285
287
|
export const fencePublishCommandById: Handler = async (req, params) => {
|
|
286
288
|
const current = getCommand(params.id!);
|
|
287
289
|
if (!current) return error("command not found", 404);
|
|
288
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) });
|
|
290
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) }));
|
|
289
291
|
if (denied) return denied;
|
|
290
292
|
const parsed = await parseBody<unknown>(req);
|
|
291
293
|
const body = parsed.ok && isRecord(parsed.body) ? parsed.body : {};
|
|
@@ -335,7 +337,7 @@ export const fencePublishCommandById: Handler = async (req, params) => {
|
|
|
335
337
|
...(fenced.reason ? { reason: fenced.reason } : {}) });
|
|
336
338
|
}
|
|
337
339
|
if (current.type === "workspace.merge" && current.landingContainmentMode === "legacy-unfenced-v0") {
|
|
338
|
-
const fenced =
|
|
340
|
+
const fenced = (await fencePublishForPushAsync(params.id!, expectedType));
|
|
339
341
|
return json({ fenced: Boolean(fenced),
|
|
340
342
|
...(fenced ? { command: serializeCommandForRead(fenced, authContextFromRequest(req)) } : {}) });
|
|
341
343
|
}
|
|
@@ -386,7 +388,7 @@ export const fencePublishCommandById: Handler = async (req, params) => {
|
|
|
386
388
|
});
|
|
387
389
|
return json({ fenced: permit.permitted, ...(permit.permitId ? { permitId: permit.permitId } : {}), ...(permit.reason ? { reason: permit.reason } : {}) });
|
|
388
390
|
}
|
|
389
|
-
const fenced =
|
|
391
|
+
const fenced = (await fencePublishForPushAsync(params.id!, expectedType));
|
|
390
392
|
return json({
|
|
391
393
|
fenced: Boolean(fenced),
|
|
392
394
|
...(fenced ? { command: serializeCommandForRead(fenced, authContextFromRequest(req)) } : {}),
|
|
@@ -400,7 +402,7 @@ export const patchCommand: Handler = async (req, params) => {
|
|
|
400
402
|
try {
|
|
401
403
|
const current = getCommand(params.id!);
|
|
402
404
|
if (!current) return error("command not found", 404);
|
|
403
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) });
|
|
405
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) }));
|
|
404
406
|
if (denied) return denied;
|
|
405
407
|
const status = optionalEnum(parsed.body.status, "status", VALID_COMMAND_STATUSES);
|
|
406
408
|
const fencedLanding = (current.type === "workspace.merge" || isLandingCommandType(current.type))
|
|
@@ -462,23 +464,23 @@ export const patchCommand: Handler = async (req, params) => {
|
|
|
462
464
|
noteCompactionCommandCompleted(command);
|
|
463
465
|
// #2095 — durable "clear committed vs no-op" signal, fired on terminal compact/clear commands.
|
|
464
466
|
noteCompactionResult(command);
|
|
465
|
-
settleSelfResumeContinuationIngestion(command);
|
|
466
|
-
enqueueContinuationInjectionAfterSelfResume(command);
|
|
467
|
-
enqueueLifecycleIdentityInjectionAfterContextCommand(command);
|
|
468
|
-
notifySelfResumeNoOp(command);
|
|
469
|
-
settleContextResetCarry(command);
|
|
470
|
-
settleSelfRestartManagedState(command);
|
|
471
|
-
settleInterruptRedirectMessage(command);
|
|
467
|
+
(await settleSelfResumeContinuationIngestion(command));
|
|
468
|
+
(await enqueueContinuationInjectionAfterSelfResume(command));
|
|
469
|
+
(await enqueueLifecycleIdentityInjectionAfterContextCommand(command));
|
|
470
|
+
await notifySelfResumeNoOp(command);
|
|
471
|
+
(await settleContextResetCarry(command));
|
|
472
|
+
(await settleSelfRestartManagedState(command));
|
|
473
|
+
(await settleInterruptRedirectMessage(command));
|
|
472
474
|
// #1565 P4b — memory rides BESIDE the continuation as its own payload (§7), delta-gated on
|
|
473
475
|
// compact; and a memory inject that SUCCEEDS is what advances that gate. Ordered LAST and
|
|
474
476
|
// contained (#1565 F8): composing a block touches the DB, ownership and cwd resolution, and a
|
|
475
477
|
// throw in any of that must not take the rest of the settle chain down with it. The continuation
|
|
476
478
|
// enqueue stays first, so it is unaffected either way.
|
|
477
|
-
settleMemoryInjectionAfterContextCommand(command);
|
|
479
|
+
(await settleMemoryInjectionAfterContextCommand(command));
|
|
478
480
|
// #1951 — startup context (validation commands, report-up, profile charter, caller context)
|
|
479
481
|
// recomposed from the DB and re-injected beside the others, delta-gated on compact. Contained
|
|
480
482
|
// the same way (a compose throw must not take the rest of the settle chain down with it).
|
|
481
|
-
settleStartupContextInjectionAfterContextCommand(command);
|
|
483
|
+
(await settleStartupContextInjectionAfterContextCommand(command));
|
|
482
484
|
if (command.type === "scheduler.command") {
|
|
483
485
|
await settleScheduledCommandTimer(command);
|
|
484
486
|
}
|
|
@@ -548,7 +550,7 @@ export const patchCommand: Handler = async (req, params) => {
|
|
|
548
550
|
if (command.type === "agent.spawn" && command.status === "failed") {
|
|
549
551
|
const parent = isRecord(command.params) ? cleanString(command.params.spawnedBy, "params.spawnedBy", { max: 240 }) : undefined;
|
|
550
552
|
if (parent) {
|
|
551
|
-
notifyAgentSpawnFailed({
|
|
553
|
+
await notifyAgentSpawnFailed({
|
|
552
554
|
parent,
|
|
553
555
|
spawnRequestId: isRecord(command.params) ? cleanString(command.params.spawnRequestId, "params.spawnRequestId", { max: 160 }) : undefined,
|
|
554
556
|
provider: isRecord(command.params) ? cleanString(command.params.provider, "params.provider", { max: 40 }) : undefined,
|
|
@@ -559,7 +561,7 @@ export const patchCommand: Handler = async (req, params) => {
|
|
|
559
561
|
if (command.type === "orchestrator.migrate-provider-config" && command.status === "succeeded" && isRecord(result)) {
|
|
560
562
|
// Seed central rows from the reported host-local files with server authority (#465); idempotent, a
|
|
561
563
|
// stored row wins. Seeds from the request: the persisted result holds only fingerprints (#3403).
|
|
562
|
-
const migration =
|
|
564
|
+
const migration = await seedMigratedProviderConfigsAsync(result);
|
|
563
565
|
if (migration?.seeded.length) {
|
|
564
566
|
const { host, seeded } = migration;
|
|
565
567
|
await auditEvent({
|
|
@@ -24,9 +24,9 @@ export const postAgentContextResetRoute: Handler = async (req, params) => {
|
|
|
24
24
|
evidence: { instanceId: cleanString(body.instanceId, "instanceId", { max: 200 }) ?? null },
|
|
25
25
|
observedAt,
|
|
26
26
|
};
|
|
27
|
-
const carry = recordContextReset(fact);
|
|
27
|
+
const carry = (await recordContextReset(fact));
|
|
28
28
|
// #3698 — a commanded reset is refreshed by its command's settle; an uncommanded one only here.
|
|
29
|
-
if (!fact.commandId) refreshContextAfterObservedReset(fact);
|
|
29
|
+
if (!fact.commandId) (await refreshContextAfterObservedReset(fact));
|
|
30
30
|
return json({ ok: true, carryMessageId: carry?.id ?? null });
|
|
31
31
|
} catch (e) {
|
|
32
32
|
if (e instanceof ValidationError) return error(e.message, 400);
|