@humwick/server 0.130.1 → 0.130.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/bundled/prompts/manifest.json +1 -0
- package/bundled/prompts/task.hydration.md +1 -1
- package/bundled/roles/builder.md +1 -1
- package/docs/guides/sub-coordinators.md +12 -5
- package/docs/guides/tools-administration.md +4 -0
- package/docs/guides/tools-coordination.md +2 -0
- package/docs/guides/tools-tasks.md +8 -0
- package/docs/guides/workflows.md +74 -0
- package/docs/openapi.json +486 -4
- package/package.json +10 -18
- package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-Bq9kr21N.js} +2 -2
- package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-Dqiroy06.js} +2 -2
- package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-DYU962-H.js} +2 -2
- package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-DhPfzioE.js} +2 -2
- package/public/assets/{activity-yLztXEBt.js → activity-DzCcQTee.js} +2 -2
- package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-SgDt9i3T.js} +2 -2
- package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
- package/public/assets/{agent-name-CTZBrSD9.js → agent-name-CcY3Aijy.js} +2 -2
- package/public/assets/agent-profiles-cxtRBn6O.js +2 -0
- package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-DGYbIhaI.js} +2 -2
- package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-DHbftV0N.js} +2 -2
- package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-CY113sp-.js} +2 -2
- package/public/assets/{agents-BYDslkJc.js → agents-BPzY7IlQ.js} +2 -2
- package/public/assets/{analytics-B-XSbEMC.js → analytics-DENFPv_a.js} +2 -2
- package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-KRvSc7sl.js} +2 -2
- package/public/assets/{artifacts-DPN1q4pA.js → artifacts-C9gSmL3s.js} +2 -2
- package/public/assets/{artifacts-oBOqks-2.js → artifacts-DT-HkI5O.js} +2 -2
- package/public/assets/{automation-4KcRFXEu.js → automation-BsmjQhKD.js} +2 -2
- package/public/assets/{backlog-Cw9xPTCF.js → backlog-8NYH_62t.js} +2 -2
- package/public/assets/{busy-health-CTu32MZt.js → busy-health-D3hwvYb4.js} +2 -2
- package/public/assets/{channels-BiXzg1G9.js → channels-DCJ5WL7O.js} +2 -2
- package/public/assets/{chat-Ctk2qwvA.js → chat-DAIl357U.js} +3 -3
- package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-CzrZfr9U.js} +2 -2
- package/public/assets/{connectors-C36ax4Vw.js → connectors-xTxtlyou.js} +2 -2
- package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BpebFLK2.js} +2 -2
- package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-BHvI5wXC.js} +2 -2
- package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-DGT0o3wJ.js} +2 -2
- package/public/assets/{deploys-Bwfq146q.js → deploys-hqWOHSHE.js} +2 -2
- package/public/assets/{display-CfO7rTuF.js → display-CDeH4I8T.js} +2 -2
- package/public/assets/{files-DhhZI2Ih.js → files-BTeGVmTg.js} +2 -2
- package/public/assets/{fleet-B_rFEbnL.js → fleet-DgXtNgCa.js} +2 -2
- package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BHEt5yc_.js} +2 -2
- package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-MLtodyPp.js} +3 -3
- package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-CAe664Z8.js} +2 -2
- package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-mapF4Fj9.js} +2 -2
- package/public/assets/index-CqqgOI5R.js +15 -0
- package/public/assets/index-MYAIwYTX.css +2 -0
- package/public/assets/{insights-fH1EL-qZ.js → insights-DNyf7IzF.js} +2 -2
- package/public/assets/{integrations-C5Oix6ng.js → integrations-DlYOHq7T.js} +2 -2
- package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-CeWBNWn7.js} +2 -2
- package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-Cib8nqdE.js} +2 -2
- package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-DSn1cPm7.js} +2 -2
- package/public/assets/{managed-agents-egllbpij.js → managed-agents-C3CkM81m.js} +2 -2
- package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-W4VQQPAv.js} +3 -3
- package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
- package/public/assets/{memory-C8WmXsyr.js → memory-BV17qtO4.js} +2 -2
- package/public/assets/{messages-BzQdqlO6.js → messages-Bm_1AqSA.js} +2 -2
- package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Dg-vfP09.js} +2 -2
- package/public/assets/{overview-DCUnI4Z7.js → overview-DcYCrvlr.js} +2 -2
- package/public/assets/{pairs-ftCd2XcD.js → pairs-8o9nuG3V.js} +2 -2
- package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-BsRyBMea.js} +2 -2
- package/public/assets/project-profile-instructions-DETKFn_E.js +2 -0
- package/public/assets/projects-M_m6AHws.js +2 -0
- package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-C_mNCgeL.js} +2 -2
- package/public/assets/provider-display-BEeLXC_D.js +2 -0
- package/public/assets/{registry-DWCU5c8q.js → registry-DDHHHE5N.js} +2 -2
- package/public/assets/run-card-Dt4I4jaP.js +2 -0
- package/public/assets/scroll-text-BKXS1ahr.js +2 -0
- package/public/assets/{secrets-C7GIUATz.js → secrets-BkVwxI5O.js} +2 -2
- package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-Crq-6a-B.js} +2 -2
- package/public/assets/{settings-C6sZ9eBa.js → settings-CYcavMFu.js} +2 -2
- package/public/assets/shipping-H6gzEeZB.js +2 -0
- package/public/assets/{stats-V9Z-GxUd.js → stats-BJVeWkpV.js} +2 -2
- package/public/assets/{status-dot-CVv0iGHL.js → status-dot-BcHyw1Vw.js} +2 -2
- package/public/assets/store-DKPDIZBe.js +9 -0
- package/public/assets/{tasks-CXU75HRF.js → tasks-qJjlQPpx.js} +2 -2
- package/public/assets/{teams-BPf976zb.js → teams-Cd5Sk1uX.js} +2 -2
- package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-CpY5_m7W.js} +3 -3
- package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
- package/public/assets/token-estimate-Co-Jdphh.js +2 -0
- package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-0yJA_buM.js} +2 -2
- package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-uJXHf34W.js} +2 -2
- package/public/assets/use-project-list-CpWl6eHQ.js +2 -0
- package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BdxBW8mL.js} +2 -2
- package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-3IndfpOc.js} +2 -2
- package/public/assets/versioned-prompt-editor-CIVg7XB1.js +8 -0
- package/public/assets/{work-queue-TCjJxeT-.js → work-queue-B9rnLwHZ.js} +2 -2
- package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-X8wxyhzC.js} +2 -2
- package/public/assets/{workflows-CXQX20Qj.js → workflows-o5YyMFW7.js} +2 -2
- package/public/assets/{workspaces-qSYzKYMA.js → workspaces-CzEGoAng.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +31 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
- package/runner/src/adapters/claude-effort.ts +2 -4
- package/runner/src/adapters/claude-headless.ts +1 -1
- package/runner/src/adapters/claude-launch-exit.ts +26 -0
- package/runner/src/adapters/claude-session-probe.ts +1 -1
- package/runner/src/adapters/claude-tmux.ts +38 -10
- package/runner/src/adapters/claude.ts +28 -75
- package/runner/src/adapters/codex-launch-config.ts +4 -5
- package/runner/src/adapters/codex.ts +1 -1
- package/runner/src/adapters/opencode-provider.ts +7 -22
- package/runner/src/adapters/opencode.ts +4 -4
- package/runner/src/adapters/provider-quota-harvest.ts +20 -71
- package/runner/src/agent-runner/credentials.ts +42 -12
- package/runner/src/agent-runner/inbox.ts +27 -0
- package/runner/src/agent-runner/lifecycle-milestones.ts +2 -4
- package/runner/src/agent-runner/liveness-exchange.ts +104 -0
- package/runner/src/bin/claude.ts +4 -0
- package/runner/src/bin/codex.ts +4 -0
- package/runner/src/bin/opencode.ts +4 -0
- package/runner/src/claude-system-prompt.ts +49 -0
- package/runner/src/index.ts +5 -2
- package/runner/src/launch-assembly.ts +14 -10
- package/runner/src/profile-home.ts +1 -1
- package/runner/src/project-instructions.ts +2 -2
- package/runner/src/provider-command.ts +18 -0
- package/runner/src/provider-setup.ts +35 -0
- package/runner/src/providers.ts +2 -1
- package/runner/src/runner-core.ts +32 -38
- package/runner/src/runner-helpers.ts +0 -8
- package/runner/src/session-scratch.ts +6 -2
- package/runner/src/spawn-input.ts +2 -1
- package/runner/src/test-run-dedup.ts +59 -56
- package/runner/test-support/provisioning-context.ts +4 -2
- package/runner/test-support/runner-harness.ts +2 -1
- package/scripts/cd-config.ts +8 -0
- package/scripts/gate-run-lease.ts +10 -7
- package/scripts/gate.sh +5 -1
- package/scripts/steward-policy-cleanup.ts +2 -2
- package/src/agent-authz.ts +2 -2
- package/src/agent-drive-arbiter.ts +3 -8
- package/src/agent-exit-cleanup-async.ts +2 -2
- package/src/agent-exit-cleanup.ts +23 -19
- package/src/agent-lifecycle-events.ts +112 -85
- package/src/agent-ref.ts +3 -2
- package/src/agent-status-events.ts +43 -14
- package/src/auth/password.ts +4 -3
- package/src/auth/session-refresh.ts +1 -1
- package/src/auth/session.test-fixture.ts +2 -2
- package/src/auth/session.ts +7 -7
- package/src/automations/crud.ts +8 -81
- package/src/automations/dispatch.ts +33 -58
- package/src/automations/index.ts +1 -1
- package/src/automations/persistence.ts +65 -0
- package/src/automations/precheck.ts +18 -16
- package/src/automations/read-async.ts +11 -0
- package/src/automations/reconcile.ts +30 -39
- package/src/automations/storage.ts +33 -10
- package/src/automations/write-async.ts +33 -0
- package/src/branch-land-notice.ts +93 -0
- package/src/branch-landed.ts +31 -98
- package/src/bus.ts +40 -39
- package/src/cd-deploy-notify.ts +32 -4
- package/src/cd-host-lag-notify.ts +7 -6
- package/src/ci/incidents.ts +2 -2
- package/src/ci/monitor.ts +5 -8
- package/src/ci/notifications.ts +4 -4
- package/src/ci/root-missing.ts +4 -9
- package/src/ci/transition-notify.ts +12 -44
- package/src/claude-app/oauth-http.ts +3 -3
- package/src/cli/cd-pauses.ts +19 -0
- package/src/cli/orchestrator.ts +1 -1
- package/src/cli/state.ts +2 -19
- package/src/cli/task-edit.ts +22 -0
- package/src/cli/task.ts +3 -1
- package/src/cli/workflow.ts +19 -4
- package/src/commands-db.ts +7 -7
- package/src/commands-write.ts +8 -0
- package/src/compaction-watch.ts +10 -8
- package/src/config-store-write.ts +13 -1
- package/src/config-store.ts +25 -14
- package/src/config.ts +4 -11
- package/src/connectors.ts +10 -8
- package/src/context-advisory.ts +22 -21
- package/src/db/activity-async.ts +6 -1
- package/src/db/activity-write-ops.ts +12 -1
- package/src/db/activity.ts +1 -14
- package/src/db/agent-action-write.ts +36 -0
- package/src/db/agent-control-async.ts +9 -0
- package/src/db/agent-control-write.ts +49 -0
- package/src/db/agent-effort-observe.ts +22 -0
- package/src/db/agent-meta.ts +14 -3
- package/src/db/agent-search.ts +1 -15
- package/src/db/agents-async.ts +59 -9
- package/src/db/agents-write-ops.ts +12 -3
- package/src/db/agents.ts +95 -65
- package/src/db/auth-identities.ts +2 -2
- package/src/db/automation-read-ops.ts +11 -0
- package/src/db/automation-write-ops.ts +46 -0
- package/src/db/blackboard.ts +2 -2
- package/src/db/browser-session-write.ts +32 -0
- package/src/db/bus-outbox-write-ops.ts +3 -1
- package/src/db/checkout-refresh-schema.ts +47 -0
- package/src/db/checkout-refresh.ts +5 -5
- package/src/db/ci-incidents-async.ts +5 -5
- package/src/db/ci-incidents-write-ops.ts +2 -2
- package/src/db/command-agent-profile-backfill.ts +39 -0
- package/src/db/command-agent-profiles.ts +5 -1
- package/src/db/command-retention.ts +126 -0
- package/src/db/command-row.ts +10 -2
- package/src/db/commands-list-query.ts +2 -0
- package/src/db/commands-planner-stats.test-fixture.ts +8 -0
- package/src/db/commands-read-ops.ts +16 -0
- package/src/db/commands-spawn-read.ts +1 -1
- package/src/db/config-store-write-ops.ts +7 -2
- package/src/db/connection.ts +1 -182
- package/src/db/context-carry-write.ts +74 -0
- package/src/db/continuation-archives-async.ts +5 -0
- package/src/db/continuation-archives-write-ops.ts +7 -0
- package/src/db/continuations.ts +6 -6
- package/src/db/db-error-registry.ts +12 -0
- package/src/db/db-writer-worker.ts +8 -1
- package/src/db/deploy-events-async.ts +1 -0
- package/src/db/deploy-events-read-ops.ts +2 -1
- package/src/db/deploy-events.ts +35 -4
- package/src/db/gateway.ts +26 -133
- package/src/db/history-retention-ops.ts +13 -0
- package/src/db/hosts-registration.ts +10 -2
- package/src/db/hosts.ts +9 -6
- package/src/db/inbox-async.ts +2 -2
- package/src/db/inbox-read-ops.ts +1 -1
- package/src/db/inbox.ts +9 -17
- package/src/db/index.ts +2 -0
- package/src/db/integrations-async.ts +8 -0
- package/src/db/integrations-ops.ts +15 -0
- package/src/db/integrations.ts +15 -21
- package/src/db/issue-associations.ts +2 -2
- package/src/db/issue-lifecycle.ts +3 -4
- package/src/db/issue-refs-async.ts +23 -0
- package/src/db/issue-refs-read-ops.ts +6 -0
- package/src/db/issue-refs-write-ops.ts +29 -0
- package/src/db/issue-refs.ts +15 -16
- package/src/db/kernel-event-log-schema.ts +2 -0
- package/src/db/land-boundaries.ts +51 -5
- package/src/db/land-gate-attestations.ts +2 -2
- package/src/db/landing-receipts.ts +2 -2
- package/src/db/lifecycle-context-write.ts +5 -0
- package/src/db/lifecycle-tail-async.ts +76 -0
- package/src/db/lifecycle-tail-write-ops.ts +62 -0
- package/src/db/lifecycle-write-window.ts +2 -1
- package/src/db/lineage-pair-dedupe-sql.ts +3 -3
- package/src/db/long-running-work.ts +2 -2
- package/src/db/main-connection-mode.ts +11 -0
- package/src/db/main-connection-writes.ts +41 -2
- package/src/db/maintenance-job-reconcile.ts +61 -0
- package/src/db/maintenance-job-runs-async.ts +14 -0
- package/src/db/maintenance-job-write-ops.ts +9 -0
- package/src/db/maintenance-pauses.ts +2 -2
- package/src/db/mappers.ts +2 -14
- package/src/db/merge-lease.ts +1 -15
- package/src/db/message-send.ts +4 -0
- package/src/db/messages.ts +31 -25
- package/src/db/migrations.ts +25 -16
- package/src/db/notification-write-ops.ts +19 -0
- package/src/db/operator-answer-write.ts +19 -0
- package/src/db/orchestrators.ts +14 -76
- package/src/db/pairs-async.ts +22 -1
- package/src/db/pairs-write-ops.ts +8 -3
- package/src/db/pairs.ts +42 -61
- package/src/db/plan-dispatch-schema.ts +5 -1
- package/src/db/plan-ready-notices.ts +43 -0
- package/src/db/plan-tools-include-migration.ts +36 -0
- package/src/db/plans-write-ops.ts +2 -0
- package/src/db/presence-buffer.ts +5 -0
- package/src/db/presence-loop.ts +18 -23
- package/src/db/presence-write.ts +0 -6
- package/src/db/project-entries-async.ts +14 -0
- package/src/db/project-entries-read-ops.ts +5 -1
- package/src/db/project-entries-write-ops.ts +8 -0
- package/src/db/project-entries.ts +15 -12
- package/src/db/project-journal.ts +2 -2
- package/src/db/project-profile-instructions.ts +50 -0
- package/src/db/project-trust-approvals.ts +2 -2
- package/src/db/prompt-templates.ts +4 -4
- package/src/db/prompt-versions.ts +9 -2
- package/src/db/provider-config-history.ts +8 -3
- package/src/db/provider-model-seed.ts +34 -0
- package/src/db/read-op-marshaling-fixtures.ts +23 -0
- package/src/db/read-ops.ts +8 -0
- package/src/db/retention.ts +13 -2
- package/src/db/review-publish-write.ts +8 -0
- package/src/db/routing-policy.ts +2 -3
- package/src/db/runtime-admin-async.ts +19 -0
- package/src/db/runtime-admin-write-ops.ts +36 -0
- package/src/db/runtime-tail-async.ts +288 -0
- package/src/db/runtime-tail-write-ops.ts +97 -0
- package/src/db/schema.ts +13 -4
- package/src/db/spawn-budget.ts +5 -0
- package/src/db/spawn-delegation-state.ts +11 -4
- package/src/db/spawn-delegation.ts +1 -11
- package/src/db/sql-audit-indexes.ts +3 -0
- package/src/db/stats-async.ts +9 -6
- package/src/db/task-entity.ts +28 -6
- package/src/db/task-list.ts +3 -1
- package/src/db/tasks.ts +1 -17
- package/src/db/team-claim-policy.ts +60 -0
- package/src/db/teams-async.ts +4 -0
- package/src/db/teams-write-ops.ts +4 -0
- package/src/db/terminal-events.ts +15 -0
- package/src/db/timer-cutover-bodies.ts +292 -0
- package/src/db/timer-cutover-core.ts +37 -278
- package/src/db/timer-cutover-state.ts +40 -0
- package/src/db/timer-cutover-write-ops.ts +1 -40
- package/src/db/timer-ingress.ts +7 -1
- package/src/db/token-db-write-ops.ts +19 -0
- package/src/db/token-standing-async.ts +12 -0
- package/src/db/token-standing.ts +21 -20
- package/src/db/token-usage-retention.ts +33 -0
- package/src/db/token-usage-write-ops.ts +1 -1
- package/src/db/token-usage.ts +4 -1
- package/src/db/user-invites-async.ts +13 -0
- package/src/db/user-invites.ts +3 -3
- package/src/db/users.ts +14 -6
- package/src/db/workflow-contact.ts +1 -1
- package/src/db/workflow-task-read-ops.ts +30 -0
- package/src/db/workspaces.ts +8 -5
- package/src/db/write-ops.ts +37 -12
- package/src/db/writer-fault-seam.ts +2 -9
- package/src/db/writer-fault-test-ops.ts +18 -0
- package/src/db/writer-gateway.ts +58 -56
- package/src/dev.ts +8 -3
- package/src/dispatch-availability.ts +10 -6
- package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
- package/src/event-loop-lag.ts +4 -2
- package/src/event-loop-yield.ts +2 -2
- package/src/events.ts +10 -8
- package/src/host/disk-alert.ts +121 -0
- package/src/host-provider-store.ts +5 -4
- package/src/hub-metrics-report.ts +5 -1
- package/src/hub-metrics.ts +38 -18
- package/src/injection-sweep-pacing.ts +6 -8
- package/src/land-gate-notifications.ts +11 -10
- package/src/land-gate-queue-progress.ts +3 -3
- package/src/land-settle-dispatch.ts +52 -92
- package/src/lifecycle-context-pressure.ts +11 -10
- package/src/lifecycle-manager.ts +107 -100
- package/src/maintenance/breaker.ts +18 -16
- package/src/maintenance/cd-watcher.ts +3 -3
- package/src/maintenance/checkout-refresh.ts +18 -1
- package/src/maintenance/critical-job-watchdog.ts +19 -20
- package/src/maintenance/events.ts +3 -3
- package/src/maintenance/history-retention-job.ts +30 -0
- package/src/maintenance/index.ts +1 -0
- package/src/maintenance/jobs.ts +32 -69
- package/src/maintenance/long-running-work.ts +3 -1
- package/src/maintenance/offline-agent-prune-job.ts +28 -0
- package/src/maintenance/orphaned-sessions.ts +5 -4
- package/src/maintenance/pauses.ts +4 -10
- package/src/maintenance/plan-ready-notice-job.ts +71 -0
- package/src/maintenance/scheduler.ts +98 -137
- package/src/maintenance/stalled-delivery-pager.ts +10 -9
- package/src/maintenance/teams.ts +19 -30
- package/src/maintenance/workspaces.ts +18 -28
- package/src/managed-policy-escalation.ts +7 -7
- package/src/managed-policy.ts +32 -28
- package/src/managed-provider-gate.ts +5 -4
- package/src/managed-spawn-reservation.ts +5 -4
- package/src/mcp/index.ts +12 -9
- package/src/mcp/output-descriptions.ts +8 -8
- package/src/mcp/presentation.ts +6 -5
- package/src/mcp/project-profile-instructions.ts +32 -0
- package/src/mcp/runtime-output.ts +6 -1
- package/src/mcp/self-care-visibility.ts +2 -2
- package/src/mcp/spawn-targets-matrix.ts +10 -1
- package/src/mcp/tool-groups.ts +4 -3
- package/src/mcp/tool-roles.ts +81 -0
- package/src/mcp/tools-spawn.ts +4 -3
- package/src/mcp/tools-workspace.ts +1 -1
- package/src/mcp-agent-action.ts +1 -2
- package/src/mcp-blackboard-tools.ts +6 -5
- package/src/mcp-decision-tools.ts +7 -7
- package/src/mcp-egress-tools.ts +10 -9
- package/src/mcp-issue-activity-tools.ts +2 -2
- package/src/mcp-issue-association-tools.ts +4 -4
- package/src/mcp-issue-ref-tools.ts +13 -12
- package/src/mcp-maintenance-tools.ts +2 -2
- package/src/mcp-merge-tools.ts +5 -5
- package/src/mcp-notification-subscription-tools.ts +14 -15
- package/src/mcp-output-levels.test-fixture.ts +1 -1
- package/src/mcp-profile-trust-tools.ts +5 -5
- package/src/mcp-project-journal-tools.ts +4 -12
- package/src/mcp-project-tools.ts +17 -18
- package/src/mcp-provider-catalog.ts +2 -2
- package/src/mcp-routing-policy-tools.ts +3 -2
- package/src/mcp-task-tools.ts +11 -5
- package/src/mcp-team-template-tools.ts +3 -3
- package/src/mcp-team-tools.ts +6 -6
- package/src/mcp-workflow-tools.ts +13 -4
- package/src/memory-area-injection.ts +13 -12
- package/src/memory-boundary-capture.ts +6 -6
- package/src/memory-injection.ts +45 -43
- package/src/merge-pause-maintenance.ts +5 -4
- package/src/notification-router.ts +44 -17
- package/src/notification-types.ts +2 -1
- package/src/notify.ts +5 -5
- package/src/observed-reset-refresh.ts +4 -4
- package/src/operator-alarm.ts +23 -11
- package/src/project-ingest.ts +6 -6
- package/src/project-instructions.ts +12 -1
- package/src/project-profile-instruction-text.ts +6 -0
- package/src/project-profile-instructions.ts +20 -0
- package/src/project-trust.ts +12 -11
- package/src/prompt-resolver.ts +3 -3
- package/src/provider-catalog-store.ts +3 -49
- package/src/provider-config-store.ts +12 -11
- package/src/provider-model-seed.ts +1 -18
- package/src/provider-quota-async.ts +5 -7
- package/src/provider-quota-config-store.ts +5 -4
- package/src/provider-secrets.test-fixture.ts +3 -3
- package/src/provider-timeline-event.ts +4 -7
- package/src/quota-band-delivery.ts +2 -2
- package/src/recipe-runner.ts +6 -5
- package/src/repo-config-source.ts +10 -4
- package/src/retention-config-store.ts +4 -3
- package/src/reviewer-pipeline.ts +11 -10
- package/src/routes/_route.ts +4 -4
- package/src/routes/_shared.ts +13 -12
- package/src/routes/agent-effort.ts +5 -5
- package/src/routes/agent-heartbeat-quota.ts +23 -0
- package/src/routes/agent-keep.ts +1 -1
- package/src/routes/agent-profiles.ts +6 -6
- package/src/routes/agent-reporting.ts +1 -1
- package/src/routes/agent-self-effort.ts +5 -5
- package/src/routes/agent-sessions.ts +24 -24
- package/src/routes/agents-spawn.ts +2 -2
- package/src/routes/agents.ts +19 -121
- package/src/routes/auth.ts +14 -15
- package/src/routes/authority-audit.ts +2 -2
- package/src/routes/automations.ts +6 -5
- package/src/routes/channel-binding-delete.ts +1 -1
- package/src/routes/channel-output.ts +3 -3
- package/src/routes/claude-api-budget.ts +5 -5
- package/src/routes/commands-listing.ts +5 -1
- package/src/routes/commands.ts +31 -29
- package/src/routes/context-resets.ts +2 -2
- package/src/routes/continuation-archives.ts +2 -2
- package/src/routes/coordinator-teams.ts +1 -1
- package/src/routes/decisions.ts +2 -2
- package/src/routes/host-secret-files.ts +1 -1
- package/src/routes/hosts.ts +11 -11
- package/src/routes/inbox.ts +3 -2
- package/src/routes/index.ts +12 -2
- package/src/routes/integrations.ts +32 -56
- package/src/routes/issue-activity.ts +2 -2
- package/src/routes/issue-associations.ts +4 -4
- package/src/routes/issue-refs.ts +9 -9
- package/src/routes/kernel-timers-operator.ts +1 -1
- package/src/routes/memory.ts +1 -1
- package/src/routes/merges.ts +11 -11
- package/src/routes/messages.ts +23 -17
- package/src/routes/orchestrator-bootstrap.ts +2 -2
- package/src/routes/orchestrator-host-registration.ts +4 -2
- package/src/routes/orchestrator-host-utilization.ts +5 -3
- package/src/routes/orchestrator-proxy.ts +4 -4
- package/src/routes/orchestrator.ts +28 -19
- package/src/routes/pairs.ts +8 -8
- package/src/routes/project-profile-instructions.ts +27 -0
- package/src/routes/project-trust.ts +3 -3
- package/src/routes/projects.ts +16 -16
- package/src/routes/prompt-templates.ts +12 -12
- package/src/routes/provider-config.ts +6 -6
- package/src/routes/provider-quota-config.ts +2 -2
- package/src/routes/provider-quotas.ts +10 -10
- package/src/routes/run-command.ts +1 -1
- package/src/routes/secrets-backup.ts +2 -2
- package/src/routes/secrets-import.ts +1 -1
- package/src/routes/secrets-vault.ts +7 -7
- package/src/routes/settings.ts +6 -6
- package/src/routes/shipping.ts +9 -1
- package/src/routes/spawn-policy.ts +8 -7
- package/src/routes/sse.ts +2 -2
- package/src/routes/stats.ts +6 -6
- package/src/routes/task-http.ts +15 -1
- package/src/routes/task-issues.ts +11 -26
- package/src/routes/tasks.ts +22 -53
- package/src/routes/team-templates.ts +12 -12
- package/src/routes/teams-config.ts +2 -2
- package/src/routes/teams.ts +10 -10
- package/src/routes/tokens.ts +30 -22
- package/src/routes/users.ts +24 -24
- package/src/routes/viewer-read.ts +3 -3
- package/src/routes/web-tool-calls.ts +4 -4
- package/src/routes/workflows.ts +22 -7
- package/src/routes/workspaces.ts +17 -16
- package/src/routing-policy-normalize.ts +1 -2
- package/src/routing-policy-push.ts +6 -6
- package/src/routing-step-defaults.ts +0 -2
- package/src/runner-token-mint-limit.ts +63 -0
- package/src/runtime-grant.ts +21 -13
- package/src/runtime-tokens.ts +59 -35
- package/src/secrets-broker/config.ts +1 -1
- package/src/secrets-broker/service.ts +2 -2
- package/src/security.ts +16 -21
- package/src/self-resume-carry.ts +21 -110
- package/src/self-resume-supersede.ts +4 -3
- package/src/self-resume.ts +54 -66
- package/src/server-background.ts +2 -2
- package/src/server.ts +26 -24
- package/src/services/agent-action.ts +12 -31
- package/src/services/agent-effort.ts +7 -32
- package/src/services/agent-hang-watchdog-job.ts +2 -2
- package/src/services/agent-heartbeat.ts +166 -0
- package/src/services/agent-reporting.ts +1 -1
- package/src/services/browser-inventory.ts +3 -3
- package/src/services/browser-session-state.ts +3 -2
- package/src/services/browser-session.ts +21 -27
- package/src/services/bus-command-update.ts +9 -9
- package/src/services/checkout-refresh-state.ts +1 -0
- package/src/services/checkout-refresh.test-fixture.ts +3 -2
- package/src/services/command-host.ts +7 -2
- package/src/services/coordinator-digest.ts +3 -2
- package/src/services/dispatch-command.ts +12 -13
- package/src/services/effective-launch-driver.ts +14 -9
- package/src/services/host-changed-paths.test-fixture.ts +5 -6
- package/src/services/host-project-readiness.ts +2 -2
- package/src/services/host-providers.ts +1 -1
- package/src/services/host-utilization.ts +27 -4
- package/src/services/idle-agent-digest.ts +17 -12
- package/src/services/idle-epics.ts +9 -10
- package/src/services/interrupt-agent.ts +12 -9
- package/src/services/issue-activity.ts +3 -3
- package/src/services/issue-associations.ts +15 -18
- package/src/services/issue-lifecycle-comments.ts +3 -2
- package/src/services/issue-lifecycle.ts +69 -72
- package/src/services/issue-refs.ts +10 -15
- package/src/services/kernel-timers-cutover-chaos-worker.ts +11 -8
- package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
- package/src/services/kernel-timers-ingress.ts +4 -4
- package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
- package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
- package/src/services/kernel-timers-outbox.ts +1 -1
- package/src/services/kernel-timers-stage10-operator.ts +1 -1
- package/src/services/kernel-timers.ts +4 -3
- package/src/services/land-gate-placement.ts +11 -2
- package/src/services/land-issue-relations.ts +5 -4
- package/src/services/land-restart-retry.ts +7 -6
- package/src/services/landed-ancestry.ts +25 -8
- package/src/services/legacy-landing-host.ts +4 -1
- package/src/services/legacy-landing-recovery.ts +8 -6
- package/src/services/managed-running.ts +17 -17
- package/src/services/memory-areas.ts +17 -53
- package/src/services/merge-pause.ts +9 -15
- package/src/services/operator-decisions.ts +37 -41
- package/src/services/orchestrator-registration-recovery.ts +6 -2
- package/src/services/orchestrator-upgrade.ts +14 -12
- package/src/services/permission-decision.ts +4 -3
- package/src/services/plan-ci-notice.ts +57 -0
- package/src/services/plan-ci-recovery.ts +2 -55
- package/src/services/plan-conformance.ts +4 -4
- package/src/services/plan-dispatch-policy.ts +10 -3
- package/src/services/plan-dispatch.ts +35 -14
- package/src/services/plan-graph.ts +39 -261
- package/src/services/plan-import.ts +1 -1
- package/src/services/plan-live-bindings.ts +8 -37
- package/src/services/plan-task-create.ts +1 -1
- package/src/services/plan-terminal-refs.ts +2 -12
- package/src/services/plan-wake-digest.ts +9 -3
- package/src/services/profile-trust.ts +6 -5
- package/src/services/project-config-read.ts +70 -0
- package/src/services/project-profile-instructions.ts +54 -0
- package/src/services/project.ts +11 -10
- package/src/services/prompt-templates.ts +6 -5
- package/src/services/provider-hold-nudge.ts +9 -9
- package/src/services/provider-hold-record.ts +13 -12
- package/src/services/provider-state-audit.ts +19 -18
- package/src/services/provisioning-harness/budget-baseline.json +4 -4
- package/src/services/provisioning-harness/driver.ts +1 -1
- package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
- package/src/services/provisioning-harness/lifecycle.ts +24 -22
- package/src/services/provisioning-harness/prepare.ts +16 -17
- package/src/services/rate-limit-resume.ts +10 -9
- package/src/services/red-main-auto-revert.ts +7 -5
- package/src/services/red-main-controller-deps.ts +20 -3
- package/src/services/red-main-incident.ts +3 -1
- package/src/services/red-main-quarantine.ts +2 -3
- package/src/services/register-agent.ts +22 -22
- package/src/services/restart-project-role.ts +1 -1
- package/src/services/restart-spawn.ts +74 -61
- package/src/services/review-publish.ts +7 -24
- package/src/services/review-ref-reconcile.ts +29 -38
- package/src/services/runtime-dependency-alert.ts +27 -0
- package/src/services/scheduler-command.ts +11 -9
- package/src/services/scheduler.ts +5 -5
- package/src/services/self-care-state.ts +2 -1
- package/src/services/self-effort-grant.ts +5 -25
- package/src/services/self-effort.ts +5 -5
- package/src/services/send-message.ts +21 -34
- package/src/services/shutdown-agent.ts +17 -14
- package/src/services/spawn-agent.ts +25 -43
- package/src/services/spawn-chain-inspector.ts +7 -14
- package/src/services/spawn-cwd-placement.ts +21 -5
- package/src/services/spawn-issue-activity.ts +8 -6
- package/src/services/spawn-launch.ts +17 -1
- package/src/services/spawn-loss-escalation.ts +1 -1
- package/src/services/spawn-policy.ts +68 -0
- package/src/services/spawn-registration-watchdog.ts +2 -2
- package/src/services/spawn-repo-probe.ts +7 -5
- package/src/services/spawn-tree-cleanup.ts +8 -9
- package/src/services/steward-reaper.ts +4 -4
- package/src/services/task-context-hydration.ts +25 -1
- package/src/services/task-delivery.ts +20 -34
- package/src/services/task-dispatch.ts +3 -0
- package/src/services/task-entity.ts +40 -203
- package/src/services/task-issue-link.ts +13 -20
- package/src/services/task-issue-weave.ts +12 -11
- package/src/services/task-lifecycle.ts +27 -31
- package/src/services/task-repo-cwd.ts +37 -0
- package/src/services/task-review-hold.ts +4 -17
- package/src/services/task-semantic-events.ts +13 -11
- package/src/services/task-state-reconcile.ts +8 -17
- package/src/services/task-validation.ts +2 -2
- package/src/services/team-templates.ts +12 -11
- package/src/services/team.ts +31 -98
- package/src/services/terminal-provider-exit.ts +6 -5
- package/src/services/timer-message-fire-chaos-worker.ts +7 -3
- package/src/services/timer-message-fire-outbox.ts +1 -1
- package/src/services/transient-agent-reaper.ts +25 -20
- package/src/services/turn-reconcile-audit.ts +9 -9
- package/src/services/user-onboarding.ts +8 -6
- package/src/services/user-profile.ts +6 -9
- package/src/services/work-finality.ts +16 -4
- package/src/services/workflow-auto-start.ts +26 -13
- package/src/services/workflow-caller.ts +61 -4
- package/src/services/workflow-child-proof-worker.ts +1 -1
- package/src/services/workflow-ci-main.ts +1 -1
- package/src/services/workflow-control-proof-worker.ts +1 -1
- package/src/services/workflow-coordinator.ts +8 -2
- package/src/services/workflow-decisions.ts +5 -5
- package/src/services/workflow-deferred-cleanup.ts +5 -3
- package/src/services/workflow-effect-driver.ts +42 -17
- package/src/services/workflow-effects.ts +58 -37
- package/src/services/workflow-land-notice.ts +10 -0
- package/src/services/workflow-pause-text.ts +43 -0
- package/src/services/workflow-pins.ts +7 -4
- package/src/services/workflow-reconcile.ts +14 -11
- package/src/services/workflow-resume-pins.ts +3 -3
- package/src/services/workflow-routing-defaults.ts +18 -0
- package/src/services/workflow-run-view.ts +6 -3
- package/src/services/workflow-run.test-fixture.ts +1 -1
- package/src/services/workflow-runs.ts +61 -33
- package/src/services/workflow-supervisor-state.ts +26 -1
- package/src/services/workflow-supervisor.ts +11 -6
- package/src/services/workspace-recovery.ts +4 -3
- package/src/settings/registry.ts +1 -2
- package/src/spawn-admission.ts +10 -2
- package/src/spawn-command.ts +4 -4
- package/src/spawn-models.ts +10 -12
- package/src/spawn-placement.ts +28 -10
- package/src/spawn-targets.ts +9 -9
- package/src/sse-agent-status.ts +15 -6
- package/src/sse.ts +49 -24
- package/src/startup-context-injection.ts +62 -57
- package/src/state-adoption/cd-cutover.ts +53 -7
- package/src/state-adoption/fleet-cutover.ts +35 -0
- package/src/state-adoption/fleet-plan.ts +36 -0
- package/src/state-adoption/index.ts +2 -2
- package/src/state-adoption/linux-plan.ts +2 -2
- package/src/state-adoption/linux.ts +2 -2
- package/src/state-adoption/macos-plan.ts +2 -2
- package/src/state-adoption/macos.ts +1 -1
- package/src/steward-handoff.ts +4 -3
- package/src/steward-policy-cleanup.ts +9 -8
- package/src/steward.ts +9 -8
- package/src/task-dispatch-live.ts +6 -3
- package/src/task-dispatcher.ts +3 -3
- package/src/teams-config-store.ts +4 -3
- package/src/token-db-write.ts +10 -0
- package/src/token-db.ts +2 -2
- package/src/token-usage-async.ts +2 -4
- package/src/user-awaiting-reply.ts +5 -5
- package/src/workspace-actions.ts +24 -29
- package/src/workspace-auto-merge.ts +14 -12
- package/src/workspace-changed-paths-client.ts +16 -5
- package/src/workspace-cleanup-stale.ts +30 -7
- package/src/workspace-command-settle.ts +26 -17
- package/src/workspace-config.ts +1 -1
- package/src/workspace-conflict-resolver.ts +9 -7
- package/src/workspace-dead-owner-recovery.ts +5 -4
- package/src/workspace-escalation.ts +12 -11
- package/src/workspace-human-escalation.ts +3 -3
- package/src/workspace-land-gate-watchdog.ts +3 -3
- package/src/workspace-land-refusal.ts +20 -0
- package/src/workspace-land-stopped.ts +1 -0
- package/src/workspace-merge.ts +10 -26
- package/src/workspace-nothing-to-land-notice.ts +2 -2
- package/src/workspace-orphans.ts +18 -37
- package/src/workspace-pr-completion.ts +10 -8
- package/src/workspace-rekey.ts +3 -3
- package/src/workspace-steward-failure.ts +2 -2
- package/src/workspace-steward-wake.ts +4 -4
- package/node_modules/@humwick/kernel/LICENSE +0 -167
- package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
- package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
- package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
- package/node_modules/@humwick/kernel/config.ts +0 -111
- package/node_modules/@humwick/kernel/contract.ts +0 -572
- package/node_modules/@humwick/kernel/control-authz.ts +0 -281
- package/node_modules/@humwick/kernel/control.ts +0 -645
- package/node_modules/@humwick/kernel/effects.ts +0 -493
- package/node_modules/@humwick/kernel/event-log.ts +0 -319
- package/node_modules/@humwick/kernel/http-transport.ts +0 -384
- package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
- package/node_modules/@humwick/kernel/identity.ts +0 -248
- package/node_modules/@humwick/kernel/index.ts +0 -28
- package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
- package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
- package/node_modules/@humwick/kernel/landing.ts +0 -953
- package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
- package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
- package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
- package/node_modules/@humwick/kernel/message-authority.ts +0 -281
- package/node_modules/@humwick/kernel/module-host.ts +0 -722
- package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
- package/node_modules/@humwick/kernel/package.json +0 -39
- package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
- package/node_modules/@humwick/kernel/persistence.ts +0 -510
- package/node_modules/@humwick/kernel/registry.ts +0 -60
- package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
- package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
- package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
- package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
- package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
- package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
- package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
- package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
- package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
- package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
- package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
- package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
- package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
- package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
- package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
- package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
- package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
- package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
- package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
- package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
- package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
- package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
- package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
- package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
- package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
- package/node_modules/@humwick/offload/LICENSE +0 -167
- package/node_modules/@humwick/offload/README.md +0 -57
- package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
- package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
- package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
- package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.js +0 -80
- package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
- package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/index.js +0 -5
- package/node_modules/@humwick/offload/dist/index.js.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
- package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
- package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/types.js +0 -176
- package/node_modules/@humwick/offload/dist/types.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
- package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
- package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.js +0 -1
- package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
- package/node_modules/@humwick/offload/package.json +0 -42
- package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
- package/node_modules/@humwick/offload/src/envelope.ts +0 -92
- package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
- package/node_modules/@humwick/offload/src/index.ts +0 -4
- package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
- package/node_modules/@humwick/offload/src/types.ts +0 -235
- package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
- package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
- package/node_modules/@humwick/offload/src/worker.ts +0 -5
- package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
- package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
- package/public/assets/index-B7ZerHLY.css +0 -2
- package/public/assets/index-BU3uWo2t.js +0 -15
- package/public/assets/projects-B_lmcqfO.js +0 -2
- package/public/assets/provider-display-DbLWpP3j.js +0 -2
- package/public/assets/run-card-CO_bguQf.js +0 -2
- package/public/assets/shipping-Bu8p1gEw.js +0 -2
- package/public/assets/store-BvtFdlGX.js +0 -9
- package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
- package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
- package/runner/src/agent-runner/http-liveness.ts +0 -85
- package/runner/src/gate-run-lease-probe.ts +0 -38
- package/src/db/claude-catalog-reconcile.ts +0 -27
- package/src/db/on-loop-write-transaction.ts +0 -34
- package/src/routing-model-aliases.ts +0 -21
package/src/workspace-actions.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { prepareCommandWriteAsync, createCommandAsync, submitPreparedCommandAsync } from "./commands-write";
|
|
2
|
+
import type { ReviewCleanupInput } from "./db/review-publish-write";
|
|
3
|
+
import { getGateway } from "./db/gateway";
|
|
1
4
|
import { recordWorkspaceAudit } from "./workspace-action-audit";
|
|
2
5
|
import { WORKSPACE_MERGE_HOLD_MESSAGE } from "./db/workspace-merge-hold";
|
|
3
6
|
import { stewardGenerationCanceled } from "./db/workspace-steward-fence";
|
|
@@ -14,22 +17,13 @@ import { stringValue } from "@humwick/sdk";
|
|
|
14
17
|
// `requestWorkspaceMerge`, the core does not emit the command event; it returns
|
|
15
18
|
// the Command and the caller emits via its own `emitCommand` (kept module-local).
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
|
|
18
21
|
import { requestWorkspaceRekey } from "./workspace-rekey";
|
|
19
22
|
import { isWorkspaceSteward, workspaceStewardRefusal } from "./workspace-steward-authority";
|
|
20
23
|
import { getStewardConfig } from "./config-store";
|
|
21
24
|
import { cancelPendingLegacyLandingsAsync } from "./commands-landing-async";
|
|
22
25
|
import { workspaceOwnerOrchestrator } from "./workspace-host";
|
|
23
|
-
import {
|
|
24
|
-
getWorkspace,
|
|
25
|
-
claimWorkspaceMetadataAsync,
|
|
26
|
-
listOrchestrators,
|
|
27
|
-
patchWorkspaceMetadataAsync,
|
|
28
|
-
releaseWorkspaceClaimMetadataAsync,
|
|
29
|
-
setWorkspaceMergeHoldAsync,
|
|
30
|
-
transitionWorkspaceLandStateAsync,
|
|
31
|
-
updateWorkspaceStatusAsync,
|
|
32
|
-
} from "./db";
|
|
26
|
+
import { getWorkspace, claimWorkspaceMetadataAsync, listOrchestrators, patchWorkspaceMetadataAsync, releaseWorkspaceClaimMetadataAsync, setWorkspaceMergeHoldAsync, transitionWorkspaceLandStateAsync, updateWorkspaceStatusAsync, REVIEW_HOLD_REJECT_MESSAGE, workspaceLandBarrier } from "./db";
|
|
33
27
|
import { isOwnerAlive, requestWorkspaceMerge } from "./workspace-merge";
|
|
34
28
|
import { buildWorkspaceCleanupCommand } from "./workspace-cleanup-stale";
|
|
35
29
|
// Re-export the land-strategy contract so the MCP land tool validates against the same
|
|
@@ -38,15 +32,13 @@ export { LAND_STRATEGIES } from "./workspace-merge";
|
|
|
38
32
|
import { claimMetadataPatch, workspaceActiveClaim, workspaceStewardHandbackPending } from "./workspace-claim";
|
|
39
33
|
import { DIRTY_WORKTREE_LAND_SKIP_REASON, LAND_IN_FLIGHT_STATUSES, READY_TO_LAND_STATUSES, TERMINAL_WORKSPACE_STATUSES, worktreeReapable } from "./workspace-phase";
|
|
40
34
|
import { LAND_BLOCK_REJECT_MESSAGE, stripReservedWorkspaceMetadataKeys } from "./land-block";
|
|
41
|
-
import { REVIEW_HOLD_REJECT_MESSAGE, workspaceLandBarrier } from "./db";
|
|
42
35
|
import { CLEAR_MERGE_NO_PROGRESS, scheduleRepoMerge } from "./workspace-auto-merge";
|
|
43
36
|
import { archiveLandAttempt, CLEAR_LAST_ATTEMPT_VERDICT, CLEAR_MERGE_RETRY } from "./workspace-merge-progress";
|
|
44
37
|
import { fetchHostMergePreview, refreshWorkspaceGitState } from "./workspace-probe";
|
|
45
38
|
import { recordLandStopped } from "./workspace-land-stopped";
|
|
46
39
|
import { finishWorkspaceStewardHandoff } from "./steward-handoff";
|
|
47
40
|
import { stewardHandoffIdentity } from "./steward-provenance";
|
|
48
|
-
import type { Command, WorkspaceAutoMergePolicy, WorkspaceLandingPolicy, WorkspaceMergeStrategy, WorkspaceRecord, WorkspaceStatus } from "./types";
|
|
49
|
-
import type { WorkspaceLandGateLevel } from "./types";
|
|
41
|
+
import type { Command, WorkspaceAutoMergePolicy, WorkspaceLandingPolicy, WorkspaceMergeStrategy, WorkspaceRecord, WorkspaceStatus, WorkspaceLandGateLevel } from "./types";
|
|
50
42
|
import type { WorkspaceLandGateAuth } from "./workspace-land-gate";
|
|
51
43
|
|
|
52
44
|
// Single source of truth for the action verb set. The route's `optionalEnum` and
|
|
@@ -326,7 +318,7 @@ export async function applyWorkspaceAction(workspace: WorkspaceRecord, input: Ap
|
|
|
326
318
|
return { ok: false, httpStatus: 422, error: `workspace ${workspace.id} has no isolated worktree to refresh` };
|
|
327
319
|
}
|
|
328
320
|
const checkOnly = input.checkOnly === true;
|
|
329
|
-
const built = buildWorkspaceDepsRefreshCommand(workspace, agentId ?? "agent", checkOnly);
|
|
321
|
+
const built = (await buildWorkspaceDepsRefreshCommand(workspace, agentId ?? "agent", checkOnly));
|
|
330
322
|
if (!built.ok) return { ok: false, httpStatus: built.status, error: built.error };
|
|
331
323
|
await recordWorkspaceAudit({
|
|
332
324
|
action,
|
|
@@ -416,11 +408,11 @@ export async function applyWorkspaceAction(workspace: WorkspaceRecord, input: Ap
|
|
|
416
408
|
error: `workspace ${workspace.id} cannot be cleaned up safely: ${safety.error}; pass force:true with a detail reason only if intentionally discarding work`,
|
|
417
409
|
};
|
|
418
410
|
}
|
|
419
|
-
const built = buildWorkspaceCleanupCommand(workspace, agentId ?? "dashboard", {
|
|
411
|
+
const built = (await buildWorkspaceCleanupCommand(workspace, agentId ?? "dashboard", {
|
|
420
412
|
force: input.force === true,
|
|
421
413
|
reason: detail,
|
|
422
414
|
autoReclaim: input.autoReclaim,
|
|
423
|
-
});
|
|
415
|
+
}));
|
|
424
416
|
if (!built.ok) return { ok: false, httpStatus: built.status, error: built.error };
|
|
425
417
|
command = built.command;
|
|
426
418
|
}
|
|
@@ -496,17 +488,17 @@ export async function applyWorkspaceAction(workspace: WorkspaceRecord, input: Ap
|
|
|
496
488
|
// captured delivered `sha`. #1452 round-5 H4: the relay deliberately does NOT derive or return a
|
|
497
489
|
// ref — the AUTHORITATIVE ref is whatever the HOST reports back on the command result (the host may
|
|
498
490
|
// run a different sanitizer version), and the ledger records it only after that settlement.
|
|
499
|
-
export function buildWorkspacePublishReviewCommand(
|
|
491
|
+
export async function buildWorkspacePublishReviewCommand(
|
|
500
492
|
workspace: WorkspaceRecord,
|
|
501
493
|
requestedBy: string,
|
|
502
|
-
opts: { taskId?: number; sha?: string; reviewRef?: string } = {},
|
|
503
|
-
): { ok: true; command: Command } | { ok: false; status: number; error: string } {
|
|
494
|
+
opts: { taskId?: number; sha?: string; reviewRef?: string; cleanup?: ReviewCleanupInput } = {},
|
|
495
|
+
): Promise<{ ok: true; command: Command } | { ok: false; status: number; error: string }> {
|
|
504
496
|
if (workspace.mode !== "isolated" || !workspace.worktreePath) {
|
|
505
497
|
return { ok: false, status: 422, error: `workspace ${workspace.id} has no worktree to publish for review` };
|
|
506
498
|
}
|
|
507
499
|
const owner = workspaceOwnerOrchestrator(workspace, listOrchestrators(), { onlineOnly: false });
|
|
508
500
|
if (!owner) return { ok: false, status: 409, error: "no orchestrator owns this workspace path" };
|
|
509
|
-
const
|
|
501
|
+
const prepared = await prepareCommandWriteAsync({
|
|
510
502
|
type: "workspace.publish-review",
|
|
511
503
|
source: "system",
|
|
512
504
|
target: owner.agentId,
|
|
@@ -527,6 +519,9 @@ export function buildWorkspacePublishReviewCommand(
|
|
|
527
519
|
queued: owner.status !== "online",
|
|
528
520
|
},
|
|
529
521
|
});
|
|
522
|
+
const command = opts.cleanup
|
|
523
|
+
? await getGateway().write("commands.createReviewPublish", { command: prepared, cleanup: opts.cleanup }) as unknown as Command
|
|
524
|
+
: await submitPreparedCommandAsync(prepared);
|
|
530
525
|
return { ok: true, command };
|
|
531
526
|
}
|
|
532
527
|
|
|
@@ -537,10 +532,10 @@ export function buildWorkspacePublishReviewCommand(
|
|
|
537
532
|
// caller passes the EXACT host-confirmed `ref` from the ledger and the host deletes THAT ref verbatim
|
|
538
533
|
// (after asserting it is under refs/review/*) — it no longer re-derives the target from branch/
|
|
539
534
|
// workspaceId, which could diverge across a relay/host sanitizer skew and leak the real ref.
|
|
540
|
-
export function buildReviewRefUnpublishCommandFromFields(
|
|
535
|
+
export async function buildReviewRefUnpublishCommandFromFields(
|
|
541
536
|
fields: { workspaceId: string; repoRoot: string; worktreePath?: string; branch?: string; orchestratorId?: string; ref?: string },
|
|
542
537
|
requestedBy: string,
|
|
543
|
-
): { ok: true; command: Command } | { ok: false; status: number; error: string } {
|
|
538
|
+
): Promise<{ ok: true; command: Command } | { ok: false; status: number; error: string }> {
|
|
544
539
|
const synthetic = {
|
|
545
540
|
orchestratorId: fields.orchestratorId,
|
|
546
541
|
sourceCwd: fields.repoRoot,
|
|
@@ -550,7 +545,7 @@ export function buildReviewRefUnpublishCommandFromFields(
|
|
|
550
545
|
} as unknown as WorkspaceRecord;
|
|
551
546
|
const owner = workspaceOwnerOrchestrator(synthetic, listOrchestrators(), { onlineOnly: false });
|
|
552
547
|
if (!owner) return { ok: false, status: 409, error: "no orchestrator owns this repo path" };
|
|
553
|
-
const command =
|
|
548
|
+
const command = (await createCommandAsync({
|
|
554
549
|
type: "workspace.unpublish-review",
|
|
555
550
|
source: "system",
|
|
556
551
|
target: owner.agentId,
|
|
@@ -566,20 +561,20 @@ export function buildReviewRefUnpublishCommandFromFields(
|
|
|
566
561
|
requestedAt: Date.now(),
|
|
567
562
|
queued: owner.status !== "online",
|
|
568
563
|
},
|
|
569
|
-
});
|
|
564
|
+
}));
|
|
570
565
|
return { ok: true, command };
|
|
571
566
|
}
|
|
572
567
|
|
|
573
568
|
// Build a `workspace.deps-refresh` command for a worktree's owning orchestrator
|
|
574
569
|
// (issue #51). checkOnly just reports staleness. Same owner-resolution as cleanup.
|
|
575
|
-
function buildWorkspaceDepsRefreshCommand(
|
|
570
|
+
async function buildWorkspaceDepsRefreshCommand(
|
|
576
571
|
workspace: WorkspaceRecord,
|
|
577
572
|
requestedBy: string,
|
|
578
573
|
checkOnly: boolean,
|
|
579
|
-
): { ok: true; command: Command } | { ok: false; status: number; error: string } {
|
|
574
|
+
): Promise<{ ok: true; command: Command } | { ok: false; status: number; error: string }> {
|
|
580
575
|
const owner = workspaceOwnerOrchestrator(workspace, listOrchestrators(), { onlineOnly: false });
|
|
581
576
|
if (!owner) return { ok: false, status: 409, error: "no online orchestrator owns this workspace path" };
|
|
582
|
-
const command =
|
|
577
|
+
const command = (await createCommandAsync({
|
|
583
578
|
type: "workspace.deps-refresh",
|
|
584
579
|
source: "system",
|
|
585
580
|
target: owner.agentId,
|
|
@@ -594,7 +589,7 @@ function buildWorkspaceDepsRefreshCommand(
|
|
|
594
589
|
requestedAt: Date.now(),
|
|
595
590
|
queued: owner.status !== "online",
|
|
596
591
|
},
|
|
597
|
-
});
|
|
592
|
+
}));
|
|
598
593
|
return { ok: true, command };
|
|
599
594
|
}
|
|
600
595
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { workspaceLandRefused } from "./workspace-land-refusal";
|
|
2
|
+
import { refreshPendingLandQueueLeaseAsync } from "./db/runtime-tail-async";
|
|
1
3
|
// Event-driven workspace merge-back engine (#237).
|
|
2
4
|
//
|
|
3
5
|
// The branch merge-back used to be driven entirely by a 2-min maintenance poll, so an
|
|
@@ -30,8 +32,8 @@ import {
|
|
|
30
32
|
patchWorkspaceMetadataAsync,
|
|
31
33
|
updateWorkspaceStatus,
|
|
32
34
|
workspaceLandBarrier, updateWorkspaceStatusAsync} from "./db";
|
|
33
|
-
import {
|
|
34
|
-
|
|
35
|
+
import { findLatestCommandByCorrelationAsync } from "./commands-write";
|
|
36
|
+
|
|
35
37
|
import { notifyBranchLandFailed } from "./branch-landed";
|
|
36
38
|
import { resolveStewardIdentity } from "./steward-identity";
|
|
37
39
|
import { emitCommandEvent } from "./command-events";
|
|
@@ -144,14 +146,14 @@ async function escalateNoProgressMerge(ws: WorkspaceRecord, _tip?: string): Prom
|
|
|
144
146
|
const payload = { kind: "workspace.auto-merge-stuck", workspaceId: ws.id, repoRoot: ws.repoRoot, branch: ws.branch, baseRef: ws.baseRef, attempts: MAX_NO_PROGRESS_MERGE_ATTEMPTS, reason: mergeError };
|
|
145
147
|
let escalated = false;
|
|
146
148
|
if (recipients.length) {
|
|
147
|
-
notifyBranchLandFailed({ workspace: ws,
|
|
149
|
+
await notifyBranchLandFailed({ workspace: ws,
|
|
148
150
|
commandId: typeof meta.mergeCommandId === "string" ? meta.mergeCommandId : undefined,
|
|
149
151
|
recipients,
|
|
150
152
|
reason: `auto-merge backed off after ${MAX_NO_PROGRESS_MERGE_ATTEMPTS} no-progress attempts (${mergeError})`,
|
|
151
153
|
});
|
|
152
154
|
escalated = true;
|
|
153
155
|
} else {
|
|
154
|
-
const human = notifyWorkspaceHumanEscalation({ subject, body, payload, source: "workspace-auto-merge" });
|
|
156
|
+
const human = (await notifyWorkspaceHumanEscalation({ subject, body, payload, source: "workspace-auto-merge" }));
|
|
155
157
|
escalated = human.accepted;
|
|
156
158
|
if (!human.accepted) {
|
|
157
159
|
console.warn(`[workspace-auto-merge] no-progress escalation for ${ws.id} had zero agent recipients and no human channel: ${human.reason ?? "unknown reason"}`);
|
|
@@ -180,7 +182,7 @@ async function notifyProtectedTipRestore(ws: WorkspaceRecord, preview: Workspace
|
|
|
180
182
|
// whose delivered tip was discarded CANNOT reach landed-on-main by any land path until the carry is
|
|
181
183
|
// explicitly confirmed. Returns ok=false if it could NOT durably record the obligation — the caller
|
|
182
184
|
// fails closed on that (withholds the steward hand-off) rather than risk a silent divergent land.
|
|
183
|
-
const carry = markWorkspaceTasksCarryPending(ws, discardedHead);
|
|
185
|
+
const carry = await markWorkspaceTasksCarryPending(ws, discardedHead);
|
|
184
186
|
const body = `Workspace \`${ws.branch ?? ws.id}\` restored protected tip \`${preview.protectedTip?.slice(0, 12) ?? "unknown"}\`; discarded HEAD \`${discardedHead.slice(0, 12)}\` was preserved at \`${discardedRef}\`.`;
|
|
185
187
|
await createActivityEventAsync({
|
|
186
188
|
clientId: `workspace-protected-tip-restore-${ws.id}-${Date.now()}`,
|
|
@@ -198,7 +200,7 @@ async function notifyProtectedTipRestore(ws: WorkspaceRecord, preview: Workspace
|
|
|
198
200
|
const { coordinatorAgentId } = resolveStewardIdentity(current);
|
|
199
201
|
const recipients = [...new Set([coordinatorAgentId, current.ownerAgentId].filter((r): r is string => Boolean(r)))];
|
|
200
202
|
if (recipients.length) {
|
|
201
|
-
routeNotification({
|
|
203
|
+
await routeNotification({
|
|
202
204
|
type: "workspace.land_gate_warning",
|
|
203
205
|
scope: { workspaceId: current.id, repoRoot: current.repoRoot, author: current.ownerAgentId, parent: coordinatorAgentId ?? undefined },
|
|
204
206
|
recipients,
|
|
@@ -492,7 +494,7 @@ async function landCandidates(
|
|
|
492
494
|
}
|
|
493
495
|
}
|
|
494
496
|
if (p.conflict === true || protectedTipRestored) {
|
|
495
|
-
emitWorkspaceTaskSemanticNotifications({
|
|
497
|
+
await emitWorkspaceTaskSemanticNotifications({
|
|
496
498
|
workspace: ws,
|
|
497
499
|
transition: "land-conflict",
|
|
498
500
|
actor: "workspace-auto-merge",
|
|
@@ -616,7 +618,7 @@ function landableWorkspaces(repoRoot?: string, baseRef?: string): WorkspaceRecor
|
|
|
616
618
|
// `review_requested` with NO authorization; after the coordinator's clear the flag is off
|
|
617
619
|
// and the promoted delivery lands normally). Covers all three sweep triggers (event,
|
|
618
620
|
// backstop, watchdog) and the conflict→steward hand-off at this single selection filter.
|
|
619
|
-
&& !workspaceLandBarrier(ws).blocked
|
|
621
|
+
&& !workspaceLandBarrier(ws).blocked && !workspaceLandRefused(ws)
|
|
620
622
|
// #1473 — nor is a workspace bound to a deliverable Task that has NOT authorized a land: a pushed
|
|
621
623
|
// `agent/*` branch in a ready-to-land status is not, by itself, a land authorization (a "HOLD" is
|
|
622
624
|
// coordinator convention only). Excluding it here keeps it out of BOTH the auto-land dispatch and
|
|
@@ -761,9 +763,9 @@ function commandIsTerminal(command: Command | null): boolean {
|
|
|
761
763
|
return Boolean(command && TERMINAL_COMMAND_STATUSES.has(command.status));
|
|
762
764
|
}
|
|
763
765
|
|
|
764
|
-
function latestWorkspaceCommand(ws: WorkspaceRecord): Command | null {
|
|
766
|
+
async function latestWorkspaceCommand(ws: WorkspaceRecord): Promise<Command | null> {
|
|
765
767
|
const type = LAND_IN_FLIGHT_STATUSES.has(ws.status) ? "workspace.merge" : "workspace.cleanup";
|
|
766
|
-
return
|
|
768
|
+
return findLatestCommandByCorrelationAsync(type, ws.id);
|
|
767
769
|
}
|
|
768
770
|
|
|
769
771
|
async function recoverAgedInFlightWorkspaces(now: number, signal?: AbortSignal): Promise<Record<string, unknown>> {
|
|
@@ -803,9 +805,9 @@ async function recoverAgedInFlightWorkspaces(now: number, signal?: AbortSignal):
|
|
|
803
805
|
// young merge_planned row the 20-min age gate would otherwise skip. Only a merge_planned row can be
|
|
804
806
|
// executor-orphaned, so a young cleanup_requested/non-merge row still pays NO command lookup (the
|
|
805
807
|
// pre-#2094 cost) — fetch only when the row is old enough for the existing recovery OR could be an orphan.
|
|
806
|
-
let command = (LAND_IN_FLIGHT_STATUSES.has(ws.status) || oldEnough(ws)) ? latestWorkspaceCommand(ws) : null;
|
|
808
|
+
let command = (LAND_IN_FLIGHT_STATUSES.has(ws.status) || oldEnough(ws)) ? await latestWorkspaceCommand(ws) : null;
|
|
807
809
|
if (command?.status === "pending" && command.type === "workspace.merge") {
|
|
808
|
-
if (
|
|
810
|
+
if ((await refreshPendingLandQueueLeaseAsync(command.id, now))) {
|
|
809
811
|
stillActive.push(ws.id);
|
|
810
812
|
continue;
|
|
811
813
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ChangedPathDiff } from "@humwick/sdk";
|
|
2
2
|
import { decideDiffGate, type DiffGateDecision } from "./services/diff-gate";
|
|
3
3
|
import { fetchOwningHostJson } from "./workspace-host-client";
|
|
4
|
+
import { workspaceHeadAlreadyOnBase } from "./services/task-nothing-to-land";
|
|
4
5
|
import type { WorkspaceRecord } from "./types";
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -87,11 +88,21 @@ export async function resolveDeliveryDiffDecision(
|
|
|
87
88
|
...(reprobe.ok ? { headSha: reprobe.headSha } : {}),
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
|
-
return
|
|
91
|
+
return await classify(workspace, reprobe);
|
|
91
92
|
}
|
|
93
|
+
return await classify(workspace, probe);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** A head the owning host proves is already on the freshly fetched base lands nothing, so no
|
|
97
|
+
* gate can protect anything: accept it without one (#3214). Probed only on the would-gate path. */
|
|
98
|
+
async function classify(workspace: WorkspaceRecord, probe: ChangedPathDiff): Promise<DeliveryDiffEvidence> {
|
|
92
99
|
const decision = decideDiffGate(probe);
|
|
93
|
-
return {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
if (!probe.ok || !probe.headSha) return { decision };
|
|
101
|
+
if (decision.requireGates && await workspaceHeadAlreadyOnBase(workspace, probe.headSha)) {
|
|
102
|
+
return {
|
|
103
|
+
decision: { requireGates: false, reason: `delivered head ${probe.headSha.slice(0, 12)} is already on ${workspace.baseRef ?? "main"}: nothing lands`, paths: probe.paths },
|
|
104
|
+
headSha: probe.headSha,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return { decision, headSha: probe.headSha };
|
|
97
108
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createCommandAsync } from "./commands-write";
|
|
1
2
|
// Cleanup-stale workspace reconciliation: builds the `workspace.cleanup` command and runs the
|
|
2
3
|
// `workspace cleanup-stale --check/--execute` sweep (#208/#965/#1066). Kept as a standalone leaf
|
|
3
4
|
// module (no workspace-auto-merge.ts dependency) so the transient-agent reap lifecycle (#1477)
|
|
@@ -7,7 +8,7 @@
|
|
|
7
8
|
|
|
8
9
|
import { statSync } from "node:fs";
|
|
9
10
|
import { emitCommandEvent } from "./command-events";
|
|
10
|
-
|
|
11
|
+
|
|
11
12
|
import { getAgent, listWorkspaces, updateWorkspaceStatusAsync } from "./db";
|
|
12
13
|
import { fetchWorkspaceGitState } from "./workspace-git-state-client";
|
|
13
14
|
import { workspaceOwnerOrchestrator } from "./workspace-host";
|
|
@@ -15,15 +16,15 @@ import { workspaceActiveClaim } from "./workspace-claim";
|
|
|
15
16
|
import { isOwnerAlive, isOwnerProcessConfirmedGone, liveAgentCwds, worktreeInUseByLiveAgent } from "./workspace-merge";
|
|
16
17
|
import { refResolvesInRepo, verifyLandedOrEquivalentContent } from "./services/landed-ancestry";
|
|
17
18
|
import { TERMINAL_WORKSPACE_STATUSES } from "./workspace-phase";
|
|
18
|
-
import type { Command, WorkspaceRecord } from "./types";
|
|
19
|
+
import type { Command, WorkspaceRecord, WorkspaceOrphan } from "./types";
|
|
19
20
|
|
|
20
21
|
// Build a `workspace.cleanup` command for the worktree's owning orchestrator.
|
|
21
22
|
// Moved here (from routes.ts) so the MCP surface reaches it without importing routes.
|
|
22
|
-
export function buildWorkspaceCleanupCommand(
|
|
23
|
+
export async function buildWorkspaceCleanupCommand(
|
|
23
24
|
workspace: WorkspaceRecord,
|
|
24
25
|
requestedBy: string,
|
|
25
26
|
opts: { force?: boolean; reason?: string; autoReclaim?: "origin-captured" } = {},
|
|
26
|
-
): { ok: true; command: Command } | { ok: false; status: number; error: string } {
|
|
27
|
+
): Promise<{ ok: true; command: Command } | { ok: false; status: number; error: string }> {
|
|
27
28
|
if (
|
|
28
29
|
opts.force !== true &&
|
|
29
30
|
workspace.mode === "isolated" &&
|
|
@@ -38,7 +39,7 @@ export function buildWorkspaceCleanupCommand(
|
|
|
38
39
|
}
|
|
39
40
|
const owner = workspaceOwnerOrchestrator(workspace);
|
|
40
41
|
if (!owner) return { ok: false, status: 409, error: "no online orchestrator owns this workspace path; retry when the host is online or use DELETE /api/workspaces/:id to purge the record" };
|
|
41
|
-
const command =
|
|
42
|
+
const command = (await createCommandAsync({
|
|
42
43
|
type: "workspace.cleanup",
|
|
43
44
|
source: "system",
|
|
44
45
|
target: owner.agentId,
|
|
@@ -58,7 +59,7 @@ export function buildWorkspaceCleanupCommand(
|
|
|
58
59
|
...(opts.autoReclaim === "origin-captured" ? { autoReclaim: "origin-captured" } : {}),
|
|
59
60
|
queued: false,
|
|
60
61
|
},
|
|
61
|
-
});
|
|
62
|
+
}));
|
|
62
63
|
return { ok: true, command };
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -190,7 +191,7 @@ export async function cleanupStaleWorkspaces(opts: CleanupStaleWorkspacesOptions
|
|
|
190
191
|
} else {
|
|
191
192
|
// Owner re-confirmed offline just above; force past buildWorkspaceCleanupCommand's
|
|
192
193
|
// live-owner guard and carry a reason so the host records an intentional force-discard.
|
|
193
|
-
const built = buildWorkspaceCleanupCommand(ws, "cleanup-stale", forced ? { force: true, reason: "operator force-discard: abandoned branch, owner offline" } : {});
|
|
194
|
+
const built = (await buildWorkspaceCleanupCommand(ws, "cleanup-stale", forced ? { force: true, reason: "operator force-discard: abandoned branch, owner offline" } : {}));
|
|
194
195
|
if (built.ok) {
|
|
195
196
|
await updateWorkspaceStatusAsync(ws.id, "cleanup_requested", { lastWorkspaceAction: "cleanup-stale", lastWorkspaceActionAt: Date.now(), cleanupProof: { ...proof, forced } });
|
|
196
197
|
emitCommandEvent(built.command, "command.requested");
|
|
@@ -229,3 +230,25 @@ export async function cleanupStaleWorkspaces(opts: CleanupStaleWorkspacesOptions
|
|
|
229
230
|
}
|
|
230
231
|
return { dryRun, landedOnly, force, repoRoot, ...(workspaceId ? { workspaceId } : {}), ...(workspaceIds ? { workspaceIds } : {}), scanned: candidates.length, eligible: rows.filter((r) => r.discardable).length, cleaned, candidates: rows };
|
|
231
232
|
}
|
|
233
|
+
|
|
234
|
+
export async function dispatchOrphanCleanup(targetAgentId: string, orphan: WorkspaceOrphan): Promise<string> {
|
|
235
|
+
const command = (await createCommandAsync({
|
|
236
|
+
type: "workspace.cleanup",
|
|
237
|
+
source: "system",
|
|
238
|
+
target: targetAgentId,
|
|
239
|
+
params: {
|
|
240
|
+
action: "cleanup",
|
|
241
|
+
worktreePath: orphan.worktreePath,
|
|
242
|
+
repoRoot: orphan.repoRoot,
|
|
243
|
+
branch: orphan.branch,
|
|
244
|
+
baseRef: orphan.baseRef,
|
|
245
|
+
baseSha: orphan.baseSha,
|
|
246
|
+
deleteBranch: true,
|
|
247
|
+
reclaim: true,
|
|
248
|
+
requestedBy: "workspace-orphan-reaper",
|
|
249
|
+
requestedAt: Date.now(),
|
|
250
|
+
},
|
|
251
|
+
}));
|
|
252
|
+
emitCommandEvent(command, `command.${command.status}`);
|
|
253
|
+
return command.id;
|
|
254
|
+
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { DELEGATED_LAND_REFUSAL_CODE } from "@humwick/sdk/worktree-config";
|
|
2
|
+
import { refuseWorkspaceLand } from "./workspace-land-refusal";
|
|
3
|
+
import { releaseMergeLeaseAsync, insertLandGateAttestationAsync } from "./db/runtime-tail-async";
|
|
1
4
|
import { commandFailureReason, settleWorkspaceCleanupCommand, type WorkspaceCommandSettleResult } from "./workspace-cleanup-settle";
|
|
2
5
|
export { type WorkspaceCommandSettleResult } from "./workspace-cleanup-settle";
|
|
3
6
|
import { fireAndForget, isRecord, sanitizeFsName, stringValue, type LandGateAttestation, type LandGateRunResult } from "@humwick/sdk";
|
|
4
7
|
import { storeTextArtifact } from "./artifact-text";
|
|
5
8
|
import { announceBranchLanded, notifyBaseWorktreeStrand, notifyBranchLandFailed, notifyLandGateFailed, notifyLandGateSkipped, notifyLandGateWarnings, recordLandingReceipt } from "./branch-landed";
|
|
6
|
-
import { getWorkspace, getArtifactAsync,
|
|
9
|
+
import { getWorkspace, getArtifactAsync, listOrchestrators, markWorkspaceLanded, patchWorkspaceMetadataAsync, setWorkspaceBranchAsync, updateWorkspaceStatusAsync, markWorkspaceLandedAsync } from "./db";
|
|
7
10
|
import { parseOwnerRepoFromRemote, repoFromGitRemote } from "./services/git-remote";
|
|
8
11
|
import { deferLandSettleSideEffect } from "./land-settle-dispatch";
|
|
9
12
|
import { recordConfirmedLandBoundary } from "./services/land-boundary-settle";
|
|
@@ -205,7 +208,7 @@ export async function settleWorkspaceMergeCommand(command: Command, opts: Worksp
|
|
|
205
208
|
command = proven;
|
|
206
209
|
}
|
|
207
210
|
const terminalSettled = WORKSPACE_MERGE_SETTLED_STATUSES.has(command.status);
|
|
208
|
-
if (terminalSettled && command.landingContainmentMode === "legacy-unfenced-v0")
|
|
211
|
+
if (terminalSettled && command.landingContainmentMode === "legacy-unfenced-v0") (await releaseMergeLeaseAsync({ commandId: command.id }));
|
|
209
212
|
const settledRepoRoot = typeof command.params.repoRoot === "string" ? command.params.repoRoot : undefined;
|
|
210
213
|
const settledBaseRef = typeof command.params.baseRef === "string" ? command.params.baseRef : undefined;
|
|
211
214
|
let transitionCompleted = false;
|
|
@@ -280,7 +283,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
280
283
|
// genuine-but-unverifiable land on its next pass instead of it being stranded as falsely-landed.
|
|
281
284
|
const landTargetRef = landedWorkspace?.baseRef ?? "main";
|
|
282
285
|
const landAncestry = mergeResult.merged === true && !prLanded && landedCommitCount !== 0 && landedWorkspace
|
|
283
|
-
? await verifyWorkspaceLandedAncestry(landedWorkspace.repoRoot, authoritativeLandedSha, landTargetRef
|
|
286
|
+
? await verifyWorkspaceLandedAncestry(landedWorkspace.repoRoot, authoritativeLandedSha, landTargetRef.startsWith("origin/") ? landTargetRef : `origin/${landTargetRef}`, cleanString(mergeResult.landVerifiedSha, "result.landVerifiedSha", { max: 64 }))
|
|
284
287
|
: "confirmed";
|
|
285
288
|
const ancestryUnconfirmed = landAncestry !== "confirmed";
|
|
286
289
|
const normalizedStatus = ancestryUnconfirmed
|
|
@@ -360,13 +363,13 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
360
363
|
if (retryableNonLand) {
|
|
361
364
|
if (ancestryUnconfirmed && landedWorkspace) {
|
|
362
365
|
const ws = transitioned ?? landedWorkspace;
|
|
363
|
-
deferLandSettleSideEffect("land-unconfirmed", () => notifyLandUnconfirmed({ workspace: ws, commandId: command.id, sha: authoritativeLandedSha, targetRef: landTargetRef, kind: landAncestry }));
|
|
366
|
+
deferLandSettleSideEffect("land-unconfirmed", async () => await notifyLandUnconfirmed({ workspace: ws, commandId: command.id, sha: authoritativeLandedSha, targetRef: landTargetRef, kind: landAncestry }));
|
|
364
367
|
}
|
|
365
368
|
return { settled: true };
|
|
366
369
|
}
|
|
367
370
|
const noopBase = nothingBase ?? (mergeResult.noop === true && !resultError && mergeResult.landMechanism !== "plain-git" && (resultStatus === "merged" || resultStatus === "active") && typeof baseSha === "string" && /^[0-9a-f]{40,64}$/.test(baseSha) ? baseSha : undefined);
|
|
368
371
|
if (noopBase && landedWorkspace) await finishWorkspaceStewardHandoff(landedWorkspace);
|
|
369
|
-
if (noopBase && landedWorkspace) deferLandSettleSideEffect("nothing-to-land", () => notifyNothingToLand(landedWorkspace, noopBase, command.id, typeof command.params.expectedHeadSha === "string" ? command.params.expectedHeadSha : undefined));
|
|
372
|
+
if (noopBase && landedWorkspace) deferLandSettleSideEffect("nothing-to-land", async () => await notifyNothingToLand(landedWorkspace, noopBase, command.id, typeof command.params.expectedHeadSha === "string" ? command.params.expectedHeadSha : undefined));
|
|
370
373
|
const landConfirmed = !nothingBase && workspaceMergeProvesLand(mergeResult, command.params);
|
|
371
374
|
const continuationBranch = normalizedStatus === "active" ? landedWorkspace?.branch : undefined;
|
|
372
375
|
// #1790 F1 — build the land notice up front so the durable RECEIPT can be written SYNCHRONOUSLY,
|
|
@@ -381,6 +384,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
381
384
|
taskIds: resolveLandedTaskIds({ workspace: landedWorkspace,
|
|
382
385
|
sourceHeadSha: typeof command.params.expectedHeadSha === "string" ? command.params.expectedHeadSha : undefined }),
|
|
383
386
|
mergedSha: authoritativeLandedSha,
|
|
387
|
+
...(landAncestry === "confirmed" && !prLanded ? { landVerifiedSha: authoritativeLandedSha } : { landVerifiedSha: stringValue(mergeResult.landVerifiedSha) }),
|
|
384
388
|
// Git/PR titles have no 200-character limit. Bound display text without rejecting the land (#3244).
|
|
385
389
|
subject: stringValue(prLanded ? prLanded.subject : mergeResult.subject)?.slice(0, 200),
|
|
386
390
|
prLand: Boolean(prLanded),
|
|
@@ -392,7 +396,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
392
396
|
...(prLanded || landedCommitCount === undefined ? {} : { landedCommitCount }),
|
|
393
397
|
}
|
|
394
398
|
: undefined;
|
|
395
|
-
if (landedNotice) recordLandingReceipt(landedNotice);
|
|
399
|
+
if (landedNotice) (await recordLandingReceipt(landedNotice));
|
|
396
400
|
// #1744 F1 — record the tree-keyed land-gate attestation. Placed HERE, not at the executor, so
|
|
397
401
|
// that "the full gate passed on tree T" only becomes deployable evidence once the relay has
|
|
398
402
|
// CONFIRMED (ancestry-gated above, #1713) that T actually reached the base ref: a gated attempt
|
|
@@ -407,7 +411,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
407
411
|
const repo = landRepo(landedWorkspace.repoRoot);
|
|
408
412
|
// No resolvable origin ⇒ no shared identity with cd-watcher's detection clone ⇒ no row.
|
|
409
413
|
if (repo) {
|
|
410
|
-
|
|
414
|
+
(await insertLandGateAttestationAsync({
|
|
411
415
|
repo,
|
|
412
416
|
treeSha: attestation.treeSha,
|
|
413
417
|
commitSha: authoritativeLandedSha,
|
|
@@ -418,7 +422,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
418
422
|
gatesRan: attestation.gatesRan,
|
|
419
423
|
workspaceId: landedWorkspace.id,
|
|
420
424
|
...(attestation.suiteCoverage ? { suiteCoverage: attestation.suiteCoverage } : {}),
|
|
421
|
-
});
|
|
425
|
+
}));
|
|
422
426
|
}
|
|
423
427
|
} catch (error) {
|
|
424
428
|
console.warn(`[land-gate-attestation] failed to record tree ${attestation.treeSha.slice(0, 12)} for ${workspaceId}: ${String(error)}`);
|
|
@@ -438,7 +442,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
438
442
|
preservedWipPaths: Array.isArray(baseWorktreeSync.preservedWipPaths) ? baseWorktreeSync.preservedWipPaths.filter((p): p is string => typeof p === "string") : undefined,
|
|
439
443
|
message: typeof baseWorktreeSync.message === "string" ? baseWorktreeSync.message : undefined,
|
|
440
444
|
};
|
|
441
|
-
deferLandSettleSideEffect("base-worktree-strand", () => notifyBaseWorktreeStrand({ workspace: ws, sync: strandSync }));
|
|
445
|
+
deferLandSettleSideEffect("base-worktree-strand", async () => await notifyBaseWorktreeStrand({ workspace: ws, sync: strandSync }));
|
|
442
446
|
}
|
|
443
447
|
// #1713 — reaching here means the land is either ancestry-CONFIRMED, a remote-verified PR land, or
|
|
444
448
|
// a proven zero-commit no-op (handled inside announceBranchLanded, #1620); an unconfirmed
|
|
@@ -449,7 +453,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
449
453
|
// i.e. the serialized writes this issue is about — so it runs off the settle hot path.
|
|
450
454
|
if (landedNotice) {
|
|
451
455
|
const notice = landedNotice;
|
|
452
|
-
deferLandSettleSideEffect("branch-landed", () => announceBranchLanded(notice));
|
|
456
|
+
deferLandSettleSideEffect("branch-landed", async () => await announceBranchLanded(notice));
|
|
453
457
|
}
|
|
454
458
|
const gateSkipped = normalizeGateSkipped(mergeResult.gateSkipped);
|
|
455
459
|
if (gateSkipped && landedWorkspace) {
|
|
@@ -461,7 +465,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
461
465
|
},
|
|
462
466
|
});
|
|
463
467
|
const ws = landedWorkspace;
|
|
464
|
-
deferLandSettleSideEffect("land-gate-skipped", () => notifyLandGateSkipped({ workspace: ws, ...gateSkipped }));
|
|
468
|
+
deferLandSettleSideEffect("land-gate-skipped", async () => await notifyLandGateSkipped({ workspace: ws, ...gateSkipped }));
|
|
465
469
|
}
|
|
466
470
|
const gateWarnings = mergeResult.merged === true ? normalizeGateWarnings(mergeResult.gateWarnings) : [];
|
|
467
471
|
if (gateWarnings.length && landedWorkspace) {
|
|
@@ -499,7 +503,7 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
499
503
|
console.warn(`land-gate-warnings artifact upload failed for ${warnWorkspace.id}: ${String(error)}`);
|
|
500
504
|
}
|
|
501
505
|
try {
|
|
502
|
-
notifyLandGateWarnings({ workspace: warnWorkspace, warnings: gateWarnings, artifactId, fullOutput: !anyTruncated });
|
|
506
|
+
await notifyLandGateWarnings({ workspace: warnWorkspace, warnings: gateWarnings, artifactId, fullOutput: !anyTruncated });
|
|
503
507
|
} catch (error) {
|
|
504
508
|
console.warn(`land-gate-warnings notify threw for ${warnWorkspace.id}: ${String(error)}`);
|
|
505
509
|
}
|
|
@@ -536,6 +540,11 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
536
540
|
if (await settleRestartKilledLand(command, current)) markTransitionCompleted();
|
|
537
541
|
return { settled: true };
|
|
538
542
|
}
|
|
543
|
+
if (!alreadyLanded && isRecord(command.result) && command.result.landingBlockerCode === DELEGATED_LAND_REFUSAL_CODE) {
|
|
544
|
+
await refuseWorkspaceLand(current, reason, command.id);
|
|
545
|
+
markTransitionCompleted();
|
|
546
|
+
return { settled: true };
|
|
547
|
+
}
|
|
539
548
|
const transitioned = await updateWorkspaceStatusAsync(command.correlationId, nextStatus, {
|
|
540
549
|
mergeCommandId: command.id,
|
|
541
550
|
landGateQueue: undefined,
|
|
@@ -552,12 +561,12 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
552
561
|
// announcements off it, so they run off the settle hot path (same as the success path's fan-out).
|
|
553
562
|
if (nextStatus === "conflict" && !alreadyLanded) {
|
|
554
563
|
// #2704 — the settle is the one conflict entry that never woke a steward (case A): give it its resolver.
|
|
555
|
-
deferLandSettleSideEffect("land-conflict-
|
|
556
|
-
deferLandSettleSideEffect("land-conflict-semantic", () => emitWorkspaceTaskSemanticNotifications({
|
|
564
|
+
deferLandSettleSideEffect("land-conflict-semantic", async () => await emitWorkspaceTaskSemanticNotifications({
|
|
557
565
|
workspace: current, transition: "land-conflict", actor: "workspace-merge",
|
|
558
566
|
idempotencyKey: landFailureEventKey(current, command.id),
|
|
559
567
|
outcome: { reason, commandId: command.id, status: nextStatus },
|
|
560
568
|
}));
|
|
569
|
+
deferLandSettleSideEffect("land-conflict-resolver", () => superviseLandConflictLater(current.id, reason, landedHead ? { tip: landedHead } : {}));
|
|
561
570
|
}
|
|
562
571
|
if (gateFailure) {
|
|
563
572
|
const gateFailedAt = Date.now();
|
|
@@ -571,9 +580,9 @@ async function settleWorkspaceMergeCommandResult(command: Command, markTransitio
|
|
|
571
580
|
});
|
|
572
581
|
} else if (!alreadyLanded && nextStatus !== "conflict") {
|
|
573
582
|
// A conflict's owner hears from its resolver instead: the steward hand-off, or the hand-back (#2704).
|
|
574
|
-
deferLandSettleSideEffect("land-failed", () => {
|
|
575
|
-
notifyBranchLandFailed({ workspace: current, commandId: command.id, reason });
|
|
576
|
-
notifyLandUnconfirmed({ workspace: current, commandId: command.id, targetRef: current.baseRef ?? "main", kind: "merge-failed", detail: reason });
|
|
583
|
+
deferLandSettleSideEffect("land-failed", async () => {
|
|
584
|
+
await notifyBranchLandFailed({ workspace: current, commandId: command.id, reason });
|
|
585
|
+
await notifyLandUnconfirmed({ workspace: current, commandId: command.id, targetRef: current.baseRef ?? "main", kind: "merge-failed", detail: reason });
|
|
577
586
|
});
|
|
578
587
|
}
|
|
579
588
|
return { settled: true };
|
package/src/workspace-config.ts
CHANGED
|
@@ -3,5 +3,5 @@ import type { WorkspaceConfig } from "@humwick/sdk";
|
|
|
3
3
|
// Single source for the isolated-worktree symlink default (config-store + settings registry).
|
|
4
4
|
// Only the untracked rig config is linked; AGENTS.md is tracked (#3516), so a worktree gets it from git.
|
|
5
5
|
export const WORKSPACE_CONFIG_DEFAULTS: WorkspaceConfig = {
|
|
6
|
-
symlinkPaths: [
|
|
6
|
+
symlinkPaths: [],
|
|
7
7
|
};
|
|
@@ -81,7 +81,8 @@ async function withdrawArmedLand(ws: WorkspaceRecord, reason: string): Promise<"
|
|
|
81
81
|
export async function handBackLandConflict(ws: WorkspaceRecord, now: number, why: string): Promise<ConflictHandback> {
|
|
82
82
|
const meta = ws.metadata as Record<string, unknown>;
|
|
83
83
|
if (conflictHandedBackForArm(meta)) return "skipped";
|
|
84
|
-
const
|
|
84
|
+
const cause = typeof meta.mergeError === "string" ? meta.mergeError : undefined;
|
|
85
|
+
const instructions = handbackInstructions(ws, cause && !why.includes(cause) ? `${why}: ${cause}` : why);
|
|
85
86
|
const withdrawn = await withdrawArmedLand(ws, instructions);
|
|
86
87
|
// The steward's shutdown fences the row out of every other lane until it settles: the sweep
|
|
87
88
|
// retries this pending hand-back (workspace-steward-watchdog.ts), never the steward path.
|
|
@@ -106,7 +107,7 @@ export async function handBackLandConflict(ws: WorkspaceRecord, now: number, why
|
|
|
106
107
|
// One notice per recipient: it also wakes the owner, so no separate `landed-failure` (whose per-arm key
|
|
107
108
|
// the land-conflict Task notice already holds). A notify failure falls through to the operator alarm.
|
|
108
109
|
try {
|
|
109
|
-
routeNotification({
|
|
110
|
+
await routeNotification({
|
|
110
111
|
type: "workspace.stranded_escalation", forceDelivery: true, ttlMs: null,
|
|
111
112
|
scope: { workspaceId: ws.id, repoRoot: ws.repoRoot, author: ws.ownerAgentId, parent: coordinator ?? undefined },
|
|
112
113
|
recipients,
|
|
@@ -130,14 +131,14 @@ export async function handBackLandConflict(ws: WorkspaceRecord, now: number, why
|
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
raiseOperatorAlarm({
|
|
134
|
+
(await raiseOperatorAlarm({
|
|
134
135
|
clientId: `steward-handoff-unescalatable-${ws.id}:${strandKey}`,
|
|
135
136
|
source: "workspace-steward-handoff-watchdog",
|
|
136
137
|
subject: "Land conflict has no one to hand it back to",
|
|
137
138
|
detail: `${branchLabel} in ${ws.repoRoot} has an unresolved land conflict and no owner, coordinator, or fallback to hand it back to (${why}). Configure AGENT_RELAY_WORKSPACE_STEWARD_FALLBACK or land/reclaim the worktree manually.`,
|
|
138
139
|
view: "orchestrators",
|
|
139
140
|
metadata: { maintenanceJobId: "workspace-steward-handoff-watchdog", workspaceId: ws.id, repoRoot: ws.repoRoot, branch: ws.branch, reason: why },
|
|
140
|
-
});
|
|
141
|
+
}));
|
|
141
142
|
await transitionWorkspaceLandStateAsync(ws.id, "merge-error", { stewardHandoffEscalatedAt: now, stewardUnavailable: true, conflictHandbackPending: undefined, ...stewardEnded });
|
|
142
143
|
if (withdrawn === "none") await finishWorkspaceStewardHandoff(ws);
|
|
143
144
|
await createActivityEventAsync({
|
|
@@ -167,14 +168,15 @@ export async function superviseLandConflict(ws: WorkspaceRecord, reason: string,
|
|
|
167
168
|
|
|
168
169
|
const inFlight = new Set<Promise<unknown>>();
|
|
169
170
|
|
|
170
|
-
/**
|
|
171
|
-
export function superviseLandConflictLater(workspaceId: string, reason: string, opts: { tip?: string } = {}): void {
|
|
171
|
+
/** Track the wake so deferred settle queues can drain its committed effects (#1790/#1870). */
|
|
172
|
+
export function superviseLandConflictLater(workspaceId: string, reason: string, opts: { tip?: string } = {}): Promise<void> {
|
|
172
173
|
const ws = getWorkspace(workspaceId);
|
|
173
|
-
if (!ws) return;
|
|
174
|
+
if (!ws) return Promise.resolve();
|
|
174
175
|
const run = superviseLandConflict(ws, reason, opts)
|
|
175
176
|
.catch((error) => console.warn(`[workspace-conflict-resolver] supervising ${workspaceId} failed; the hand-off watchdog retries: ${errMessage(error)}`))
|
|
176
177
|
.finally(() => inFlight.delete(run));
|
|
177
178
|
inFlight.add(run);
|
|
179
|
+
return run.then(() => {});
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
export async function settleConflictSupervisionForTests(): Promise<void> {
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
+
import { createCommandAsync } from "./commands-write";
|
|
1
2
|
// Host-bound rescue for an unpushed dead-owner workspace. Kept separate from
|
|
2
3
|
// the orphan sweep so command construction remains reusable without inflating
|
|
3
4
|
// the disk⇄DB reconciler.
|
|
4
5
|
import type { WorkspaceRecord } from "./types";
|
|
5
|
-
|
|
6
|
+
|
|
6
7
|
import { emitCommandEvent } from "./command-events";
|
|
7
8
|
|
|
8
|
-
export function dispatchDeadOwnerRescue(orch: { agentId: string }, workspace: WorkspaceRecord): string {
|
|
9
|
-
const command =
|
|
9
|
+
export async function dispatchDeadOwnerRescue(orch: { agentId: string }, workspace: WorkspaceRecord): Promise<string> {
|
|
10
|
+
const command = (await createCommandAsync({
|
|
10
11
|
type: "workspace.reconcile", source: "system", target: orch.agentId, correlationId: workspace.id,
|
|
11
12
|
params: {
|
|
12
13
|
action: "reconcile", workspaceId: workspace.id, repoRoot: workspace.repoRoot,
|
|
13
14
|
worktreePath: workspace.worktreePath, branch: workspace.branch, baseRef: workspace.baseRef,
|
|
14
15
|
baseSha: workspace.baseSha, autoReclaim: "dead-owner", requestedBy: "workspace-dead-owner-reaper", requestedAt: Date.now(),
|
|
15
16
|
},
|
|
16
|
-
});
|
|
17
|
+
}));
|
|
17
18
|
emitCommandEvent(command, `command.${command.status}`);
|
|
18
19
|
return command.id;
|
|
19
20
|
}
|