@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,3 +1,5 @@
|
|
|
1
|
+
import { pauseMaintenanceJobAsync } from "../db/runtime-tail-async";
|
|
2
|
+
import { createActivityEventAsync } from "../db/activity-async";
|
|
1
3
|
// #1724 stage 1 — the maintenance circuit breaker's bookkeeping and trip actions.
|
|
2
4
|
//
|
|
3
5
|
// The design (§5.4, §8.5) asks for a breaker that, when a job repeatedly starves the event loop (or
|
|
@@ -15,7 +17,7 @@
|
|
|
15
17
|
|
|
16
18
|
import { errMessage } from "@humwick/sdk";
|
|
17
19
|
import { MAINTENANCE_BREAKER_MAX_STRIKES } from "../config";
|
|
18
|
-
import { AUTO_BREAKER_PAUSE_HOLDER
|
|
20
|
+
import { AUTO_BREAKER_PAUSE_HOLDER } from "../db";
|
|
19
21
|
|
|
20
22
|
// Two strike counters per job, because the two failure signals want different reset semantics — and
|
|
21
23
|
// getting this wrong silently defeats the breaker:
|
|
@@ -81,7 +83,7 @@ export interface BreakerStrikeResult {
|
|
|
81
83
|
* and, on reaching MAINTENANCE_BREAKER_MAX_STRIKES, trips: a non-critical job is durably auto-paused;
|
|
82
84
|
* a critical one is escalated LOUDLY but never paused. Idempotent per runId.
|
|
83
85
|
*/
|
|
84
|
-
export function recordBreakerStrike(input: BreakerStrikeInput): BreakerStrikeResult {
|
|
86
|
+
export async function recordBreakerStrike(input: BreakerStrikeInput): Promise<BreakerStrikeResult> {
|
|
85
87
|
if (!markStruck(input.runId)) {
|
|
86
88
|
return { struck: false, strikes: breakerStrikeCount(input.jobId), tripped: false };
|
|
87
89
|
}
|
|
@@ -92,7 +94,7 @@ export function recordBreakerStrike(input: BreakerStrikeInput): BreakerStrikeRes
|
|
|
92
94
|
if (count < MAINTENANCE_BREAKER_MAX_STRIKES) {
|
|
93
95
|
return { struck: true, strikes: breakerStrikeCount(input.jobId), tripped: false };
|
|
94
96
|
}
|
|
95
|
-
const action = trip(input.jobId, input.critical, input.reason);
|
|
97
|
+
const action = (await trip(input.jobId, input.critical, input.reason));
|
|
96
98
|
return { struck: true, strikes: 0, tripped: true, action };
|
|
97
99
|
}
|
|
98
100
|
|
|
@@ -119,34 +121,34 @@ export function isRunStruck(runId: string): boolean {
|
|
|
119
121
|
return struckRunIds.has(runId);
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
function trip(jobId: string, critical: boolean, reason: string): "paused" | "escalated" | "pause-conflict" {
|
|
124
|
+
async function trip(jobId: string, critical: boolean, reason: string): Promise<"paused" | "escalated" | "pause-conflict"> {
|
|
123
125
|
// Reset BOTH counters first: after a trip the job is either paused (won't run) or escalated; either
|
|
124
126
|
// way the next strike should start a fresh count rather than instantly re-trip on every later run.
|
|
125
127
|
timeoutStrikes.delete(jobId);
|
|
126
128
|
lagStrikes.delete(jobId);
|
|
127
129
|
if (critical) {
|
|
128
|
-
escalateCritical(jobId, reason);
|
|
130
|
+
(await escalateCritical(jobId, reason));
|
|
129
131
|
return "escalated";
|
|
130
132
|
}
|
|
131
|
-
return autoPause(jobId, reason);
|
|
133
|
+
return (await autoPause(jobId, reason));
|
|
132
134
|
}
|
|
133
135
|
|
|
134
|
-
function autoPause(jobId: string, reason: string): "paused" | "pause-conflict" {
|
|
136
|
+
async function autoPause(jobId: string, reason: string): Promise<"paused" | "pause-conflict"> {
|
|
135
137
|
const pauseReason = `auto-paused by circuit breaker: ${reason}`;
|
|
136
138
|
console.warn(`[relay] maintenance circuit breaker TRIPPED — durably auto-pausing ${jobId}: ${reason}`);
|
|
137
139
|
try {
|
|
138
140
|
// Indefinite on purpose: a job that was starving the loop must NOT quietly resume itself on a
|
|
139
141
|
// timer. A human resumes it once it is fixed — and the `maintenance-auto-paused` health arm is
|
|
140
142
|
// what makes sure a human sees it (this pause is otherwise invisible to the critical-only arm).
|
|
141
|
-
const result =
|
|
142
|
-
auditBreakerEvent({
|
|
143
|
+
const result = (await pauseMaintenanceJobAsync({ jobId, holder: AUTO_BREAKER_PAUSE_HOLDER, reason: pauseReason, indefinite: true }));
|
|
144
|
+
(await auditBreakerEvent({
|
|
143
145
|
jobId,
|
|
144
146
|
clientId: `server-maintenance-breaker-pause-${jobId}-${result.pause.createdAt}`,
|
|
145
147
|
title: `Maintenance circuit breaker auto-paused ${jobId}`,
|
|
146
148
|
body: `${jobId} was auto-paused by the event-loop-lag circuit breaker after ${MAINTENANCE_BREAKER_MAX_STRIKES} strikes — ${reason}. It will stay paused until a human resumes it.`,
|
|
147
149
|
icon: "ti-alert-octagon",
|
|
148
150
|
metadata: { breaker: true, pauseId: result.pause.id, alreadyHeld: !result.ok },
|
|
149
|
-
});
|
|
151
|
+
}));
|
|
150
152
|
return result.ok ? "paused" : "pause-conflict";
|
|
151
153
|
} catch (error) {
|
|
152
154
|
console.warn(`[relay] maintenance circuit breaker could not pause ${jobId}: ${errMessage(error)}`);
|
|
@@ -154,27 +156,27 @@ function autoPause(jobId: string, reason: string): "paused" | "pause-conflict" {
|
|
|
154
156
|
}
|
|
155
157
|
}
|
|
156
158
|
|
|
157
|
-
function escalateCritical(jobId: string, reason: string): void {
|
|
159
|
+
async function escalateCritical(jobId: string, reason: string): Promise<void> {
|
|
158
160
|
// §8.5 — the one thing the breaker must never do is silence a critical job the way a bare
|
|
159
161
|
// `enabled=0` silenced cd-watcher for nine hours. So a critical job is escalated, never paused: it
|
|
160
162
|
// KEEPS running (and keeps being reported by criticalMaintenanceJobsCheck if it is genuinely
|
|
161
163
|
// failing), and a loud, attributed event tells a human to intervene deliberately.
|
|
162
164
|
console.warn(`[relay] maintenance circuit breaker: CRITICAL job ${jobId} repeatedly misbehaving (${reason}) — NOT auto-paused (see #1645/§8.5), escalating for a human`);
|
|
163
|
-
auditBreakerEvent({
|
|
165
|
+
(await auditBreakerEvent({
|
|
164
166
|
jobId,
|
|
165
167
|
clientId: `server-maintenance-breaker-escalate-${jobId}-${Date.now()}`,
|
|
166
168
|
title: `Maintenance circuit breaker: critical job ${jobId} needs a human`,
|
|
167
169
|
body: `${jobId} repeatedly starved the event loop or overran its deadline (${reason}). Because it is CRITICAL, the breaker did NOT auto-pause it — a machine silencing a critical job is the #1645 blackout. A human must decide what to do.`,
|
|
168
170
|
icon: "ti-alert-triangle",
|
|
169
171
|
metadata: { breaker: true, critical: true, escalated: true },
|
|
170
|
-
});
|
|
172
|
+
}));
|
|
171
173
|
}
|
|
172
174
|
|
|
173
|
-
function auditBreakerEvent(input: { jobId: string; clientId: string; title: string; body: string; icon: string; metadata: Record<string, unknown> }): void {
|
|
175
|
+
async function auditBreakerEvent(input: { jobId: string; clientId: string; title: string; body: string; icon: string; metadata: Record<string, unknown> }): Promise<void> {
|
|
174
176
|
try {
|
|
175
177
|
// #1912 S3.2: sync-retained — the lag sampler invokes recordBreakerStrike synchronously and
|
|
176
178
|
// cannot await without redesigning the event-loop attribution callback contract.
|
|
177
|
-
|
|
179
|
+
(await createActivityEventAsync({
|
|
178
180
|
clientId: input.clientId,
|
|
179
181
|
kind: "operator",
|
|
180
182
|
title: input.title,
|
|
@@ -183,7 +185,7 @@ function auditBreakerEvent(input: { jobId: string; clientId: string; title: stri
|
|
|
183
185
|
icon: input.icon,
|
|
184
186
|
view: "activity",
|
|
185
187
|
metadata: { source: "server", maintenanceJobId: input.jobId, ...input.metadata },
|
|
186
|
-
});
|
|
188
|
+
}));
|
|
187
189
|
} catch (error) {
|
|
188
190
|
// The pause/escalation itself already happened; losing the timeline entry must not throw back
|
|
189
191
|
// into the scheduler's tick.
|
|
@@ -140,7 +140,7 @@ export async function runCdWatcherJob(context: MaintenanceJobContext = { signal:
|
|
|
140
140
|
// `offThread: true` mirrors the #1725 off-thread jobs (old-message-prune, db-maintenance, …): it
|
|
141
141
|
// records in the run's persisted result that the heavy work ran in a subprocess, so an operator
|
|
142
142
|
// reading the last result sees the same proof the run registry acted on for breaker attribution.
|
|
143
|
-
return { ...result, offThread: true, transition: notifyMainCiTransition(result.observation) };
|
|
143
|
+
return { ...result, offThread: true, transition: await notifyMainCiTransition(result.observation) };
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
/** Best-effort Cosmos deploy hero-shot: read the ledger row this deploy just
|
|
@@ -164,9 +164,9 @@ async function emitDeployHeroShot(sha: string | null): Promise<void> {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
/** Best-effort transition alert; never throws into the deploy job. */
|
|
167
|
-
function notifyMainCiTransition(observation: CiObservation): Record<string, unknown
|
|
167
|
+
async function notifyMainCiTransition(observation: CiObservation): Promise<Record<string, unknown>> {
|
|
168
168
|
try {
|
|
169
|
-
const { transition, incidentId, notified, messages } = notifyCiTransition(observation);
|
|
169
|
+
const { transition, incidentId, notified, messages } = await notifyCiTransition(observation);
|
|
170
170
|
return { flip: transition, notified, messages, ...(incidentId ? { incidentId } : {}) };
|
|
171
171
|
} catch (error) {
|
|
172
172
|
const message = errMessage(error);
|
|
@@ -9,6 +9,7 @@ import { isRecord } from "@humwick/sdk";
|
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
10
|
import { sendMessageServiceAsync } from "../services/send-message";
|
|
11
11
|
import { checkoutRefreshEnabled } from "../config";
|
|
12
|
+
import { runGit } from "../services/git-process";
|
|
12
13
|
|
|
13
14
|
async function notice(projectId: string, projectSlug: string, host: string, rootPath: string, reason: string): Promise<void> {
|
|
14
15
|
const key = createHash("sha256").update(JSON.stringify([projectId, host, rootPath, reason])).digest("hex");
|
|
@@ -28,6 +29,7 @@ export function reconcileCheckoutRefresh(signal?: AbortSignal): Promise<Record<s
|
|
|
28
29
|
async function reconcile(signal?: AbortSignal): Promise<Record<string, unknown>> {
|
|
29
30
|
const dispatched: string[] = [];
|
|
30
31
|
const skipped: string[] = [];
|
|
32
|
+
const remoteTips = new Map<string, Promise<string | undefined>>();
|
|
31
33
|
for (const project of await listProjectsAsync()) {
|
|
32
34
|
if (signal?.aborted) break;
|
|
33
35
|
const roots = await rootsForProjectAsync(project.id);
|
|
@@ -55,8 +57,23 @@ async function reconcile(signal?: AbortSignal): Promise<Record<string, unknown>>
|
|
|
55
57
|
if (prior && ["pending", "accepted", "running"].includes(prior.status)) continue;
|
|
56
58
|
// The host reported once that it cannot refresh; re-asking every tick only repeats that (#3629).
|
|
57
59
|
if (health === "unsupported") { skipped.push(`${project.slug}: unsupported host ${hostId} for ${root.rootPath}`); continue; }
|
|
60
|
+
// Completed receipts remain valid until the remote default branch moves (#3813).
|
|
61
|
+
if (prior?.status === "succeeded" && prior.result?.targetSha && ["current", "refreshed", "disabled"].includes(prior.result.status)) {
|
|
62
|
+
let tip = remoteTips.get(root.remoteUrl!);
|
|
63
|
+
if (!tip) {
|
|
64
|
+
tip = runGit(["ls-remote", "--symref", "--", root.remoteUrl!, "HEAD"], 10_000, 4096).then(result => {
|
|
65
|
+
if (result.exitCode !== 0 || result.unavailable || !/^ref: refs\/heads\/.+\tHEAD$/m.test(result.stdout)) return undefined;
|
|
66
|
+
return result.stdout.match(/^([0-9a-f]{40,64})\tHEAD$/m)?.[1];
|
|
67
|
+
});
|
|
68
|
+
remoteTips.set(root.remoteUrl!, tip);
|
|
69
|
+
}
|
|
70
|
+
const sha = await tip;
|
|
71
|
+
if (!sha) { skipped.push(`${project.slug}: remote default branch unavailable`); continue; }
|
|
72
|
+
if (sha === prior.result.targetSha) continue;
|
|
73
|
+
}
|
|
58
74
|
// Leave one tick of backoff after terminal failure, including restart/lease recovery (#3691).
|
|
59
75
|
if (prior && (["failed", "timed_out"].includes(prior.status) || prior.result?.status === "error") && Date.now() < (prior.updatedAt ?? 0) + 60_000) continue;
|
|
76
|
+
if (signal?.aborted) break;
|
|
60
77
|
const command = await createCommandAsync({ type: "project.checkout.refresh", source: "system", target: `orchestrator-${hostId}`,
|
|
61
78
|
params: { projectId: project.id, rootPath: root.rootPath, remoteUrl: root.remoteUrl, orchestratorId: hostId, enabled: true, ...(prior?.result ? { previousResult: prior.result } : {}) } });
|
|
62
79
|
emitCommandEvent(command, "command.requested");
|
|
@@ -66,7 +83,7 @@ async function reconcile(signal?: AbortSignal): Promise<Record<string, unknown>>
|
|
|
66
83
|
return { enabled: true, dispatched, skipped };
|
|
67
84
|
}
|
|
68
85
|
|
|
69
|
-
//
|
|
86
|
+
// Publish hints and external pushes use the same remote-tip comparison.
|
|
70
87
|
subscribeRelayEvents((event) => {
|
|
71
88
|
if (!event.type.startsWith("command.") || !isRecord(event.data.command)) return;
|
|
72
89
|
const command = event.data.command;
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
// - the configured fleet-ops agent target, so something that can actually act is woken.
|
|
18
18
|
|
|
19
19
|
import { errMessage } from "@humwick/sdk";
|
|
20
|
-
import { getConfig
|
|
20
|
+
import { getConfig } from "../config-store";
|
|
21
|
+
import { setConfigAsync } from "../config-store-write";
|
|
22
|
+
import { resetExpiredCriticalRunsAsync } from "../db/maintenance-job-runs-async";
|
|
21
23
|
import { stewardFallbackTarget } from "../config";
|
|
22
24
|
import {
|
|
23
25
|
evaluateCriticalMaintenanceJobs,
|
|
24
26
|
legacyHungCriticalMaintenanceRuns,
|
|
25
|
-
resetExpiredCriticalMaintenanceRuns,
|
|
26
27
|
type CriticalJobCondition,
|
|
27
28
|
type LegacyHungCriticalMaintenanceRun,
|
|
28
29
|
type ResetCriticalMaintenanceRun,
|
|
@@ -69,11 +70,11 @@ export interface CriticalJobWatchdogResult {
|
|
|
69
70
|
suppressed?: "unchanged-within-reminder-window" | "awaiting-second-failure";
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
export function runCriticalJobWatchdog(now: number = Date.now()): CriticalJobWatchdogResult {
|
|
73
|
+
export async function runCriticalJobWatchdog(now: number = Date.now()): Promise<CriticalJobWatchdogResult> {
|
|
73
74
|
// Do this before evaluating health so the durable scheduler latch is recovered even if the
|
|
74
75
|
// notification path is unavailable. A normal timed-out run clears itself; this is only the
|
|
75
76
|
// safety net for a row stranded in `running` after its own deadline lease elapsed.
|
|
76
|
-
const resetRuns =
|
|
77
|
+
const resetRuns = await resetExpiredCriticalRunsAsync(now);
|
|
77
78
|
const legacyHungRuns = legacyHungCriticalMaintenanceRuns(now);
|
|
78
79
|
const conditions = evaluateCriticalMaintenanceJobs(now);
|
|
79
80
|
const errors = conditions.filter((condition) => condition.status === "error");
|
|
@@ -86,9 +87,9 @@ export function runCriticalJobWatchdog(now: number = Date.now()): CriticalJobWat
|
|
|
86
87
|
state.missedChecks[key] = checks;
|
|
87
88
|
return checks >= 2;
|
|
88
89
|
});
|
|
89
|
-
const persist = () => {
|
|
90
|
+
const persist = async () => {
|
|
90
91
|
if (JSON.stringify(state) !== JSON.stringify(prior)) {
|
|
91
|
-
|
|
92
|
+
await setConfigAsync(STATE_NAMESPACE, STATE_KEY, state, "critical-job-watchdog");
|
|
92
93
|
}
|
|
93
94
|
};
|
|
94
95
|
const heldRestartEpoch = currentHeldRestartEpoch(now);
|
|
@@ -97,7 +98,7 @@ export function runCriticalJobWatchdog(now: number = Date.now()): CriticalJobWat
|
|
|
97
98
|
// Recovered (or never degraded): clear the marker so the NEXT degradation notifies immediately
|
|
98
99
|
// rather than being swallowed by the reminder window opened by the previous one.
|
|
99
100
|
state.lastNotified = null;
|
|
100
|
-
persist();
|
|
101
|
+
await persist();
|
|
101
102
|
return errors.length > 0
|
|
102
103
|
? { status: "error", degradedJobIds: errors.map((condition) => condition.jobId), notified: false, recipients: [], suppressed: "awaiting-second-failure" }
|
|
103
104
|
: { status: conditions.length > 0 ? "warn" : "ok", degradedJobIds: [], notified: false, recipients: [] };
|
|
@@ -115,7 +116,7 @@ export function runCriticalJobWatchdog(now: number = Date.now()): CriticalJobWat
|
|
|
115
116
|
...(heldRestartEpoch ? [`epoch:${heldRestartEpoch.id}:${heldRestartEpoch.blockerCode}`] : []),
|
|
116
117
|
].sort().join("|");
|
|
117
118
|
if (state.lastNotified?.fingerprint === fingerprint && now - state.lastNotified.notifiedAt < DEGRADED_REMINDER_MS) {
|
|
118
|
-
persist();
|
|
119
|
+
await persist();
|
|
119
120
|
return {
|
|
120
121
|
status: "error", degradedJobIds,
|
|
121
122
|
...(resetRuns.length > 0 ? { resetJobIds: resetRuns.map((run) => run.jobId) } : {}),
|
|
@@ -127,18 +128,18 @@ export function runCriticalJobWatchdog(now: number = Date.now()): CriticalJobWat
|
|
|
127
128
|
|
|
128
129
|
const { subject, body, payload } = composeNotice(degraded, resetRuns, legacyHungRuns, heldRestartEpoch, now);
|
|
129
130
|
const recipients: string[] = [];
|
|
130
|
-
const human = notifyWorkspaceHumanEscalation({
|
|
131
|
+
const human = (await notifyWorkspaceHumanEscalation({
|
|
131
132
|
subject,
|
|
132
133
|
body,
|
|
133
134
|
payload,
|
|
134
135
|
source: "maintenance-critical-job-watchdog",
|
|
135
136
|
tags: ["agent-relay", "maintenance"],
|
|
136
|
-
});
|
|
137
|
+
}));
|
|
137
138
|
if (human.accepted && human.channelId) recipients.push(human.channelId);
|
|
138
139
|
|
|
139
140
|
const agentTarget = stewardFallbackTarget();
|
|
140
141
|
if (agentTarget) {
|
|
141
|
-
const routed = notifyTarget("maintenance.degraded", {}, agentTarget, subject, body, payload);
|
|
142
|
+
const routed = await notifyTarget("maintenance.degraded", {}, agentTarget, subject, body, payload);
|
|
142
143
|
if (routed) recipients.push(routed);
|
|
143
144
|
}
|
|
144
145
|
|
|
@@ -154,7 +155,7 @@ export function runCriticalJobWatchdog(now: number = Date.now()): CriticalJobWat
|
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
state.lastNotified = { fingerprint, notifiedAt: now };
|
|
157
|
-
persist();
|
|
158
|
+
await persist();
|
|
158
159
|
return {
|
|
159
160
|
status: "error", degradedJobIds,
|
|
160
161
|
...(resetRuns.length > 0 ? { resetJobIds: resetRuns.map((run) => run.jobId) } : {}),
|
|
@@ -236,16 +237,14 @@ function composeNotice(
|
|
|
236
237
|
|
|
237
238
|
/** Handler wrapper: a watchdog that throws must not mark itself failed-and-silent, so failures are
|
|
238
239
|
* reported as a result the job record carries. */
|
|
239
|
-
export function criticalJobWatchdogJob(context: { signal?: AbortSignal } = {}): Record<string, unknown
|
|
240
|
-
// #1819 —
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
// of critical jobs (one today), so overrun is not a live risk; if that ever changes this is an
|
|
245
|
-
// #1809 offload candidate, not a place for more checks.
|
|
240
|
+
export async function criticalJobWatchdogJob(context: { signal?: AbortSignal } = {}): Promise<Record<string, unknown>> {
|
|
241
|
+
// #1819 — single-unit: one `evaluateCriticalMaintenanceJobs` read then one notify fan-out that must not
|
|
242
|
+
// be split (the `lastNotified` fingerprint is stamped only after the sends, so a half-run would re-page
|
|
243
|
+
// on the next tick). The only safe checkpoint is before it starts. Its two writes (the lease reset and
|
|
244
|
+
// the state persist) are writer ops (#1870 S7).
|
|
246
245
|
if (context.signal?.aborted) return { status: "ok", aborted: true, degradedJobIds: [], notified: false, recipients: [] };
|
|
247
246
|
try {
|
|
248
|
-
return { ...runCriticalJobWatchdog() };
|
|
247
|
+
return { ...(await runCriticalJobWatchdog()) };
|
|
249
248
|
} catch (error) {
|
|
250
249
|
return { status: "error", error: errMessage(error) };
|
|
251
250
|
}
|
|
@@ -9,7 +9,7 @@ export function emitCommand(command: Command): void {
|
|
|
9
9
|
|
|
10
10
|
// Route a maintenance notification, swallowing failures (a stale/missing/misconfigured
|
|
11
11
|
// target must never break the sweep). Returns the target on success, null otherwise.
|
|
12
|
-
export function notifyTarget(
|
|
12
|
+
export async function notifyTarget(
|
|
13
13
|
type: NotificationType,
|
|
14
14
|
scope: NotificationScope,
|
|
15
15
|
target: string,
|
|
@@ -17,10 +17,10 @@ export function notifyTarget(
|
|
|
17
17
|
body: string,
|
|
18
18
|
payload: Record<string, unknown>,
|
|
19
19
|
idempotencyKey?: string,
|
|
20
|
-
): string | null {
|
|
20
|
+
): Promise<string | null> {
|
|
21
21
|
if (!target) return null;
|
|
22
22
|
try {
|
|
23
|
-
routeNotification({ type, scope, recipients: [target], message: { subject, body, payload, idempotencyKey } });
|
|
23
|
+
await routeNotification({ type, scope, recipients: [target], message: { subject, body, payload, idempotencyKey } });
|
|
24
24
|
return target;
|
|
25
25
|
} catch {
|
|
26
26
|
return null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getGateway } from "../db/gateway";
|
|
2
|
+
import type { MaintenanceJobDefinition } from "./types";
|
|
3
|
+
|
|
4
|
+
export const HISTORY_RETENTION_JOB: MaintenanceJobDefinition = {
|
|
5
|
+
id: "history-retention", critical: false,
|
|
6
|
+
title: "Command, kernel replay and token history retention",
|
|
7
|
+
description: "Expire superseded checkout refresh commands after one hour, other non-spawn terminal commands and kernel replay receipts after 30 days, and raw usage after 90 days. Preserve references, expired replay keys and permanent budget spend (#3619, #3797).",
|
|
8
|
+
intervalMs: 60 * 60_000, backlogIntervalMs: 1_000, deadlineMs: 30_000, runOnStart: true,
|
|
9
|
+
async handler(context) {
|
|
10
|
+
const gateway = getGateway();
|
|
11
|
+
const result = { prunedCommands: 0, prunedKernelReceipts: 0, prunedTokenReports: 0, moreWork: false };
|
|
12
|
+
for (const [op, key] of [
|
|
13
|
+
["historyRetention.commands", "prunedCommands"],
|
|
14
|
+
["historyRetention.kernel", "prunedKernelReceipts"],
|
|
15
|
+
["historyRetention.tokens", "prunedTokenReports"],
|
|
16
|
+
] as const) {
|
|
17
|
+
if (context.signal.aborted) return { ...result, aborted: true, moreWork: true };
|
|
18
|
+
const start = performance.now();
|
|
19
|
+
let batch: { pruned: number; moreWork: boolean };
|
|
20
|
+
do {
|
|
21
|
+
if (context.signal.aborted) return { ...result, aborted: true, moreWork: true };
|
|
22
|
+
batch = await gateway.write(op, {}) as typeof batch;
|
|
23
|
+
result[key] += batch.pruned;
|
|
24
|
+
// Each await releases the writer for foreground work; bound the whole catch-up run (#3807).
|
|
25
|
+
} while (op === "historyRetention.commands" && batch.moreWork && performance.now() - start < 250);
|
|
26
|
+
result.moreWork ||= batch.moreWork;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
},
|
|
30
|
+
};
|
package/src/maintenance/index.ts
CHANGED
package/src/maintenance/jobs.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { OFFLINE_AGENT_PRUNE_JOB } from "./offline-agent-prune-job";
|
|
2
|
+
import { pruneOrphanedSharedWorkspacesAsync, releaseExpiredDriveLeasesAsync } from "../db/runtime-tail-async";
|
|
3
|
+
import { HISTORY_RETENTION_JOB } from "./history-retention-job";
|
|
1
4
|
import { isHumanAgentId } from "@humwick/sdk";
|
|
2
|
-
import {
|
|
5
|
+
import { REAP_INTERVAL_MS, STALE_TTL_MS } from "../config";
|
|
6
|
+
import { IDLE_EPICS_JOB, PENDING_ISSUE_CLOSE_JOB, PLAN_READY_NOTICE_JOB } from "./long-running-work";
|
|
3
7
|
import { CHECKOUT_REFRESH_JOB } from "./checkout-refresh";
|
|
4
8
|
import { CLAUDE_API_BUDGET_RECONCILE_JOB } from "./claude-api-budget-job";
|
|
5
9
|
import { SERVICE_ACCESS_JOBS } from "./service-access-job";
|
|
@@ -15,27 +19,9 @@ import { deriveAgentBusyHealth } from "../agent-busy-health";
|
|
|
15
19
|
import { expireStaleBusAgents } from "../bus";
|
|
16
20
|
import { eventLoopLagGraceMs } from "../event-loop-lag";
|
|
17
21
|
import { pruneOutboxAsync } from "../bus-outbox-async";
|
|
18
|
-
import {
|
|
22
|
+
import { expireCommandsAsync } from "../db/runtime-admin-async";
|
|
19
23
|
import { getRetentionConfig } from "../retention-config-store";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
createActivityEventAsync,
|
|
23
|
-
evaluatePoolBindingsAsync,
|
|
24
|
-
getAgent,
|
|
25
|
-
listAgents,
|
|
26
|
-
listStaleQueuedDirectTargetsAsync,
|
|
27
|
-
pruneOrphanedSharedWorkspaces,
|
|
28
|
-
pruneOfflineAgentsAsync,
|
|
29
|
-
pruneRetentionBatchAsync,
|
|
30
|
-
pruneProviderQuotaHistoryAsync,
|
|
31
|
-
reapStaleOrchestratorsAsync,
|
|
32
|
-
releaseExpiredClaimsAsync,
|
|
33
|
-
releaseExpiredDriveLeases,
|
|
34
|
-
releaseOrphanedTasksAsync,
|
|
35
|
-
reapStaleAgentsAsync,
|
|
36
|
-
revokeOrphanedRuntimeTokensAsync,
|
|
37
|
-
runDbMaintenanceAsync,
|
|
38
|
-
} from "../db";
|
|
24
|
+
import { createActivityEventAsync, evaluatePoolBindingsAsync, getAgent, listAgents, listStaleQueuedDirectTargetsAsync, pruneRetentionBatchAsync, pruneProviderQuotaHistoryAsync, reapStaleOrchestratorsAsync, releaseExpiredClaimsAsync, releaseOrphanedTasksAsync, reapStaleAgentsAsync, revokeOrphanedRuntimeTokensAsync, runDbMaintenanceAsync } from "../db";
|
|
39
25
|
import { isAgentUnavailable } from "../db/agent-predicates";
|
|
40
26
|
import { resolveTeamCoordinatorAgentId } from "../coordinator-authority";
|
|
41
27
|
import { flushQueuedDirectMessages } from "../services/managed-running";
|
|
@@ -49,7 +35,6 @@ import { getLifecycleManager } from "../lifecycle-manager";
|
|
|
49
35
|
import { applyCommandToRecipe } from "../recipe-runner";
|
|
50
36
|
import { settleWorkspaceCommand } from "../workspace-command-settle";
|
|
51
37
|
import {
|
|
52
|
-
emitAgentRemoved,
|
|
53
38
|
emitAgentStatus,
|
|
54
39
|
emitMessageClaimReleased,
|
|
55
40
|
emitOrchestratorStatus,
|
|
@@ -64,7 +49,6 @@ import { runIdleAgentDigest } from "../services/idle-agent-digest";
|
|
|
64
49
|
import { runShutdownWatchdog } from "../services/shutdown-watchdog";
|
|
65
50
|
import { AGENT_HANG_WATCHDOG_MAINTENANCE_JOB } from "../services/agent-hang-watchdog-job";
|
|
66
51
|
import { reapIdleStewards } from "../services/steward-reaper";
|
|
67
|
-
import { emitWorkFinalityResult } from "../services/work-finality";
|
|
68
52
|
import { escalateExpiredSpawnCommands } from "../services/spawn-loss-escalation";
|
|
69
53
|
import { reapUnregisteredSpawnCommands } from "../services/spawn-registration-watchdog";
|
|
70
54
|
import { resumeRateLimitedAgents } from "../services/rate-limit-resume";
|
|
@@ -182,7 +166,7 @@ export async function runStuckBusyWatchdog(input: { now?: number; signal?: Abort
|
|
|
182
166
|
},
|
|
183
167
|
});
|
|
184
168
|
|
|
185
|
-
const messages = routeNotification({
|
|
169
|
+
const messages = await routeNotification({
|
|
186
170
|
type: "agent.stuck_busy",
|
|
187
171
|
scope: { agentId: agent.id, parent: agent.spawnedBy, teamId: agent.teamId },
|
|
188
172
|
message: {
|
|
@@ -300,9 +284,9 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
300
284
|
runOnStart: true,
|
|
301
285
|
// #1819 — SYNCHRONOUS, one atomic statement, no fan-out: nothing to split, so the pre-flight
|
|
302
286
|
// check is the whole of its cooperation.
|
|
303
|
-
handler(context) {
|
|
287
|
+
async handler(context) {
|
|
304
288
|
if (context.signal?.aborted) return { releasedDriveLeaseAgentIds: [], aborted: true };
|
|
305
|
-
return { releasedDriveLeaseAgentIds:
|
|
289
|
+
return { releasedDriveLeaseAgentIds: (await releaseExpiredDriveLeasesAsync()) };
|
|
306
290
|
},
|
|
307
291
|
},
|
|
308
292
|
{
|
|
@@ -339,7 +323,7 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
339
323
|
// message belongs in the queue (this is hooked to agent availability,
|
|
340
324
|
// not pool-slot reclaim).
|
|
341
325
|
if (!agent || isAgentUnavailable(agent)) continue;
|
|
342
|
-
const flushed = flushQueuedDirectMessages(agent!.id);
|
|
326
|
+
const flushed = await flushQueuedDirectMessages(agent!.id);
|
|
343
327
|
if (flushed.length > 0) reswept[target] = flushed.length;
|
|
344
328
|
}
|
|
345
329
|
return { resweptTargets: reswept };
|
|
@@ -359,19 +343,14 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
359
343
|
// by heartbeat and deleted on removal, so a missing/offline agent record for the
|
|
360
344
|
// target means it will never poll this command again. A merely-busy (online) host is
|
|
361
345
|
// left alone, preserving the #930/#953 "don't sweep before the host can claim it".
|
|
362
|
-
const commands =
|
|
363
|
-
|
|
364
|
-
if (!command.target || command.target === "system") return false;
|
|
365
|
-
const agent = getAgent(command.target);
|
|
366
|
-
return !agent || agent.status === "offline";
|
|
367
|
-
},
|
|
368
|
-
});
|
|
346
|
+
const commands = await expireCommandsAsync();
|
|
347
|
+
|
|
369
348
|
// #1819 — deliberately NOT checkpointed: `expireCommands` already moved these rows terminal
|
|
370
349
|
// and nothing re-runs this settle, so bailing would strand their workspace and recipe forever.
|
|
371
350
|
// Bounded by one expiry sweep.
|
|
372
351
|
for (const command of commands) {
|
|
373
|
-
notifySelfResumeNoOp(command);
|
|
374
|
-
settleContextResetCarry(command);
|
|
352
|
+
await notifySelfResumeNoOp(command);
|
|
353
|
+
(await settleContextResetCarry(command));
|
|
375
354
|
noteCompactionResult(command);
|
|
376
355
|
await settleWorkspaceCommand(command, { onMergeSettled: scheduleRepoMerge });
|
|
377
356
|
await applyCommandToRecipe(command);
|
|
@@ -412,7 +391,7 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
412
391
|
// #1819 — deliberately NOT checkpointed, as in command-expiration: the attachment is already
|
|
413
392
|
// expired, and this is the one place a parent is told its agent died.
|
|
414
393
|
for (const id of expired.agentIds) {
|
|
415
|
-
getLifecycleManager().onAgentDisappeared(id);
|
|
394
|
+
(await getLifecycleManager().onAgentDisappeared(id));
|
|
416
395
|
// #636/#659 — only after the stale reconnect grace expires do we turn a bare
|
|
417
396
|
// heartbeat gap into a terminal parent notification. A live runner that
|
|
418
397
|
// reconnects before this point heals from `stale` without a false exit.
|
|
@@ -420,7 +399,7 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
420
399
|
// when a succeeded agent.shutdown command explains the silence, instead of the
|
|
421
400
|
// heartbeat-lost/transport-loss verdict a graceful reap used to receive.
|
|
422
401
|
const { reason, diagnosis } = classifyBusExpirationDeath(id);
|
|
423
|
-
notifyAgentOffline(id, reason, diagnosis);
|
|
402
|
+
(await notifyAgentOffline(id, reason, diagnosis));
|
|
424
403
|
}
|
|
425
404
|
for (const task of expired.orphanedTasks) emitTaskChanged(task, "task.updated");
|
|
426
405
|
return {
|
|
@@ -464,26 +443,7 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
464
443
|
return { reapedAgentIds };
|
|
465
444
|
},
|
|
466
445
|
},
|
|
467
|
-
|
|
468
|
-
id: "offline-agent-prune",
|
|
469
|
-
critical: false,
|
|
470
|
-
title: "Offline agent prune",
|
|
471
|
-
description: "Delete long-offline provider agents and release their claims.",
|
|
472
|
-
intervalMs: REAP_INTERVAL_MS,
|
|
473
|
-
runOnStart: false,
|
|
474
|
-
async handler(context) {
|
|
475
|
-
if (context.signal?.aborted) return { prunedAgentIds: [], aborted: true };
|
|
476
|
-
// #1084 crash-final-loss fix-forward — defense-in-depth: `notifyAgentOffline` is the primary
|
|
477
|
-
// flush point when an agent first goes offline, so this is normally a no-op by the time an
|
|
478
|
-
// agent reaches prune horizon; the async facade snapshots its held queue and performs the DB
|
|
479
|
-
// finalization in the SAME worker transaction before deleting the agent row.
|
|
480
|
-
const prunedAgentIds = await pruneOfflineAgentsAsync(OFFLINE_PRUNE_MS, {
|
|
481
|
-
onFinality: emitWorkFinalityResult,
|
|
482
|
-
});
|
|
483
|
-
for (const id of prunedAgentIds) emitAgentRemoved(id);
|
|
484
|
-
return { prunedAgentIds };
|
|
485
|
-
},
|
|
486
|
-
},
|
|
446
|
+
OFFLINE_AGENT_PRUNE_JOB,
|
|
487
447
|
AGENT_IDENTITY_ARCHIVE_PRUNE_JOB,
|
|
488
448
|
{
|
|
489
449
|
id: "orphan-token-revoker",
|
|
@@ -498,8 +458,9 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
498
458
|
// event loop was stalled, a live replacement's heartbeats may still be unprocessed, so the
|
|
499
459
|
// grace widens by the observed lag instead of misreading the backlog as post-mortem silence.
|
|
500
460
|
// #1895 (S3.2 L10, review finding 3) — routed through the async gateway facade.
|
|
501
|
-
|
|
502
|
-
|
|
461
|
+
// #3776 — paged short writes, bounded by the abort signal and a time budget.
|
|
462
|
+
const { revoked, complete } = await revokeOrphanedRuntimeTokensAsync(STALE_TTL_MS, eventLoopLagGraceMs(), { signal: context.signal });
|
|
463
|
+
return { revokedOrphanTokens: revoked, moreWork: !complete };
|
|
503
464
|
},
|
|
504
465
|
},
|
|
505
466
|
{
|
|
@@ -509,12 +470,12 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
509
470
|
description: "Stop spawned sessions whose relay agent is offline/gone but whose process the orchestrator still reports running, after a grace period for self-heal.",
|
|
510
471
|
intervalMs: ORPHAN_REAPER_INTERVAL_MS,
|
|
511
472
|
runOnStart: false,
|
|
512
|
-
handler: (context) => reapOrphanedSessions({ signal: context.signal }),
|
|
473
|
+
handler: async (context) => (await reapOrphanedSessions({ signal: context.signal })),
|
|
513
474
|
},
|
|
514
|
-
{ id: "transient-agent-reaper", critical: false, title: "Transient agent reaper", description: "Cleanly shut down transient spawned agents once they are idle and any isolated branch work has landed; also flushes a persistent agent's held work-final report once it has settled idle (#1084 HIGH fix-forward).", intervalMs: REAP_INTERVAL_MS, runOnStart: false, handler: (context) => reapTransientAgents({ signal: context.signal }) },
|
|
475
|
+
{ id: "transient-agent-reaper", critical: false, title: "Transient agent reaper", description: "Cleanly shut down transient spawned agents once they are idle and any isolated branch work has landed; also flushes a persistent agent's held work-final report once it has settled idle (#1084 HIGH fix-forward).", intervalMs: REAP_INTERVAL_MS, runOnStart: false, handler: async (context) => (await reapTransientAgents({ signal: context.signal })) },
|
|
515
476
|
{ id: "idle-agent-digest", critical: false, title: "Idle-agent digest", description: "One digest per coordinator window listing idle children; stops provably safe ones when the team allows it (#3428). Off until the idle-digest setting enables it.", intervalMs: REAP_INTERVAL_MS, runOnStart: false, handler: (context) => runIdleAgentDigest({ signal: context.signal }) },
|
|
516
477
|
{ id: "shutdown-watchdog", critical: false, title: "Shutdown kill-switch watchdog", description: "#1746 — recover a NON-policy agent stuck `shutting-down` past its grace whose shutdown command never executed (owning host offline / command expired): re-issue exactly one forceful shutdown, then surface a terminal `kill-failed` if it is still alive a further grace window later. Policy/steward agents are excluded (the lifecycle-manager owns their retry ladder, #1761).", intervalMs: REAP_INTERVAL_MS, runOnStart: false, handler: (context) => runShutdownWatchdog({ signal: context.signal }) },
|
|
517
|
-
{ id: "steward-reaper", critical: false, title: "Orphan steward reaper", description: "Independent backstop (#1761) for the lifecycle reconcile: reap ORPHANED stewards ONLY — a live steward agent no managed policy state references (left when a respawn overwrote the state's agentId, or handed off after the lifecycle exhausted its forceful stop budget). Reaps an orphan once idle past the dashboard keepalive grace, or immediately when steward spawning is disabled. Never reaps a busy/provider-blocked/mid-land (claim-holding) steward, reaps each orphan at most once (idempotent), and never touches a still-tracked steward — that one is the lifecycle reconcile's (its keepalive idle-timeout, policy-disabled stop, and forceful stopping-wedge escalation), so the two can never race.", intervalMs: REAP_INTERVAL_MS, runOnStart: false, handler: (context) => reapIdleStewards({ signal: context.signal }) },
|
|
478
|
+
{ id: "steward-reaper", critical: false, title: "Orphan steward reaper", description: "Independent backstop (#1761) for the lifecycle reconcile: reap ORPHANED stewards ONLY — a live steward agent no managed policy state references (left when a respawn overwrote the state's agentId, or handed off after the lifecycle exhausted its forceful stop budget). Reaps an orphan once idle past the dashboard keepalive grace, or immediately when steward spawning is disabled. Never reaps a busy/provider-blocked/mid-land (claim-holding) steward, reaps each orphan at most once (idempotent), and never touches a still-tracked steward — that one is the lifecycle reconcile's (its keepalive idle-timeout, policy-disabled stop, and forceful stopping-wedge escalation), so the two can never race.", intervalMs: REAP_INTERVAL_MS, runOnStart: false, handler: async (context) => (await reapIdleStewards({ signal: context.signal })) },
|
|
518
479
|
{
|
|
519
480
|
id: "restart-epoch-reconcile",
|
|
520
481
|
// CRITICAL: if this stops running, an epoch opened by a deploy is never released — every
|
|
@@ -555,7 +516,7 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
555
516
|
description: "Auto-resume agents held on a provider usage/rate-limit stall once their reset window has passed (#286).",
|
|
556
517
|
intervalMs: REAP_INTERVAL_MS,
|
|
557
518
|
runOnStart: false,
|
|
558
|
-
handler: (context) => resumeRateLimitedAgents({ signal: context.signal }),
|
|
519
|
+
handler: async (context) => (await resumeRateLimitedAgents({ signal: context.signal })),
|
|
559
520
|
},
|
|
560
521
|
{ id: "provider-still-held-nudge", critical: false, title: "Provider still-held nudge", description: "Notify a child's parent while it remains provider-blocked, and page the operator once a top-level provider block passes its threshold.", intervalMs: REAP_INTERVAL_MS, runOnStart: false, handler: async (context) => await sendStillHeldNudges(Date.now(), context.signal) },
|
|
561
522
|
{
|
|
@@ -647,6 +608,7 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
647
608
|
prunedMessages: result.prunedMessages,
|
|
648
609
|
prunedActivityEvents: result.prunedActivityEvents,
|
|
649
610
|
prunedSpawnCommands: result.prunedSpawnCommands,
|
|
611
|
+
slimmedSpawnProfiles: result.slimmedSpawnProfiles,
|
|
650
612
|
offThread: result.offThread,
|
|
651
613
|
moreWork: result.moreWork, // #1758 — bounded-progress signal; drives backlogIntervalMs reschedule.
|
|
652
614
|
};
|
|
@@ -661,6 +623,7 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
661
623
|
SNAPSHOT_LEDGER_PRUNE_JOB,
|
|
662
624
|
PROVIDER_SECRET_SCRUB_JOB,
|
|
663
625
|
WEB_TOOL_CALL_PRUNE_JOB,
|
|
626
|
+
HISTORY_RETENTION_JOB,
|
|
664
627
|
CONTINUATION_ARCHIVE_SEARCH_SYNC_JOB,
|
|
665
628
|
SHIPPING_STATS_ROLLUP_JOB,
|
|
666
629
|
REPLY_OBLIGATION_PARITY_JOB,
|
|
@@ -761,9 +724,9 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
761
724
|
intervalMs: REAP_INTERVAL_MS,
|
|
762
725
|
runOnStart: true,
|
|
763
726
|
// #1819 — SYNCHRONOUS, one atomic sweep: pre-flight check only, nothing to split.
|
|
764
|
-
handler(context) {
|
|
727
|
+
async handler(context) {
|
|
765
728
|
if (context.signal?.aborted) return { prunedSharedWorkspaceIds: [], aborted: true };
|
|
766
|
-
const prunedSharedWorkspaceIds =
|
|
729
|
+
const prunedSharedWorkspaceIds = (await pruneOrphanedSharedWorkspacesAsync());
|
|
767
730
|
return { prunedSharedWorkspaceIds };
|
|
768
731
|
},
|
|
769
732
|
},
|
|
@@ -829,7 +792,7 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
829
792
|
intervalMs: WORKSPACE_IDLE_REFRESH_INTERVAL_MS,
|
|
830
793
|
runOnStart: false,
|
|
831
794
|
deadlineMs: 60 * 1000,
|
|
832
|
-
handler: (context) => refreshIdleWorkspaces({ signal: context.signal }),
|
|
795
|
+
handler: async (context) => (await refreshIdleWorkspaces({ signal: context.signal })),
|
|
833
796
|
},
|
|
834
797
|
{
|
|
835
798
|
id: "workspace-gc",
|
|
@@ -843,14 +806,14 @@ export const definitions: MaintenanceJobDefinition[] = [
|
|
|
843
806
|
// otherwise never run it at all — the backstop effectively off exactly when it's needed.
|
|
844
807
|
runOnStart: true,
|
|
845
808
|
deadlineMs: 60 * 1000,
|
|
846
|
-
handler: (context) => workspaceGC({ signal: context.signal }),
|
|
809
|
+
handler: async (context) => (await workspaceGC({ signal: context.signal })),
|
|
847
810
|
},
|
|
848
811
|
{ id: "agent-exit-cleanup", critical: false, title: "Agent exit cleanup",
|
|
849
812
|
description: "Save exited owners on origin, then remove their workspace, branch, outbox and provider home on each host (#2749).",
|
|
850
813
|
intervalMs: 15 * 60_000, runOnStart: true, logRuns: true, deadlineMs: 60_000,
|
|
851
814
|
handler: (context) => requestAgentExitCleanupSweep(context.signal),
|
|
852
815
|
},
|
|
853
|
-
IDLE_EPICS_JOB, PENDING_ISSUE_CLOSE_JOB,
|
|
816
|
+
IDLE_EPICS_JOB, PENDING_ISSUE_CLOSE_JOB, PLAN_READY_NOTICE_JOB,
|
|
854
817
|
REVIEW_REF_RECONCILE_JOB,
|
|
855
818
|
CHECKOUT_REFRESH_JOB,
|
|
856
819
|
ARTIFACT_CHECKOUT_GC_JOB,
|
|
@@ -5,6 +5,8 @@ import { routeNotification } from "../notification-router";
|
|
|
5
5
|
import { DAY_MS } from "./constants";
|
|
6
6
|
import type { MaintenanceJobDefinition } from "./types";
|
|
7
7
|
|
|
8
|
+
export { PLAN_READY_NOTICE_JOB } from "./plan-ready-notice-job";
|
|
9
|
+
|
|
8
10
|
export const PENDING_ISSUE_CLOSE_JOB: MaintenanceJobDefinition = {
|
|
9
11
|
id: "pending-issue-closes", title: "Issues awaiting Task completion", critical: false,
|
|
10
12
|
description: "Close landed delivery issues when their Tasks reach doneWhen and pass validation.",
|
|
@@ -23,7 +25,7 @@ export async function remindIdleEpics(signal: AbortSignal, now = Date.now()): Pr
|
|
|
23
25
|
if (signal.aborted) break;
|
|
24
26
|
const lines = [...renderTeamIdleEpics(team.id), ...teamFailures.map(failure => `- ${failure}`)];
|
|
25
27
|
if (!lines.length) continue;
|
|
26
|
-
routeNotification({
|
|
28
|
+
await routeNotification({
|
|
27
29
|
type: "team.idle", scope: { teamId: team.id }, recipients: [`coordinator:${team.id}`],
|
|
28
30
|
message: { kind: "system", from: "system", subject: "Open idle epics and Plans", body: lines.join("\n"), replyExpected: false,
|
|
29
31
|
payload: { kind: "team.idle-epics", teamId: team.id }, idempotencyKey: `idle-epics:${team.id}:${Math.floor(now / DAY_MS)}` },
|