@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
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { updateCommandAsync, createCommandAsync } from "../commands-write";
|
|
2
|
+
import { setOrchestratorUpgradeStateAsync } from "../db/orchestrators-async";
|
|
3
|
+
import { getOrchestrator } from "../db";
|
|
4
|
+
import { getCommand } from "../commands-db";
|
|
3
5
|
import { emitOrchestratorStatus } from "../sse";
|
|
4
6
|
import { emitCommandEvent } from "../command-events";
|
|
5
7
|
import type { ActivityEventInput } from "../types";
|
|
@@ -10,18 +12,18 @@ export const ORCH_UPGRADE_DEADLINE_MS = 5 * 60_000;
|
|
|
10
12
|
// central provider-config rows (#465). The orchestrator reports its files via the
|
|
11
13
|
// command result; the server seeds the rows (see patchCommand). Capability-gated so
|
|
12
14
|
// pre-#465 orchestrators that lack the handler never get a command they'd reject.
|
|
13
|
-
export function dispatchProviderConfigMigration(
|
|
15
|
+
export async function dispatchProviderConfigMigration(
|
|
14
16
|
orch: NonNullable<ReturnType<typeof getOrchestrator>>,
|
|
15
17
|
requestedBy = "system",
|
|
16
|
-
): ReturnType<typeof
|
|
18
|
+
): Promise<ReturnType<typeof createCommandAsync> | null> {
|
|
17
19
|
if (!orch.capabilities?.migrateProviderConfig) return null;
|
|
18
|
-
const command =
|
|
20
|
+
const command = (await createCommandAsync({
|
|
19
21
|
type: "orchestrator.migrate-provider-config",
|
|
20
22
|
source: "system",
|
|
21
23
|
target: orch.agentId,
|
|
22
24
|
ttlMs: 10 * 60_000,
|
|
23
25
|
params: { orchestratorId: orch.id, requestedBy },
|
|
24
|
-
});
|
|
26
|
+
}));
|
|
25
27
|
emitCommandEvent(command, "command.requested");
|
|
26
28
|
return command;
|
|
27
29
|
}
|
|
@@ -42,14 +44,14 @@ export async function reconcileOrchestratorUpgrade(
|
|
|
42
44
|
// before retrying. The running process's gitSha is the artifact identity and must match too.
|
|
43
45
|
if (reachedTarget && up.status === "succeeded" && up.error) {
|
|
44
46
|
const { error: _previousError, ...successState } = up;
|
|
45
|
-
|
|
47
|
+
(await setOrchestratorUpgradeStateAsync(orch.id, successState));
|
|
46
48
|
emitOrchestratorStatus(orch.id);
|
|
47
49
|
return;
|
|
48
50
|
}
|
|
49
51
|
if (reachedTarget && reported && (up.status === "pending" || up.status === "failed")) {
|
|
50
|
-
if (up.commandId)
|
|
52
|
+
if (up.commandId) (await updateCommandAsync(up.commandId, { status: "succeeded", result: { version: reported, ...(up.fromVersion ? { fromVersion: up.fromVersion } : {}) } }));
|
|
51
53
|
const { error: _previousError, ...successState } = up;
|
|
52
|
-
|
|
54
|
+
(await setOrchestratorUpgradeStateAsync(orch.id, { ...successState, status: "succeeded", settledAt: Date.now() }));
|
|
53
55
|
await auditEvent({
|
|
54
56
|
clientId: `server-orchestrator-upgraded-${orch.id}-${Date.now()}`,
|
|
55
57
|
kind: "state",
|
|
@@ -62,12 +64,12 @@ export async function reconcileOrchestratorUpgrade(
|
|
|
62
64
|
});
|
|
63
65
|
// Upgrade settled — the orchestrator is now running new-enough code to handle
|
|
64
66
|
// the provider-config migration, so seed the central rows from its local files (#465).
|
|
65
|
-
dispatchProviderConfigMigration(orch);
|
|
67
|
+
(await dispatchProviderConfigMigration(orch));
|
|
66
68
|
emitOrchestratorStatus(orch.id);
|
|
67
69
|
} else if (up.status === "pending" && Date.now() - up.requestedAt > ORCH_UPGRADE_DEADLINE_MS) {
|
|
68
70
|
const errMsg = `upgrade timed out; orchestrator still reports ${reported ?? "unknown"} (wanted ${up.desiredVersion})`;
|
|
69
|
-
if (up.commandId)
|
|
70
|
-
|
|
71
|
+
if (up.commandId) (await updateCommandAsync(up.commandId, { status: "failed", error: errMsg }));
|
|
72
|
+
(await setOrchestratorUpgradeStateAsync(orch.id, { ...up, status: "failed", settledAt: Date.now(), error: errMsg }));
|
|
71
73
|
await auditEvent({
|
|
72
74
|
clientId: `server-orchestrator-upgrade-failed-${orch.id}-${Date.now()}`,
|
|
73
75
|
kind: "state",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isHumanAgentId } from "@humwick/sdk";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import {
|
|
3
|
+
import { createAgentControlAsync } from "../db/agent-control-async";
|
|
4
4
|
import { emitCommandEvent } from "../command-events";
|
|
5
5
|
import { ValidationError, createActivityEventAsync, getAgent } from "../db";
|
|
6
6
|
import { agentProviderState } from "../provider-state";
|
|
@@ -66,7 +66,7 @@ export async function dispatchAgentPermissionDecision(
|
|
|
66
66
|
): Promise<AgentPermissionDecisionResult> {
|
|
67
67
|
const agent = getAgent(input.agentId);
|
|
68
68
|
if (!agent) throw new PermissionDecisionTargetError(`agent ${input.agentId} not found`);
|
|
69
|
-
authorizeShutdown(ctx, { agentId: agent.id, requestedVia: input.requestedVia });
|
|
69
|
+
(await authorizeShutdown(ctx, { agentId: agent.id, requestedVia: input.requestedVia }));
|
|
70
70
|
assertControlEligible(agent);
|
|
71
71
|
|
|
72
72
|
const pendingApprovalId = currentApprovalId(agent);
|
|
@@ -122,7 +122,8 @@ export async function dispatchAgentPermissionDecision(
|
|
|
122
122
|
// Audit admission precedes the durable command, matching the other service-layer agent controls.
|
|
123
123
|
const event = await createActivityEventAsync(activityInput);
|
|
124
124
|
revalidatePendingApproval(agent, approvalId);
|
|
125
|
-
const command =
|
|
125
|
+
const { command: admitted } = await createAgentControlAsync({ agent, commandInput, commandId, approvalId });
|
|
126
|
+
const command = admitted!;
|
|
126
127
|
emitCommandEvent(command, "command.requested");
|
|
127
128
|
emitActivityEvent(event);
|
|
128
129
|
return { approvalId, decision: input.decision, command };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// #3716 — workflow effects read CI episodes without depending on workflow launch or recovery.
|
|
2
|
+
import { ValidationError } from "../db/connection";
|
|
3
|
+
import { computeCiFailureFingerprint } from "../ci/incidents";
|
|
4
|
+
import type { CiShaObservation } from "../db/ci-incidents";
|
|
5
|
+
import type { StoredPlanCiBlock } from "../db/plan-ci-blocks";
|
|
6
|
+
import { getGateway } from "../db/gateway";
|
|
7
|
+
import { getPlanGraphProjectionAsync } from "../db/plan-graph-async";
|
|
8
|
+
import { planNoticeTarget } from "../db/plan-completion";
|
|
9
|
+
import { notifySystemMessage } from "../notify";
|
|
10
|
+
import type { WorkflowRunRecord } from "@humwick/kernel/workflow.pilot";
|
|
11
|
+
|
|
12
|
+
/** Same watch and landed SHA, or the same failing jobs: an unrelated red main must not quiet this failure. */
|
|
13
|
+
export async function correlatedCiIncidents(rows: Array<{ workflow: string; row?: CiShaObservation }>): Promise<string[]> {
|
|
14
|
+
const ids: string[] = [];
|
|
15
|
+
for (const { workflow, row } of rows) {
|
|
16
|
+
if (!row) return [];
|
|
17
|
+
const incident = await getGateway().read("ciIncidents.activeForWatch", { watchKey: row.watchKey });
|
|
18
|
+
if (!incident) return [];
|
|
19
|
+
if (incident.openedHeadSha !== row.headSha) {
|
|
20
|
+
if (!row.failingJobs?.length) return [];
|
|
21
|
+
const fingerprint = computeCiFailureFingerprint({ workflow, failingRuns: [{ id: "sha", status: "completed", jobs: row.failingJobs.map((job) => ({ id: job.name, name: job.name })) }], conclusion: "failure" });
|
|
22
|
+
if (fingerprint !== incident.fingerprint) return [];
|
|
23
|
+
}
|
|
24
|
+
ids.push(incident.id);
|
|
25
|
+
}
|
|
26
|
+
return [...new Set(ids)].sort();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Return a quiet receipt only after both the blocked attempt and the actionable plan notice are durable. */
|
|
30
|
+
export async function planCiNotice(run: WorkflowRunRecord, payload: Record<string, unknown>, result = false): Promise<Record<string, unknown> | undefined> {
|
|
31
|
+
const owner = await getGateway().read("planDispatch.owner", { taskId: run.taskId });
|
|
32
|
+
if (!owner || owner.audit) return undefined;
|
|
33
|
+
let block = await getGateway().read("planDispatch.ci.block", { runId: run.id });
|
|
34
|
+
const incidentIds = Array.isArray(payload.incidentIds) ? payload.incidentIds.filter((id): id is string => typeof id === "string") : [];
|
|
35
|
+
if (!result && incidentIds.length && typeof payload.landedSha === "string") {
|
|
36
|
+
try {
|
|
37
|
+
block = await getGateway().write("planDispatch.ci.block", { planId: owner.planId, taskId: run.taskId, runId: run.id, sha: payload.landedSha, incidentIds, waitKey: run.escalation?.waitKey ?? "" }) as unknown as StoredPlanCiBlock;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
// A superseded attempt must still send its normal CI notice (#3660).
|
|
40
|
+
if (error instanceof ValidationError && error.message === "CI blocker no longer owns its plan slot") return undefined;
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (!block || (result && (block.retriedAt !== undefined || block.waitKey !== run.escalation?.waitKey)) || (!result && !incidentIds.length)) return undefined;
|
|
45
|
+
const plan = await getPlanGraphProjectionAsync({ planId: owner.planId });
|
|
46
|
+
const to = plan && planNoticeTarget(plan);
|
|
47
|
+
if (!to) return undefined;
|
|
48
|
+
for (const incidentId of block.incidentIds) {
|
|
49
|
+
await notifySystemMessage(to, {
|
|
50
|
+
subject: `Plan ${plan.title ?? plan.id}: CI blocked`,
|
|
51
|
+
body: `Plan ${plan.id}: T${run.taskId}, run ${run.id}, landed SHA ${block.sha}, is blocked by CI incident ${incidentId}. Fix the incident; Relay automatically retries each blocked run's exact landed SHA after clearance. Slots and dependents wait. relay_plan_get shows every blocked Task and run.`,
|
|
52
|
+
idempotencyKey: `plan:${plan.id}:ci:${incidentId}`, replyExpected: false,
|
|
53
|
+
payload: { kind: "plan.ci-blocked", planId: plan.id, incidentId, taskId: run.taskId, runId: run.id, landedSha: block.sha },
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return { quiet: "plan-ci-episode", planId: owner.planId, incidentIds: block.incidentIds };
|
|
57
|
+
}
|
|
@@ -1,62 +1,9 @@
|
|
|
1
|
-
// #3660 —
|
|
2
|
-
import {
|
|
3
|
-
import { computeCiFailureFingerprint } from "../ci/incidents";
|
|
4
|
-
import type { CiShaObservation } from "../db/ci-incidents";
|
|
1
|
+
// #3660 — clearance reuses the original run's CI resume path.
|
|
2
|
+
import type { WorkflowRunRecord } from "@humwick/kernel/workflow.pilot";
|
|
5
3
|
import type { StoredPlanCiBlock } from "../db/plan-ci-blocks";
|
|
6
4
|
import { getGateway } from "../db/gateway";
|
|
7
|
-
import { getPlanGraphProjectionAsync } from "../db/plan-graph-async";
|
|
8
|
-
import { planNoticeTarget } from "../db/plan-completion";
|
|
9
|
-
import { notifySystemMessage } from "../notify";
|
|
10
|
-
import type { WorkflowRunRecord } from "@humwick/kernel/workflow.pilot";
|
|
11
5
|
import { resumeWorkflowRun } from "./workflow-runs";
|
|
12
6
|
|
|
13
|
-
/** Same watch and landed SHA, or the same failing jobs: an unrelated red main must not quiet this failure. */
|
|
14
|
-
export async function correlatedCiIncidents(rows: Array<{ workflow: string; row?: CiShaObservation }>): Promise<string[]> {
|
|
15
|
-
const ids: string[] = [];
|
|
16
|
-
for (const { workflow, row } of rows) {
|
|
17
|
-
if (!row) return [];
|
|
18
|
-
const incident = await getGateway().read("ciIncidents.activeForWatch", { watchKey: row.watchKey });
|
|
19
|
-
if (!incident) return [];
|
|
20
|
-
if (incident.openedHeadSha !== row.headSha) {
|
|
21
|
-
if (!row.failingJobs?.length) return [];
|
|
22
|
-
const fingerprint = computeCiFailureFingerprint({ workflow, failingRuns: [{ id: "sha", status: "completed", jobs: row.failingJobs.map((job) => ({ id: job.name, name: job.name })) }], conclusion: "failure" });
|
|
23
|
-
if (fingerprint !== incident.fingerprint) return [];
|
|
24
|
-
}
|
|
25
|
-
ids.push(incident.id);
|
|
26
|
-
}
|
|
27
|
-
return [...new Set(ids)].sort();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Return a quiet receipt only after both the blocked attempt and the actionable plan notice are durable. */
|
|
31
|
-
export async function planCiNotice(run: WorkflowRunRecord, payload: Record<string, unknown>, result = false): Promise<Record<string, unknown> | undefined> {
|
|
32
|
-
const owner = await getGateway().read("planDispatch.owner", { taskId: run.taskId });
|
|
33
|
-
if (!owner || owner.audit) return undefined;
|
|
34
|
-
let block = await getGateway().read("planDispatch.ci.block", { runId: run.id });
|
|
35
|
-
const incidentIds = Array.isArray(payload.incidentIds) ? payload.incidentIds.filter((id): id is string => typeof id === "string") : [];
|
|
36
|
-
if (!result && incidentIds.length && typeof payload.landedSha === "string") {
|
|
37
|
-
try {
|
|
38
|
-
block = await getGateway().write("planDispatch.ci.block", { planId: owner.planId, taskId: run.taskId, runId: run.id, sha: payload.landedSha, incidentIds, waitKey: run.escalation?.waitKey ?? "" }) as unknown as StoredPlanCiBlock;
|
|
39
|
-
} catch (error) {
|
|
40
|
-
// A superseded attempt must still send its normal CI notice (#3660).
|
|
41
|
-
if (error instanceof ValidationError && error.message === "CI blocker no longer owns its plan slot") return undefined;
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (!block || (result && (block.retriedAt !== undefined || block.waitKey !== run.escalation?.waitKey)) || (!result && !incidentIds.length)) return undefined;
|
|
46
|
-
const plan = await getPlanGraphProjectionAsync({ planId: owner.planId });
|
|
47
|
-
const to = plan && planNoticeTarget(plan);
|
|
48
|
-
if (!to) return undefined;
|
|
49
|
-
for (const incidentId of block.incidentIds) {
|
|
50
|
-
notifySystemMessage(to, {
|
|
51
|
-
subject: `Plan ${plan.title ?? plan.id}: CI blocked`,
|
|
52
|
-
body: `Plan ${plan.id}: T${run.taskId}, run ${run.id}, landed SHA ${block.sha}, is blocked by CI incident ${incidentId}. Fix the incident; Relay automatically retries each blocked run's exact landed SHA after clearance. Slots and dependents wait. relay_plan_get shows every blocked Task and run.`,
|
|
53
|
-
idempotencyKey: `plan:${plan.id}:ci:${incidentId}`, replyExpected: false,
|
|
54
|
-
payload: { kind: "plan.ci-blocked", planId: plan.id, incidentId, taskId: run.taskId, runId: run.id, landedSha: block.sha },
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
return { quiet: "plan-ci-episode", planId: owner.planId, incidentIds: block.incidentIds };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
7
|
/** A kernel resume note is the durable receipt if the process dies before marking the plan's row. */
|
|
61
8
|
export async function recoverPlanCiBlock(run: WorkflowRunRecord): Promise<StoredPlanCiBlock | null> {
|
|
62
9
|
const block = await getGateway().read("planDispatch.ci.block", { runId: run.id });
|
|
@@ -71,15 +71,15 @@ function cleanVerdictItems(value: unknown): PlanConformanceItem[] {
|
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export function emitPlanTaskEvents(events: PlanGraphTaskEvent[] | undefined): void {
|
|
74
|
+
export async function emitPlanTaskEvents(events: PlanGraphTaskEvent[] | undefined): Promise<void> {
|
|
75
75
|
for (const event of events ?? []) {
|
|
76
76
|
emitTaskChanged(event.task, event.type);
|
|
77
77
|
if (event.type === "task.created") {
|
|
78
78
|
// A Task is created once, so a replayed aggregate write (its gateway result re-read) notifies once (#3660).
|
|
79
|
-
emitTaskSemanticNotification({ task: event.task, transition: "created", actor: event.actor, occurrenceKey: "created" });
|
|
79
|
+
await emitTaskSemanticNotification({ task: event.task, transition: "created", actor: event.actor, occurrenceKey: "created" });
|
|
80
80
|
} else {
|
|
81
81
|
const transition = taskTransitionForStatus(event.task.status, event.task.blockedBy);
|
|
82
|
-
if (transition) emitTaskSemanticNotification({ task: event.task, transition, actor: event.actor, occurrenceKey: undefined });
|
|
82
|
+
if (transition) await emitTaskSemanticNotification({ task: event.task, transition, actor: event.actor, occurrenceKey: undefined });
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -100,6 +100,6 @@ export async function recordPlanConformance(input: { planId?: unknown; mainSha?:
|
|
|
100
100
|
const mainShaCheck = await checkMainSha(planId, mainSha);
|
|
101
101
|
const result = await recordPlanConformanceAsync({ planId, mainSha, mainShaCheck, items, actor });
|
|
102
102
|
emitRelayEvent({ type: "plan.changed", source: actor, subject: result.plan.id, data: { plan: result.plan, actor } });
|
|
103
|
-
emitPlanTaskEvents(result.taskEvents);
|
|
103
|
+
await emitPlanTaskEvents(result.taskEvents);
|
|
104
104
|
return { planId: result.plan.id, version: result.plan.version, verdict: result.verdict, completion: result.plan.completion, gapTaskIds: result.gapTaskIds, ...(result.reusedGapTaskIds.length ? { reusedGapTaskIds: result.reusedGapTaskIds } : {}), conformance: result.plan.conformance };
|
|
105
105
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// #3660 — plan autopilot readiness and wake policy as pure rules over durable facts (slots, Tasks, runs).
|
|
2
|
-
import { planSlotOccupies, type Plan, type PlanDispatchSlot, type PlanDispatchSlotStatus, type TaskDetail, type TaskTerminalStage } from "../types";
|
|
2
|
+
import { planSlotOccupies, type Plan, type PlanNode, type PlanDispatchSlot, type PlanDispatchSlotStatus, type TaskDetail, type TaskTerminalStage } from "../types";
|
|
3
3
|
import { taskTerminalStage } from "../task-completion";
|
|
4
4
|
|
|
5
5
|
export interface PlanMember { nodeId: string; taskId: number }
|
|
@@ -12,13 +12,13 @@ export function planMembers(plan: Pick<Plan, "nodes">): PlanMember[] {
|
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
/**
|
|
15
|
+
/** Only unfinished automatic work needs a Task; settled facts and manual gates are valid (#3819). */
|
|
16
16
|
export function unsupportedPlanShape(plan: Pick<Plan, "nodes" | "acceptance">): string[] {
|
|
17
17
|
const problems: string[] = [];
|
|
18
18
|
if (!plan.acceptance?.length) problems.push("PLAN_ACCEPTANCE_REQUIRED: the auditor checks the plan's acceptance; add acceptance items");
|
|
19
19
|
if (!plan.nodes.length) problems.push("UNSUPPORTED_PLAN_SHAPE: the plan has no nodes");
|
|
20
20
|
const members = new Set(planMembers(plan).map((member) => member.nodeId));
|
|
21
|
-
const unbound = plan.nodes.filter((node) => !members.has(node.id)).map((node) => node.id);
|
|
21
|
+
const unbound = plan.nodes.filter((node) => node.status !== "landed" && node.statusSource !== "manual" && !members.has(node.id)).map((node) => node.id);
|
|
22
22
|
if (unbound.length) problems.push(`UNSUPPORTED_PLAN_SHAPE: nodes ${unbound.join(", ")} are not bound to a Task (status-pinned or unbound nodes cannot be dispatched; create them with relay_task_create plan:{...})`);
|
|
23
23
|
return problems;
|
|
24
24
|
}
|
|
@@ -48,6 +48,13 @@ export function taskSucceeded(task: PrerequisiteTask | null, slot: Pick<PlanDisp
|
|
|
48
48
|
return prerequisiteState(task, requiredStage).state === "satisfied";
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/** Existing settled nodes are facts; a dispatched run still needs its verified result, including CI. */
|
|
52
|
+
export function planNodeSettled(node: PlanNode, task: PrerequisiteTask | null, slot?: PlanDispatchSlot, requiredStage?: TaskTerminalStage): boolean {
|
|
53
|
+
if (node.statusSource === "manual") return node.status === "landed";
|
|
54
|
+
if (slot) return taskSucceeded(task, slot, requiredStage);
|
|
55
|
+
return node.status === "landed" || task?.status === "done" || task?.status === "canceled";
|
|
56
|
+
}
|
|
57
|
+
|
|
51
58
|
/** The stage an edge requires of its prerequisite; unnamed edges keep the original landed-on-main rule. */
|
|
52
59
|
export function dependencyStage(task: Pick<TaskDetail, "dependsOnStages">, prerequisiteId: number): TaskTerminalStage {
|
|
53
60
|
return task.dependsOnStages?.[String(prerequisiteId)] ?? "landed-on-main";
|
|
@@ -18,7 +18,7 @@ import { launchWorkflowRun, prepareWorkflowRun } from "./workflow-runs";
|
|
|
18
18
|
import { ensureSupervisor, invoke, type Supervisor } from "./workflow-supervisor";
|
|
19
19
|
import { stampPins } from "./workflow-pins";
|
|
20
20
|
import { emitPlan } from "./plan-graph";
|
|
21
|
-
import { dependencyStage, memberReady, occupiedSlots, planMembers, prerequisiteState, slotFromRun, taskSucceeded, unsupportedPlanShape } from "./plan-dispatch-policy";
|
|
21
|
+
import { dependencyStage, memberReady, occupiedSlots, planMembers, planNodeSettled, prerequisiteState, slotFromRun, taskSucceeded, unsupportedPlanShape } from "./plan-dispatch-policy";
|
|
22
22
|
import type { AuthContext } from "./auth-context";
|
|
23
23
|
import { planSlotOccupies, type Plan, type PlanDispatch, type PlanDispatchSlot, type TaskDetail } from "../types";
|
|
24
24
|
|
|
@@ -44,9 +44,13 @@ export async function startPlanDispatch(input: { planId?: unknown; expectedVersi
|
|
|
44
44
|
if (plan.archived) throw new ValidationError(`plan ${plan.id} is archived`);
|
|
45
45
|
const problems = unsupportedPlanShape(plan);
|
|
46
46
|
if (problems.length) throw new ValidationError(problems.join("; "));
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
47
|
+
const nodes = new Map(plan.nodes.map((node) => [node.id, node]));
|
|
48
|
+
const allMembers = planMembers(plan);
|
|
49
|
+
const allTasks = await Promise.all(allMembers.map((member) => getTaskDetailAsync(member.taskId)));
|
|
50
|
+
const unfinished = allMembers.flatMap((member, index) => planNodeSettled(nodes.get(member.nodeId)!, allTasks[index]!) ? [] : [{ member, task: allTasks[index]! }]);
|
|
51
|
+
const members = unfinished.map(({ member }) => member);
|
|
52
|
+
const tasks = unfinished.map(({ task }) => task);
|
|
53
|
+
const memberIds = new Set(plan.nodes.map((node) => Number(node.refs?.taskId)));
|
|
50
54
|
for (const member of tasks) {
|
|
51
55
|
for (const id of member?.dependsOn ?? []) {
|
|
52
56
|
if (memberIds.has(id)) continue;
|
|
@@ -55,7 +59,7 @@ export async function startPlanDispatch(input: { planId?: unknown; expectedVersi
|
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
const repos = new Set(tasks.map((task) => task?.repo).filter(Boolean));
|
|
58
|
-
if (repos.size !== 1) throw new ValidationError(`UNSUPPORTED_PLAN_SHAPE: slice 1a dispatches one repo; the plan's Tasks name ${repos.size ? [...repos].join(", ") : "no repo"}`);
|
|
62
|
+
if (tasks.length && repos.size !== 1) throw new ValidationError(`UNSUPPORTED_PLAN_SHAPE: slice 1a dispatches one repo; the plan's Tasks name ${repos.size ? [...repos].join(", ") : "no repo"}`);
|
|
59
63
|
let cwd: string | undefined;
|
|
60
64
|
for (const [index, task] of tasks.entries()) {
|
|
61
65
|
if (!task || task.status === "canceled") throw new ValidationError(`UNSUPPORTED_PLAN_SHAPE: T${members[index]!.taskId} is missing or canceled`);
|
|
@@ -115,6 +119,8 @@ function ensureListening(): void {
|
|
|
115
119
|
if (event.type === "task.stage" || event.type === "task.status" || event.type === "task.updated") {
|
|
116
120
|
const plans = watched.get(Number(event.data.id ?? event.subject));
|
|
117
121
|
if (plans?.size) void fireAndForget("[plan-dispatch] reconcile", () => requestReconcile(plans));
|
|
122
|
+
} else if (event.type === "plan.changed" && event.subject && dispatching.has(event.subject)) {
|
|
123
|
+
void fireAndForget("[plan-dispatch] reconcile", () => requestReconcile([event.subject!]));
|
|
118
124
|
} else if (dispatching.size && (event.type === "workflow.changed" || event.type === "branch.landed" || event.type === "ci.status")) {
|
|
119
125
|
void fireAndForget("[plan-dispatch] reconcile", () => requestReconcile());
|
|
120
126
|
}
|
|
@@ -184,9 +190,22 @@ async function reconcilePlan(planId: string): Promise<void> {
|
|
|
184
190
|
changed ||= next !== slot;
|
|
185
191
|
slots.set(slot.taskId, next);
|
|
186
192
|
}
|
|
193
|
+
const nodes = new Map(plan.nodes.map((node) => [node.id, node]));
|
|
194
|
+
const nodesForTask = new Map(plan.nodes.filter((node) => node.refs?.taskId).map((node) => [Number(node.refs!.taskId), node]));
|
|
195
|
+
const prerequisites = new Map<string, string[]>();
|
|
196
|
+
for (const edge of plan.edges) {
|
|
197
|
+
if (!prerequisites.has(edge.to)) prerequisites.set(edge.to, []);
|
|
198
|
+
prerequisites.get(edge.to)!.push(edge.from);
|
|
199
|
+
}
|
|
200
|
+
const settledNode = async (nodeId: string, requiredStage?: Parameters<typeof taskSucceeded>[2]) => {
|
|
201
|
+
const node = nodes.get(nodeId)!;
|
|
202
|
+
const id = Number(node.refs?.taskId);
|
|
203
|
+
return planNodeSettled(node, Number.isSafeInteger(id) && id > 0 ? await task(id) : null, slots.get(id), requiredStage);
|
|
204
|
+
};
|
|
187
205
|
if (dispatch.state === "active") {
|
|
188
206
|
for (const { nodeId, taskId } of members) {
|
|
189
207
|
const slot = slots.get(taskId);
|
|
208
|
+
if (!slot && await settledNode(nodeId)) continue;
|
|
190
209
|
if (slot && (slot.status !== "launch-failed" && slot.status !== "failed" && slot.status !== "cancelled")) {
|
|
191
210
|
const dispatched = planSlotOccupies(slot.status) ? await task(taskId) : null;
|
|
192
211
|
if (dispatched) await escalateRegressions(plan, nodeId, dispatched, memberTaskIds, task);
|
|
@@ -207,14 +226,16 @@ async function reconcilePlan(planId: string): Promise<void> {
|
|
|
207
226
|
for (const id of member.dependsOn) {
|
|
208
227
|
const prerequisite = await task(id);
|
|
209
228
|
const required = dependencyStage(member, id);
|
|
210
|
-
|
|
229
|
+
const node = nodesForTask.get(id);
|
|
230
|
+
if (node ? await settledNode(node.id, required) : taskSucceeded(prerequisite, slots.get(id), required)) succeeded.add(id);
|
|
211
231
|
else {
|
|
212
232
|
const state = prerequisiteState(prerequisite, required);
|
|
213
233
|
if (state.state === "unreachable") {
|
|
214
|
-
notifyPlan(plan, `T${taskId} prerequisite unreachable`, `Plan ${plan.id}, node ${nodeId} (T${taskId}) waits on T${id}, which is ${state.reason}. Replace the edge with relay_task_remove_dependency then relay_task_add_dependency, cancel the node, or wait for T${id} to be reopened. The dependent keeps waiting.`, `plan:${plan.id}:prereq:T${id}:${state.reason}`, { kind: "plan.prerequisite-unreachable", planId, nodeId, taskId, prerequisiteTaskId: id, reason: state.reason, nextActions: ["replace-edge", "cancel-node", "wait-for-reopen"] });
|
|
234
|
+
await notifyPlan(plan, `T${taskId} prerequisite unreachable`, `Plan ${plan.id}, node ${nodeId} (T${taskId}) waits on T${id}, which is ${state.reason}. Replace the edge with relay_task_remove_dependency then relay_task_add_dependency, cancel the node, or wait for T${id} to be reopened. The dependent keeps waiting.`, `plan:${plan.id}:prereq:T${id}:${state.reason}`, { kind: "plan.prerequisite-unreachable", planId, nodeId, taskId, prerequisiteTaskId: id, reason: state.reason, nextActions: ["replace-edge", "cancel-node", "wait-for-reopen"] });
|
|
215
235
|
}
|
|
216
236
|
}
|
|
217
237
|
}
|
|
238
|
+
if (!(await Promise.all((prerequisites.get(nodeId) ?? []).map((id) => settledNode(id)))).every(Boolean)) continue;
|
|
218
239
|
if (!memberReady(member, undefined, (id) => succeeded.has(id))) continue;
|
|
219
240
|
if (occupiedSlots(slots.values()) >= dispatch.concurrency) continue;
|
|
220
241
|
const claimed = await write<{ slot?: PlanDispatchSlot; reserved: boolean }>("planDispatch.slot.reserve", { planId, taskId, nodeId });
|
|
@@ -223,7 +244,7 @@ async function reconcilePlan(planId: string): Promise<void> {
|
|
|
223
244
|
if (fault === "after-reserve") { halted = true; throw new Error("plan dispatch test fault: the process stopped after reserving a slot"); }
|
|
224
245
|
slots.set(taskId, await launch(plan, claimed.slot));
|
|
225
246
|
}
|
|
226
|
-
const settled = await Promise.all(
|
|
247
|
+
const settled = await Promise.all(plan.nodes.map((node) => settledNode(node.id)));
|
|
227
248
|
if (settled.every(Boolean)) {
|
|
228
249
|
await openAudit(plan, dispatch, members.map(({ taskId }) => tasks.get(taskId)).find(Boolean) ?? null);
|
|
229
250
|
changed = true;
|
|
@@ -245,7 +266,7 @@ async function escalateRegressions(plan: Plan, nodeId: string, member: TaskDetai
|
|
|
245
266
|
const state = prerequisiteState(prerequisite, required);
|
|
246
267
|
if (state.state === "satisfied") continue;
|
|
247
268
|
const now = prerequisite ? `status ${prerequisite.status}, stage ${prerequisite.deliverableStage ?? "none"}${state.state === "unreachable" ? `, ${state.reason}` : ""}` : "missing";
|
|
248
|
-
notifyPlan(plan, `T${member.id} prerequisite regressed`, `Plan ${plan.id}, node ${nodeId} (T${member.id}) was dispatched on T${id} reaching ${required}, which no longer holds (${now}). The run continues; check whether its work is still valid, or cancel the node.`, `plan:${plan.id}:prereq:T${id}:regressed`, { kind: "plan.prerequisite-unreachable", planId: plan.id, nodeId, taskId: member.id, prerequisiteTaskId: id, reason: "regressed", requiredStage: required, nextActions: ["check-run", "cancel-node", "wait-for-recovery"] });
|
|
269
|
+
await notifyPlan(plan, `T${member.id} prerequisite regressed`, `Plan ${plan.id}, node ${nodeId} (T${member.id}) was dispatched on T${id} reaching ${required}, which no longer holds (${now}). The run continues; check whether its work is still valid, or cancel the node.`, `plan:${plan.id}:prereq:T${id}:regressed`, { kind: "plan.prerequisite-unreachable", planId: plan.id, nodeId, taskId: member.id, prerequisiteTaskId: id, reason: "regressed", requiredStage: required, nextActions: ["check-run", "cancel-node", "wait-for-recovery"] });
|
|
249
270
|
}
|
|
250
271
|
}
|
|
251
272
|
|
|
@@ -279,7 +300,7 @@ async function launch(plan: Plan, slot: PlanDispatchSlot): Promise<PlanDispatchS
|
|
|
279
300
|
const started = await launchWorkflowRun(prepared, { ...(inputs ? { inputs } : {}), ...(pins ? { pins } : {}), requestKey: `plan:${plan.id}:T${task.id}:a${slot.attempt}` }, AUTOPILOT_CTX);
|
|
280
301
|
return (await write<PlanDispatchSlot | undefined>("planDispatch.slot.update", { taskId: slot.taskId, attempt: slot.attempt, runId: String(started.runId), status: String(started.status) })) ?? slot;
|
|
281
302
|
} catch (error) {
|
|
282
|
-
notifyPlan(plan, `T${slot.taskId} could not start`, `Plan ${plan.id} could not start T${slot.taskId}'s workflow: ${errMessage(error)}. Its slot is free and its dependents wait. Fix the cause, then start its workflow by hand (relay_workflow_start); the plan adopts that run.`, `plan:${plan.id}:launch-failed:T${slot.taskId}:a${slot.attempt}`, { kind: "plan.dispatch-failed", planId: plan.id, taskId: slot.taskId });
|
|
303
|
+
await notifyPlan(plan, `T${slot.taskId} could not start`, `Plan ${plan.id} could not start T${slot.taskId}'s workflow: ${errMessage(error)}. Its slot is free and its dependents wait. Fix the cause, then start its workflow by hand (relay_workflow_start); the plan adopts that run.`, `plan:${plan.id}:launch-failed:T${slot.taskId}:a${slot.attempt}`, { kind: "plan.dispatch-failed", planId: plan.id, taskId: slot.taskId });
|
|
283
304
|
return (await write<PlanDispatchSlot | undefined>("planDispatch.slot.update", { taskId: slot.taskId, attempt: slot.attempt, status: "launch-failed", error: errMessage(error).slice(0, 2000) })) ?? slot;
|
|
284
305
|
}
|
|
285
306
|
}
|
|
@@ -310,7 +331,7 @@ async function driveAudit(sup: Supervisor, plan: Plan): Promise<boolean> {
|
|
|
310
331
|
const started = await launchWorkflowRun(prepared, { requestKey: `plan:${plan.id}:audit` }, AUTOPILOT_CTX);
|
|
311
332
|
await write("planDispatch.audit.update", { planId: plan.id, runId: String(started.runId), status: String(started.status) });
|
|
312
333
|
} catch (error) {
|
|
313
|
-
notifyPlan(plan, "audit could not start", `Plan ${plan.id}: every node landed, but its conformance audit (T${audit.taskId}) could not start: ${errMessage(error)}. Start ${PLAN_CONFORMANCE_WORKFLOW} on T${audit.taskId} by hand, or audit and record relay_plan_conformance yourself.`, `plan:${plan.id}:audit-failed`, { kind: "plan.dispatch-failed", planId: plan.id, taskId: audit.taskId });
|
|
334
|
+
await notifyPlan(plan, "audit could not start", `Plan ${plan.id}: every node landed, but its conformance audit (T${audit.taskId}) could not start: ${errMessage(error)}. Start ${PLAN_CONFORMANCE_WORKFLOW} on T${audit.taskId} by hand, or audit and record relay_plan_conformance yourself.`, `plan:${plan.id}:audit-failed`, { kind: "plan.dispatch-failed", planId: plan.id, taskId: audit.taskId });
|
|
314
335
|
await write("planDispatch.audit.update", { planId: plan.id, status: "launch-failed" });
|
|
315
336
|
}
|
|
316
337
|
return true;
|
|
@@ -324,14 +345,14 @@ async function driveAudit(sup: Supervisor, plan: Plan): Promise<boolean> {
|
|
|
324
345
|
dispatching.delete(plan.id);
|
|
325
346
|
watchPlan(plan.id, new Set());
|
|
326
347
|
const slots = plan.dispatch!.slots.map((slot) => `${slot.nodeId} T${slot.taskId} ${slot.runId ?? "no run"} ${slot.landedSha?.slice(0, 12) ?? ""}`.trim());
|
|
327
|
-
notifyPlan(plan, "done", [`Plan ${plan.id}${plan.title ? ` "${plan.title}"` : ""} is done: conformance passed on ${audit.mainSha} at version ${plan.version}.`, ...slots, `Audit T${audit.taskId} run ${audit.runId}.`].join("\n"), `plan:${plan.id}:result:v${plan.version}`, { kind: "plan.result", planId: plan.id, planVersion: plan.version, mainSha: audit.mainSha });
|
|
348
|
+
await notifyPlan(plan, "done", [`Plan ${plan.id}${plan.title ? ` "${plan.title}"` : ""} is done: conformance passed on ${audit.mainSha} at version ${plan.version}.`, ...slots, `Audit T${audit.taskId} run ${audit.runId}.`].join("\n"), `plan:${plan.id}:result:v${plan.version}`, { kind: "plan.result", planId: plan.id, planVersion: plan.version, mainSha: audit.mainSha });
|
|
328
349
|
}
|
|
329
350
|
return true;
|
|
330
351
|
}
|
|
331
352
|
|
|
332
|
-
function notifyPlan(plan: Plan, subject: string, body: string, idempotencyKey: string, payload: Json): void {
|
|
353
|
+
async function notifyPlan(plan: Plan, subject: string, body: string, idempotencyKey: string, payload: Json): Promise<void> {
|
|
333
354
|
const to = planNoticeTarget(plan);
|
|
334
|
-
if (to) notifySystemMessage(to, { subject: `Plan ${plan.title ?? plan.id}: ${subject}`, body, idempotencyKey, replyExpected: false, payload });
|
|
355
|
+
if (to) await notifySystemMessage(to, { subject: `Plan ${plan.title ?? plan.id}: ${subject}`, body, idempotencyKey, replyExpected: false, payload });
|
|
335
356
|
}
|
|
336
357
|
|
|
337
358
|
// --- serving ---------------------------------------------------------------------------------------
|