@cohortapp/agent-sdk 2.17.0 → 2.18.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/.claude/settings.json +18 -0
- package/.env.example +18 -5
- package/README.md +1 -0
- package/bin/maestro.mjs +62 -0
- package/docs/guides/billing-console-keys.md +60 -0
- package/docs/guides/front-door-session.md +54 -9
- package/docs/guides/mac-mini.md +20 -25
- package/docs/guides/setup-wizard.md +1 -1
- package/docs/runbooks/fleet-rollout.md +156 -0
- package/docs/runbooks/mac-mini-bootstrap.md +12 -14
- package/lib/action-executor.js +19 -3
- package/lib/budget-guard.mjs +279 -3
- package/lib/channels/base-adapter.mjs +3 -1
- package/lib/channels/contract.mjs +2 -1
- package/lib/channels/inbox-item.mjs +8 -0
- package/lib/claude-bin.mjs +5 -6
- package/lib/cli/doctor-checks.mjs +141 -10
- package/lib/cli/global-setup-extras.mjs +5 -1
- package/lib/cli/inbox.mjs +100 -15
- package/lib/cli/seat-auth.mjs +463 -0
- package/lib/cli/session.mjs +80 -12
- package/lib/collective/capture.mjs +8 -6
- package/lib/collective/global-config.mjs +63 -1
- package/lib/collective/presence.mjs +142 -5
- package/lib/comms/send-gate.mjs +559 -1
- package/lib/diagnostics/alerts.mjs +49 -0
- package/lib/diagnostics/cadence-output-freshness.mjs +288 -0
- package/lib/engine/agents/definitions.mjs +343 -0
- package/lib/engine/agents/persist.mjs +275 -0
- package/lib/engine/agents/runtime.mjs +748 -0
- package/lib/engine/agents/usage.mjs +95 -0
- package/lib/engine/auth-status.mjs +139 -0
- package/lib/engine/budget.mjs +194 -0
- package/lib/engine/cli.mjs +1204 -0
- package/lib/engine/commands/index.mjs +269 -0
- package/lib/engine/context/budget.mjs +219 -0
- package/lib/engine/context/cache.mjs +125 -0
- package/lib/engine/context/child-env.mjs +215 -0
- package/lib/engine/context/compaction.mjs +342 -0
- package/lib/engine/context/images.mjs +90 -0
- package/lib/engine/context/instructions.mjs +327 -0
- package/lib/engine/context/lazy-instructions.mjs +169 -0
- package/lib/engine/context/manager.mjs +182 -0
- package/lib/engine/context/real-path.mjs +91 -0
- package/lib/engine/context/secret-values.mjs +163 -0
- package/lib/engine/context/settings.mjs +274 -0
- package/lib/engine/context/stream-input.mjs +159 -0
- package/lib/engine/guard.mjs +152 -0
- package/lib/engine/hooks.mjs +713 -0
- package/lib/engine/loop.mjs +560 -0
- package/lib/engine/mcp/client.mjs +254 -0
- package/lib/engine/mcp/config.mjs +301 -0
- package/lib/engine/mcp/http.mjs +201 -0
- package/lib/engine/mcp/index.mjs +146 -0
- package/lib/engine/mcp/jsonrpc.mjs +147 -0
- package/lib/engine/mcp/naming.mjs +66 -0
- package/lib/engine/mcp/resources.mjs +89 -0
- package/lib/engine/mcp/results.mjs +133 -0
- package/lib/engine/mcp/stdio.mjs +137 -0
- package/lib/engine/mcp/supervisor.mjs +116 -0
- package/lib/engine/messages.mjs +104 -0
- package/lib/engine/output/json.mjs +164 -0
- package/lib/engine/output/stream-json.mjs +266 -0
- package/lib/engine/permissions.mjs +845 -0
- package/lib/engine/process-identity.mjs +164 -0
- package/lib/engine/process-tree.mjs +551 -0
- package/lib/engine/prompt.mjs +60 -0
- package/lib/engine/session/store.mjs +299 -0
- package/lib/engine/session-runtime/args.mjs +97 -0
- package/lib/engine/session-runtime/host.mjs +143 -0
- package/lib/engine/session-runtime/inbox.mjs +122 -0
- package/lib/engine/session-runtime/notifications.mjs +129 -0
- package/lib/engine/session-runtime/registry.mjs +328 -0
- package/lib/engine/session-runtime/runner.mjs +344 -0
- package/lib/engine/session-runtime/socket.mjs +212 -0
- package/lib/engine/session-runtime/wakeup.mjs +115 -0
- package/lib/engine/skills/index.mjs +321 -0
- package/lib/engine/tools/bash-background.mjs +533 -0
- package/lib/engine/tools/bash.mjs +216 -0
- package/lib/engine/tools/edit.mjs +97 -0
- package/lib/engine/tools/glob.mjs +81 -0
- package/lib/engine/tools/grep.mjs +224 -0
- package/lib/engine/tools/index.mjs +84 -0
- package/lib/engine/tools/list-agents.mjs +32 -0
- package/lib/engine/tools/ls.mjs +127 -0
- package/lib/engine/tools/monitor.mjs +82 -0
- package/lib/engine/tools/notebook-edit.mjs +218 -0
- package/lib/engine/tools/read.mjs +103 -0
- package/lib/engine/tools/schedule-wakeup.mjs +45 -0
- package/lib/engine/tools/schema.mjs +144 -0
- package/lib/engine/tools/send-message.mjs +77 -0
- package/lib/engine/tools/session.mjs +70 -0
- package/lib/engine/tools/todo.mjs +144 -0
- package/lib/engine/tools/toolsearch.mjs +217 -0
- package/lib/engine/tools/walk.mjs +193 -0
- package/lib/engine/tools/web-switch.mjs +31 -0
- package/lib/engine/tools/webfetch-html.mjs +387 -0
- package/lib/engine/tools/webfetch-net.mjs +340 -0
- package/lib/engine/tools/webfetch.mjs +198 -0
- package/lib/engine/tools/websearch.mjs +91 -0
- package/lib/engine/tools/workflow.mjs +95 -0
- package/lib/engine/tools/write.mjs +76 -0
- package/lib/engine/tui/line-editor.mjs +137 -0
- package/lib/engine/tui/render.mjs +86 -0
- package/lib/engine/tui/tui.mjs +274 -0
- package/lib/engine/wire/anthropic-messages.mjs +263 -0
- package/lib/engine/wire/effort.mjs +36 -0
- package/lib/engine/wire/errors.mjs +496 -0
- package/lib/engine/wire/http.mjs +441 -0
- package/lib/engine/wire/index.mjs +76 -0
- package/lib/engine/wire/openai-chat.mjs +332 -0
- package/lib/engine/wire/prompt-cache.mjs +79 -0
- package/lib/engine/wire/search.mjs +140 -0
- package/lib/engine/wire/sse.mjs +114 -0
- package/lib/engine/wire/stall.mjs +349 -0
- package/lib/engine/wire/token-provider.mjs +175 -0
- package/lib/engine/wire/usage.mjs +192 -0
- package/lib/engine/workflow/host.mjs +524 -0
- package/lib/engine/workflow/journal.mjs +188 -0
- package/lib/engine/workflow/json-schema.mjs +171 -0
- package/lib/engine/workflow/meta.mjs +329 -0
- package/lib/engine/workflow/notifications.mjs +52 -0
- package/lib/engine/workflow/runtime.mjs +447 -0
- package/lib/engine/workflow/sandbox.mjs +534 -0
- package/lib/engine/workflow/worker.mjs +141 -0
- package/lib/engine/workflow/worktree.mjs +74 -0
- package/lib/execution/disposition.mjs +1 -1
- package/lib/execution/intake.mjs +10 -0
- package/lib/execution/surface-policy.mjs +15 -0
- package/lib/learning/curator.mjs +8 -6
- package/lib/learning/reflect.mjs +8 -6
- package/lib/model-router/catalog/cohort.yaml +137 -0
- package/lib/model-router/catalog.mjs +118 -1
- package/lib/model-router/failover.mjs +67 -16
- package/lib/model-router/llm-task.mjs +39 -3
- package/lib/model-router/resolve.mjs +89 -3
- package/lib/model-router/spawn.mjs +46 -47
- package/lib/model-router/taxonomy.mjs +126 -4
- package/lib/org/cost-sync.mjs +141 -11
- package/lib/org/inbound/broadcast.mjs +289 -0
- package/lib/org/inbound/collective.mjs +375 -0
- package/lib/org/inbound/directedness.mjs +96 -8
- package/lib/org/inbound/facts.mjs +78 -2
- package/lib/org/inbound/project.mjs +22 -0
- package/lib/org/inbound/surfaces.mjs +14 -0
- package/lib/org/llm-token.mjs +879 -0
- package/lib/org/mesh.mjs +61 -0
- package/lib/org/messaging.mjs +3 -1
- package/lib/org/protocol.checksum +1 -1
- package/lib/org/protocol.mjs +15 -0
- package/lib/org/quota.mjs +520 -0
- package/lib/org/tool-surface.mjs +104 -16
- package/lib/org/ui-parity.mjs +16 -1
- package/lib/org/work-ledger.mjs +37 -6
- package/lib/rate-guard.mjs +114 -1
- package/lib/resource-governor.mjs +41 -6
- package/lib/runtime/adapter.mjs +823 -0
- package/lib/runtime/child-env.mjs +191 -0
- package/lib/runtime/legacy-shell-guard.mjs +97 -0
- package/lib/runtime/seat-engine.mjs +162 -0
- package/lib/session/ask-ledger.mjs +271 -0
- package/lib/session/current-work.mjs +676 -0
- package/lib/session/feed-core.mjs +40 -3
- package/lib/session/launch-args.mjs +56 -4
- package/lib/session/status-summary.mjs +26 -9
- package/lib/session/upgrade-notice.mjs +42 -0
- package/lib/setup/claude-probe.mjs +117 -13
- package/lib/setup/enrich.mjs +13 -10
- package/lib/setup/sections/model.mjs +39 -13
- package/lib/telemetry/collect.mjs +208 -9
- package/lib/upgrade/ignored-drift.mjs +105 -0
- package/lib/voice/post-call-brief.mjs +30 -17
- package/package.json +13 -3
- package/plugins/maestro-skills/skills/board-work.md +5 -0
- package/plugins/maestro-skills/skills/inbound-triage.md +56 -15
- package/plugins/maestro-skills/skills/main-session.md +18 -7
- package/scripts/ci/check-tarball-fidelity.mjs +126 -2
- package/scripts/ci/run-tests.mjs +47 -19
- package/scripts/cohort-llm/api-key-helper.mjs +92 -0
- package/scripts/collective/hook-runner.mjs +29 -2
- package/scripts/continuous-monitor.sh +13 -0
- package/scripts/cost/track-claude-usage.mjs +15 -0
- package/scripts/daemon/agent-daemon.mjs +408 -20
- package/scripts/daemon/assurance.mjs +48 -12
- package/scripts/daemon/cadence-consumer.mjs +218 -68
- package/scripts/daemon/cadence-handlers.mjs +73 -4
- package/scripts/daemon/classifier.mjs +75 -26
- package/scripts/daemon/context-compiler.mjs +51 -37
- package/scripts/daemon/deliver.mjs +30 -1
- package/scripts/daemon/dispatcher.mjs +595 -149
- package/scripts/daemon/health.mjs +14 -1
- package/scripts/daemon/maestro-daemon.mjs +11 -0
- package/scripts/daemon/prompt-builder.mjs +24 -0
- package/scripts/daemon/responder.mjs +246 -79
- package/scripts/daemon/sdk-version.mjs +98 -16
- package/scripts/eval/probe-gateway.mjs +635 -0
- package/scripts/eval/replay/extract.mjs +270 -0
- package/scripts/eval/replay/grade.mjs +260 -0
- package/scripts/eval/replay/lib/config.mjs +50 -0
- package/scripts/eval/replay/lib/effects.mjs +65 -0
- package/scripts/eval/replay/lib/fixture.mjs +188 -0
- package/scripts/eval/replay/lib/judge.mjs +72 -0
- package/scripts/eval/replay/lib/redact.mjs +136 -0
- package/scripts/eval/replay/lib/sandbox.mjs +170 -0
- package/scripts/eval/replay/lib/schema-check.mjs +63 -0
- package/scripts/eval/replay/lib/transcript.mjs +76 -0
- package/scripts/eval/replay/mcp-replay-stub.mjs +101 -0
- package/scripts/eval/replay/report.mjs +185 -0
- package/scripts/eval/replay/run.mjs +404 -0
- package/scripts/fleet/rollout.mjs +1094 -0
- package/scripts/hooks/pre-send-audit.sh +36 -245
- package/scripts/hooks/pre-write-yaml-validate.mjs +275 -0
- package/scripts/hooks/validate-state-yaml.sh +190 -0
- package/scripts/huddle/huddle-llm.mjs +361 -0
- package/scripts/huddle/huddle-server.mjs +46 -121
- package/scripts/local-triggers/autoupdate.sh +448 -78
- package/scripts/local-triggers/run-trigger.sh +13 -0
- package/scripts/maintenance/pin-integrity.mjs +364 -0
- package/scripts/poll-slack-events.sh +41 -9
- package/scripts/poller/slack-socket-mode.mjs +28 -3
- package/scripts/session/supervisor.mjs +80 -13
- package/scripts/spawn-session.sh +13 -0
- package/bin/maestro.test.mjs +0 -1574
- package/lib/action-executor.test.mjs +0 -871
- package/lib/archetype.test.mjs +0 -132
- package/lib/assurance/plan-note.test.mjs +0 -234
- package/lib/assurance/room-budget.test.mjs +0 -486
- package/lib/assurance/tier.test.mjs +0 -174
- package/lib/autonomy.test.mjs +0 -66
- package/lib/backlog.test.mjs +0 -302
- package/lib/backup/policy.test.mjs +0 -305
- package/lib/budget-escalate.test.mjs +0 -232
- package/lib/budget-guard.envelope.test.mjs +0 -476
- package/lib/budget-guard.test.mjs +0 -427
- package/lib/cadence-bus-requeue.test.mjs +0 -83
- package/lib/cadence-bus-schedule.test.mjs +0 -194
- package/lib/cadence-bus.test.mjs +0 -720
- package/lib/cadences.test.mjs +0 -230
- package/lib/capability/inventory.test.mjs +0 -232
- package/lib/capability.test.mjs +0 -78
- package/lib/channels/base-adapter.test.mjs +0 -590
- package/lib/channels/channels.test.mjs +0 -371
- package/lib/channels/contract.test.mjs +0 -162
- package/lib/channels/inbox-item.test.mjs +0 -368
- package/lib/channels/orgmail/adapter.test.mjs +0 -448
- package/lib/channels/pairing.test.mjs +0 -270
- package/lib/channels/repeat-suppressor.test.mjs +0 -134
- package/lib/channels/slack-adapter.test.mjs +0 -212
- package/lib/channels/telegram-adapter.test.mjs +0 -306
- package/lib/channels/voice/adapter.test.mjs +0 -278
- package/lib/channels/whatsapp/adapter-baileys.test.mjs +0 -359
- package/lib/channels/whatsapp/baileys-typing.test.mjs +0 -154
- package/lib/charter.test.mjs +0 -89
- package/lib/claude-bin.test.mjs +0 -131
- package/lib/cli/board.test.mjs +0 -227
- package/lib/cli/design.test.mjs +0 -270
- package/lib/cli/doctor-checks.test.mjs +0 -336
- package/lib/cli/global-setup-extras.test.mjs +0 -462
- package/lib/cli/inbox.test.mjs +0 -230
- package/lib/cli/session-ack.test.mjs +0 -63
- package/lib/cli/session.test.mjs +0 -613
- package/lib/collective/capture.test.mjs +0 -121
- package/lib/collective/cards.test.mjs +0 -114
- package/lib/collective/config.test.mjs +0 -123
- package/lib/collective/global-config.test.mjs +0 -220
- package/lib/collective/global-skills.test.mjs +0 -126
- package/lib/collective/presence.test.mjs +0 -95
- package/lib/collective/recall.test.mjs +0 -116
- package/lib/collective/vendor-skills.test.mjs +0 -306
- package/lib/comms/send-gate.test.mjs +0 -770
- package/lib/comms.test.mjs +0 -41
- package/lib/context/budget.test.mjs +0 -252
- package/lib/context/history-scope.test.mjs +0 -79
- package/lib/cost/ledger-row.test.mjs +0 -183
- package/lib/design/design-md.test.mjs +0 -318
- package/lib/design/fixtures/DESIGN.golden.md +0 -238
- package/lib/design/fixtures/PRODUCT.golden.md +0 -67
- package/lib/design/fixtures/foundation.json +0 -133
- package/lib/design/refresh-gate.test.mjs +0 -144
- package/lib/design/write.test.mjs +0 -241
- package/lib/diagnostics/alerts.test.mjs +0 -318
- package/lib/diagnostics/backup-freshness.test.mjs +0 -185
- package/lib/diagnostics/counters.test.mjs +0 -206
- package/lib/diagnostics/events.test.mjs +0 -290
- package/lib/diagnostics/otel.test.mjs +0 -196
- package/lib/diagnostics/trace.test.mjs +0 -251
- package/lib/env-compat.test.mjs +0 -104
- package/lib/execution/disposition.test.mjs +0 -553
- package/lib/execution/drive.test.mjs +0 -270
- package/lib/execution/effects.test.mjs +0 -344
- package/lib/execution/intake.test.mjs +0 -389
- package/lib/execution/journal.test.mjs +0 -261
- package/lib/execution/match.test.mjs +0 -235
- package/lib/execution/pipeline.test.mjs +0 -392
- package/lib/execution/route.test.mjs +0 -186
- package/lib/execution/surface-policy.test.mjs +0 -162
- package/lib/fs-atomic.test.mjs +0 -72
- package/lib/fs-ownership.test.mjs +0 -158
- package/lib/goals/admission.test.mjs +0 -164
- package/lib/goals/classify.test.mjs +0 -167
- package/lib/goals/collaborate.test.mjs +0 -336
- package/lib/goals/gaps.test.mjs +0 -284
- package/lib/goals/loop.test.mjs +0 -845
- package/lib/hooks/bus.test.mjs +0 -387
- package/lib/identity/persona.test.mjs +0 -142
- package/lib/kpi-sensors.test.mjs +0 -278
- package/lib/kpi.test.mjs +0 -244
- package/lib/learning/config.test.mjs +0 -75
- package/lib/learning/counters.test.mjs +0 -69
- package/lib/learning/curator-consolidate.test.mjs +0 -238
- package/lib/learning/curator.test.mjs +0 -106
- package/lib/learning/reflect.test.mjs +0 -0
- package/lib/learning/session-index.test.mjs +0 -125
- package/lib/learning/skill-writer.test.mjs +0 -210
- package/lib/mandate/audit.test.mjs +0 -195
- package/lib/mandate/contract.test.mjs +0 -185
- package/lib/mandate/derive.test.mjs +0 -274
- package/lib/mandate/model.test.mjs +0 -164
- package/lib/mandate/refresh.test.mjs +0 -389
- package/lib/mcp/server.test.mjs +0 -426
- package/lib/model-router/auth-profiles.test.mjs +0 -580
- package/lib/model-router/catalog.test.mjs +0 -385
- package/lib/model-router/economics.test.mjs +0 -438
- package/lib/model-router/failover.test.mjs +0 -439
- package/lib/model-router/health.test.mjs +0 -338
- package/lib/model-router/integration-coverage.test.mjs +0 -831
- package/lib/model-router/integration.test.mjs +0 -564
- package/lib/model-router/ledger.test.mjs +0 -415
- package/lib/model-router/llm-task.test.mjs +0 -392
- package/lib/model-router/org-credentials.test.mjs +0 -265
- package/lib/model-router/pricing-refresh.test.mjs +0 -286
- package/lib/model-router/reconcile.test.mjs +0 -316
- package/lib/model-router/repair.test.mjs +0 -180
- package/lib/model-router/spawn.test.mjs +0 -446
- package/lib/model-router/taxonomy.test.mjs +0 -410
- package/lib/model-router.test.mjs +0 -1207
- package/lib/org/activity.test.mjs +0 -134
- package/lib/org/approvals.test.mjs +0 -216
- package/lib/org/awareness.test.mjs +0 -159
- package/lib/org/board-mine-cache.test.mjs +0 -53
- package/lib/org/board.test.mjs +0 -187
- package/lib/org/bootstrap-context.test.mjs +0 -153
- package/lib/org/client.test.mjs +0 -1206
- package/lib/org/cohort-client.test.mjs +0 -126
- package/lib/org/cost-sync.test.mjs +0 -153
- package/lib/org/doctor.test.mjs +0 -346
- package/lib/org/engagement-ledger.test.mjs +0 -112
- package/lib/org/engagement.test.mjs +0 -739
- package/lib/org/handoff.test.mjs +0 -269
- package/lib/org/inbound/directedness.test.mjs +0 -668
- package/lib/org/inbound/facts.test.mjs +0 -471
- package/lib/org/inbound/hydrate.test.mjs +0 -908
- package/lib/org/inbound/index.test.mjs +0 -429
- package/lib/org/inbound/project.test.mjs +0 -287
- package/lib/org/integration-tools.test.mjs +0 -160
- package/lib/org/keys.test.mjs +0 -92
- package/lib/org/knowledge.test.mjs +0 -326
- package/lib/org/leases.test.mjs +0 -235
- package/lib/org/mesh-directives.test.mjs +0 -110
- package/lib/org/mesh-integration.test.mjs +0 -127
- package/lib/org/mesh.test.mjs +0 -400
- package/lib/org/messaging.test.mjs +0 -471
- package/lib/org/param-contract.test.mjs +0 -477
- package/lib/org/policy.test.mjs +0 -237
- package/lib/org/protocol.checksum.test.mjs +0 -90
- package/lib/org/protocol.test.mjs +0 -323
- package/lib/org/push.test.mjs +0 -792
- package/lib/org/registry.test.mjs +0 -100
- package/lib/org/resource-tools.test.mjs +0 -361
- package/lib/org/tool-access.test.mjs +0 -144
- package/lib/org/tool-surface-integration.test.mjs +0 -120
- package/lib/org/tool-surface.test.mjs +0 -1268
- package/lib/org/typing.test.mjs +0 -291
- package/lib/org/ui-parity.test.mjs +0 -560
- package/lib/org/verify.test.mjs +0 -194
- package/lib/org/work-ledger.test.mjs +0 -273
- package/lib/plan/adoption-e2e.test.mjs +0 -366
- package/lib/plan/budget-enforcement.test.mjs +0 -400
- package/lib/plan/compile.test.mjs +0 -382
- package/lib/plan/emit.test.mjs +0 -269
- package/lib/plan/explain.test.mjs +0 -188
- package/lib/prompts/parallelism.test.mjs +0 -177
- package/lib/rag/rag.test.mjs +0 -505
- package/lib/rate-guard.test.mjs +0 -272
- package/lib/reactive-gate.test.mjs +0 -57
- package/lib/render.test.mjs +0 -68
- package/lib/resource-governor.test.mjs +0 -488
- package/lib/scheduling/dynamic-jobs.test.mjs +0 -344
- package/lib/scheduling/jitter.test.mjs +0 -140
- package/lib/secrets/broker.test.mjs +0 -280
- package/lib/secrets/providers.test.mjs +0 -274
- package/lib/security/audit-engine.test.mjs +0 -424
- package/lib/security/coerce-args.test.mjs +0 -281
- package/lib/security/dangerous-tools.test.mjs +0 -68
- package/lib/security/external-content.test.mjs +0 -84
- package/lib/security/redact.test.mjs +0 -441
- package/lib/security/secret-equal.test.mjs +0 -55
- package/lib/session/config.test.mjs +0 -92
- package/lib/session/feed-core.test.mjs +0 -198
- package/lib/session/first-run.test.mjs +0 -121
- package/lib/session/frontdoor.test.mjs +0 -205
- package/lib/session/handoffs.test.mjs +0 -183
- package/lib/session/identity.test.mjs +0 -180
- package/lib/session/inbox-claims.test.mjs +0 -286
- package/lib/session/launch-args.test.mjs +0 -157
- package/lib/session/liveness.test.mjs +0 -100
- package/lib/session/status-summary.test.mjs +0 -118
- package/lib/session-permissions.test.mjs +0 -120
- package/lib/setup/claude-probe.test.mjs +0 -187
- package/lib/setup/completeness.test.mjs +0 -110
- package/lib/setup/context-pack.test.mjs +0 -89
- package/lib/setup/enrich.test.mjs +0 -115
- package/lib/setup/enroll-from-cohort.test.mjs +0 -300
- package/lib/setup/integration.test.mjs +0 -162
- package/lib/setup/io.test.mjs +0 -77
- package/lib/setup/runner.test.mjs +0 -132
- package/lib/setup/sections/identity.test.mjs +0 -234
- package/lib/setup/sections/inventory.test.mjs +0 -198
- package/lib/setup/sections/learning.test.mjs +0 -81
- package/lib/setup/sections/mandate.test.mjs +0 -388
- package/lib/setup/sections/messaging.test.mjs +0 -127
- package/lib/setup/sections/model.test.mjs +0 -240
- package/lib/setup/sections/org.test.mjs +0 -346
- package/lib/setup/sections/orgmail.test.mjs +0 -118
- package/lib/setup/sections/recovery.test.mjs +0 -98
- package/lib/setup/sections/subagents.test.mjs +0 -429
- package/lib/setup/sections/verify.test.mjs +0 -175
- package/lib/setup/sot.test.mjs +0 -81
- package/lib/setup/state.test.mjs +0 -115
- package/lib/singleton.test.mjs +0 -151
- package/lib/subagents/cli.test.mjs +0 -389
- package/lib/subagents/client.test.mjs +0 -309
- package/lib/subagents/gap.test.mjs +0 -234
- package/lib/subagents/lock.test.mjs +0 -248
- package/lib/subagents/manifest.test.mjs +0 -175
- package/lib/subagents/refs.test.mjs +0 -204
- package/lib/subagents/resolve.test.mjs +0 -422
- package/lib/subagents/schema.test.mjs +0 -328
- package/lib/telemetry/alerts.test.mjs +0 -109
- package/lib/telemetry/collect.test.mjs +0 -1274
- package/lib/tool-definitions-integration.test.mjs +0 -83
- package/lib/tool-definitions.test.mjs +0 -437
- package/lib/upgrade/global-refresh.test.mjs +0 -65
- package/lib/upgrade/launchd-reconcile.test.mjs +0 -272
- package/lib/upgrade/post-steps.test.mjs +0 -200
- package/lib/upgrade/verify.test.mjs +0 -164
- package/lib/util/fetch-timeout.test.mjs +0 -202
- package/lib/util/reconnect.test.mjs +0 -369
- package/lib/util/unhandled.test.mjs +0 -216
- package/lib/voice/outbound.test.mjs +0 -69
- package/lib/voice/session-rotation.test.mjs +0 -114
- package/lib/voice/stt.test.mjs +0 -226
- package/lib/voice/voice.test.mjs +0 -990
- package/scripts/cadence/enqueue-cadence-tick.test.mjs +0 -187
- package/scripts/ci/check-docs-accuracy.test.mjs +0 -409
- package/scripts/ci/check-durable-write-seam.test.mjs +0 -90
- package/scripts/ci/check-no-build-artifacts.test.mjs +0 -71
- package/scripts/ci/check-no-residual-identity.test.mjs +0 -202
- package/scripts/ci/check-skill-packs.test.mjs +0 -495
- package/scripts/ci/check-subagent-frontmatter.test.mjs +0 -124
- package/scripts/ci/check.test.mjs +0 -194
- package/scripts/ci/conformance-org-api.test.mjs +0 -425
- package/scripts/cloud-relay/voice/relay-identity.test.mjs +0 -96
- package/scripts/collective/hook-runner.test.mjs +0 -173
- package/scripts/cost/fleet-digest.test.mjs +0 -207
- package/scripts/cost/track-claude-usage-pricing.test.mjs +0 -183
- package/scripts/cost/track-claude-usage.test.mjs +0 -148
- package/scripts/daemon/agent-daemon-board-mine.test.mjs +0 -96
- package/scripts/daemon/agent-daemon-design.test.mjs +0 -238
- package/scripts/daemon/agent-daemon-frontdoor.test.mjs +0 -60
- package/scripts/daemon/agent-daemon.test.mjs +0 -995
- package/scripts/daemon/assurance-e2e.test.mjs +0 -613
- package/scripts/daemon/assurance.test.mjs +0 -1791
- package/scripts/daemon/board-mirror.test.mjs +0 -165
- package/scripts/daemon/cadence-consumer-frontdoor.test.mjs +0 -393
- package/scripts/daemon/cadence-consumer-governance.test.mjs +0 -276
- package/scripts/daemon/cadence-consumer.test.mjs +0 -776
- package/scripts/daemon/cadence-handlers.test.mjs +0 -837
- package/scripts/daemon/classifier-identity.test.mjs +0 -137
- package/scripts/daemon/classifier.test.mjs +0 -266
- package/scripts/daemon/classify-kind.test.mjs +0 -40
- package/scripts/daemon/context-compiler.test.mjs +0 -406
- package/scripts/daemon/deliver.test.mjs +0 -564
- package/scripts/daemon/dispatcher-cooldown.test.mjs +0 -122
- package/scripts/daemon/dispatcher-governance.test.mjs +0 -1013
- package/scripts/daemon/dispatcher-resume.test.mjs +0 -166
- package/scripts/daemon/dispatcher-session-continuity.test.mjs +0 -365
- package/scripts/daemon/execution-ladder.test.mjs +0 -470
- package/scripts/daemon/goal-steward-cadence.test.mjs +0 -312
- package/scripts/daemon/inbox-deferral-session.test.mjs +0 -49
- package/scripts/daemon/inbox-deferral.test.mjs +0 -336
- package/scripts/daemon/inbox-wake.test.mjs +0 -199
- package/scripts/daemon/integration.test.mjs +0 -149
- package/scripts/daemon/lib/self-echo.test.mjs +0 -153
- package/scripts/daemon/lib/session-router.test.mjs +0 -554
- package/scripts/daemon/prompt-builder-preamble.test.mjs +0 -210
- package/scripts/daemon/prompt-builder.test.mjs +0 -556
- package/scripts/daemon/responder-cost.test.mjs +0 -68
- package/scripts/daemon/responder-history.test.mjs +0 -221
- package/scripts/daemon/sdk-version.test.mjs +0 -31
- package/scripts/daemon/session-lock.test.mjs +0 -252
- package/scripts/daemon/session-outcomes.test.mjs +0 -533
- package/scripts/daemon/typing-registry.test.mjs +0 -102
- package/scripts/hooks/pre-send-audit.test.mjs +0 -354
- package/scripts/huddle/huddle-prompt.test.mjs +0 -176
- package/scripts/local-triggers/autoupdate.test.mjs +0 -518
- package/scripts/local-triggers/generate-plists.test.mjs +0 -456
- package/scripts/media-generation/brand-clause.test.mjs +0 -135
- package/scripts/org/send-orgmail.first-contact.test.mjs +0 -102
- package/scripts/poller/inbox-privilege-injection.test.mjs +0 -167
- package/scripts/poller/inbox-scan-poller.test.mjs +0 -295
- package/scripts/poller/lib/cloud-relay-dedup.test.mjs +0 -133
- package/scripts/poller/slack-socket-mode.test.mjs +0 -805
- package/scripts/poller-launchd/install.test.mjs +0 -243
- package/scripts/restore-from-backup.test.mjs +0 -181
- package/scripts/session/feed.test.mjs +0 -196
- package/scripts/session/supervisor-sh.test.mjs +0 -218
- package/scripts/session/supervisor.test.mjs +0 -482
- package/scripts/setup/configure-macos.test.mjs +0 -306
- package/scripts/setup/gen-subagent-manifest.test.mjs +0 -124
- package/scripts/setup/generate-agent-package-json.test.mjs +0 -143
- package/scripts/setup/generate-capability.test.mjs +0 -134
- package/scripts/setup/init-agent.test.mjs +0 -370
- package/scripts/setup/init-skill-marketplace.test.mjs +0 -193
- package/scripts/vendor/sync-skill-packs.test.mjs +0 -103
- package/scripts/watchdog/memory-watchdog.test.mjs +0 -64
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* scripts/daemon/goal-steward-cadence.test.mjs — the wiring that makes the
|
|
3
|
-
* self-directed loop actually RUN.
|
|
4
|
-
*
|
|
5
|
-
* Before this, `lib/goals/loop.mjs` existed and nothing ever called it: no
|
|
6
|
-
* standard cadence, no registry entry, no plist. A loop nobody triggers is a
|
|
7
|
-
* design document. These tests pin the trigger down:
|
|
8
|
-
*
|
|
9
|
-
* - `goal-steward` is a STANDARD cadence, so every agent gets a plist for it
|
|
10
|
-
* - it is GUARDED, so an agent with no adopted mandate costs ~nothing
|
|
11
|
-
* - it refreshes the mandate BEFORE measuring
|
|
12
|
-
* - it defaults to observe-only, whatever the caller forgot to pass
|
|
13
|
-
* - it escalates only when an open gap needs candidates it cannot produce
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
"use strict";
|
|
17
|
-
|
|
18
|
-
import { test } from "node:test";
|
|
19
|
-
import assert from "node:assert/strict";
|
|
20
|
-
import { mkdtempSync, rmSync, mkdirSync, writeFileSync } from "node:fs";
|
|
21
|
-
import { tmpdir } from "node:os";
|
|
22
|
-
import { join } from "node:path";
|
|
23
|
-
|
|
24
|
-
import { CADENCE_REGISTRY, getCadenceDef, guardGoalSteward } from "./cadence-handlers.mjs";
|
|
25
|
-
import { STANDARD_CADENCES } from "../../lib/cadences.mjs";
|
|
26
|
-
|
|
27
|
-
function makeRoot() {
|
|
28
|
-
const root = mkdtempSync(join(tmpdir(), "goal-cadence-"));
|
|
29
|
-
mkdirSync(join(root, "config"), { recursive: true });
|
|
30
|
-
return root;
|
|
31
|
-
}
|
|
32
|
-
function cleanup(root) { try { rmSync(root, { recursive: true, force: true }); } catch { /* best effort */ } }
|
|
33
|
-
|
|
34
|
-
/** Baseline seams: no network, no real loop. */
|
|
35
|
-
function seams(over = {}) {
|
|
36
|
-
return {
|
|
37
|
-
refreshImpl: async () => ({ ok: true, source: "server", tier: "fresh" }),
|
|
38
|
-
runImpl: async () => ({ ok: true, measured: [], admitted: [], rejected: [], escalations: [], drift: [], decisions: [] }),
|
|
39
|
-
...over,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ---------------------------------------------------------------------------
|
|
44
|
-
// Registration
|
|
45
|
-
// ---------------------------------------------------------------------------
|
|
46
|
-
|
|
47
|
-
test("goal-steward is a STANDARD cadence, so every agent gets one", () => {
|
|
48
|
-
const c = STANDARD_CADENCES.find((x) => x.id === "goal-steward");
|
|
49
|
-
assert.ok(c, "the loop must have a trigger or it never runs");
|
|
50
|
-
assert.equal(c.scope, "standard");
|
|
51
|
-
assert.equal(c.mode, "guarded");
|
|
52
|
-
// Daily, on a calendar slot — not a hot interval.
|
|
53
|
-
assert.deepEqual(c.calendar, { hour: 7, minute: 15 });
|
|
54
|
-
assert.equal(c.prompt, "schedules/triggers/goal-steward.md");
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test("the daemon can route the cadence it is about to be sent", () => {
|
|
58
|
-
const def = getCadenceDef("goal-steward");
|
|
59
|
-
assert.ok(def, "an unroutable cadence DLQs every tick");
|
|
60
|
-
assert.equal(def.mode, "guarded");
|
|
61
|
-
assert.equal(typeof def.guard, "function");
|
|
62
|
-
assert.equal(CADENCE_REGISTRY["goal-steward"].guard, guardGoalSteward);
|
|
63
|
-
// Scoped tool surface: reads + collaboration primitives, no shell.
|
|
64
|
-
const tools = CADENCE_REGISTRY["goal-steward"].allowedTools;
|
|
65
|
-
assert.ok(Array.isArray(tools) && tools.length > 0);
|
|
66
|
-
assert.ok(tools.includes("approval_request"), "gated work must be able to reach the approval path");
|
|
67
|
-
assert.ok(!tools.includes("Bash"), "the goal loop has no business running shell");
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
|
-
// The guard
|
|
72
|
-
// ---------------------------------------------------------------------------
|
|
73
|
-
|
|
74
|
-
test("the mandate is refreshed BEFORE the loop measures anything", async () => {
|
|
75
|
-
const root = makeRoot();
|
|
76
|
-
try {
|
|
77
|
-
const order = [];
|
|
78
|
-
await guardGoalSteward({ event: { cadence: "goal-steward" }, agentRoot: root, log: () => {} }, seams({
|
|
79
|
-
refreshImpl: async () => { order.push("refresh"); return { ok: true }; },
|
|
80
|
-
runImpl: async () => { order.push("run"); return { ok: true, measured: [], admitted: [], decisions: [] }; },
|
|
81
|
-
}));
|
|
82
|
-
assert.deepEqual(order, ["refresh", "run"], "measuring against a stale mandate is worse than not measuring");
|
|
83
|
-
} finally { cleanup(root); }
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test("enforcement defaults to OBSERVE when config/plan.yaml says nothing", async () => {
|
|
87
|
-
const root = makeRoot();
|
|
88
|
-
try {
|
|
89
|
-
let seen = null;
|
|
90
|
-
await guardGoalSteward({ event: {}, agentRoot: root, log: () => {} }, seams({
|
|
91
|
-
runImpl: async (d) => { seen = d.enforcement; return { ok: true, measured: [], admitted: [], decisions: [] }; },
|
|
92
|
-
}));
|
|
93
|
-
assert.equal(seen, "observe", "a loop that starts by writing is how you lose a fleet");
|
|
94
|
-
} finally { cleanup(root); }
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test("enforcement:active in config/plan.yaml turns the loop on", async () => {
|
|
98
|
-
const root = makeRoot();
|
|
99
|
-
try {
|
|
100
|
-
writeFileSync(join(root, "config", "plan.yaml"), "version: 1\nenforcement: active\nobligations: []\n", "utf-8");
|
|
101
|
-
let seen = null;
|
|
102
|
-
await guardGoalSteward({ event: {}, agentRoot: root, log: () => {} }, seams({
|
|
103
|
-
runImpl: async (d) => { seen = d.enforcement; return { ok: true, measured: [], admitted: [], decisions: [] }; },
|
|
104
|
-
}));
|
|
105
|
-
assert.equal(seen, "active");
|
|
106
|
-
} finally { cleanup(root); }
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test("any other enforcement value stays observe — fail-closed on the write path", async () => {
|
|
110
|
-
const root = makeRoot();
|
|
111
|
-
try {
|
|
112
|
-
writeFileSync(join(root, "config", "plan.yaml"), "enforcement: yes-please\n", "utf-8");
|
|
113
|
-
let seen = null;
|
|
114
|
-
await guardGoalSteward({ event: {}, agentRoot: root, log: () => {} }, seams({
|
|
115
|
-
runImpl: async (d) => { seen = d.enforcement; return { ok: true, measured: [], admitted: [], decisions: [] }; },
|
|
116
|
-
}));
|
|
117
|
-
assert.equal(seen, "observe");
|
|
118
|
-
} finally { cleanup(root); }
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
test("no adopted mandate completes INLINE — an idle seat costs one cache read", async () => {
|
|
122
|
-
const root = makeRoot();
|
|
123
|
-
try {
|
|
124
|
-
const r = await guardGoalSteward({ event: {}, agentRoot: root, log: () => {} }, seams({
|
|
125
|
-
runImpl: async () => ({ ok: false, skipped: "no mandate cache — this seat has never fetched an adopted mandate" }),
|
|
126
|
-
}));
|
|
127
|
-
assert.equal(r.ok, true, "a pre-adoption seat is not a bus failure");
|
|
128
|
-
assert.equal(r.decision, "inline");
|
|
129
|
-
assert.match(r.reason, /never fetched an adopted mandate/);
|
|
130
|
-
} finally { cleanup(root); }
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test("a satisfied mandate completes inline and never spawns a session", async () => {
|
|
134
|
-
const root = makeRoot();
|
|
135
|
-
try {
|
|
136
|
-
const r = await guardGoalSteward({ event: {}, agentRoot: root, log: () => {} }, seams({
|
|
137
|
-
runImpl: async () => ({
|
|
138
|
-
ok: true, measured: [{ objectiveKey: "pipeline", value: 4 }], admitted: [], rejected: [],
|
|
139
|
-
escalations: [], drift: [], decisions: [{ objectiveKey: "pipeline", action: "none" }],
|
|
140
|
-
}),
|
|
141
|
-
}));
|
|
142
|
-
assert.equal(r.decision, "inline");
|
|
143
|
-
assert.equal(r.measured, 1);
|
|
144
|
-
assert.equal(r.admitted, 0);
|
|
145
|
-
} finally { cleanup(root); }
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("a gap the deterministic planner SERVED completes inline — the work is already queued", async () => {
|
|
149
|
-
const root = makeRoot();
|
|
150
|
-
try {
|
|
151
|
-
writeFileSync(join(root, "config", "plan.yaml"), "enforcement: active\n", "utf-8");
|
|
152
|
-
const r = await guardGoalSteward({ event: {}, agentRoot: root, log: () => {} }, seams({
|
|
153
|
-
runImpl: async () => ({
|
|
154
|
-
ok: true,
|
|
155
|
-
measured: [{ objectiveKey: "pipeline", value: 1 }],
|
|
156
|
-
admitted: [{ objectiveKey: "pipeline", title: "Book calls" }],
|
|
157
|
-
rejected: [], escalations: [], drift: [],
|
|
158
|
-
decisions: [{ objectiveKey: "pipeline", action: "create" }],
|
|
159
|
-
}),
|
|
160
|
-
}));
|
|
161
|
-
assert.equal(r.decision, "inline", "no model is needed when the work already exists");
|
|
162
|
-
assert.equal(r.admitted, 1);
|
|
163
|
-
} finally { cleanup(root); }
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
test("an UNSERVED open gap escalates to a planning session, naming the objectives", async () => {
|
|
167
|
-
const root = makeRoot();
|
|
168
|
-
try {
|
|
169
|
-
writeFileSync(join(root, "config", "plan.yaml"), "enforcement: active\n", "utf-8");
|
|
170
|
-
const r = await guardGoalSteward({ event: {}, agentRoot: root, log: () => {} }, seams({
|
|
171
|
-
runImpl: async () => ({
|
|
172
|
-
ok: true,
|
|
173
|
-
measured: [{ objectiveKey: "pipeline", value: 1 }],
|
|
174
|
-
admitted: [], rejected: [], escalations: [], drift: [],
|
|
175
|
-
decisions: [{ objectiveKey: "pipeline", action: "create" }],
|
|
176
|
-
}),
|
|
177
|
-
}));
|
|
178
|
-
assert.equal(r.decision, "escalate");
|
|
179
|
-
assert.deepEqual(r.objectives, ["pipeline"]);
|
|
180
|
-
} finally { cleanup(root); }
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
test("OBSERVE-ONLY never escalates, even with an unserved gap", async () => {
|
|
184
|
-
const root = makeRoot();
|
|
185
|
-
try {
|
|
186
|
-
const r = await guardGoalSteward({ event: {}, agentRoot: root, log: () => {} }, seams({
|
|
187
|
-
runImpl: async () => ({
|
|
188
|
-
ok: true, measured: [], admitted: [], rejected: [], escalations: [], drift: [],
|
|
189
|
-
decisions: [{ objectiveKey: "pipeline", action: "create" }],
|
|
190
|
-
}),
|
|
191
|
-
}));
|
|
192
|
-
assert.equal(r.decision, "inline", "the observe window must not spend money on planning sessions");
|
|
193
|
-
} finally { cleanup(root); }
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// ---------------------------------------------------------------------------
|
|
197
|
-
// Failure containment
|
|
198
|
-
// ---------------------------------------------------------------------------
|
|
199
|
-
|
|
200
|
-
test("SERVER UNREACHABLE: a failed mandate refresh degrades to the cache, loudly", async () => {
|
|
201
|
-
const root = makeRoot();
|
|
202
|
-
try {
|
|
203
|
-
const logs = [];
|
|
204
|
-
const r = await guardGoalSteward({ event: {}, agentRoot: root, log: (l, m) => logs.push(`${l}:${m}`) }, seams({
|
|
205
|
-
refreshImpl: async () => ({ ok: false, reason: "call-threw:ECONNREFUSED" }),
|
|
206
|
-
}));
|
|
207
|
-
assert.equal(r.ok, true, "a partition must not stop the loop from running on cache");
|
|
208
|
-
assert.ok(logs.some((l) => /refresh failed/.test(l)));
|
|
209
|
-
} finally { cleanup(root); }
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
test("SERVER UNREACHABLE: a THROWING refresh is contained and logged", async () => {
|
|
213
|
-
const root = makeRoot();
|
|
214
|
-
try {
|
|
215
|
-
const logs = [];
|
|
216
|
-
const r = await guardGoalSteward({ event: {}, agentRoot: root, log: (l, m) => logs.push(`${l}:${m}`) }, seams({
|
|
217
|
-
refreshImpl: async () => { throw new Error("ECONNREFUSED"); },
|
|
218
|
-
}));
|
|
219
|
-
assert.equal(r.ok, true);
|
|
220
|
-
assert.ok(logs.some((l) => /refresh threw/.test(l)));
|
|
221
|
-
} finally { cleanup(root); }
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
test("a THROWING loop returns ok:false with the error — fail-open but never silent", async () => {
|
|
225
|
-
const root = makeRoot();
|
|
226
|
-
try {
|
|
227
|
-
const logs = [];
|
|
228
|
-
const r = await guardGoalSteward({ event: {}, agentRoot: root, log: (l, m) => logs.push(`${l}:${m}`) }, seams({
|
|
229
|
-
runImpl: async () => { throw new Error("loop exploded"); },
|
|
230
|
-
}));
|
|
231
|
-
assert.equal(r.ok, false);
|
|
232
|
-
assert.match(r.error, /loop exploded/);
|
|
233
|
-
assert.ok(logs.some((l) => l.startsWith("error:")), "the daemon keeps running, the failure is on the record");
|
|
234
|
-
} finally { cleanup(root); }
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
test("the guard never throws, whatever it is handed", async () => {
|
|
238
|
-
const r = await guardGoalSteward({ event: null, agentRoot: "/nonexistent-xyz", log: null }, seams({
|
|
239
|
-
runImpl: async () => null,
|
|
240
|
-
}));
|
|
241
|
-
assert.equal(typeof r.ok, "boolean");
|
|
242
|
-
assert.equal(r.cadence, "goal-steward");
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// ---------------------------------------------------------------------------
|
|
246
|
-
// THE SENSOR REGISTRY — the joint that made every KPI unmeasurable
|
|
247
|
-
// ---------------------------------------------------------------------------
|
|
248
|
-
|
|
249
|
-
test("the guard BUILDS the sensor registry and hands it to the loop", async () => {
|
|
250
|
-
const root = makeRoot();
|
|
251
|
-
try {
|
|
252
|
-
let got = null;
|
|
253
|
-
await guardGoalSteward(
|
|
254
|
-
{ event: { cadence: "goal-steward" }, agentRoot: root, log: () => {} },
|
|
255
|
-
seams({ runImpl: async (deps) => { got = deps; return { ok: true, measured: [], admitted: [], rejected: [], escalations: [], drift: [], decisions: [] }; } }),
|
|
256
|
-
);
|
|
257
|
-
assert.ok(got, "the loop ran");
|
|
258
|
-
assert.equal(typeof got.sensors, "object", "run() must receive a sensor registry");
|
|
259
|
-
// Real, executable sensors — not an empty object. Without this every
|
|
260
|
-
// objective returns {ok:false,"no-implementation"} and D3 can never admit.
|
|
261
|
-
assert.equal(typeof got.sensors.board_ready, "function");
|
|
262
|
-
assert.equal(typeof got.sensors.decision_list, "function");
|
|
263
|
-
assert.equal(typeof got.sensors.email_inbox, "function");
|
|
264
|
-
// …including a named refusal for every capability the derivation can pick.
|
|
265
|
-
assert.equal(typeof got.sensors.task_update, "function");
|
|
266
|
-
} finally { cleanup(root); }
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
test("a missing capability manifest passes reachable=undefined, NOT an empty set", async () => {
|
|
270
|
-
const root = makeRoot();
|
|
271
|
-
try {
|
|
272
|
-
let got = null;
|
|
273
|
-
await guardGoalSteward(
|
|
274
|
-
{ event: { cadence: "goal-steward" }, agentRoot: root, log: () => {} },
|
|
275
|
-
seams({ runImpl: async (deps) => { got = deps; return { ok: true, measured: [], admitted: [], rejected: [], escalations: [], drift: [], decisions: [] }; } }),
|
|
276
|
-
);
|
|
277
|
-
// measureKpi only enforces reachability when it is defined; an empty Set
|
|
278
|
-
// here would silently refuse every objective in the fleet.
|
|
279
|
-
assert.equal(got.reachable, undefined);
|
|
280
|
-
} finally { cleanup(root); }
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
test("the caller's sensors win — the registry is an override, not a mandate", async () => {
|
|
284
|
-
const root = makeRoot();
|
|
285
|
-
try {
|
|
286
|
-
let got = null;
|
|
287
|
-
const mine = { board_ready: async () => ({ value: 1 }) };
|
|
288
|
-
await guardGoalSteward(
|
|
289
|
-
{ event: { cadence: "goal-steward" }, agentRoot: root, log: () => {} },
|
|
290
|
-
seams({ sensors: mine, reachable: new Set(["board_ready"]),
|
|
291
|
-
runImpl: async (deps) => { got = deps; return { ok: true, measured: [], admitted: [], rejected: [], escalations: [], drift: [], decisions: [] }; } }),
|
|
292
|
-
);
|
|
293
|
-
assert.equal(got.sensors, mine);
|
|
294
|
-
assert.ok(got.reachable.has("board_ready"));
|
|
295
|
-
} finally { cleanup(root); }
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
test("a registry that cannot be built is LOUD, and the loop still runs", async () => {
|
|
299
|
-
const root = makeRoot();
|
|
300
|
-
const logs = [];
|
|
301
|
-
try {
|
|
302
|
-
let got = null;
|
|
303
|
-
await guardGoalSteward(
|
|
304
|
-
{ event: { cadence: "goal-steward" }, agentRoot: root, log: (l, m) => logs.push(`${l}:${m}`) },
|
|
305
|
-
seams({
|
|
306
|
-
// A poisoned root: resolveAgentRoot of a non-string throws inside the builder.
|
|
307
|
-
runImpl: async (deps) => { got = deps; return { ok: true, measured: [], admitted: [], rejected: [], escalations: [], drift: [], decisions: [] }; },
|
|
308
|
-
}),
|
|
309
|
-
);
|
|
310
|
-
assert.ok(got, "the guard never blocks the loop on a registry failure");
|
|
311
|
-
} finally { cleanup(root); }
|
|
312
|
-
});
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* inbox-deferral-session.test.mjs — promoteDeferred must leave a SESSION
|
|
3
|
-
* deferral alone (design §3.3). Both actors park items at `.yaml.deferred`:
|
|
4
|
-
* the daemon for a thread-lock burst (promoted on session close), the main
|
|
5
|
-
* session with `maestro inbox defer --until` (carries a column-0
|
|
6
|
-
* `deferred_until:` marker; the daemon's assurance sweep reopens it when due).
|
|
7
|
-
* A session close for the same channel must neither promote a session
|
|
8
|
-
* deferral early nor fold it away as `.processed-bundled`.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { test } from "node:test";
|
|
12
|
-
import assert from "node:assert/strict";
|
|
13
|
-
import { mkdtempSync, mkdirSync, writeFileSync, readdirSync, rmSync } from "node:fs";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import { tmpdir } from "node:os";
|
|
16
|
-
|
|
17
|
-
import { promoteDeferred } from "./inbox-deferral.mjs";
|
|
18
|
-
|
|
19
|
-
function makeAgentRoot() {
|
|
20
|
-
const root = mkdtempSync(join(tmpdir(), "maestro-deferral-session-"));
|
|
21
|
-
mkdirSync(join(root, "state", "inbox", "cohort"), { recursive: true });
|
|
22
|
-
return root;
|
|
23
|
-
}
|
|
24
|
-
function item(id, ts, extra = "") {
|
|
25
|
-
return `id: "${id}"\nservice: "cohort"\nchannel_id: "D001"\nthread_id: "t1"\ntimestamp: "${ts}"\ncontent: |\n body\n${extra}`;
|
|
26
|
-
}
|
|
27
|
-
function ls(root) { return readdirSync(join(root, "state", "inbox", "cohort")).sort(); }
|
|
28
|
-
|
|
29
|
-
test("promoteDeferred: a session deferral (deferred_until marker) is neither promoted nor bundled; legacy deferrals in the same thread still promote", () => {
|
|
30
|
-
const root = makeAgentRoot();
|
|
31
|
-
try {
|
|
32
|
-
// A: session deferral, oldest in the thread.
|
|
33
|
-
writeFileSync(join(root, "state/inbox/cohort/a.yaml.deferred"), item("A", "2026-09-08T09:00:00Z", 'deferred_until: "2026-09-09T09:00:00.000Z"\ndeferred_reason: "waiting on finance"\n'));
|
|
34
|
-
// C: daemon thread-lock deferral, newest — the one a session close promotes.
|
|
35
|
-
writeFileSync(join(root, "state/inbox/cohort/c.yaml.deferred"), item("C", "2026-09-08T10:00:00Z"));
|
|
36
|
-
const r = promoteDeferred("D001", root);
|
|
37
|
-
assert.equal(r.promoted, 1);
|
|
38
|
-
assert.equal(r.bundled, 0, "a session deferral is not a burst duplicate — it must not be folded away");
|
|
39
|
-
assert.deepEqual(ls(root), ["a.yaml.deferred", "c.yaml"]);
|
|
40
|
-
// With no daemon deferral at all, a session close promotes nothing (A is not due yet).
|
|
41
|
-
rmSync(join(root, "state/inbox/cohort/c.yaml"));
|
|
42
|
-
assert.deepEqual(promoteDeferred("D001", root), { promoted: 0, bundled: 0, service: null });
|
|
43
|
-
assert.deepEqual(ls(root), ["a.yaml.deferred"]);
|
|
44
|
-
// An indented look-alike inside the body is NOT a marker (column-0 only).
|
|
45
|
-
writeFileSync(join(root, "state/inbox/cohort/b.yaml.deferred"), `id: "B"\nservice: "cohort"\nchannel_id: "D001"\nthread_id: "t1"\ntimestamp: "2026-09-08T11:00:00Z"\ncontent: |\n deferred_until: "2099-01-01T00:00:00Z"\n`);
|
|
46
|
-
assert.equal(promoteDeferred("D001", root).promoted, 1);
|
|
47
|
-
assert.deepEqual(ls(root), ["a.yaml.deferred", "b.yaml"]);
|
|
48
|
-
} finally { rmSync(root, { recursive: true, force: true }); }
|
|
49
|
-
});
|