@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
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { isRecord, stringValue } from "@humwick/sdk";
|
|
2
|
+
import { attachRecoveryCommand, carryingRecoveryObligations, closeRecoveryObligations, insertContextReset, openRecoveryObligation, readsToCarry, type ContextResetFact, type RecoveryObligation } from "./context-reset-carry";
|
|
3
|
+
import { sendMessageWithResultInternal, type SendMessageResult } from "./messages";
|
|
4
|
+
import { isContinuationSelfResumeCommand } from "../self-resume-command";
|
|
5
|
+
import type { Command } from "../types";
|
|
6
|
+
const LISTED_IDS = 200;
|
|
7
|
+
const CARRY_MARGIN_MS = 10 * 60_000;
|
|
8
|
+
const FALLBACK_STATUSES = new Set(["failed", "canceled", "timed_out", "rejected"]);
|
|
9
|
+
|
|
10
|
+
export function recordContextResetBody(fact: ContextResetFact, now: number): SendMessageResult | null {
|
|
11
|
+
if (!insertContextReset(fact, now)) return null;
|
|
12
|
+
const carrying = carryingRecoveryObligations(fact.agentId);
|
|
13
|
+
if (!carrying.length) return null;
|
|
14
|
+
const result = sendCarry(fact.agentId, carrying, `${fact.resetId}:0`, { resetId: fact.resetId, kind: fact.kind });
|
|
15
|
+
closeRecoveryObligations(fact.agentId, settledBy(fact, carrying), `reset:${fact.resetId}`, now);
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
export function settleContextResetCarryBody(command: Command, now: number): SendMessageResult | null {
|
|
19
|
+
const boundary = FALLBACK_STATUSES.has(command.status) ? commandBoundary(command) : null;
|
|
20
|
+
if (!boundary) return null;
|
|
21
|
+
const carrying = carryingRecoveryObligations(boundary.agentId);
|
|
22
|
+
if (!carrying.some(obligation => obligation.open && obligation.generation === boundary.generation)) return null;
|
|
23
|
+
const sent = sendCarry(boundary.agentId, carrying, `${command.id}:fallback`, { boundaryCommandId: command.id, status: command.status });
|
|
24
|
+
if (isRecord(command.result) && command.result.destructiveInputSubmitted === false) closeRecoveryObligations(boundary.agentId, [boundary.generation], `submit-aborted:${command.id}`, now);
|
|
25
|
+
return sent;
|
|
26
|
+
}
|
|
27
|
+
/** A reset settles only the boundary its provider evidence names; a replaced process settles all. */
|
|
28
|
+
function settledBy(fact: ContextResetFact, carrying: RecoveryObligation[]): number[] {
|
|
29
|
+
const open = carrying.filter((obligation) => obligation.open);
|
|
30
|
+
if (fact.kind === "restart") return open.map((obligation) => obligation.generation);
|
|
31
|
+
return open.filter((obligation) => fact.commandId !== undefined && obligation.commandId === fact.commandId).map((obligation) => obligation.generation);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function commandBoundary(command: Command): { agentId: string; generation: number } | null {
|
|
35
|
+
const selfResume = isRecord(command.params.selfResume) ? command.params.selfResume : undefined;
|
|
36
|
+
const generation = selfResume?.generation;
|
|
37
|
+
if (typeof generation !== "number") return null;
|
|
38
|
+
if (command.type === "agent.restart") {
|
|
39
|
+
const agentId = stringValue(command.params.agentId);
|
|
40
|
+
return agentId && isRecord(command.params.selfRestart) ? { agentId, generation } : null;
|
|
41
|
+
}
|
|
42
|
+
return isContinuationSelfResumeCommand(command) ? { agentId: command.target, generation } : null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type SendResult = SendMessageResult;
|
|
46
|
+
|
|
47
|
+
// Floor: the earliest capture start minus the margin. No upper bound: a read after the reset is a duplicate, never a loss, and needs no clock comparison.
|
|
48
|
+
function sendCarry(agentId: string, carrying: RecoveryObligation[], key: string, detail: Record<string, unknown>): SendResult | null {
|
|
49
|
+
const ids = readsToCarry(agentId, Math.min(...carrying.map((obligation) => obligation.openedAt)) - CARRY_MARGIN_MS);
|
|
50
|
+
if (!ids.length) return null;
|
|
51
|
+
return sendMessageWithResultInternal({
|
|
52
|
+
from: "system",
|
|
53
|
+
to: agentId,
|
|
54
|
+
kind: "system",
|
|
55
|
+
subject: "Possible unread messages",
|
|
56
|
+
body: renderCarryBody(ids),
|
|
57
|
+
payload: { selfResumeCarry: { ...detail, generations: carrying.map((obligation) => obligation.generation), messageIds: ids } },
|
|
58
|
+
idempotencyKey: `self-resume-carry:${agentId}:${key}`,
|
|
59
|
+
replyExpected: false,
|
|
60
|
+
maxAgeSeconds: null,
|
|
61
|
+
}, false);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function renderCarryBody(ids: number[]): string {
|
|
65
|
+
const listed = ids.slice(0, LISTED_IDS).map((id) => `#${id}`).join(" ");
|
|
66
|
+
const rest = ids.length > LISTED_IDS ? `\n…and ${ids.length - LISTED_IDS} more, up to #${ids.at(-1)}; every id is in this message's payload.` : "";
|
|
67
|
+
return [
|
|
68
|
+
`Possible unread messages: ${ids.length} message${ids.length === 1 ? "" : "s"} reached you around your context reset, after or shortly before you saved your working state, so your current context may not hold them.`,
|
|
69
|
+
"Check each one your working state does not already cover with relay_get_message <id>, and handle it. Some may be duplicates of work you have done.",
|
|
70
|
+
"Messages you already handled may appear here, including the reset instruction itself: do not repeat a reset instruction found here.",
|
|
71
|
+
"",
|
|
72
|
+
`${listed}${rest}`,
|
|
73
|
+
].join("\n");
|
|
74
|
+
}
|
|
@@ -3,6 +3,7 @@ import { getDbPath, runDbMaintenanceWorker } from "./connection.ts";
|
|
|
3
3
|
import { purgeContinuationArchives, type ContinuationArchivePurgeInput, type ContinuationArchivePurgeResult } from "./continuation-archive-purge.ts";
|
|
4
4
|
import { syncInMemoryContinuationArchiveSearchIndex, type ContinuationArchiveSearchSyncInput, type ContinuationArchiveSearchSyncResult } from "./continuation-archive-search.ts";
|
|
5
5
|
import { getGateway } from "./gateway.ts";
|
|
6
|
+
import type { appendContinuationArchiveRefs } from "./continuations.ts";
|
|
6
7
|
import type { archiveAndAdvanceContinuation, archiveContinuationSegment, getContinuationArchiveByRef, searchContinuationArchives } from "./continuation-archives.ts";
|
|
7
8
|
|
|
8
9
|
// Anything left after the budget is still removed, by the agent delete's cascade.
|
|
@@ -24,6 +25,10 @@ export function archiveAndAdvanceContinuationAsync(input: Parameters<typeof arch
|
|
|
24
25
|
return getGateway().write("continuationArchives.compact", { input }, { idempotencyKey: requestId }) as unknown as Promise<ReturnType<typeof archiveAndAdvanceContinuation>>;
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
export function appendContinuationArchiveRefsAsync(agentId: string, refs: string[]): Promise<ReturnType<typeof appendContinuationArchiveRefs>> {
|
|
29
|
+
return getGateway().write("continuationArchives.appendRefs", { agentId, refs }) as unknown as Promise<ReturnType<typeof appendContinuationArchiveRefs>>;
|
|
30
|
+
}
|
|
31
|
+
|
|
27
32
|
/**
|
|
28
33
|
* #3012 — catch the side FTS index up. A lock-free reader probe gates the run; the work runs in the
|
|
29
34
|
* maintenance subprocess against the side file's own write lock, never on the hub's loop. An
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { archiveAndAdvanceContinuation, archiveContinuationSegment } from "./continuation-archives.ts";
|
|
2
|
+
import { appendContinuationArchiveRefs } from "./continuations.ts";
|
|
2
3
|
import type { WriterOpContext, WriterOpSpec } from "./write-ops.ts";
|
|
3
4
|
|
|
4
5
|
export const CONTINUATION_ARCHIVES_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Object.freeze({
|
|
@@ -14,4 +15,10 @@ export const CONTINUATION_ARCHIVES_WRITE_OPS: Readonly<Record<string, WriterOpSp
|
|
|
14
15
|
fn: (args: { input: Parameters<typeof archiveAndAdvanceContinuation>[0] }, ctx: WriterOpContext) =>
|
|
15
16
|
archiveAndAdvanceContinuation({ ...args.input, now: args.input.now ?? ctx.now }),
|
|
16
17
|
},
|
|
18
|
+
// #1870 S7: the envelope's ref list is a set, so a replay converges.
|
|
19
|
+
"continuationArchives.appendRefs": {
|
|
20
|
+
offLoop: true,
|
|
21
|
+
idempotent: true,
|
|
22
|
+
fn: (args: { agentId: string; refs: string[] }, ctx: WriterOpContext) => appendContinuationArchiveRefs(args.agentId, args.refs, ctx.now),
|
|
23
|
+
},
|
|
17
24
|
});
|
package/src/db/continuations.ts
CHANGED
|
@@ -26,12 +26,12 @@ export function ensureContinuationEnvelope(input: {
|
|
|
26
26
|
agentId: string;
|
|
27
27
|
objective?: string;
|
|
28
28
|
now?: number;
|
|
29
|
-
}): ContinuationEnvelope {
|
|
29
|
+
}, submittedAt: number = Date.now()): ContinuationEnvelope {
|
|
30
30
|
const existing = getContinuationEnvelope(input.agentId);
|
|
31
31
|
if (existing) return existing;
|
|
32
32
|
const objective = input.objective;
|
|
33
33
|
if (!objective?.trim()) throw new ValidationError("objective required for first self-resume when no spawn prompt was recorded");
|
|
34
|
-
const now = input.now ??
|
|
34
|
+
const now = input.now ?? submittedAt;
|
|
35
35
|
getDb().query(`
|
|
36
36
|
INSERT INTO agent_continuations (agent_id, objective, objective_epoch, generation, ledger, working_state, archive_refs, budget, created_at, updated_at)
|
|
37
37
|
VALUES (?, ?, ?, 0, '[]', '', '[]', ?, ?, ?)
|
|
@@ -40,11 +40,11 @@ export function ensureContinuationEnvelope(input: {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/** Replace Relay-owned objective text and start a new render-time ledger epoch. */
|
|
43
|
-
export function updateContinuationObjective(input: { agentId: string; objective: string; now?: number }): ContinuationEnvelope {
|
|
43
|
+
export function updateContinuationObjective(input: { agentId: string; objective: string; now?: number }, submittedAt: number = Date.now()): ContinuationEnvelope {
|
|
44
44
|
if (!input.objective.trim()) throw new ValidationError("objective required");
|
|
45
45
|
const existing = getContinuationEnvelope(input.agentId);
|
|
46
46
|
if (!existing) throw new ValidationError("continuation envelope not found");
|
|
47
|
-
const now = input.now ??
|
|
47
|
+
const now = input.now ?? submittedAt;
|
|
48
48
|
getDb().query(`
|
|
49
49
|
UPDATE agent_continuations
|
|
50
50
|
SET objective = ?, objective_epoch = ?, updated_at = ?
|
|
@@ -143,7 +143,7 @@ function mergeLedger(
|
|
|
143
143
|
return { ledger: merged.slice(start), dropped: merged.slice(0, start) };
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
export function appendContinuationArchiveRefs(agentId: string, archiveRefs: string[]): ContinuationEnvelope | null {
|
|
146
|
+
export function appendContinuationArchiveRefs(agentId: string, archiveRefs: string[], now: number = Date.now()): ContinuationEnvelope | null {
|
|
147
147
|
if (archiveRefs.length === 0) return getContinuationEnvelope(agentId);
|
|
148
148
|
const existing = getContinuationEnvelope(agentId);
|
|
149
149
|
if (!existing) return null;
|
|
@@ -155,7 +155,7 @@ export function appendContinuationArchiveRefs(agentId: string, archiveRefs: stri
|
|
|
155
155
|
UPDATE agent_continuations
|
|
156
156
|
SET archive_refs = ?, updated_at = ?
|
|
157
157
|
WHERE agent_id = ?
|
|
158
|
-
`).run(JSON.stringify(refs),
|
|
158
|
+
`).run(JSON.stringify(refs), now, agentId);
|
|
159
159
|
return getContinuationEnvelope(agentId);
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { EffortReportRejected } from "./agent-effort-state";
|
|
2
|
+
import { TeamAuthError, TeamNotFoundError } from "./team-claim-policy";
|
|
3
|
+
import { EffortReportFenced } from "./agent-effort-observe";
|
|
4
|
+
import { KernelReplayExpiredError } from "@humwick/kernel/sqlite-kernel-persistence";
|
|
1
5
|
import { VaultError } from "../secrets-vault/keys";
|
|
2
6
|
// H2 (ADR 0001 §3.7) — the error-reconstruction registry for the async DB seam.
|
|
3
7
|
//
|
|
@@ -92,6 +96,10 @@ export const DB_ERROR_REGISTRY: Readonly<Record<string, DbErrorSpec>> = Object.f
|
|
|
92
96
|
fields: ["code"],
|
|
93
97
|
reconstruct: (message, fields) => new VaultError(String(fields.code ?? message), message),
|
|
94
98
|
},
|
|
99
|
+
EffortReportRejected: { fields: [], reconstruct: message => new EffortReportRejected(message) },
|
|
100
|
+
EffortReportFenced: { fields: [], reconstruct: (message) => new EffortReportFenced(message) },
|
|
101
|
+
TeamAuthError: { fields: [], reconstruct: message => new TeamAuthError(message) },
|
|
102
|
+
TeamNotFoundError: { fields: [], reconstruct: message => new TeamNotFoundError(message) },
|
|
95
103
|
ValidationError: {
|
|
96
104
|
// Empty subclass — the prototype IS the payload; message carries everything.
|
|
97
105
|
fields: [],
|
|
@@ -213,6 +221,10 @@ export const DB_ERROR_REGISTRY: Readonly<Record<string, DbErrorSpec>> = Object.f
|
|
|
213
221
|
return err;
|
|
214
222
|
},
|
|
215
223
|
},
|
|
224
|
+
KernelReplayExpiredError: {
|
|
225
|
+
fields: ["operation", "requestKey"],
|
|
226
|
+
reconstruct: (_message, f) => new KernelReplayExpiredError(String(f.operation), String(f.requestKey)),
|
|
227
|
+
},
|
|
216
228
|
WorkflowHistoryExpiredError: {
|
|
217
229
|
// Thrown by reopenInstance inside the controlWorkflow write op, so it crosses the writer seam (#3018).
|
|
218
230
|
fields: ["instanceId"],
|
|
@@ -14,12 +14,19 @@
|
|
|
14
14
|
// It default-exports the offload task function; `createWorkerPool` invokes it via the offload
|
|
15
15
|
// worker-runtime bootstrap.
|
|
16
16
|
|
|
17
|
+
import { relayEnv } from "@humwick/sdk/env";
|
|
17
18
|
import type { OffloadWorkerTask } from "@humwick/offload/worker";
|
|
18
19
|
import { Database } from "bun:sqlite";
|
|
19
20
|
import { applyConnectionPragmas, closeDb, getDbPath, setDb } from "./connection.ts";
|
|
20
21
|
import { serializeDbError } from "./db-error-registry.ts";
|
|
21
22
|
import { runWriterBatch, runWriterOp, type SerializedBatchEntry, type WriterJobInput, type WriterJobResult } from "./write-ops.ts";
|
|
22
23
|
|
|
24
|
+
// A lock-contention test may shorten the wait; production keeps 4 s.
|
|
25
|
+
function writerBusyTimeoutMs(): number {
|
|
26
|
+
const override = Number(relayEnv(process.env, "AGENT_RELAY_WRITER_BUSY_TIMEOUT_MS")?.trim() || Number.NaN);
|
|
27
|
+
return Number.isSafeInteger(override) && override >= 0 ? override : 4000;
|
|
28
|
+
}
|
|
29
|
+
|
|
23
30
|
/** Ensure this worker's thread-local RW connection points at `dbPath`, opening it once and reusing
|
|
24
31
|
* it across jobs. A path change (never expected in production) reopens — cheap and defensive. */
|
|
25
32
|
function ensureConnection(dbPath: string): void {
|
|
@@ -33,7 +40,7 @@ function ensureConnection(dbPath: string): void {
|
|
|
33
40
|
// per-connection pragmas before it begins executing serialized write operations.
|
|
34
41
|
applyConnectionPragmas(conn, { ensureWal: false });
|
|
35
42
|
// #1870: external 1.2 s holds wait here, below the gateway's 5 s deadline, never on the loop.
|
|
36
|
-
conn.run(
|
|
43
|
+
conn.run(`PRAGMA busy_timeout = ${writerBusyTimeoutMs()}`);
|
|
37
44
|
setDb(conn, dbPath);
|
|
38
45
|
}
|
|
39
46
|
|
|
@@ -25,6 +25,7 @@ export function tryBeginDeployEventAsync(input: TryBeginDeployEventInput): Promi
|
|
|
25
25
|
export function backfillDeployEventVersionAsync(id: string, version: string): Promise<DeployEvent | null> {
|
|
26
26
|
return write("deployEvents.backfillVersion", { id, version });
|
|
27
27
|
}
|
|
28
|
+
export function getDeployEventForCommitAsync(commitSha: string): Promise<DeployEvent | null> { return read("deployEvents.forCommit", { commitSha }); }
|
|
28
29
|
export function getDeployEventAsync(id: string): Promise<DeployEvent | null> { return read("deployEvents.get", { id }); }
|
|
29
30
|
export function listDeployEventsAsync(limit: number, offset: number): Promise<DeployEvent[]> {
|
|
30
31
|
return read("deployEvents.list", { limit, offset });
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
currentPendingDeployEvent,
|
|
5
5
|
deployChangesForCommits,
|
|
6
|
-
getDeployEvent,
|
|
6
|
+
getDeployEvent, getDeployEventForCommit,
|
|
7
7
|
latestFailedDeployForCommit,
|
|
8
8
|
latestSuccessfulDeploy,
|
|
9
9
|
listDeployEvents,
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "./deploy-events.ts";
|
|
15
15
|
|
|
16
16
|
export const DEPLOY_EVENTS_READ_OPS = {
|
|
17
|
+
"deployEvents.forCommit": (args: { commitSha: string }): DeployEvent | null => getDeployEventForCommit(args.commitSha),
|
|
17
18
|
"deployEvents.get": (args: { id: string }): DeployEvent | null => getDeployEvent(args.id),
|
|
18
19
|
"deployEvents.list": (args: { limit: number; offset: number }): DeployEvent[] => listDeployEvents(args.limit, args.offset),
|
|
19
20
|
"deployEvents.needingChanges": (args: { limit: number }): DeployEvent[] => listDeployEventsNeedingChanges(args.limit),
|
package/src/db/deploy-events.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import { defaultTaskIssueRelation } from "./task-issue-relation";
|
|
2
|
+
import { parseJson, type TaskDispatch } from "@humwick/sdk";
|
|
1
3
|
import { randomUUID } from "node:crypto";
|
|
2
4
|
import { getDb, writeTransaction } from "./connection.ts";
|
|
3
5
|
import { setTaskStageBody } from "./task-entity.ts";
|
|
4
6
|
import { insertTaskEvent } from "./task-core.ts";
|
|
5
7
|
import { listIssuesForEntity } from "./issue-associations.ts";
|
|
6
|
-
import type { IssueRef } from "../types";
|
|
8
|
+
import type { IssueRef, IssueRefRelation } from "../types";
|
|
7
9
|
|
|
8
10
|
export type DeployStatus = "pending" | "succeeded" | "failed" | "rolled-back";
|
|
9
11
|
export type DeployHost = { id: string; fromVersion?: string; toVersion?: string; status: string; reason?: string };
|
|
10
12
|
export type DeployCommit = { sha: string; subject: string };
|
|
11
|
-
export type DeployTaskChange = { id: number; label: string; issues: IssueRef
|
|
13
|
+
export type DeployTaskChange = { id: number; label: string; issues: Array<IssueRef & { relation?: IssueRefRelation }>; onDeploy?: string };
|
|
12
14
|
export type DeployChangesSummary = {
|
|
13
15
|
range: { previousSha?: string; commitSha: string };
|
|
14
16
|
tasks: DeployTaskChange[];
|
|
@@ -219,6 +221,24 @@ export function getDeployEvent(id: string): DeployEvent | null {
|
|
|
219
221
|
return row ? rowToDeployEvent(row) : null;
|
|
220
222
|
}
|
|
221
223
|
|
|
224
|
+
/** The running artifact may boot while its deploy ledger is still pending (#3761). */
|
|
225
|
+
export function getDeployEventForCommit(commitSha: string): DeployEvent | null {
|
|
226
|
+
const row = getDb().query("SELECT * FROM deploy_events WHERE commit_sha = ? ORDER BY started_at DESC LIMIT 1").get(commitSha);
|
|
227
|
+
const event = row ? rowToDeployEvent(row) : null;
|
|
228
|
+
if (event?.changes?.state === "ready" && event.changes.tasks.length) {
|
|
229
|
+
const notes = getDb().query("SELECT id, on_deploy, dispatch, owner_agent_id FROM tasks WHERE id IN (SELECT value FROM json_each(?))")
|
|
230
|
+
.all(JSON.stringify(event.changes.tasks.map(task => task.id))) as Array<{ id: number; on_deploy: string | null; dispatch: string | null; owner_agent_id: string | null }>;
|
|
231
|
+
const byId = new Map(notes.map(task => [task.id, task]));
|
|
232
|
+
event.changes.tasks = event.changes.tasks.map(task => {
|
|
233
|
+
const { onDeploy, ...snapshot } = task;
|
|
234
|
+
const current = byId.get(task.id);
|
|
235
|
+
const note = current ? current.on_deploy : onDeploy;
|
|
236
|
+
return { ...snapshot, ...(current ? { issues: deployTaskIssues(task.id, current.dispatch, current.owner_agent_id) } : {}), ...(note ? { onDeploy: note } : {}) };
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return event;
|
|
240
|
+
}
|
|
241
|
+
|
|
222
242
|
/** Newest-first page of the deploy ledger for the dashboard timeline (#1327). */
|
|
223
243
|
export function listDeployEvents(limit: number, offset: number): DeployEvent[] {
|
|
224
244
|
const rows = getDb()
|
|
@@ -250,6 +270,11 @@ export function listDeployEventsNeedingChanges(limit: number): DeployEvent[] {
|
|
|
250
270
|
return rows.map(rowToDeployEvent);
|
|
251
271
|
}
|
|
252
272
|
|
|
273
|
+
function deployTaskIssues(id: number, dispatch: string | null, ownerAgentId: string | null): DeployTaskChange["issues"] {
|
|
274
|
+
const relation = defaultTaskIssueRelation(parseJson<TaskDispatch | undefined>(dispatch, undefined), ownerAgentId ?? undefined);
|
|
275
|
+
return listIssuesForEntity("task", String(id)).map(item => ({ ...item.issueRef, relation: item.association.relation ?? relation }));
|
|
276
|
+
}
|
|
277
|
+
|
|
253
278
|
/**
|
|
254
279
|
* Match a deploy's ordered commit list to every durable Task with an exact stored
|
|
255
280
|
* commit SHA. This CD-only query loads the task commit payload once; the HTTP
|
|
@@ -258,7 +283,7 @@ export function listDeployEventsNeedingChanges(limit: number): DeployEvent[] {
|
|
|
258
283
|
export function deployChangesForCommits(commits: DeployCommit[]): Pick<DeployChangesSummary, "tasks" | "unmatchedCommits"> {
|
|
259
284
|
const rangeShas = new Set(commits.map((commit) => commit.sha));
|
|
260
285
|
const matchedShas = new Set<string>();
|
|
261
|
-
const rows = getDb().query("SELECT id, title, commits FROM tasks WHERE kind = 'deliverable' AND commits IS NOT NULL ORDER BY id ASC").all() as any[];
|
|
286
|
+
const rows = getDb().query("SELECT id, title, commits, on_deploy, dispatch, owner_agent_id FROM tasks WHERE kind = 'deliverable' AND commits IS NOT NULL ORDER BY id ASC").all() as any[];
|
|
262
287
|
const tasks: DeployTaskChange[] = [];
|
|
263
288
|
for (const row of rows) {
|
|
264
289
|
let taskCommits: Array<{ sha?: unknown }>;
|
|
@@ -268,7 +293,8 @@ export function deployChangesForCommits(commits: DeployCommit[]): Pick<DeployCha
|
|
|
268
293
|
tasks.push({
|
|
269
294
|
id: Number(row.id),
|
|
270
295
|
label: String(row.title),
|
|
271
|
-
issues:
|
|
296
|
+
issues: deployTaskIssues(Number(row.id), row.dispatch, row.owner_agent_id),
|
|
297
|
+
...(row.on_deploy ? { onDeploy: String(row.on_deploy) } : {}),
|
|
272
298
|
});
|
|
273
299
|
}
|
|
274
300
|
return { tasks, unmatchedCommits: commits.filter((commit) => !matchedShas.has(commit.sha)) };
|
|
@@ -316,6 +342,11 @@ export function renewDeployEventLease(input: { id: string; now?: number }): bool
|
|
|
316
342
|
return writeTransaction(() => renewDeployEventLeaseBody(input, input.now ?? Date.now()));
|
|
317
343
|
}
|
|
318
344
|
|
|
345
|
+
/** Migration progress shares the existing deploy row and dashboard surface (#3470). */
|
|
346
|
+
export function recordDeployEventHosts(id: string, hosts: DeployHost[]): boolean {
|
|
347
|
+
return getDb().query("UPDATE deploy_events SET hosts = ? WHERE id = ? AND status = 'pending'").run(JSON.stringify(hosts), id).changes > 0;
|
|
348
|
+
}
|
|
349
|
+
|
|
319
350
|
/**
|
|
320
351
|
* Emergency operator recovery for a genuinely stranded deploy owner:
|
|
321
352
|
* `bun run scripts/release.ts --clear-deploy-lease <event-id>` (→ `failed`), or
|
package/src/db/gateway.ts
CHANGED
|
@@ -37,34 +37,12 @@
|
|
|
37
37
|
// inherits the phantom-failure guarantee ("a write may be committed even when reported as failed";
|
|
38
38
|
// reconcile via the key, never blind-retry) for free by routing through this surface.
|
|
39
39
|
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
// path, so this whole module SHIPS GREEN with ZERO callsite moves. Under `bun test` the in-process
|
|
44
|
-
// backend still round-trips args/results/errors through the SAME marshaling path as the worker
|
|
45
|
-
// (H1 §3.8.1), so the default suite fails exactly where production would.
|
|
46
|
-
// - worker-backed (a file DB, gated on explicitly, §7 Phase 1/2): writes to the size-1 writer pool,
|
|
47
|
-
// reads to the reader pool. Off the loop; proven by the file-backed integration suite. Production
|
|
48
|
-
// rollout flips per-domain in S3 (§11.5) — this module does NOT turn it on at bootstrap.
|
|
49
|
-
//
|
|
50
|
-
// THE TWO BACKENDS ARE SELECTED PER HALF (#1960 T1). `initGateway` takes `readerBackend` / `writerBackend`
|
|
51
|
-
// independently (with `backend` kept as the both-halves shorthand); BOTH default to in-process, so this
|
|
52
|
-
// change is behavior-preserving by construction. The split exists because the halves are different risk
|
|
53
|
-
// classes, and coupling them is what blocked the rollout:
|
|
54
|
-
// - READS are safe to offload. Under WAL a reader takes no write lock, so a worker reader cannot block
|
|
55
|
-
// or be blocked by the writer, and no main-thread state changes. This is ADR §7 Phase 1 verbatim
|
|
56
|
-
// ("Route reader ops through the reader pool in production; keep writes in-process on the loop
|
|
57
|
-
// initially") — and it accounts for ~55% of measured on-loop block-ms on prod.
|
|
58
|
-
// - WRITES are not. A worker WRITER owns the sole RW connection, so its bootstrap calls `closeDb()`
|
|
59
|
-
// and every surviving main-thread `getDb()` callsite — ~1380 of them, `/health` included — starts
|
|
60
|
-
// throwing. That is the S3 burn-down (#1870), not a config flip.
|
|
61
|
-
// So a reader-only flip must leave the writer half COMPLETELY untouched: same in-process writer, same
|
|
62
|
-
// live ambient connection, `closeDb()` never called by this module. Everything keyed off "is the main RW
|
|
63
|
-
// connection still ours?" (`gatewayBackend()`, the writer fault seam, the writer self-heal path) is
|
|
64
|
-
// therefore keyed off the WRITER half specifically, never off "either half is a worker".
|
|
40
|
+
// File databases always use the writer thread (#1870 S8). The main connection remains available
|
|
41
|
+
// for reads and boot migrations; the in-process writer is only for :memory:. Reader placement is
|
|
42
|
+
// independent and still controlled by the reader backend option.
|
|
65
43
|
|
|
66
44
|
import { errMessage } from "@humwick/sdk";
|
|
67
|
-
import { getDbPath } from "./connection.ts";
|
|
45
|
+
import { getDbGeneration, getDbPath } from "./connection.ts";
|
|
68
46
|
// Op-timing capture source (#1882 / ADR §5). One-way dependency — loop-block-attribution imports
|
|
69
47
|
// event-loop-lag + config only, never the gateway/writer stack, so this closes no cycle.
|
|
70
48
|
import { withLoopFrameCapture } from "../loop-block-attribution.ts";
|
|
@@ -237,74 +215,38 @@ export interface DbGatewayStats {
|
|
|
237
215
|
}
|
|
238
216
|
|
|
239
217
|
export interface InitGatewayOptions {
|
|
240
|
-
/**
|
|
218
|
+
/** Defaults to the live getDbPath(). File databases default both pools to workers. */
|
|
241
219
|
dbPath?: string;
|
|
242
|
-
/**
|
|
243
|
-
* Shorthand that sets BOTH halves at once. Defaults to `"in-process"` — the Phase-0 no-op that runs
|
|
244
|
-
* every op synchronously against the ambient main connection (so bootstrap spawns NO worker threads
|
|
245
|
-
* and behavior is unchanged). `"worker"` requires a file DB and stands up the writer + reader pools;
|
|
246
|
-
* it is used by the integration suite and by the per-domain S3 rollout, never at Phase-0 bootstrap.
|
|
247
|
-
*
|
|
248
|
-
* `readerBackend` / `writerBackend` override this per half — see them for the split rationale.
|
|
249
|
-
*/
|
|
220
|
+
/** Shorthand for reader placement; file writes always run on the worker. */
|
|
250
221
|
backend?: GatewayBackend;
|
|
251
|
-
/**
|
|
252
|
-
* The READ path's backend, overriding `backend`. Defaults to `backend ?? "in-process"`.
|
|
253
|
-
*
|
|
254
|
-
* THE POINT OF THE SPLIT (#1960 T1 / ADR §7 Phase 1). Reads are the safe half to offload: under WAL a
|
|
255
|
-
* reader takes no write lock and cannot block or be blocked by the writer, so a worker-backed reader
|
|
256
|
-
* changes NOTHING about write behavior. The writer half is a different risk class entirely — the
|
|
257
|
-
* worker writer owns the sole RW connection, so its bootstrap calls `closeDb()` and every surviving
|
|
258
|
-
* main-thread `getDb()` callsite (incl. `/health`) starts throwing. Keeping the writer in-process
|
|
259
|
-
* while the reader moves off-loop is therefore the only landable first step, and before this split it
|
|
260
|
-
* was not even expressible: one `backend` flag flipped both halves together.
|
|
261
|
-
*/
|
|
262
222
|
readerBackend?: GatewayBackend;
|
|
263
|
-
/**
|
|
264
|
-
* The WRITE path's backend, overriding `backend`. Defaults to `backend ?? "in-process"`.
|
|
265
|
-
*
|
|
266
|
-
* CAUTION: a worker writer takes ownership of the sole RW connection — its callers are expected to
|
|
267
|
-
* `closeDb()` first (see the module header and `initWriter`). Leave this `"in-process"` unless you
|
|
268
|
-
* are deliberately doing that; a reader-only flip must NOT touch it.
|
|
269
|
-
*/
|
|
223
|
+
/** Legacy preference; a file database always resolves to worker. */
|
|
270
224
|
writerBackend?: GatewayBackend;
|
|
271
|
-
/** Writer-pool tuning (queue high-water, hard cap, writer-job deadline) — see `InitWriterOptions`. */
|
|
272
225
|
writer?: Omit<InitWriterOptions, "path">;
|
|
273
|
-
/** Reader-pool tuning (size, queue high-water, per-job timeout). */
|
|
274
226
|
reader?: { size?: number; queueHighWater?: number; timeoutMs?: number };
|
|
275
227
|
}
|
|
276
228
|
|
|
277
|
-
/** The resolved per-half backend selection — what `initGateway` actually stands up. */
|
|
278
229
|
export interface ResolvedGatewayBackends {
|
|
279
230
|
reader: GatewayBackend;
|
|
280
231
|
writer: GatewayBackend;
|
|
281
232
|
}
|
|
282
233
|
|
|
283
|
-
/**
|
|
284
|
-
* Resolve the per-half backends from the options: the specific `readerBackend`/`writerBackend` wins,
|
|
285
|
-
* then the `backend` shorthand, then the in-process default. Pure, so the selection matrix is testable
|
|
286
|
-
* without standing up pools or spawning threads (mirrors `resolveReaderBackend` in reader-pool.ts).
|
|
287
|
-
*/
|
|
288
234
|
export function resolveGatewayBackends(options: InitGatewayOptions = {}): ResolvedGatewayBackends {
|
|
289
|
-
const
|
|
290
|
-
return {
|
|
235
|
+
const path = options.dbPath ?? getDbPath();
|
|
236
|
+
return {
|
|
237
|
+
reader: options.readerBackend ?? options.backend ?? (path && path !== ":memory:" ? "worker" : "in-process"),
|
|
238
|
+
writer: path && path !== ":memory:" ? "worker" : options.writerBackend ?? options.backend ?? "in-process",
|
|
239
|
+
};
|
|
291
240
|
}
|
|
292
241
|
|
|
293
242
|
// ── Backend state ───────────────────────────────────────────────────────────────────────────────
|
|
294
243
|
|
|
295
244
|
let reader: ReaderGateway | undefined;
|
|
296
|
-
// The two halves are tracked SEPARATELY (#1960 T1). Both default to in-process, so a cold/plain
|
|
297
|
-
// bootstrap is byte-for-byte the pre-split behavior.
|
|
298
245
|
let currentReaderBackend: GatewayBackend = "in-process";
|
|
299
246
|
let currentWriterBackend: GatewayBackend = "in-process";
|
|
300
|
-
//
|
|
301
|
-
// (ensureInit self-heal after a lone shutdownWriter) can reconstruct the worker writer WITHOUT
|
|
302
|
-
// depending on `getDbPath()` — worker-WRITER bootstrap intentionally calls `closeDb()` (the worker owns
|
|
303
|
-
// the sole RW connection), which clears `getDbPath()`, so relying on it would silently re-init the
|
|
304
|
-
// writer in-process against a torn-down main handle (HIGH-1, codex-terra L1 review). Deliberately
|
|
305
|
-
// tracks the WRITER only: a worker READER never closes the main handle, so an in-process writer under a
|
|
306
|
-
// worker reader must still self-heal to `":memory:"` (= the ambient `getDb()`), never to a file path.
|
|
247
|
+
// Retained for callers that release their bootstrap handle after initializing the gateway.
|
|
307
248
|
let writerWorkerDbPath: string | undefined;
|
|
249
|
+
let gatewayDbGeneration = -1;
|
|
308
250
|
|
|
309
251
|
function replaceReader(next: ReaderGateway): void {
|
|
310
252
|
const previous = reader;
|
|
@@ -314,19 +256,7 @@ function replaceReader(next: ReaderGateway): void {
|
|
|
314
256
|
if (previous) void previous.destroy().catch((error) => console.error(`[gateway] reader teardown failed: ${errMessage(error)}`));
|
|
315
257
|
}
|
|
316
258
|
|
|
317
|
-
/**
|
|
318
|
-
* Stand up the unified gateway. Idempotent-friendly: re-calling it replaces the backend (tearing the
|
|
319
|
-
* old one down). Chooses in-process for BOTH halves by default — the Phase-0 no-op — so a plain
|
|
320
|
-
* `getGateway()` never spawns worker threads. Pass `{ backend: "worker" }` (file DB) to route both
|
|
321
|
-
* families through the real pools, or `{ readerBackend: "worker" }` alone for the Phase-R shape:
|
|
322
|
-
* reads off the loop, writes still on the ambient main connection.
|
|
323
|
-
*
|
|
324
|
-
* THE TWO HALVES ARE STOOD UP INDEPENDENTLY and neither reaches into the other's state. In particular
|
|
325
|
-
* this function NEVER touches the main connection: `closeDb()` is the CALLER's step, required only for
|
|
326
|
-
* a worker WRITER (which then owns the sole RW connection). So `{ readerBackend: "worker" }` leaves the
|
|
327
|
-
* writer exactly as a default init leaves it — in-process, running op bodies against the live ambient
|
|
328
|
-
* `getDb()` — and the ~1380 raw-handle callsites (incl. `/health`) keep working untouched.
|
|
329
|
-
*/
|
|
259
|
+
/** Select reader placement independently; file writes always use one FIFO and one worker. */
|
|
330
260
|
export function initGateway(options: InitGatewayOptions = {}): void {
|
|
331
261
|
const { reader: readerB, writer: writerB } = resolveGatewayBackends(options);
|
|
332
262
|
const dbPath = options.dbPath ?? getDbPath();
|
|
@@ -338,17 +268,8 @@ export function initGateway(options: InitGatewayOptions = {}): void {
|
|
|
338
268
|
`requested worker half(s): ${halves}`,
|
|
339
269
|
);
|
|
340
270
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
// The in-process writer holds no connection of its own and runs the op against the ambient `getDb()`
|
|
344
|
-
// (the real main handle, file or memory) — which is why an in-process writer is passed `":memory:"`
|
|
345
|
-
// even when the process is on a file DB, and why it is unaffected by a worker-backed reader.
|
|
346
|
-
initWriter({ ...options.writer, path: writerB === "worker" ? (dbPath as string) : ":memory:" });
|
|
347
|
-
// RETAIN for writer-only self-heal (HIGH-1) — getDbPath() is cleared by a worker writer's closeDb().
|
|
348
|
-
writerWorkerDbPath = writerB === "worker" ? (dbPath as string) : undefined;
|
|
349
|
-
// ── READER half ─────────────────────────────────────────────────────────────────────────────────
|
|
350
|
-
// Force the backend rather than letting it fall out of the path, so a file-DB server in Phase 0 still
|
|
351
|
-
// runs every read synchronously on the main connection (no worker spawned, no callsite moved).
|
|
271
|
+
initWriter({ ...options.writer, path: writerB === "worker" ? dbPath : ":memory:" });
|
|
272
|
+
writerWorkerDbPath = writerB === "worker" ? dbPath : undefined;
|
|
352
273
|
replaceReader(
|
|
353
274
|
readerB === "worker"
|
|
354
275
|
? createReaderGateway({
|
|
@@ -362,6 +283,7 @@ export function initGateway(options: InitGatewayOptions = {}): void {
|
|
|
362
283
|
);
|
|
363
284
|
currentReaderBackend = readerB;
|
|
364
285
|
currentWriterBackend = writerB;
|
|
286
|
+
gatewayDbGeneration = getDbGeneration();
|
|
365
287
|
// An in-transaction crash seam is a main-thread closure; once op bodies run on the WRITER thread it
|
|
366
288
|
// can never be delivered, so arming one must FAIL rather than silently inject nothing (L-C #1899).
|
|
367
289
|
// Keyed on the WRITER half only — the seam is armed inside write-op bodies, so a worker reader leaves
|
|
@@ -369,7 +291,7 @@ export function initGateway(options: InitGatewayOptions = {}): void {
|
|
|
369
291
|
setWriterFaultsDeliverable(writerB === "in-process");
|
|
370
292
|
}
|
|
371
293
|
|
|
372
|
-
/** Tear the gateway down (both pools).
|
|
294
|
+
/** Tear the gateway down (both pools). The next getGateway() selects placement from the current database. */
|
|
373
295
|
export async function shutdownGateway(): Promise<void> {
|
|
374
296
|
const previousReader = reader;
|
|
375
297
|
reader = undefined;
|
|
@@ -381,17 +303,7 @@ export async function shutdownGateway(): Promise<void> {
|
|
|
381
303
|
await previousReader?.destroy();
|
|
382
304
|
}
|
|
383
305
|
|
|
384
|
-
/**
|
|
385
|
-
* Tear down JUST the reader half — terminates any worker-pool threads and replaces them with a fresh
|
|
386
|
-
* in-process reader. The writer is left COMPLETELY untouched (#1960 T2 server teardown).
|
|
387
|
-
*
|
|
388
|
-
* Deliberately NOT `shutdownGateway()`: that also calls `shutdownWriter()`, which unconditionally
|
|
389
|
-
* REJECTS every write still queued at the writer (writer-gateway.ts) — a needless side effect on a
|
|
390
|
-
* clean stop, since Phase-R never puts the writer on a worker (it stays in-process always). This is
|
|
391
|
-
* the shutdown counterpart the design pass calls for (§1.5): "worker threads must be torn down on
|
|
392
|
-
* shutdown or a restart can leave orphaned threads holding WAL read marks." Safe to call even when the
|
|
393
|
-
* reader was never worker-backed — the in-process reader's `destroy()` resolves immediately.
|
|
394
|
-
*/
|
|
306
|
+
/** Release reader workers without rejecting the writer FIFO during graceful shutdown. */
|
|
395
307
|
export async function shutdownGatewayReader(): Promise<void> {
|
|
396
308
|
const previous = reader;
|
|
397
309
|
reader = createReaderGateway({ backend: "in-process" });
|
|
@@ -404,16 +316,7 @@ export function isGatewayInitialized(): boolean {
|
|
|
404
316
|
return reader !== undefined;
|
|
405
317
|
}
|
|
406
318
|
|
|
407
|
-
/**
|
|
408
|
-
* The live WRITER backend. Domains whose post-commit main-thread work is not yet worker-safe (e.g.
|
|
409
|
-
* getDb-backed effect delivery) read this to refuse rather than commit-then-silently-drop.
|
|
410
|
-
*
|
|
411
|
-
* DELIBERATELY THE WRITER HALF, not "either half" (#1960 T1). Every caller is really asking "is the
|
|
412
|
-
* main RW connection still ours?" — `events.ts`'s keyless-append guard and `managed-policy.ts`'s
|
|
413
|
-
* worker-safe builder both branch on that, and it is the WRITER flip that surrenders the connection.
|
|
414
|
-
* A worker-backed READER changes nothing for them, so they must not start refusing when reads move off
|
|
415
|
-
* the loop. Use `readerBackend()` for the read half.
|
|
416
|
-
*/
|
|
319
|
+
/** The live writer placement, retained as the historical backend alias. */
|
|
417
320
|
export function gatewayBackend(): GatewayBackend {
|
|
418
321
|
return currentWriterBackend;
|
|
419
322
|
}
|
|
@@ -429,23 +332,13 @@ export function writerBackend(): GatewayBackend {
|
|
|
429
332
|
}
|
|
430
333
|
|
|
431
334
|
function ensureInit(): void {
|
|
432
|
-
if (reader === undefined) {
|
|
433
|
-
//
|
|
335
|
+
if (reader === undefined || (getDbPath() !== undefined && gatewayDbGeneration !== getDbGeneration())) {
|
|
336
|
+
// A replaced database owns new pools; never send its writes to the previous file (#1870 S8).
|
|
434
337
|
initGateway();
|
|
435
338
|
return;
|
|
436
339
|
}
|
|
437
|
-
//
|
|
438
|
-
// initGateway()/shutdownGateway(), but the writer CAN be torn down on its own (`shutdownWriter()` —
|
|
439
|
-
// used by the writer suite's afterEach and reachable directly), leaving `reader` defined while the
|
|
440
|
-
// writer backend is undefined. A reader-only sentinel then skips re-init and the next write hits
|
|
441
|
-
// `requireBackend()` → "writer gateway not initialized" — the failure L1 (#1875) surfaced once feature
|
|
442
|
-
// writes began routing through `getGateway().write/coalesce(...)`. Restore JUST the writer, matching
|
|
443
|
-
// the live backend, so a lone shutdownWriter() self-heals WITHOUT disturbing the reader (never
|
|
444
|
-
// downgrading a worker-backed reader to in-process).
|
|
340
|
+
// A lone writer teardown preserves reader placement. Rebuild only that writer.
|
|
445
341
|
if (!isWriterInitialized()) {
|
|
446
|
-
// Reconstruct the writer against the RETAINED WRITER worker path (never getDbPath(), which closeDb()
|
|
447
|
-
// clears at worker-writer bootstrap — HIGH-1). For in-process, ":memory:" selects the in-process
|
|
448
|
-
// writer. Keyed on the WRITER half so a worker READER never drags the writer onto a worker.
|
|
449
342
|
initWriter({ path: currentWriterBackend === "worker" ? writerWorkerDbPath : ":memory:" });
|
|
450
343
|
}
|
|
451
344
|
}
|
|
@@ -503,8 +396,8 @@ const GATEWAY: DbGateway = {
|
|
|
503
396
|
};
|
|
504
397
|
|
|
505
398
|
/**
|
|
506
|
-
* The process-wide DB gateway — the sole sanctioned DB entry point (ADR §3.3). Lazily
|
|
507
|
-
*
|
|
399
|
+
* The process-wide DB gateway — the sole sanctioned DB entry point (ADR §3.3). Lazily selects pools for the
|
|
400
|
+
* current database on first use if `initGateway()` was not called explicitly, so a caller never sees
|
|
508
401
|
* an uninitialized gateway. The returned facade is stable across `initGateway()` re-inits.
|
|
509
402
|
*/
|
|
510
403
|
export function getGateway(): DbGateway {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { pruneKernelReplayResults } from "@humwick/kernel/sqlite-kernel-persistence";
|
|
2
|
+
import { getDb } from "./connection";
|
|
3
|
+
import { pruneTerminalCommands } from "./command-retention";
|
|
4
|
+
import { pruneTokenUsage } from "./token-usage-retention";
|
|
5
|
+
import type { WriterOpSpec } from "./write-ops";
|
|
6
|
+
|
|
7
|
+
// One gateway call is one small transaction; never drain a backlog inside the writer job (#3619).
|
|
8
|
+
const BATCH = 25;
|
|
9
|
+
export const HISTORY_RETENTION_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = {
|
|
10
|
+
"historyRetention.kernel": { offLoop: true, idempotent: true, fn: (_args, ctx) => pruneKernelReplayResults(getDb(), ctx.now, BATCH) },
|
|
11
|
+
"historyRetention.tokens": { offLoop: true, idempotent: true, fn: (_args, ctx) => pruneTokenUsage(ctx.now - 90 * 24 * 60 * 60_000, BATCH) },
|
|
12
|
+
"historyRetention.commands": { offLoop: true, idempotent: true, fn: (_args, ctx) => pruneTerminalCommands(ctx.now - 30 * 24 * 60 * 60_000, 1_000, ctx.now - 60 * 60_000) },
|
|
13
|
+
};
|
|
@@ -139,8 +139,16 @@ export type HardwareReconciliation =
|
|
|
139
139
|
|
|
140
140
|
/** Capacity is an observed, runtime-varying property, not host identity. WSL2 in particular can
|
|
141
141
|
* report less RAM after a reboot, and swap may appear/disappear with zram configuration. Keep the
|
|
142
|
-
* latest value for placement without making a legitimate capacity change an anti-spoof conflict.
|
|
143
|
-
|
|
142
|
+
* latest value for placement without making a legitimate capacity change an anti-spoof conflict.
|
|
143
|
+
* `osVersion` (the kernel string) changes on every OS patch; it is not hardware identity (#3770). */
|
|
144
|
+
const TOLERANT_CAPACITY_HARDWARE_FIELDS = new Set(["totalMemMb", "totalStorageMb", "totalSwapMb", "osVersion"]);
|
|
145
|
+
|
|
146
|
+
/** The identity-defining keys present on both sides with different values: what a conflict notice names. */
|
|
147
|
+
export function conflictingHardwareFields(stored: HostHardware, reported: HostHardware): string[] {
|
|
148
|
+
const a = stored as unknown as Record<string, unknown>;
|
|
149
|
+
const b = reported as unknown as Record<string, unknown>;
|
|
150
|
+
return Object.keys(a).filter((key) => !TOLERANT_CAPACITY_HARDWARE_FIELDS.has(key) && a[key] !== undefined && b[key] !== undefined && a[key] !== b[key]).sort();
|
|
151
|
+
}
|
|
144
152
|
|
|
145
153
|
export function reconcileHardwareFields(stored: HostHardware, reported: HostHardware): HardwareReconciliation {
|
|
146
154
|
const storedRec = stored as unknown as Record<string, unknown>;
|