@cohortapp/agent-sdk 2.16.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 +23 -7
- 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/poller-daemon-setup.md +4 -1
- 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/context/budget.mjs +327 -0
- package/lib/context/history-scope.mjs +138 -0
- 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/economics.mjs +9 -0
- package/lib/model-router/failover.mjs +67 -16
- package/lib/model-router/llm-task.mjs +39 -3
- package/lib/model-router/resolve.mjs +95 -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 +82 -4
- package/lib/org/inbound/hydrate.mjs +555 -51
- 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 +15 -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 +104 -59
- package/scripts/daemon/deliver.mjs +30 -1
- package/scripts/daemon/dispatcher.mjs +804 -157
- package/scripts/daemon/health.mjs +14 -1
- package/scripts/daemon/lib/session-router.mjs +310 -42
- package/scripts/daemon/maestro-daemon.mjs +11 -0
- package/scripts/daemon/prompt-builder.mjs +121 -12
- package/scripts/daemon/responder.mjs +315 -146
- 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/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 -453
- 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 -300
- 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/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 -295
- package/scripts/daemon/prompt-builder-preamble.test.mjs +0 -210
- package/scripts/daemon/prompt-builder.test.mjs +0 -344
- package/scripts/daemon/responder-cost.test.mjs +0 -68
- package/scripts/daemon/responder-history.test.mjs +0 -185
- 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,188 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* explain.test.mjs — the OFFLINE provenance walk (SPEC §8).
|
|
3
|
-
* Run: node --test lib/plan/explain.test.mjs
|
|
4
|
-
*
|
|
5
|
-
* The claim this module has to defend: every scheduled job an agent runs can be
|
|
6
|
-
* traced back to an outcome a human adopted, WITHOUT calling hq. These tests
|
|
7
|
-
* inject the whole world (plan, mandate cache, agent.json) so the walk is proven
|
|
8
|
-
* to touch no network and to REPORT an incomplete chain rather than fake one.
|
|
9
|
-
*/
|
|
10
|
-
"use strict";
|
|
11
|
-
|
|
12
|
-
import { test } from "node:test";
|
|
13
|
-
import assert from "node:assert/strict";
|
|
14
|
-
|
|
15
|
-
import { explain, findObligation, findObjective, findCharterSection, renderExplanation } from "./explain.mjs";
|
|
16
|
-
|
|
17
|
-
const OBLIGATION = {
|
|
18
|
-
key: "schedule.measure.pipeline-coverage",
|
|
19
|
-
kind: "SCHEDULE",
|
|
20
|
-
cadence_id: "measure-pipeline-coverage",
|
|
21
|
-
status: "active",
|
|
22
|
-
source: { origin: "mandate", ref: "obj_7Kx", charter_section: "cs_12" },
|
|
23
|
-
objective_id: "obj_7Kx",
|
|
24
|
-
schedule: { calendar: { weekday: 2, hour: 14, minute: 30 } },
|
|
25
|
-
uses: ["crm_list_deals"],
|
|
26
|
-
allowed_tools: ["Glob", "Grep", "LS", "Read", "crm_list_deals"],
|
|
27
|
-
budget_cents_per_period: 500,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const STANDARD_OBLIGATION = {
|
|
31
|
-
key: "schedule.inbox-processor",
|
|
32
|
-
kind: "SCHEDULE",
|
|
33
|
-
cadence_id: "inbox-processor",
|
|
34
|
-
status: "active",
|
|
35
|
-
source: { origin: "standard", ref: "inbox-processor" },
|
|
36
|
-
schedule: { interval: 300 },
|
|
37
|
-
uses: ["email_inbox"],
|
|
38
|
-
allowed_tools: ["Read", "email_inbox"],
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const PLAN = { schemaVersion: 1, obligations: [OBLIGATION, STANDARD_OBLIGATION] };
|
|
42
|
-
|
|
43
|
-
function mandate(over = {}) {
|
|
44
|
-
return {
|
|
45
|
-
version: 3,
|
|
46
|
-
body: {
|
|
47
|
-
memberId: "mem_SELF",
|
|
48
|
-
objectives: [{
|
|
49
|
-
id: "obj_7Kx",
|
|
50
|
-
key: "pipeline-coverage",
|
|
51
|
-
text: "Keep qualified pipeline at 3x the quarterly target",
|
|
52
|
-
metric: "pipeline_coverage_x",
|
|
53
|
-
target: 3,
|
|
54
|
-
direction: "up",
|
|
55
|
-
cadence: "weekly",
|
|
56
|
-
state: "active",
|
|
57
|
-
memberId: "mem_SELF",
|
|
58
|
-
adoptedById: "mem_HUMAN",
|
|
59
|
-
adoptedAt: "2026-08-01T10:00:00.000Z",
|
|
60
|
-
charterSectionId: "cs_12",
|
|
61
|
-
sensor: { capability: "crm_list_deals", source: "method" },
|
|
62
|
-
...over,
|
|
63
|
-
}],
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const AGENT_CFG = {
|
|
69
|
-
charter: {
|
|
70
|
-
sections: [{ id: "cs_12", kind: "PILLAR", title: "Revenue durability", body: "Sustain a predictable commercial engine." }],
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
test("explain walks obligation → objective → adoption → charter clause", () => {
|
|
75
|
-
const res = explain({ agentRoot: "/agent", key: "schedule.measure.pipeline-coverage", plan: PLAN, mandate: mandate(), agentCfg: AGENT_CFG });
|
|
76
|
-
|
|
77
|
-
assert.equal(res.found, true);
|
|
78
|
-
assert.equal(res.gap, null);
|
|
79
|
-
const steps = res.provenance.map((p) => p.step);
|
|
80
|
-
assert.deepEqual(steps, ["obligation", "objective", "adoption", "charter"]);
|
|
81
|
-
|
|
82
|
-
const [ob, obj, adopt, charter] = res.provenance;
|
|
83
|
-
assert.equal(ob.kind, "SCHEDULE");
|
|
84
|
-
assert.deepEqual(ob.allowedTools, ["Glob", "Grep", "LS", "Read", "crm_list_deals"]);
|
|
85
|
-
assert.equal(obj.metric, "pipeline_coverage_x");
|
|
86
|
-
assert.equal(obj.target, 3);
|
|
87
|
-
assert.equal(adopt.adoptedById, "mem_HUMAN");
|
|
88
|
-
assert.equal(adopt.selfAdopted, false);
|
|
89
|
-
assert.equal(charter.resolved, true);
|
|
90
|
-
assert.equal(charter.title, "Revenue durability");
|
|
91
|
-
assert.match(res.summary, /Keep qualified pipeline/);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test("explain resolves a launchd CADENCE ID, not just the obligation key", () => {
|
|
95
|
-
// A launchd job only knows `measure-pipeline-coverage`.
|
|
96
|
-
const res = explain({ key: "measure-pipeline-coverage", plan: PLAN, mandate: mandate(), agentCfg: AGENT_CFG });
|
|
97
|
-
assert.equal(res.found, true);
|
|
98
|
-
assert.equal(res.key, "schedule.measure.pipeline-coverage");
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
test("a standard cadence is honestly reported as the floor, not as a gap", () => {
|
|
102
|
-
const res = explain({ key: "inbox-processor", plan: PLAN, mandate: mandate(), agentCfg: AGENT_CFG });
|
|
103
|
-
assert.equal(res.found, true);
|
|
104
|
-
assert.equal(res.gap, null, "the baseline set is not drift");
|
|
105
|
-
assert.match(res.summary, /baseline every agent runs/);
|
|
106
|
-
assert.equal(res.provenance.length, 1);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test("a mandate-origin obligation with no objective_id is flagged as unjustified", () => {
|
|
110
|
-
const orphan = { ...OBLIGATION, key: "schedule.orphan", cadence_id: "orphan", objective_id: undefined, source: { origin: "mandate" } };
|
|
111
|
-
const res = explain({ key: "schedule.orphan", plan: { obligations: [orphan] }, mandate: mandate(), agentCfg: AGENT_CFG });
|
|
112
|
-
assert.equal(res.gap, "no-objective");
|
|
113
|
-
assert.match(res.summary, /unjustified/);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test("SELF-ADOPTION is surfaced as a governance violation (the anti-Goodhart law)", () => {
|
|
117
|
-
// adoptedById === the objective's own owner: a seat defining, measuring and
|
|
118
|
-
// being graded on the same number.
|
|
119
|
-
const res = explain({ key: "schedule.measure.pipeline-coverage", plan: PLAN, mandate: mandate({ adoptedById: "mem_SELF" }), agentCfg: AGENT_CFG });
|
|
120
|
-
assert.equal(res.gap, "self-adopted");
|
|
121
|
-
assert.match(res.summary, /GOVERNANCE VIOLATION/);
|
|
122
|
-
assert.equal(res.provenance.find((p) => p.step === "adoption").selfAdopted, true);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test("a proposed (un-adopted) objective reports the not-adopted gap", () => {
|
|
126
|
-
const res = explain({ key: "schedule.measure.pipeline-coverage", plan: PLAN, mandate: mandate({ state: "proposed", adoptedById: null, adoptedAt: null }), agentCfg: AGENT_CFG });
|
|
127
|
-
assert.equal(res.gap, "not-adopted");
|
|
128
|
-
assert.match(res.summary, /not yet adopted/);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test("an incomplete chain is REPORTED, never faked", () => {
|
|
132
|
-
// No mandate cache at all (an offline agent that never synced).
|
|
133
|
-
const noCache = explain({ key: "schedule.measure.pipeline-coverage", plan: PLAN, mandate: null, agentCfg: AGENT_CFG });
|
|
134
|
-
assert.equal(noCache.found, true);
|
|
135
|
-
assert.equal(noCache.gap, "no-mandate-cache");
|
|
136
|
-
assert.equal(noCache.provenance.length, 1, "the walk stops where the evidence stops");
|
|
137
|
-
|
|
138
|
-
// No plan at all.
|
|
139
|
-
const noPlan = explain({ key: "whatever", plan: null });
|
|
140
|
-
assert.equal(noPlan.found, false);
|
|
141
|
-
assert.equal(noPlan.gap, "no-plan");
|
|
142
|
-
|
|
143
|
-
// Plan present, key unknown.
|
|
144
|
-
const noOb = explain({ key: "schedule.nonexistent", plan: PLAN, mandate: mandate() });
|
|
145
|
-
assert.equal(noOb.found, false);
|
|
146
|
-
assert.equal(noOb.gap, "no-obligation");
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
test("an unresolvable charter clause is marked unresolved rather than dropped", () => {
|
|
150
|
-
const res = explain({ key: "schedule.measure.pipeline-coverage", plan: PLAN, mandate: mandate(), agentCfg: { charter: { sections: [] } } });
|
|
151
|
-
const charter = res.provenance.find((p) => p.step === "charter");
|
|
152
|
-
assert.ok(charter, "the charter step is still emitted");
|
|
153
|
-
assert.equal(charter.resolved, false);
|
|
154
|
-
assert.equal(charter.sectionId, "cs_12");
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test("lookup helpers match on either id or key", () => {
|
|
158
|
-
assert.equal(findObligation(PLAN, "measure-pipeline-coverage").key, "schedule.measure.pipeline-coverage");
|
|
159
|
-
assert.equal(findObligation(PLAN, "nope"), null);
|
|
160
|
-
const body = mandate().body;
|
|
161
|
-
assert.equal(findObjective(body, "obj_7Kx").key, "pipeline-coverage");
|
|
162
|
-
assert.equal(findObjective(body, "pipeline-coverage").id, "obj_7Kx");
|
|
163
|
-
assert.equal(findObjective(body, "nope"), null);
|
|
164
|
-
assert.equal(findCharterSection(AGENT_CFG, "cs_12").kind, "PILLAR");
|
|
165
|
-
assert.equal(findCharterSection(AGENT_CFG, "cs_99"), null);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
test("renderExplanation prints every step it walked", () => {
|
|
169
|
-
const res = explain({ key: "schedule.measure.pipeline-coverage", plan: PLAN, mandate: mandate(), agentCfg: AGENT_CFG });
|
|
170
|
-
const text = renderExplanation(res);
|
|
171
|
-
assert.match(text, /obligation {2}schedule\.measure\.pipeline-coverage/);
|
|
172
|
-
assert.match(text, /objective {3}pipeline-coverage/);
|
|
173
|
-
assert.match(text, /adoption {4}by mem_HUMAN/);
|
|
174
|
-
assert.match(text, /charter {5}cs_12 — Revenue durability/);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test("explain touches no network and no clock (pure over injected inputs)", () => {
|
|
178
|
-
// Same inputs, twice, with fetch sabotaged: identical output.
|
|
179
|
-
const realFetch = globalThis.fetch;
|
|
180
|
-
globalThis.fetch = () => { throw new Error("explain must not call the network"); };
|
|
181
|
-
try {
|
|
182
|
-
const a = explain({ key: "schedule.measure.pipeline-coverage", plan: PLAN, mandate: mandate(), agentCfg: AGENT_CFG });
|
|
183
|
-
const b = explain({ key: "schedule.measure.pipeline-coverage", plan: PLAN, mandate: mandate(), agentCfg: AGENT_CFG });
|
|
184
|
-
assert.deepEqual(a, b);
|
|
185
|
-
} finally {
|
|
186
|
-
globalThis.fetch = realFetch;
|
|
187
|
-
}
|
|
188
|
-
});
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* parallelism.test.mjs — the fleet-wide parallelism directive (WP-M7 mechanic 5).
|
|
3
|
-
*
|
|
4
|
-
* Three things are pinned here, and each has a distinct failure it prevents:
|
|
5
|
-
*
|
|
6
|
-
* 1. THE BYTES. The directive is quoted verbatim in the design spec and is the
|
|
7
|
-
* one place a fleet-wide behaviour change is auditable. A silent reword —
|
|
8
|
-
* dropping the file-scope sentence, say — would turn "maximum safe
|
|
9
|
-
* parallelism" into two agents editing one file. So the expected text is
|
|
10
|
-
* written out longhand below, NOT derived from the constant.
|
|
11
|
-
* 2. IDEMPOTENCE. Two seams apply it (`session spawn` and the daemon's
|
|
12
|
-
* prompt-builder) and they compose. A doubled directive reads as emphasis
|
|
13
|
-
* to a model, which is exactly how the safety sentence loses to the
|
|
14
|
-
* permission sentence.
|
|
15
|
-
* 3. BOTH WIRINGS. A constant nothing calls is worth nothing; the two seams
|
|
16
|
-
* are driven for real here.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { test } from "node:test";
|
|
20
|
-
import assert from "node:assert/strict";
|
|
21
|
-
|
|
22
|
-
import { PARALLELISM_DIRECTIVE, withParallelism, countParallelism } from "./parallelism.mjs";
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* The directive, longhand. Deliberately NOT built from the import: a test that
|
|
26
|
-
* compares a constant to itself proves nothing about the wording.
|
|
27
|
-
*/
|
|
28
|
-
const EXPECTED = [
|
|
29
|
-
"You are allowed to run multiple sub-agents concurrently.",
|
|
30
|
-
"",
|
|
31
|
-
"When the plan contains independent tasks, dispatch them together in a single parallel batch rather than waiting for each task to finish before starting the next.",
|
|
32
|
-
"",
|
|
33
|
-
"Only run tasks sequentially when one task genuinely depends on the output of another.",
|
|
34
|
-
"",
|
|
35
|
-
"Before dispatching any batch, check the planned file scope for each task and ensure that no two agents are assigned to edit the same file. If tasks would overlap on a file, sequence those tasks or redefine their scope to eliminate the conflict.",
|
|
36
|
-
"",
|
|
37
|
-
"Default to maximum safe parallelism.",
|
|
38
|
-
].join("\n");
|
|
39
|
-
|
|
40
|
-
test("PARALLELISM_DIRECTIVE is the spec's text, byte for byte", () => {
|
|
41
|
-
assert.equal(PARALLELISM_DIRECTIVE, EXPECTED);
|
|
42
|
-
// The two sentences that carry the whole point, named individually so a
|
|
43
|
-
// partial reword fails with a readable diff rather than one giant blob.
|
|
44
|
-
assert.match(PARALLELISM_DIRECTIVE, /single parallel batch/);
|
|
45
|
-
assert.match(PARALLELISM_DIRECTIVE, /no two agents are assigned to edit the same file/);
|
|
46
|
-
assert.ok(!PARALLELISM_DIRECTIVE.endsWith("\n"), "no trailing newline — the joiner adds the separator");
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("withParallelism prepends once and is idempotent", () => {
|
|
50
|
-
const prompt = "Reply to the message below.";
|
|
51
|
-
const once = withParallelism(prompt);
|
|
52
|
-
assert.ok(once.startsWith(PARALLELISM_DIRECTIVE), "the directive leads");
|
|
53
|
-
assert.ok(once.endsWith(prompt), "the caller's prompt survives intact");
|
|
54
|
-
assert.equal(countParallelism(once), 1);
|
|
55
|
-
|
|
56
|
-
const twice = withParallelism(once);
|
|
57
|
-
assert.equal(twice, once, "a second application changes nothing");
|
|
58
|
-
assert.equal(countParallelism(twice), 1);
|
|
59
|
-
|
|
60
|
-
const thrice = withParallelism(withParallelism(withParallelism(prompt)));
|
|
61
|
-
assert.equal(countParallelism(thrice), 1);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test("withParallelism tolerates an empty or non-string prompt", () => {
|
|
65
|
-
assert.equal(withParallelism(""), PARALLELISM_DIRECTIVE);
|
|
66
|
-
assert.equal(withParallelism(" \n "), PARALLELISM_DIRECTIVE);
|
|
67
|
-
assert.equal(withParallelism(undefined), PARALLELISM_DIRECTIVE);
|
|
68
|
-
assert.equal(withParallelism(null), PARALLELISM_DIRECTIVE);
|
|
69
|
-
assert.equal(withParallelism(42), PARALLELISM_DIRECTIVE);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test("a prompt that already carries the directive mid-body is not re-led", () => {
|
|
73
|
-
const embedded = `Context first.\n\n${PARALLELISM_DIRECTIVE}\n\nThen the task.`;
|
|
74
|
-
assert.equal(withParallelism(embedded), embedded);
|
|
75
|
-
assert.equal(countParallelism(withParallelism(embedded)), 1);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test("countParallelism counts non-overlapping occurrences", () => {
|
|
79
|
-
assert.equal(countParallelism(""), 0);
|
|
80
|
-
assert.equal(countParallelism(null), 0);
|
|
81
|
-
assert.equal(countParallelism("nothing here"), 0);
|
|
82
|
-
assert.equal(countParallelism(`${PARALLELISM_DIRECTIVE}\n\n${PARALLELISM_DIRECTIVE}`), 2);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// ── the two wired seams ─────────────────────────────────────────────────────
|
|
86
|
-
|
|
87
|
-
test("maestro session spawn leads every peer prompt with the directive, exactly once", async () => {
|
|
88
|
-
const { buildSpawnArgs } = await import("../cli/session.mjs");
|
|
89
|
-
const prompt = "Sweep the backlog and file what you find.";
|
|
90
|
-
const args = buildSpawnArgs({ first: "nova", slug: "sweep", prompt, env: {}, allowedTools: [] });
|
|
91
|
-
|
|
92
|
-
assert.equal(args[0], "--name");
|
|
93
|
-
assert.equal(args[1], "nova-sweep");
|
|
94
|
-
const sent = args[args.length - 1];
|
|
95
|
-
assert.ok(sent.startsWith(PARALLELISM_DIRECTIVE), "the peer's prompt is led by the directive");
|
|
96
|
-
assert.ok(sent.endsWith(prompt));
|
|
97
|
-
assert.equal(countParallelism(sent), 1);
|
|
98
|
-
|
|
99
|
-
// The composing case: a prompt that already carries it is not doubled.
|
|
100
|
-
const pre = withParallelism(prompt);
|
|
101
|
-
const again = buildSpawnArgs({ first: "nova", slug: "sweep", prompt: pre, env: {}, allowedTools: [] });
|
|
102
|
-
assert.equal(countParallelism(again[again.length - 1]), 1);
|
|
103
|
-
assert.equal(again[again.length - 1], pre);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test("the daemon's prompt-builder leads every sub-session prompt with the directive, exactly once", async (t) => {
|
|
107
|
-
const { mkdtempSync, mkdirSync, writeFileSync } = await import("node:fs");
|
|
108
|
-
const { join } = await import("node:path");
|
|
109
|
-
const { tmpdir } = await import("node:os");
|
|
110
|
-
|
|
111
|
-
const root = mkdtempSync(join(tmpdir(), "maestro-parallelism-prompt-"));
|
|
112
|
-
mkdirSync(join(root, "config"), { recursive: true });
|
|
113
|
-
writeFileSync(join(root, "config", "agent.json"), JSON.stringify({ firstName: "Nova" }));
|
|
114
|
-
const prevAgentDir = process.env.AGENT_DIR;
|
|
115
|
-
process.env.AGENT_DIR = root;
|
|
116
|
-
t.after(() => {
|
|
117
|
-
if (prevAgentDir === undefined) delete process.env.AGENT_DIR;
|
|
118
|
-
else process.env.AGENT_DIR = prevAgentDir;
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
const url = new URL("../../scripts/daemon/prompt-builder.mjs", import.meta.url);
|
|
122
|
-
const pb = await import(`${url.href}?parallelism=${Math.random()}`);
|
|
123
|
-
const prompt = await pb.buildPrompt(
|
|
124
|
-
{ sender: "Ana", content: "Three unrelated things need doing.", channel: "slack" },
|
|
125
|
-
{ action: "respond", priority: "normal", summary: "three things" },
|
|
126
|
-
{ type: "inbox" },
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
assert.ok(prompt.startsWith(PARALLELISM_DIRECTIVE), "the directive leads the built prompt");
|
|
130
|
-
assert.equal(countParallelism(prompt), 1);
|
|
131
|
-
assert.match(prompt, /Three unrelated things need doing\./, "the item's own content is still there");
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test("the persona's precedence sentence names itself, so leading the prompt with the directive cannot mis-scope it", async (t) => {
|
|
135
|
-
// The sentence used to read "The section above … anything below". That was
|
|
136
|
-
// true only while the persona was the first thing in the prompt; once the
|
|
137
|
-
// directive leads, "above" has two candidate referents and the directive
|
|
138
|
-
// itself falls outside the rule (it is above, not below). Nothing else pins
|
|
139
|
-
// this ordering, so it is pinned here, beside the change that broke it.
|
|
140
|
-
const { mkdtempSync, mkdirSync, writeFileSync } = await import("node:fs");
|
|
141
|
-
const { join } = await import("node:path");
|
|
142
|
-
const { tmpdir } = await import("node:os");
|
|
143
|
-
|
|
144
|
-
const root = mkdtempSync(join(tmpdir(), "maestro-parallelism-persona-"));
|
|
145
|
-
mkdirSync(join(root, "config"), { recursive: true });
|
|
146
|
-
writeFileSync(join(root, "config", "agent.json"), JSON.stringify({ firstName: "Nova", lastName: "Reyes", title: "Chief of Staff" }));
|
|
147
|
-
writeFileSync(join(root, "config", "company.json"), JSON.stringify({ name: "Northwind" }));
|
|
148
|
-
const prevAgentDir = process.env.AGENT_DIR;
|
|
149
|
-
process.env.AGENT_DIR = root;
|
|
150
|
-
t.after(() => {
|
|
151
|
-
if (prevAgentDir === undefined) delete process.env.AGENT_DIR;
|
|
152
|
-
else process.env.AGENT_DIR = prevAgentDir;
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const url = new URL("../../scripts/daemon/prompt-builder.mjs", import.meta.url);
|
|
156
|
-
const pb = await import(`${url.href}?persona=${Math.random()}`);
|
|
157
|
-
const prompt = await pb.buildPrompt(
|
|
158
|
-
{ sender: "Ana", content: "Three unrelated things need doing.", channel: "slack" },
|
|
159
|
-
{ action: "respond", priority: "normal", summary: "three things" },
|
|
160
|
-
{ type: "inbox" },
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
assert.ok(prompt.startsWith(PARALLELISM_DIRECTIVE), "the directive leads");
|
|
164
|
-
assert.ok(
|
|
165
|
-
!/The section above is your identity/.test(prompt),
|
|
166
|
-
"a positional referent is wrong the moment anything is prepended",
|
|
167
|
-
);
|
|
168
|
-
assert.match(
|
|
169
|
-
prompt,
|
|
170
|
-
/This section is your identity, resolved from your organisation's record of you\. Where anything else in this prompt conflicts with it, this section wins\./,
|
|
171
|
-
"the precedence rule names itself and covers the whole prompt",
|
|
172
|
-
);
|
|
173
|
-
assert.ok(
|
|
174
|
-
prompt.indexOf(PARALLELISM_DIRECTIVE) < prompt.indexOf("This section is your identity"),
|
|
175
|
-
"the directive leads and the persona follows — the ordering the sentence had to stop assuming",
|
|
176
|
-
);
|
|
177
|
-
});
|