@humwick/server 0.130.2 → 0.130.4
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/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-coordination.md +1 -0
- package/docs/guides/workflows.md +16 -0
- package/docs/openapi.json +175 -4
- package/package.json +8 -7
- package/public/assets/{MessageBubble-BWLqMGKG.js → MessageBubble-BOkmEvgZ.js} +2 -2
- package/public/assets/{PlanGraphPanel-3TlIQpjk.js → PlanGraphPanel-BkaDJp0r.js} +2 -2
- package/public/assets/{TraceView-Wimm0Czv.js → TraceView-B99Uu2yT.js} +2 -2
- package/public/assets/{VaultDecisionCard-Bau_vNax.js → VaultDecisionCard-DUIfTTFF.js} +2 -2
- package/public/assets/{activity-CrSurn-r.js → activity-ZIX0N1El.js} +2 -2
- package/public/assets/{agent-lineage-CknAJKcb.js → agent-lineage-kq9TPYFw.js} +2 -2
- package/public/assets/agent-liveness-DSQY1Aa_.js +2 -0
- package/public/assets/{agent-name-DKbiIhBo.js → agent-name-C_7F4DFR.js} +2 -2
- package/public/assets/{agent-profiles-DwF6EQ4R.js → agent-profiles-BNOcrGcY.js} +2 -2
- package/public/assets/{agent-project-badge-Diz4Sjjb.js → agent-project-badge-B6yAh70a.js} +2 -2
- package/public/assets/{agent-tools-CRhpRQza.js → agent-tools-CcrhmOzF.js} +2 -2
- package/public/assets/{agent-type-icon-LrUEU3lB.js → agent-type-icon-CXSLrKiq.js} +2 -2
- package/public/assets/{agents-B-v66C-4.js → agents-DIZG97_X.js} +2 -2
- package/public/assets/{analytics-BqCb-LKi.js → analytics-rasmoPjR.js} +2 -2
- package/public/assets/{artifact-viewer-kf4pGuAR.js → artifact-viewer-tBpTrEPb.js} +2 -2
- package/public/assets/{artifacts-DJevXcvg.js → artifacts-BNkrynP1.js} +2 -2
- package/public/assets/{artifacts-D32zyw4Y.js → artifacts-Bjq-ZyBA.js} +2 -2
- package/public/assets/{automation-BpRajx_5.js → automation-Cx422L3L.js} +2 -2
- package/public/assets/{backlog-D_UjTdzX.js → backlog-RuFQ8PUu.js} +2 -2
- package/public/assets/{busy-health-N3VEh4ao.js → busy-health-BvNQ9g5x.js} +2 -2
- package/public/assets/{channels-9jopungq.js → channels-DNbKAS0I.js} +2 -2
- package/public/assets/{chat-CSXrTB3C.js → chat-Bp3Fx73h.js} +3 -3
- package/public/assets/{code-preview-p1NnmqK0.js → code-preview-KIRZA6cz.js} +2 -2
- package/public/assets/{connectors-CZdqlDNL.js → connectors-k7vO4vvc.js} +2 -2
- package/public/assets/{cosmos-BgdsE4dG.js → cosmos-BuVoq1aw.js} +2 -2
- package/public/assets/{crate-agent-30aXTKva.js → crate-agent-irqlt4NH.js} +2 -2
- package/public/assets/{dependency-graph-B_jvw2GE.js → dependency-graph-D_rurNBz.js} +2 -2
- package/public/assets/{deploys-DoN6bAb5.js → deploys-yzZqIpxE.js} +2 -2
- package/public/assets/{display-BrKWFGJz.js → display-BemJG1f_.js} +2 -2
- package/public/assets/{files-D6XEu8Ng.js → files-DXWcrxOz.js} +2 -2
- package/public/assets/{fleet-C7jQWbw2.js → fleet-TEuOCZXE.js} +2 -2
- package/public/assets/{fleet-metrics-BiDs3MLx.js → fleet-metrics-BGoDAFI-.js} +2 -2
- package/public/assets/{formatted-body-impl-DyG0WsQS.js → formatted-body-impl-BB9eq9nN.js} +2 -2
- package/public/assets/{formatted-body-CQBwc1fb.js → formatted-body-qy2nTD_1.js} +3 -3
- package/public/assets/{host-providers-dialog-DKaW31dN.js → host-providers-dialog-BGPHxuwT.js} +2 -2
- package/public/assets/{index-CRHep3M9.js → index-BC5XZc0z.js} +5 -5
- package/public/assets/{index-MYAIwYTX.css → index-D8Rp9pz2.css} +1 -1
- package/public/assets/{insights-CzrtkpOE.js → insights-C-KQG0h-.js} +2 -2
- package/public/assets/{integrations-aVsUmigt.js → integrations-ClPRPyKU.js} +2 -2
- package/public/assets/{issue-ref-chip-BnSlM_95.js → issue-ref-chip-DbH8J9Ak.js} +2 -2
- package/public/assets/{log-viewer-qe7Ee47Z.js → log-viewer-PH4zVn24.js} +2 -2
- package/public/assets/{maintenance-NfjqFZAk.js → maintenance-5lV43uTL.js} +2 -2
- package/public/assets/{managed-agents-BiH0HgaE.js → managed-agents-BdgU35aX.js} +2 -2
- package/public/assets/{markdown-preview-BixaT3Xr.js → markdown-preview-DNT4OUwQ.js} +3 -3
- package/public/assets/{markdown-preview-impl-DNGlWIS3.js → markdown-preview-impl-CnCcPy0A.js} +2 -2
- package/public/assets/{memory-DNsCl6UX.js → memory--GgWH1gH.js} +2 -2
- package/public/assets/{messages-DopU1L1X.js → messages-CzFl_97O.js} +2 -2
- package/public/assets/{orchestrators-Cq7ckLQT.js → orchestrators-CVvJVkzv.js} +2 -2
- package/public/assets/overview-DsrZvE86.js +2 -0
- package/public/assets/{pairs-DE_m6rrE.js → pairs-D2d0d2py.js} +2 -2
- package/public/assets/{profile-icon-B3rfh77F.js → profile-icon-_SMuSbYF.js} +2 -2
- package/public/assets/{project-profile-instructions-DQWZE0kA.js → project-profile-instructions-Apn15y43.js} +2 -2
- package/public/assets/{projects-Br2Bd2h1.js → projects-D3B6kto5.js} +2 -2
- package/public/assets/{prompt-settings-BKvFsvGD.js → prompt-settings-DnPB6Ez6.js} +2 -2
- package/public/assets/provider-display-bWwiuedV.js +2 -0
- package/public/assets/{registry-Cw38_6gW.js → registry-D790cIhN.js} +2 -2
- package/public/assets/run-card-BCro-Odj.js +2 -0
- package/public/assets/{secrets-DxI-vzSq.js → secrets-CVXvfvbU.js} +2 -2
- package/public/assets/{service-access-settings-D9s_VJbd.js → service-access-settings-D3Xxqb9w.js} +2 -2
- package/public/assets/{settings-CKZTVGIx.js → settings-CoUC7Jci.js} +2 -2
- package/public/assets/shipping-D_Lp9n_J.js +2 -0
- package/public/assets/{stats-DyUBKyWI.js → stats-CXiNjB9S.js} +2 -2
- package/public/assets/{status-dot-DYqlEUhJ.js → status-dot-C703YIy1.js} +2 -2
- package/public/assets/store-BgDALGIX.js +9 -0
- package/public/assets/{tasks-Bh7Chr4-.js → tasks-DO0WpJCx.js} +2 -2
- package/public/assets/{teams-bowI7qVY.js → teams-FGkdi_tL.js} +2 -2
- package/public/assets/{terminal-viewer-BgVLHdsU.js → terminal-viewer-Dh8dSC7e.js} +3 -3
- package/public/assets/{terminal-viewer-impl-Dz22UPy6.js → terminal-viewer-impl-B5Zriip3.js} +2 -2
- package/public/assets/{use-agent-terminal-DSQQ-iY7.js → use-agent-terminal-CRUVDvLC.js} +2 -2
- package/public/assets/{use-decisions-samMQhQf.js → use-decisions-CoaqRh4l.js} +2 -2
- package/public/assets/{use-project-list-59LheVP7.js → use-project-list-X-BgT53X.js} +2 -2
- package/public/assets/{use-selectors-BZa25xEB.js → use-selectors-0X_UZkk-.js} +2 -2
- package/public/assets/{user-avatar-DHxlvUvV.js → user-avatar-CkLhVBGu.js} +2 -2
- package/public/assets/{versioned-prompt-editor-BmED5DnJ.js → versioned-prompt-editor-BkTi7eim.js} +2 -2
- package/public/assets/{work-queue-CSvpuNLz.js → work-queue-DDOLEyKo.js} +2 -2
- package/public/assets/{workflow-marker-DAZcj5qt.js → workflow-marker-CzOsB8BM.js} +2 -2
- package/public/assets/{workflows-DdmxRSyg.js → workflows-DJilvmRM.js} +2 -2
- package/public/assets/{workspaces-BxeKfVuF.js → workspaces-CHcfbLR3.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +29 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/src/adapters/claude-api.ts +1 -1
- 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/provider-quota-harvest.ts +20 -71
- package/runner/src/agent-runner/lifecycle-milestones.ts +2 -2
- package/runner/src/agent-runner/liveness-exchange.ts +104 -0
- package/runner/src/claude-system-prompt.ts +49 -0
- 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 +3 -2
- package/runner/src/runner-core.ts +14 -15
- package/runner/src/runner-helpers.ts +0 -8
- package/runner/src/session-scratch.ts +6 -2
- package/runner/test-support/provisioning-context.ts +4 -2
- package/runner/test-support/runner-harness.ts +2 -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/login-link.ts +35 -0
- 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 +3 -3
- package/src/branch-landed.ts +25 -23
- package/src/bus.ts +21 -19
- package/src/cd-deploy-notify.ts +2 -2
- package/src/ci/notifications.ts +4 -4
- package/src/ci/root-missing.ts +3 -3
- package/src/ci/transition-notify.ts +5 -5
- package/src/claude-app/oauth-http.ts +3 -3
- package/src/cli/index.ts +7 -1
- package/src/cli/init.ts +53 -0
- package/src/cli/orchestrator.ts +1 -7
- package/src/cli/setup.ts +6 -4
- package/src/cli/workflow.ts +12 -3
- package/src/commands-db.ts +4 -4
- package/src/commands-write.ts +8 -0
- package/src/compaction-watch.ts +10 -8
- package/src/config-store-write.ts +2 -2
- package/src/config.ts +4 -11
- package/src/connectors.ts +10 -8
- package/src/context-advisory.ts +22 -21
- 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/agents-async.ts +8 -5
- package/src/db/agents.ts +15 -12
- 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/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/commands-planner-stats.test-fixture.ts +8 -0
- package/src/db/commands-read-ops.ts +16 -0
- package/src/db/connection.ts +1 -182
- package/src/db/context-carry-write.ts +74 -0
- package/src/db/continuations.ts +4 -4
- package/src/db/db-error-registry.ts +12 -0
- package/src/db/gateway.ts +26 -133
- package/src/db/history-retention-ops.ts +13 -0
- package/src/db/inbox-async.ts +2 -2
- package/src/db/inbox-read-ops.ts +1 -1
- package/src/db/inbox.ts +9 -3
- package/src/db/issue-associations.ts +2 -2
- package/src/db/issue-refs-async.ts +4 -1
- package/src/db/issue-refs-read-ops.ts +6 -0
- package/src/db/issue-refs.ts +8 -8
- 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/main-connection-mode.ts +11 -0
- package/src/db/main-connection-writes.ts +20 -2
- package/src/db/maintenance-job-runs-async.ts +2 -2
- package/src/db/maintenance-job-write-ops.ts +1 -1
- package/src/db/maintenance-pauses.ts +2 -2
- package/src/db/message-send.ts +4 -0
- package/src/db/messages.ts +31 -25
- package/src/db/migrations.ts +18 -1
- package/src/db/notification-write-ops.ts +19 -0
- package/src/db/operator-answer-write.ts +19 -0
- package/src/db/orchestrators.ts +10 -4
- package/src/db/pairs-async.ts +22 -1
- package/src/db/pairs-write-ops.ts +8 -3
- package/src/db/pairs.ts +41 -48
- 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-trust-approvals.ts +2 -2
- package/src/db/prompt-templates.ts +4 -4
- package/src/db/read-op-marshaling-fixtures.ts +18 -0
- package/src/db/read-ops.ts +4 -0
- package/src/db/retention.ts +13 -2
- package/src/db/review-publish-write.ts +8 -0
- 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 +4 -1
- package/src/db/spawn-budget.ts +5 -0
- package/src/db/spawn-delegation.ts +3 -12
- package/src/db/sql-audit-indexes.ts +3 -0
- package/src/db/stats-async.ts +5 -3
- package/src/db/task-entity.ts +5 -4
- 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/token-db-write-ops.ts +2 -0
- package/src/db/token-standing-async.ts +12 -0
- package/src/db/token-standing.ts +6 -9
- 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-execution.ts +3 -3
- package/src/db/workspaces.ts +8 -5
- package/src/db/write-ops.ts +31 -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 +42 -46
- package/src/dev.ts +12 -16
- 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-provider-store.ts +5 -4
- package/src/hub-metrics-report.ts +5 -1
- package/src/hub-metrics.ts +38 -18
- package/src/init.ts +299 -0
- package/src/injection-sweep-pacing.ts +6 -8
- package/src/invite-link.ts +16 -9
- 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 +104 -98
- package/src/maintenance/breaker.ts +18 -16
- package/src/maintenance/checkout-refresh.ts +18 -1
- package/src/maintenance/critical-job-watchdog.ts +3 -3
- package/src/maintenance/events.ts +3 -3
- package/src/maintenance/history-retention-job.ts +30 -0
- package/src/maintenance/jobs.ts +29 -67
- 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 +18 -13
- package/src/maintenance/stalled-delivery-pager.ts +4 -4
- package/src/maintenance/teams.ts +19 -30
- package/src/maintenance/workspaces.ts +17 -27
- package/src/managed-policy-escalation.ts +7 -7
- package/src/managed-policy.ts +3 -3
- package/src/managed-provider-gate.ts +5 -4
- package/src/managed-spawn-reservation.ts +5 -4
- package/src/mcp/index.ts +8 -8
- package/src/mcp/output-descriptions.ts +1 -1
- package/src/mcp/presentation.ts +2 -1
- 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 +3 -2
- package/src/mcp/tool-roles.ts +81 -0
- package/src/mcp/tools-workspace.ts +1 -1
- 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 +3 -3
- 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 +1 -1
- package/src/mcp-project-journal-tools.ts +4 -12
- package/src/mcp-project-tools.ts +17 -18
- package/src/mcp-routing-policy-tools.ts +3 -2
- package/src/mcp-team-tools.ts +6 -6
- package/src/mcp-workflow-tools.ts +5 -3
- 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/notify.ts +5 -5
- package/src/observed-reset-refresh.ts +4 -4
- package/src/operator-alarm.ts +2 -5
- package/src/project-ingest.ts +6 -6
- package/src/project-instructions.ts +8 -1
- package/src/project-trust.ts +12 -11
- package/src/prompt-resolver.ts +3 -3
- package/src/provider-quota-async.ts +5 -7
- package/src/provider-timeline-event.ts +4 -7
- package/src/quota-band-delivery.ts +2 -2
- package/src/recipe-runner.ts +4 -3
- 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-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 +1 -1
- package/src/routes/agents.ts +17 -119
- package/src/routes/auth.ts +44 -17
- 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 +1 -1
- package/src/routes/commands.ts +29 -27
- package/src/routes/context-resets.ts +2 -2
- package/src/routes/coordinator-teams.ts +1 -1
- package/src/routes/decisions.ts +2 -2
- package/src/routes/host-providers.ts +18 -0
- 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 +7 -3
- package/src/routes/integrations.ts +9 -7
- package/src/routes/issue-activity.ts +2 -2
- package/src/routes/issue-associations.ts +4 -4
- package/src/routes/issue-refs.ts +3 -3
- 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 +3 -1
- package/src/routes/orchestrator-host-registration.ts +2 -0
- package/src/routes/orchestrator-host-utilization.ts +2 -2
- package/src/routes/orchestrator-proxy.ts +2 -2
- package/src/routes/orchestrator.ts +27 -18
- package/src/routes/pairs.ts +8 -8
- package/src/routes/project-profile-instructions.ts +1 -1
- package/src/routes/project-trust.ts +1 -1
- package/src/routes/projects.ts +16 -16
- package/src/routes/prompt-templates.ts +12 -12
- package/src/routes/provider-quotas.ts +10 -10
- package/src/routes/run-command.ts +1 -1
- package/src/routes/secrets-backup.ts +4 -5
- package/src/routes/secrets-import.ts +3 -4
- package/src/routes/secrets-vault.ts +12 -14
- package/src/routes/settings.ts +1 -1
- 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/team-templates.ts +7 -7
- package/src/routes/teams.ts +10 -10
- package/src/routes/tokens.ts +18 -17
- 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 +2 -2
- package/src/routes/workspaces.ts +17 -16
- package/src/routing-policy-push.ts +6 -6
- package/src/runtime-grant.ts +17 -11
- package/src/runtime-install.ts +30 -0
- package/src/runtime-tokens.ts +20 -28
- package/src/secrets-broker/config.ts +1 -1
- package/src/secrets-broker/service.ts +2 -2
- package/src/security.ts +3 -1
- 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 +1 -1
- package/src/server.ts +25 -26
- 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/auth-context.ts +6 -0
- 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 +9 -9
- package/src/services/idle-agent-digest.ts +17 -12
- package/src/services/idle-epics.ts +4 -4
- 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 +14 -13
- package/src/services/issue-refs.ts +4 -5
- package/src/services/kernel-timers-cutover-chaos-worker.ts +1 -1
- package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
- package/src/services/kernel-timers-ingress.ts +3 -3
- 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 +6 -5
- 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 +3 -3
- 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 +1 -1
- 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 +8 -3
- package/src/services/profile-trust.ts +2 -2
- package/src/services/project.ts +11 -10
- package/src/services/prompt-templates.ts +6 -5
- package/src/services/provider-api-key.ts +73 -0
- 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/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 +17 -16
- 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-effort-grant.ts +5 -25
- package/src/services/send-message.ts +16 -33
- package/src/services/shutdown-agent.ts +17 -14
- package/src/services/spawn-agent.ts +12 -41
- package/src/services/spawn-chain-inspector.ts +1 -1
- 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-registration-watchdog.ts +2 -2
- package/src/services/spawn-repo-probe.ts +7 -5
- package/src/services/spawn-tree-cleanup.ts +7 -8
- 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-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 +3 -4
- package/src/services/task-validation.ts +2 -2
- package/src/services/team-templates.ts +5 -5
- 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 +22 -19
- 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 +2 -1
- package/src/services/workflow-caller.ts +61 -4
- package/src/services/workflow-child-proof-worker.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 +1 -1
- package/src/services/workflow-effect-driver.ts +42 -19
- package/src/services/workflow-effects.ts +41 -27
- package/src/services/workflow-pins.ts +7 -4
- package/src/services/workflow-reconcile.ts +1 -0
- 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 +4 -3
- package/src/services/workflow-run.test-fixture.ts +1 -1
- package/src/services/workflow-runs.ts +34 -22
- package/src/services/workflow-supervisor-state.ts +21 -1
- package/src/services/workflow-supervisor.ts +4 -3
- package/src/services/workspace-recovery.ts +4 -3
- package/src/setup.ts +47 -8
- package/src/spawn-admission.ts +10 -2
- package/src/spawn-placement.ts +27 -9
- package/src/spawn-targets.ts +8 -8
- package/src/sse-agent-status.ts +15 -6
- package/src/sse.ts +49 -24
- package/src/startup-context-injection.ts +61 -57
- package/src/steward-handoff.ts +4 -3
- package/src/steward-policy-cleanup.ts +9 -8
- package/src/steward.ts +2 -2
- package/src/task-dispatch-live.ts +5 -2
- package/src/task-dispatcher.ts +2 -2
- 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/utils.ts +7 -0
- 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 +24 -16
- 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 +2 -2
- package/public/assets/agent-liveness-CaNwK0Zf.js +0 -2
- package/public/assets/overview-C1DCTzzV.js +0 -2
- package/public/assets/provider-display-DsuWMvVL.js +0 -2
- package/public/assets/run-card-CpKqRbhg.js +0 -2
- package/public/assets/shipping-B9YtnwtG.js +0 -2
- package/public/assets/store-DcClXLH0.js +0 -9
- package/runner/src/agent-runner/http-liveness.ts +0 -85
- package/src/db/on-loop-write-transaction.ts +0 -34
package/src/memory-injection.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { setConfigAsync } from "./config-store-write";
|
|
2
|
+
import { createCommandAsync } from "./commands-write";
|
|
1
3
|
import { contextInjectUnsupported, launchContextSurvivesCompact, launchSystemPromptAppend } from "./context-injection-channel";
|
|
2
4
|
// #1565 P4b — closing the auto-inject loop at the OTHER two boundaries (design §4.4).
|
|
3
5
|
//
|
|
@@ -56,10 +58,10 @@ import { contextInjectUnsupported, launchContextSurvivesCompact, launchSystemPro
|
|
|
56
58
|
import { createHash } from "node:crypto";
|
|
57
59
|
import { stripRenderedAtLine } from "./context-block-rendered-at";
|
|
58
60
|
import { errMessage, stringValue } from "@humwick/sdk";
|
|
59
|
-
import {
|
|
61
|
+
import { findLaunchPromptCommandForAgent } from "./commands-db";
|
|
60
62
|
import { emitCommandEvent } from "./command-events";
|
|
61
63
|
import { REAP_INTERVAL_MS } from "./config";
|
|
62
|
-
import { getConfig
|
|
64
|
+
import { getConfig } from "./config-store";
|
|
63
65
|
import { findMessageByIdempotencyKey, getAgent, type MemoryIdentity } from "./db";
|
|
64
66
|
import { composeMemoryPreamble, describeInstructionTruncation, describeMemoryDemotions, describeMemoryOmissions, describeUnresolvedInstructions, extractMemoryPreamble, memoryRetractionBlock, unresolvedInstructionSlugs, withMemorySupersedeNotice, type ComposedMemoryPreamble } from "./memory-preamble";
|
|
65
67
|
import {
|
|
@@ -124,8 +126,8 @@ export function readMemoryInjectionState(agentId: string): MemoryInjectionState
|
|
|
124
126
|
return getConfig<MemoryInjectionState>(MEMORY_INJECTION_NAMESPACE, agentId)?.value ?? null;
|
|
125
127
|
}
|
|
126
128
|
|
|
127
|
-
export function recordMemoryInjectionState(agentId: string, state: MemoryInjectionState): void {
|
|
128
|
-
|
|
129
|
+
export async function recordMemoryInjectionState(agentId: string, state: MemoryInjectionState): Promise<void> {
|
|
130
|
+
(await setConfigAsync(MEMORY_INJECTION_NAMESPACE, agentId, state, "memory-injection"));
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
/** #2591 — the journal gate's "what did this agent last receive" record. Same lifetime rules
|
|
@@ -144,8 +146,8 @@ export function readJournalInjectionState(agentId: string): JournalInjectionStat
|
|
|
144
146
|
return getConfig<JournalInjectionState>(JOURNAL_INJECTION_NAMESPACE, agentId)?.value ?? null;
|
|
145
147
|
}
|
|
146
148
|
|
|
147
|
-
export function recordJournalInjectionState(agentId: string, state: JournalInjectionState): void {
|
|
148
|
-
|
|
149
|
+
export async function recordJournalInjectionState(agentId: string, state: JournalInjectionState): Promise<void> {
|
|
150
|
+
(await setConfigAsync(JOURNAL_INJECTION_NAMESPACE, agentId, state, "journal-injection"));
|
|
149
151
|
}
|
|
150
152
|
|
|
151
153
|
/**
|
|
@@ -298,7 +300,7 @@ function hasEmptyBlockAccounting(seam: ResolvedMemorySeam, composed: ComposedMem
|
|
|
298
300
|
* normal outcome (unchanged set, nothing resolvable, provider cannot inject) and is always
|
|
299
301
|
* reported in the `relay-injection` event rather than being inferred from silence.
|
|
300
302
|
*/
|
|
301
|
-
export function enqueueMemoryInjectionAfterContextCommand(command: Command, now: number = Date.now()): Command | null {
|
|
303
|
+
export async function enqueueMemoryInjectionAfterContextCommand(command: Command, now: number = Date.now()): Promise<Command | null> {
|
|
302
304
|
// #2291 — the boundary's status answers "did the runner CONFIRM the destructive step", not "did a
|
|
303
305
|
// boundary HAPPEN". This used to read `!== "succeeded"`, which silently dropped the whole memory
|
|
304
306
|
// block on every unconfirmed clear and every timed-out compact: on the live coordinator that was
|
|
@@ -335,7 +337,7 @@ export function enqueueMemoryInjectionAfterContextCommand(command: Command, now:
|
|
|
335
337
|
if (contextInjectUnsupported(agent)) {
|
|
336
338
|
// Declared and logged, never a crash: this agent keeps whatever its spawn put in the system
|
|
337
339
|
// prompt and simply does not get the boundary refresh.
|
|
338
|
-
emitMemorySkip(agent, event, seam, composed, "inject-unsupported", command, now);
|
|
340
|
+
(await emitMemorySkip(agent, event, seam, composed, "inject-unsupported", command, now));
|
|
339
341
|
return null;
|
|
340
342
|
}
|
|
341
343
|
|
|
@@ -366,7 +368,7 @@ export function enqueueMemoryInjectionAfterContextCommand(command: Command, now:
|
|
|
366
368
|
// empty block reached the agent when the spawn-time block is in fact still in its prompt.
|
|
367
369
|
// Nothing needs the write either — the recorded hash is the block the agent LAST RECEIVED, and
|
|
368
370
|
// if memory reappears the composed hash differs from it and the next boundary re-injects.
|
|
369
|
-
if (hasEmptyBlockAccounting(seam, composed)) emitMemorySkip(agent, event, seam, composed, "nothing-to-inject", command, now);
|
|
371
|
+
if (hasEmptyBlockAccounting(seam, composed)) (await emitMemorySkip(agent, event, seam, composed, "nothing-to-inject", command, now));
|
|
370
372
|
if (!journal.delivers) return null;
|
|
371
373
|
} else if (event === "compact" && launchContextSurvivesCompact(agent) && launchBakedMemoryHash(agent) === hash) {
|
|
372
374
|
// §4.3(4): a native compact preserves a real system prompt, so a block BAKED there and still
|
|
@@ -375,7 +377,7 @@ export function enqueueMemoryInjectionAfterContextCommand(command: Command, now:
|
|
|
375
377
|
// of this delta skip (#3698). A clear destroys the context — nothing survives it to be unchanged. #2596 —
|
|
376
378
|
// this reads `launchBakedMemoryHash`, NOT the "recorded last delivery" hash: a block that only
|
|
377
379
|
// ever rode a transcript message has no such proof (see that function's doc).
|
|
378
|
-
emitMemorySkip(agent, event, seam, composed, "unchanged", command, now);
|
|
380
|
+
(await emitMemorySkip(agent, event, seam, composed, "unchanged", command, now));
|
|
379
381
|
if (!journal.delivers) return null;
|
|
380
382
|
} else {
|
|
381
383
|
memoryDelivers = true;
|
|
@@ -414,7 +416,7 @@ export function enqueueMemoryInjectionAfterContextCommand(command: Command, now:
|
|
|
414
416
|
// keeping its own markers, notice and gate state).
|
|
415
417
|
const content = [memoryContent, journal.content].filter(Boolean).join("\n\n");
|
|
416
418
|
const boundaryKey = command.type === "agent.clearContext" ? { afterClearCommandId: command.id } : { afterCompactCommandId: command.id };
|
|
417
|
-
const inject =
|
|
419
|
+
const inject = (await createCommandAsync({
|
|
418
420
|
type: "agent.injectContext",
|
|
419
421
|
source: "system",
|
|
420
422
|
target: command.target,
|
|
@@ -448,16 +450,16 @@ export function enqueueMemoryInjectionAfterContextCommand(command: Command, now:
|
|
|
448
450
|
}
|
|
449
451
|
: {}),
|
|
450
452
|
},
|
|
451
|
-
});
|
|
453
|
+
}));
|
|
452
454
|
emitCommandEvent(inject, "command.requested");
|
|
453
|
-
emitRelayInjectionEvent({
|
|
455
|
+
(await emitRelayInjectionEvent({
|
|
454
456
|
agentId: agent.id,
|
|
455
457
|
category: "memory",
|
|
456
458
|
summary: deliverySummary(event, composed, memoryDelivers, journal),
|
|
457
459
|
detail: injectionDetail(agent, event, seam, composed, { commandId: inject.id, content, seamVerified, ...journalEventDetail(journal) }),
|
|
458
460
|
timestamp: now,
|
|
459
461
|
idempotencyKey: memoryBoundaryEventKey("delivered", agent.id, command.id),
|
|
460
|
-
});
|
|
462
|
+
}));
|
|
461
463
|
return inject;
|
|
462
464
|
}
|
|
463
465
|
|
|
@@ -552,8 +554,8 @@ function memoryBoundaryEventKey(outcome: "delivered" | "skipped" | "failed", age
|
|
|
552
554
|
* swallowed silently: the operator sees the failure on the agent's timeline. The continuation
|
|
553
555
|
* enqueue runs BEFORE this and is untouched by it, which is the ordering that matters.
|
|
554
556
|
*/
|
|
555
|
-
export function settleMemoryInjectionAfterContextCommand(command: Command, now: number = Date.now()): Command | null {
|
|
556
|
-
return containedMemoryInjection(command, now).inject;
|
|
557
|
+
export async function settleMemoryInjectionAfterContextCommand(command: Command, now: number = Date.now()): Promise<Command | null> {
|
|
558
|
+
return (await containedMemoryInjection(command, now)).inject;
|
|
557
559
|
}
|
|
558
560
|
|
|
559
561
|
/**
|
|
@@ -564,24 +566,24 @@ export function settleMemoryInjectionAfterContextCommand(command: Command, now:
|
|
|
564
566
|
* both callers share one containment and one error report — a second try/catch in the sweep would
|
|
565
567
|
* be a second place for the reporting to drift.
|
|
566
568
|
*/
|
|
567
|
-
function containedMemoryInjection(command: Command, now: number, sweep = false): { inject: Command | null; composeFailed: boolean } {
|
|
569
|
+
async function containedMemoryInjection(command: Command, now: number, sweep = false): Promise<{ inject: Command | null; composeFailed: boolean }> {
|
|
568
570
|
try {
|
|
569
|
-
const inject = enqueueMemoryInjectionAfterContextCommand(command, now);
|
|
570
|
-
settleMemoryInjectionCommand(command, now);
|
|
571
|
-
settleAreaMemoryCommand(command, now);
|
|
571
|
+
const inject = (await enqueueMemoryInjectionAfterContextCommand(command, now));
|
|
572
|
+
(await settleMemoryInjectionCommand(command, now));
|
|
573
|
+
(await settleAreaMemoryCommand(command, now));
|
|
572
574
|
return { inject, composeFailed: false };
|
|
573
575
|
} catch (error) {
|
|
574
576
|
// #2712 — the sweep runs on a fast-fail connection; a held write lock defers the boundary to the
|
|
575
577
|
// next run rather than counting against its compose-failure cap.
|
|
576
578
|
if (sweep && isSqliteBusyError(error)) throw error;
|
|
577
|
-
emitRelayInjectionEvent({
|
|
579
|
+
(await emitRelayInjectionEvent({
|
|
578
580
|
agentId: command.target,
|
|
579
581
|
category: "memory",
|
|
580
582
|
summary: `memory re-injection failed to compose after ${command.type === "agent.compact" ? "compact" : command.type === "agent.clearContext" ? "clear" : command.type}: ${errMessage(error)}`,
|
|
581
583
|
detail: { source: "memory-preamble", agentId: command.target, commandId: command.id, failed: true },
|
|
582
584
|
timestamp: now,
|
|
583
585
|
idempotencyKey: memoryBoundaryEventKey("failed", command.target, command.id),
|
|
584
|
-
});
|
|
586
|
+
}));
|
|
585
587
|
return { inject: null, composeFailed: true };
|
|
586
588
|
}
|
|
587
589
|
}
|
|
@@ -635,12 +637,12 @@ function containedMemoryInjection(command: Command, now: number, sweep = false):
|
|
|
635
637
|
* continuation sweep's existing policy (redundant beats wiped) applied to a larger payload, not a
|
|
636
638
|
* new one; the runner's `ProviderInputQueue` serializes them rather than dropping any.
|
|
637
639
|
*/
|
|
638
|
-
export function sweepMissedMemoryInjections(now: number = Date.now(), signal?: AbortSignal): { enqueuedCommandIds: string[]; aborted?: true } {
|
|
640
|
+
export async function sweepMissedMemoryInjections(now: number = Date.now(), signal?: AbortSignal): Promise<{ enqueuedCommandIds: string[]; aborted?: true }> {
|
|
639
641
|
const enqueuedCommandIds: string[] = [];
|
|
640
642
|
// #1819 — one candidate is the unit; bailing between candidates leaves the rest for the next tick.
|
|
641
643
|
for (const command of newestBoundaryPerAgent(now, signal)) {
|
|
642
644
|
if (signal?.aborted) break;
|
|
643
|
-
sweepMemoryBoundary(command, now, enqueuedCommandIds);
|
|
645
|
+
(await sweepMemoryBoundary(command, now, enqueuedCommandIds));
|
|
644
646
|
}
|
|
645
647
|
return { enqueuedCommandIds, ...(signal?.aborted ? { aborted: true as const } : {}) };
|
|
646
648
|
}
|
|
@@ -648,27 +650,27 @@ export function sweepMissedMemoryInjections(now: number = Date.now(), signal?: A
|
|
|
648
650
|
/** #2712 — the job's form of {@link sweepMissedMemoryInjections}: the same units, one macrotask each. */
|
|
649
651
|
async function sweepMissedMemoryInjectionsPaced(now: number, signal?: AbortSignal): Promise<{ enqueuedCommandIds: string[]; aborted?: true; moreWork?: true }> {
|
|
650
652
|
const enqueuedCommandIds: string[] = [];
|
|
651
|
-
const { moreWork } = await pacedInjectionSweep(() => newestBoundaryPerAgent(now, signal), (command) => sweepMemoryBoundary(command, now, enqueuedCommandIds), signal);
|
|
653
|
+
const { moreWork } = await pacedInjectionSweep(() => newestBoundaryPerAgent(now, signal), async (command) => (await sweepMemoryBoundary(command, now, enqueuedCommandIds)), signal);
|
|
652
654
|
return { enqueuedCommandIds, ...(signal?.aborted ? { aborted: true as const } : {}), ...(moreWork ? { moreWork: true as const } : {}) };
|
|
653
655
|
}
|
|
654
656
|
|
|
655
|
-
function sweepMemoryBoundary(command: Command, now: number, enqueuedCommandIds: string[]): void {
|
|
657
|
+
async function sweepMemoryBoundary(command: Command, now: number, enqueuedCommandIds: string[]): Promise<void> {
|
|
656
658
|
const { decision, attempts } = injectionAttemptDecision(command, MEMORY_INJECTION_REASON);
|
|
657
659
|
if (decision === "in-flight") return;
|
|
658
660
|
if (decision === "exhausted") {
|
|
659
|
-
notifyMemoryInjectionExhausted(command, attempts, now);
|
|
661
|
+
(await notifyMemoryInjectionExhausted(command, attempts, now));
|
|
660
662
|
return;
|
|
661
663
|
}
|
|
662
664
|
if (attempts === 0 && (sweepAlreadyDecided(command) || boundaryAlreadyDecided(command))) return;
|
|
663
665
|
// Through the CONTAINED enqueue: composing reaches into the store, the ownership seam and
|
|
664
666
|
// cwd→project resolution, and a throw on one agent must not abort the sweep for every agent
|
|
665
667
|
// behind it (the #1565 F8 rationale, one level up).
|
|
666
|
-
const { inject, composeFailed } = containedMemoryInjection(command, now, true);
|
|
668
|
+
const { inject, composeFailed } = (await containedMemoryInjection(command, now, true));
|
|
667
669
|
if (inject) {
|
|
668
670
|
enqueuedCommandIds.push(inject.id);
|
|
669
671
|
return;
|
|
670
672
|
}
|
|
671
|
-
rememberSweepDecision(command, composeFailed, now);
|
|
673
|
+
(await rememberSweepDecision(command, composeFailed, now));
|
|
672
674
|
}
|
|
673
675
|
|
|
674
676
|
/**
|
|
@@ -752,13 +754,13 @@ function sweepAlreadyDecided(command: Command): boolean {
|
|
|
752
754
|
return held?.commandId === command.id && held.done;
|
|
753
755
|
}
|
|
754
756
|
|
|
755
|
-
function rememberSweepDecision(command: Command, composeFailed: boolean, now: number): void {
|
|
757
|
+
async function rememberSweepDecision(command: Command, composeFailed: boolean, now: number): Promise<void> {
|
|
756
758
|
const held = sweptBoundaryDecisions.get(command.target);
|
|
757
759
|
const composeFailures = (held?.commandId === command.id ? held.composeFailures : 0) + (composeFailed ? 1 : 0);
|
|
758
760
|
const done = !composeFailed || composeFailures >= MAX_INJECTION_ATTEMPTS;
|
|
759
761
|
if (sweptBoundaryDecisions.size >= MAX_SWEPT_DECISIONS && !held) sweptBoundaryDecisions.clear();
|
|
760
762
|
sweptBoundaryDecisions.set(command.target, { commandId: command.id, composeFailures, done });
|
|
761
|
-
if (composeFailed && done) notifyMemoryInjectionExhausted(command, composeFailures, now, "compose");
|
|
763
|
+
if (composeFailed && done) (await notifyMemoryInjectionExhausted(command, composeFailures, now, "compose"));
|
|
762
764
|
}
|
|
763
765
|
|
|
764
766
|
export const MEMORY_INJECTION_SWEEP_JOB = {
|
|
@@ -785,22 +787,22 @@ function boundaryAlreadyDecided(command: Command): boolean {
|
|
|
785
787
|
* exactly the state #2291 showed nobody can infer from silence. The two ways to spend it — the
|
|
786
788
|
* DELIVERY failing and the COMPOSITION throwing — carry different keys, or the first one reported
|
|
787
789
|
* would silence the other for the same boundary. */
|
|
788
|
-
function notifyMemoryInjectionExhausted(command: Command, attempts: number, now: number, kind: "delivery" | "compose" = "delivery"): void {
|
|
790
|
+
async function notifyMemoryInjectionExhausted(command: Command, attempts: number, now: number, kind: "delivery" | "compose" = "delivery"): Promise<void> {
|
|
789
791
|
const idempotencyKey = `memory-injection-exhausted${kind === "compose" ? "-compose" : ""}:${command.target}:${command.id}`;
|
|
790
792
|
if (findMessageByIdempotencyKey(command.target, idempotencyKey)) return;
|
|
791
793
|
const event = command.type === "agent.compact" ? "compact" : "clear";
|
|
792
794
|
const what = kind === "compose" ? "failed to compose" : "could not be delivered";
|
|
793
|
-
emitRelayInjectionEvent({
|
|
795
|
+
(await emitRelayInjectionEvent({
|
|
794
796
|
agentId: command.target,
|
|
795
797
|
category: "memory",
|
|
796
798
|
summary: `memory re-injection gave up after ${attempts} attempt(s) at a ${event} boundary — it ${what}, so this agent is running without the current block`,
|
|
797
799
|
detail: { source: "memory-preamble", agentId: command.target, commandId: command.id, event, attempts, exhausted: kind },
|
|
798
800
|
timestamp: now,
|
|
799
801
|
idempotencyKey,
|
|
800
|
-
});
|
|
802
|
+
}));
|
|
801
803
|
}
|
|
802
804
|
|
|
803
|
-
function emitMemorySkip(
|
|
805
|
+
async function emitMemorySkip(
|
|
804
806
|
agent: AgentCard,
|
|
805
807
|
event: MemoryInjectionEvent,
|
|
806
808
|
seam: ResolvedMemorySeam,
|
|
@@ -808,20 +810,20 @@ function emitMemorySkip(
|
|
|
808
810
|
skipped: MemoryInjectionSkip,
|
|
809
811
|
command: Command,
|
|
810
812
|
now: number,
|
|
811
|
-
): void {
|
|
813
|
+
): Promise<void> {
|
|
812
814
|
const summaries: Record<MemoryInjectionSkip, string> = {
|
|
813
815
|
unchanged: `memory unchanged after ${event} — re-injection skipped (${entriesLabel(renderedCount(composed))}, ${composed.tokens}t)`,
|
|
814
816
|
"inject-unsupported": `memory NOT re-injected after ${event}: provider declares context.inject:false (spawn-time block only)`,
|
|
815
817
|
"nothing-to-inject": `memory resolved nothing to inject after ${event}${omissionSuffix(composed)}`,
|
|
816
818
|
};
|
|
817
|
-
emitRelayInjectionEvent({
|
|
819
|
+
(await emitRelayInjectionEvent({
|
|
818
820
|
agentId: agent.id,
|
|
819
821
|
category: "memory",
|
|
820
822
|
summary: summaries[skipped],
|
|
821
823
|
detail: injectionDetail(agent, event, seam, composed, { skipped, commandId: command.id }),
|
|
822
824
|
timestamp: now,
|
|
823
825
|
idempotencyKey: memoryBoundaryEventKey("skipped", agent.id, command.id),
|
|
824
|
-
});
|
|
826
|
+
}));
|
|
825
827
|
}
|
|
826
828
|
|
|
827
829
|
/**
|
|
@@ -836,7 +838,7 @@ function emitMemorySkip(
|
|
|
836
838
|
* the same only-on-success rule. Each side records only when ITS payload rode the command, so a
|
|
837
839
|
* journal-only delivery never stamps a phantom memory hash (and vice versa).
|
|
838
840
|
*/
|
|
839
|
-
export function settleMemoryInjectionCommand(command: Command, now: number = Date.now()): void {
|
|
841
|
+
export async function settleMemoryInjectionCommand(command: Command, now: number = Date.now()): Promise<void> {
|
|
840
842
|
if (command.type !== "agent.injectContext" || command.status !== "succeeded") return;
|
|
841
843
|
if (command.params.reason !== MEMORY_INJECTION_REASON) return;
|
|
842
844
|
const memory = command.params.memory;
|
|
@@ -844,13 +846,13 @@ export function settleMemoryInjectionCommand(command: Command, now: number = Dat
|
|
|
844
846
|
const record = memory as Record<string, unknown>;
|
|
845
847
|
const hash = typeof record.hash === "string" ? record.hash : undefined;
|
|
846
848
|
if (hash !== undefined) {
|
|
847
|
-
recordMemoryInjectionState(command.target, {
|
|
849
|
+
(await recordMemoryInjectionState(command.target, {
|
|
848
850
|
hash,
|
|
849
851
|
tokens: typeof record.tokens === "number" ? record.tokens : 0,
|
|
850
852
|
entries: typeof record.entries === "number" ? record.entries : 0,
|
|
851
853
|
event: record.event === "clear" ? "clear" : "compact",
|
|
852
854
|
at: now,
|
|
853
|
-
});
|
|
855
|
+
}));
|
|
854
856
|
}
|
|
855
857
|
}
|
|
856
858
|
const journal = command.params.journal;
|
|
@@ -858,13 +860,13 @@ export function settleMemoryInjectionCommand(command: Command, now: number = Dat
|
|
|
858
860
|
const record = journal as Record<string, unknown>;
|
|
859
861
|
const hash = typeof record.hash === "string" ? record.hash : undefined;
|
|
860
862
|
if (hash !== undefined) {
|
|
861
|
-
recordJournalInjectionState(command.target, {
|
|
863
|
+
(await recordJournalInjectionState(command.target, {
|
|
862
864
|
hash,
|
|
863
865
|
tokens: typeof record.tokens === "number" ? record.tokens : 0,
|
|
864
866
|
fields: typeof record.fields === "number" ? record.fields : 0,
|
|
865
867
|
event: record.event === "clear" ? "clear" : "compact",
|
|
866
868
|
at: now,
|
|
867
|
-
});
|
|
869
|
+
}));
|
|
868
870
|
}
|
|
869
871
|
}
|
|
870
872
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { releaseExpiredMergePausesAsync } from "./db/runtime-tail-async";
|
|
1
2
|
import { REAP_INTERVAL_MS } from "./config";
|
|
2
|
-
|
|
3
|
+
|
|
3
4
|
|
|
4
5
|
export const MERGE_PAUSE_MAINTENANCE_JOB = {
|
|
5
6
|
id: "merge-pause-expiration",
|
|
@@ -8,12 +9,12 @@ export const MERGE_PAUSE_MAINTENANCE_JOB = {
|
|
|
8
9
|
description: "Release expired repo/base auto-merge pauses.",
|
|
9
10
|
intervalMs: REAP_INTERVAL_MS,
|
|
10
11
|
runOnStart: true,
|
|
11
|
-
// #1819 — SYNCHRONOUS, and ONE atomic statement: `
|
|
12
|
+
// #1819 — SYNCHRONOUS, and ONE atomic statement: `releaseExpiredMergePausesAsync` is a single UPDATE …
|
|
12
13
|
// RETURNING. There is no interior checkpoint to add — splitting it would mean splitting a
|
|
13
14
|
// transaction — so the pre-flight check is the whole of its cooperation. It cannot overrun a
|
|
14
15
|
// deadline in any realistic fleet; if it ever does, the fix is #1809 offload, not more checks.
|
|
15
|
-
handler(context: { signal?: AbortSignal }) {
|
|
16
|
+
async handler(context: { signal?: AbortSignal }) {
|
|
16
17
|
if (context.signal?.aborted) return { releasedMergePauseIds: [], aborted: true };
|
|
17
|
-
return { releasedMergePauseIds:
|
|
18
|
+
return { releasedMergePauseIds: (await releaseExpiredMergePausesAsync()) };
|
|
18
19
|
},
|
|
19
20
|
};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import { isRecord } from "@humwick/sdk";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
3
|
+
import { getGateway } from "./db/gateway";
|
|
4
|
+
import { emitNewMessage } from "./sse";
|
|
5
|
+
import type { SendMessageResult } from "./db/messages";
|
|
6
|
+
import type { AgentNoticeSlot } from "./db/terminal-events";
|
|
7
|
+
import { createActivityEventAsync, getAgent, getMessage } from "./db";
|
|
4
8
|
import { optedInNotificationRecipients, subscriptionDecisionFor } from "./db/notification-subscriptions";
|
|
5
9
|
import { notificationEnabledFor } from "./notification-settings-store";
|
|
6
|
-
import type { Message, MessageKind, NotificationRoutingExplanation, NotificationRoutingPreview, NotificationRoutingRecipientInput } from "./types";
|
|
10
|
+
import type { Message, SendMessageInput, MessageKind, NotificationRoutingExplanation, NotificationRoutingPreview, NotificationRoutingRecipientInput } from "./types";
|
|
7
11
|
import { DEFAULT_TTL_MS } from "./notification-types";
|
|
8
12
|
import type { NotificationScope, NotificationType } from "./notification-types";
|
|
9
13
|
import { isNotificationSuppressedForRole, notificationTarget, resolveAudience } from "./notification-rules";
|
|
@@ -89,17 +93,33 @@ function effectiveTtlMs(type: NotificationType, ttlMs: number | null | undefined
|
|
|
89
93
|
* Recipients are de-duplicated and emptied of falsy entries, so emitters can pass optional ids
|
|
90
94
|
* without guarding. A notification with zero resolved recipients is a no-op.
|
|
91
95
|
*/
|
|
92
|
-
export function routeNotification(input: RouteNotificationInput): Message[] {
|
|
96
|
+
export async function routeNotification(input: RouteNotificationInput): Promise<Message[]> {
|
|
97
|
+
const { inputs, preview, maxAgeSeconds } = prepareNotification(input);
|
|
98
|
+
if (!inputs.length) return [];
|
|
99
|
+
const results = await getGateway().write("notifications.route", { inputs }, { critical: true, idempotencyKey: randomUUID() }) as unknown as SendMessageResult[];
|
|
100
|
+
await emitNotificationResults(results, preview, maxAgeSeconds);
|
|
101
|
+
return results.map(result => result.message);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** #1870 — the generation slot and every recipient message commit in one writer transaction. */
|
|
105
|
+
export async function routeAgentNotice(slot: AgentNoticeSlot, input?: RouteNotificationInput): Promise<boolean> {
|
|
106
|
+
const prepared = input ? prepareNotification(input) : undefined;
|
|
107
|
+
const result = await getGateway().write("notifications.agentNotice", { slot, inputs: prepared?.inputs ?? [] }, { critical: true, idempotencyKey: randomUUID() }) as unknown as { created: boolean; results: SendMessageResult[] };
|
|
108
|
+
if (prepared) await emitNotificationResults(result.results, prepared.preview, prepared.maxAgeSeconds);
|
|
109
|
+
return result.created;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function prepareNotification(input: RouteNotificationInput) {
|
|
93
113
|
const ttl = effectiveTtlMs(input.type, input.ttlMs);
|
|
94
114
|
const emittedAt = input.emittedAt ?? Date.now();
|
|
95
115
|
|
|
96
116
|
// Staleness guard (#451): if the triggering event is already older than its TTL, drop before
|
|
97
117
|
// sending. On the normal synchronous path emittedAt ≈ now so this rarely fires, but it makes the
|
|
98
118
|
// router correct for any caller that routes a delayed/replayed event.
|
|
99
|
-
if (ttl !== null && Date.now() - emittedAt > ttl) return [];
|
|
119
|
+
if (ttl !== null && Date.now() - emittedAt > ttl) return { inputs: [], preview: previewNotificationRouting({ ...input, recipients: [] }), maxAgeSeconds: null };
|
|
100
120
|
|
|
101
121
|
const preview = previewNotificationRouting(input);
|
|
102
|
-
|
|
122
|
+
|
|
103
123
|
|
|
104
124
|
// Stamp the TTL on the message so the delivery/poll path (pollMessages) enforces it for offline
|
|
105
125
|
// or late-joining recipients too. An explicit `null` (never-expire) is authoritative: it suppresses
|
|
@@ -107,7 +127,8 @@ export function routeNotification(input: RouteNotificationInput): Message[] {
|
|
|
107
127
|
// never-expire intent instead of inheriting the moderate baseline.
|
|
108
128
|
const maxAgeSeconds = ttl === null ? null : Math.max(1, Math.ceil(ttl / 1000));
|
|
109
129
|
|
|
110
|
-
|
|
130
|
+
const inputs: SendMessageInput[] = [];
|
|
131
|
+
for (const routing of preview.recipients) {
|
|
111
132
|
const meta = getAgent(routing.recipient)?.meta;
|
|
112
133
|
const channel = meta?.kind === "channel" ? meta : undefined;
|
|
113
134
|
const notificationPayload = {
|
|
@@ -115,7 +136,8 @@ export function routeNotification(input: RouteNotificationInput): Message[] {
|
|
|
115
136
|
...(input.message.wake === false ? { wake: false } : {}),
|
|
116
137
|
routing: compactRoutingExplanation(routing),
|
|
117
138
|
};
|
|
118
|
-
|
|
139
|
+
inputs.push({
|
|
140
|
+
to: routing.recipient,
|
|
119
141
|
subject: input.message.subject,
|
|
120
142
|
body: input.message.body,
|
|
121
143
|
payload: channel ? {
|
|
@@ -124,16 +146,21 @@ export function routeNotification(input: RouteNotificationInput): Message[] {
|
|
|
124
146
|
event: { title: input.message.subject, body: input.message.body, notification: notificationPayload },
|
|
125
147
|
} : notificationPayload,
|
|
126
148
|
idempotencyKey: recipientScopedIdempotencyKey(input.message.idempotencyKey, routing.recipient),
|
|
127
|
-
kind: channel ? "channel.event" : input.message.kind,
|
|
128
|
-
from: input.message.from,
|
|
149
|
+
kind: channel ? "channel.event" : input.message.kind ?? "system",
|
|
150
|
+
from: input.message.from ?? "system",
|
|
129
151
|
replyExpected: channel ? false : input.message.replyExpected,
|
|
130
152
|
maxAgeSeconds,
|
|
131
153
|
});
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
154
|
+
}
|
|
155
|
+
return { inputs, preview, maxAgeSeconds };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function emitNotificationResults(results: SendMessageResult[], preview: NotificationRoutingPreview, maxAgeSeconds: number | null): Promise<void> {
|
|
159
|
+
for (const result of results) {
|
|
160
|
+
if (!result.created && !result.updated) continue;
|
|
161
|
+
emitNewMessage(result.message);
|
|
162
|
+
await auditRoutingTrace(result.message, preview, maxAgeSeconds);
|
|
163
|
+
}
|
|
137
164
|
}
|
|
138
165
|
|
|
139
166
|
function recipientScopedIdempotencyKey(key: string | undefined, recipient: string): string | undefined {
|
|
@@ -301,9 +328,9 @@ function routingExplanationFromPayload(value: unknown): NotificationRoutingExpla
|
|
|
301
328
|
};
|
|
302
329
|
}
|
|
303
330
|
|
|
304
|
-
function auditRoutingTrace(message: Message, preview: NotificationRoutingPreview, maxAgeSeconds: number | null): void {
|
|
331
|
+
async function auditRoutingTrace(message: Message, preview: NotificationRoutingPreview, maxAgeSeconds: number | null): Promise<void> {
|
|
305
332
|
try {
|
|
306
|
-
|
|
333
|
+
await createActivityEventAsync({
|
|
307
334
|
clientId: `notification-route-${message.id}`,
|
|
308
335
|
kind: "state",
|
|
309
336
|
title: "Notification routed",
|
package/src/notify.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sendMessageWithResultAsync } from "./db/message-send";
|
|
2
2
|
import { emitNewMessage } from "./sse";
|
|
3
3
|
import type { Message, MessageKind } from "./types";
|
|
4
4
|
|
|
@@ -33,13 +33,13 @@ interface SystemNotifyOptions {
|
|
|
33
33
|
* "relay tells an agent something happened" — store-ahead delivers it on next poll if the
|
|
34
34
|
* recipient is offline (#234). Used by the GC sweep (maintenance) and lifecycle events (#239).
|
|
35
35
|
*/
|
|
36
|
-
export function notifySystemMessage(to: string, opts: SystemNotifyOptions): Message {
|
|
37
|
-
return notifySystemMessageWithResult(to, opts).message;
|
|
36
|
+
export async function notifySystemMessage(to: string, opts: SystemNotifyOptions): Promise<Message> {
|
|
37
|
+
return (await notifySystemMessageWithResult(to, opts)).message;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/** Same send seam with creation provenance for callers that own one-shot side effects/audits. */
|
|
41
|
-
export function notifySystemMessageWithResult(to: string, opts: SystemNotifyOptions) {
|
|
42
|
-
const result =
|
|
41
|
+
export async function notifySystemMessageWithResult(to: string, opts: SystemNotifyOptions) {
|
|
42
|
+
const result = await sendMessageWithResultAsync({
|
|
43
43
|
from: opts.from ?? "system",
|
|
44
44
|
to,
|
|
45
45
|
kind: opts.kind ?? "system",
|
|
@@ -8,14 +8,14 @@ import { settleStartupContextInjectionAfterContextCommand } from "./startup-cont
|
|
|
8
8
|
/** #3698 — a `/clear` typed into the provider, or its auto-compaction, keeps the process and its
|
|
9
9
|
* launch-baked system prompt. Refresh identity, memory + journal and startup context through the
|
|
10
10
|
* SAME seams a commanded clear/compact settles; each is idempotent per boundary id. Never throws. */
|
|
11
|
-
export function refreshContextAfterObservedReset(reset: ObservedContextReset, now: number = Date.now()): void {
|
|
11
|
+
export async function refreshContextAfterObservedReset(reset: ObservedContextReset, now: number = Date.now()): Promise<void> {
|
|
12
12
|
const boundary = observedResetBoundary(reset);
|
|
13
13
|
try {
|
|
14
|
-
enqueueLifecycleIdentityInjectionAfterContextCommand(boundary);
|
|
14
|
+
(await enqueueLifecycleIdentityInjectionAfterContextCommand(boundary));
|
|
15
15
|
} catch (error) {
|
|
16
16
|
console.error(`#3698 identity refresh after observed ${reset.kind} ${reset.resetId} for ${reset.agentId} failed: ${errMessage(error)}`);
|
|
17
17
|
}
|
|
18
18
|
// Both contained: they report their own failures on the agent's timeline.
|
|
19
|
-
settleMemoryInjectionAfterContextCommand(boundary, now);
|
|
20
|
-
settleStartupContextInjectionAfterContextCommand(boundary, now);
|
|
19
|
+
(await settleMemoryInjectionAfterContextCommand(boundary, now));
|
|
20
|
+
(await settleStartupContextInjectionAfterContextCommand(boundary, now));
|
|
21
21
|
}
|
package/src/operator-alarm.ts
CHANGED
|
@@ -40,11 +40,8 @@ function emitAlarm(input: OperatorAlarmInput): void {
|
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export function raiseOperatorAlarm(input: OperatorAlarmInput): boolean {
|
|
44
|
-
|
|
45
|
-
if (input.dedupeEvent && !created) return false;
|
|
46
|
-
emitAlarm(input);
|
|
47
|
-
return true;
|
|
43
|
+
export async function raiseOperatorAlarm(input: OperatorAlarmInput): Promise<boolean> {
|
|
44
|
+
return raiseOperatorAlarmAsync(input);
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
/** Same as `raiseOperatorAlarm`, with the activity row written on the writer thread. */
|
package/src/project-ingest.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { listProjectEntriesAsync, rootsForProjectAsync, retractProjectEntryAsync, writeProjectEntryAsync } from "./db";
|
|
3
3
|
import { projectFileRoots, readProjectRootFile } from "./project-file-source";
|
|
4
4
|
import type { ProjectEntry } from "./types";
|
|
5
5
|
|
|
@@ -117,7 +117,7 @@ export async function ingestClaudeMd(projectId: string, authorId: string): Promi
|
|
|
117
117
|
// Index prior *ingested* entries by origin_ref (newest active wins). We only ever
|
|
118
118
|
// read source:'ingested' here — manual/promoted are invisible to ingest by design.
|
|
119
119
|
const byOrigin = new Map<string, ProjectEntry>();
|
|
120
|
-
for (const entry of
|
|
120
|
+
for (const entry of await listProjectEntriesAsync(projectId)) {
|
|
121
121
|
if (entry.source !== "ingested" || !entry.originRef) continue;
|
|
122
122
|
if (!byOrigin.has(entry.originRef)) byOrigin.set(entry.originRef, entry);
|
|
123
123
|
}
|
|
@@ -128,7 +128,7 @@ export async function ingestClaudeMd(projectId: string, authorId: string): Promi
|
|
|
128
128
|
let updated = 0;
|
|
129
129
|
let unchanged = 0;
|
|
130
130
|
|
|
131
|
-
const registered = projectFileRoots(
|
|
131
|
+
const registered = projectFileRoots(await rootsForProjectAsync(projectId));
|
|
132
132
|
if (!registered.length && byOrigin.size) throw new Error(`no confirmed checkout host owns project ${projectId}`);
|
|
133
133
|
for (const root of registered) {
|
|
134
134
|
let filePath = join(root.rootPath, INGEST_FILENAME);
|
|
@@ -153,7 +153,7 @@ export async function ingestClaudeMd(projectId: string, authorId: string): Promi
|
|
|
153
153
|
unchanged++;
|
|
154
154
|
continue;
|
|
155
155
|
}
|
|
156
|
-
|
|
156
|
+
await writeProjectEntryAsync({
|
|
157
157
|
projectId,
|
|
158
158
|
authorId,
|
|
159
159
|
kind: "rule",
|
|
@@ -166,7 +166,7 @@ export async function ingestClaudeMd(projectId: string, authorId: string): Promi
|
|
|
166
166
|
});
|
|
167
167
|
updated++;
|
|
168
168
|
} else {
|
|
169
|
-
|
|
169
|
+
await writeProjectEntryAsync({
|
|
170
170
|
projectId,
|
|
171
171
|
authorId,
|
|
172
172
|
kind: "rule",
|
|
@@ -187,7 +187,7 @@ export async function ingestClaudeMd(projectId: string, authorId: string): Promi
|
|
|
187
187
|
let retracted = 0;
|
|
188
188
|
for (const [originRef, entry] of byOrigin) {
|
|
189
189
|
if (seen.has(originRef)) continue;
|
|
190
|
-
|
|
190
|
+
await retractProjectEntryAsync(entry.id);
|
|
191
191
|
retracted++;
|
|
192
192
|
}
|
|
193
193
|
|
|
@@ -262,6 +262,13 @@ export function stripHumwickIdentitySection(value: string): string {
|
|
|
262
262
|
.replace(/\n\n+$/, "");
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
+
/** The relay-owned marked sections a prompt carries on top of the startup blocks: identity, memory
|
|
266
|
+
* and journal. The ONE strip every reader of a launched prompt uses, so a block added here (#3782:
|
|
267
|
+
* the journal) cannot be forgotten by one of them. */
|
|
268
|
+
export function stripRelayOwnedSections(value: string): string {
|
|
269
|
+
return stripJournalPreamble(stripMemoryPreamble(stripHumwickIdentitySection(value)));
|
|
270
|
+
}
|
|
271
|
+
|
|
265
272
|
export function composeSpawnInstructionsWithEvents(input: {
|
|
266
273
|
/** Resolved fact from the selected profile's Project Instructions cell. Absent fails closed. */
|
|
267
274
|
projectInstructionsEnabled?: boolean;
|
|
@@ -526,7 +533,7 @@ export function composeSpawnInstructionsWithEvents(input: {
|
|
|
526
533
|
// strict about what it removes, so a brief that merely mentions a marker survives intact — and
|
|
527
534
|
// neutralizing what survives keeps it from being read as this prompt's memory/journal block later.
|
|
528
535
|
const callerSystemPromptAppend = input.callerSystemPromptAppend
|
|
529
|
-
? neutralizeJournalMarkers(neutralizeMemoryMarkers(
|
|
536
|
+
? neutralizeJournalMarkers(neutralizeMemoryMarkers(stripRelayOwnedSections(input.callerSystemPromptAppend)))
|
|
530
537
|
: undefined;
|
|
531
538
|
if (callerSystemPromptAppend?.trim()) {
|
|
532
539
|
appendBlocks.push(callerSystemPromptAppend);
|