@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,366 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/plan/adoption-e2e.test.mjs — the SDK half of THE ADOPTION PROOF.
|
|
3
|
-
*
|
|
4
|
-
* The state this exists to end: seat A016 compiled 28 obligations — 24 SCHEDULE,
|
|
5
|
-
* 4 REACT, **0 OUTCOME** — because 0 of its 35 objectives were adopted. With no
|
|
6
|
-
* OUTCOME obligation there is no measured KPI, with no measured KPI there is no
|
|
7
|
-
* gap, and `lib/goals/admission.mjs` refuses every candidate at the `adoption`
|
|
8
|
-
* gate before the honesty gate is even reached. D3 (self-directed work) was
|
|
9
|
-
* structurally incapable of producing anything, and the whole ladder was inert.
|
|
10
|
-
*
|
|
11
|
-
* The input here is NOT a hand-written fixture. `MANDATE_BODY` is the byte
|
|
12
|
-
* output of hq's real `mandate.adopt` handler — see
|
|
13
|
-
* `~/hq/src/server/methods/mandate/adoption-e2e.test.ts`, which writes it to
|
|
14
|
-
* `$MANDATE_ADOPTION_OUT`. Set `MANDATE_ADOPTION_IN` to that file to re-run this
|
|
15
|
-
* against a freshly-published body; otherwise the committed copy below is used,
|
|
16
|
-
* so the proof survives in CI without a cross-repo dependency. Each repo
|
|
17
|
-
* agreeing with itself proves nothing; the number crossing the boundary does.
|
|
18
|
-
*
|
|
19
|
-
* The four things proven, in order:
|
|
20
|
-
* 1. an ADOPTED objective compiles an OUTCOME obligation (it used not to
|
|
21
|
-
* exist at all, because nothing was ever adopted);
|
|
22
|
-
* 2. a real METHOD sensor measures it and the sample is `source:"method"`;
|
|
23
|
-
* 3. the gap admits a proactive backlog item, and every gate that passed it
|
|
24
|
-
* is named;
|
|
25
|
-
* 4. the counterfactuals: the SAME objective left `proposed`, or SELF-adopted,
|
|
26
|
-
* compiles nothing and admits nothing.
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
"use strict";
|
|
30
|
-
|
|
31
|
-
import { test } from "node:test";
|
|
32
|
-
import assert from "node:assert/strict";
|
|
33
|
-
import { mkdtempSync, mkdirSync, readFileSync, existsSync } from "node:fs";
|
|
34
|
-
import yaml from "js-yaml";
|
|
35
|
-
import { tmpdir } from "node:os";
|
|
36
|
-
import { join } from "node:path";
|
|
37
|
-
|
|
38
|
-
import { compilePlan } from "./compile.mjs";
|
|
39
|
-
import { writeCache } from "../mandate/cache.mjs";
|
|
40
|
-
import { runGoalSteward, GOALS_QUEUE_REL } from "../goals/loop.mjs";
|
|
41
|
-
import { admit } from "../goals/admission.mjs";
|
|
42
|
-
import { gapFor, readSeries } from "../kpi.mjs";
|
|
43
|
-
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
|
-
// The body hq published (mandate.adopt → MandateSnapshot v1)
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Committed copy of hq's published body, captured from a real
|
|
50
|
-
* `MANDATE_ADOPTION_OUT` run. Point `$MANDATE_ADOPTION_IN` at a fresh one to
|
|
51
|
-
* re-prove the joint against today's handler.
|
|
52
|
-
*
|
|
53
|
-
* `checksum` is carried verbatim as hq stamped it and is NOT re-verified here:
|
|
54
|
-
* `adoptedAt` comes off the server clock, so a fresh publish legitimately
|
|
55
|
-
* produces a different digest for the same governance facts. What this file
|
|
56
|
-
* pins is the SHAPE and the LAW, not one particular second.
|
|
57
|
-
*/
|
|
58
|
-
const COMMITTED = {
|
|
59
|
-
version: 1,
|
|
60
|
-
checksum: "7c427ccc6dbe17283ca0a91cbd644407f793924cdc8f224f66c803c617d4255a",
|
|
61
|
-
source: "server",
|
|
62
|
-
body: {
|
|
63
|
-
contractVersion: 1,
|
|
64
|
-
memberId: "member_2",
|
|
65
|
-
objectives: [
|
|
66
|
-
{
|
|
67
|
-
id: "obj_1",
|
|
68
|
-
key: "pipeline-coverage",
|
|
69
|
-
kind: "OBJECTIVE",
|
|
70
|
-
state: "active",
|
|
71
|
-
text: "Hold pipeline coverage at 3x of the quarter's target",
|
|
72
|
-
memberId: "member_2",
|
|
73
|
-
parentId: null,
|
|
74
|
-
parentKey: null,
|
|
75
|
-
charterSectionId: "sec_pillar",
|
|
76
|
-
workstreamId: null,
|
|
77
|
-
metric: "pipeline_coverage_x",
|
|
78
|
-
unit: "x",
|
|
79
|
-
direction: "up",
|
|
80
|
-
baseline: 1.6,
|
|
81
|
-
target: 3,
|
|
82
|
-
value: null,
|
|
83
|
-
tolerance: 0.2,
|
|
84
|
-
weight: 1,
|
|
85
|
-
progress: 0,
|
|
86
|
-
cadence: "weekly",
|
|
87
|
-
dueAt: null,
|
|
88
|
-
sensor: { capability: "crm_list_deals", params: {}, source: "method" },
|
|
89
|
-
budgetCentsPerPeriod: 25000,
|
|
90
|
-
collaborators: [
|
|
91
|
-
{ memberId: "agent_1", role: "APPROVER", source: "objective.adoptedById" },
|
|
92
|
-
],
|
|
93
|
-
version: 2,
|
|
94
|
-
proposedById: "agent_2",
|
|
95
|
-
// NOT the owner (`member_2`) — hq's `resolveAdoptionAuthority` refused
|
|
96
|
-
// the owner outright and refused a peer seat holding `mandate.write`;
|
|
97
|
-
// this is the supervisor's principal.
|
|
98
|
-
adoptedById: "agent_1",
|
|
99
|
-
adoptedAt: "2026-08-12T00:00:00.000Z",
|
|
100
|
-
createdAt: "2026-08-11T00:00:00.000Z",
|
|
101
|
-
updatedAt: "2026-08-11T00:00:00.000Z",
|
|
102
|
-
},
|
|
103
|
-
],
|
|
104
|
-
proposed: [],
|
|
105
|
-
budgetCentsPerPeriod: null,
|
|
106
|
-
seatBudgetCents: 25000,
|
|
107
|
-
budgetPeriod: "monthly",
|
|
108
|
-
budgetSource: "employee.payBasis.meteredBudget",
|
|
109
|
-
collaborators: [
|
|
110
|
-
{ memberId: "member_1", role: "REVIEWER", source: "workforceMember.supervisorId" },
|
|
111
|
-
],
|
|
112
|
-
reactsTo: [],
|
|
113
|
-
degradations: [],
|
|
114
|
-
generatedAt: "2026-08-11T00:00:00.000Z",
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const SNAPSHOT = (() => {
|
|
119
|
-
const p = process.env.MANDATE_ADOPTION_IN;
|
|
120
|
-
if (p && existsSync(p)) return JSON.parse(readFileSync(p, "utf-8"));
|
|
121
|
-
return COMMITTED;
|
|
122
|
-
})();
|
|
123
|
-
|
|
124
|
-
const OWNER = SNAPSHOT.body.memberId;
|
|
125
|
-
const KEY = SNAPSHOT.body.objectives[0].key;
|
|
126
|
-
|
|
127
|
-
const MANIFEST = {
|
|
128
|
-
schemaVersion: 1,
|
|
129
|
-
entries: [
|
|
130
|
-
{ id: "crm_list_deals", plane: "protocol", kind: "method", reachable: true, blastRadius: "internal" },
|
|
131
|
-
{ id: "board_ready", plane: "protocol", kind: "method", reachable: true, blastRadius: "internal" },
|
|
132
|
-
{ id: "board_claim", plane: "protocol", kind: "method", reachable: true, blastRadius: "internal" },
|
|
133
|
-
{ id: "task_update", plane: "protocol", kind: "method", reachable: true, blastRadius: "internal" },
|
|
134
|
-
],
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const STANDARD = [
|
|
138
|
-
{ id: "cadence-bus-heartbeat", mode: "inline", interval: 300 },
|
|
139
|
-
{ id: "inbox-processor", mode: "guarded", calendar: { hour: 9 } },
|
|
140
|
-
];
|
|
141
|
-
|
|
142
|
-
/** Deep clone with one objective field overridden. */
|
|
143
|
-
function withObjective(over) {
|
|
144
|
-
const body = JSON.parse(JSON.stringify(SNAPSHOT.body));
|
|
145
|
-
Object.assign(body.objectives[0], over);
|
|
146
|
-
return body;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function compile(body, log = () => {}) {
|
|
150
|
-
return compilePlan({
|
|
151
|
-
mandate: body,
|
|
152
|
-
manifest: MANIFEST,
|
|
153
|
-
standardCadences: STANDARD,
|
|
154
|
-
mandateVersion: SNAPSHOT.version,
|
|
155
|
-
log,
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// ---------------------------------------------------------------------------
|
|
160
|
-
// 1. an ADOPTED objective compiles an OUTCOME obligation
|
|
161
|
-
// ---------------------------------------------------------------------------
|
|
162
|
-
|
|
163
|
-
test("an adopted objective compiles an OUTCOME obligation — the rung D3 needs", () => {
|
|
164
|
-
const plan = compile(SNAPSHOT.body);
|
|
165
|
-
|
|
166
|
-
const outcome = plan.obligations.find((o) => o.key === `outcome.${KEY}`);
|
|
167
|
-
assert.ok(outcome, `expected outcome.${KEY}; got ${plan.obligations.map((o) => o.key).join(", ")}`);
|
|
168
|
-
assert.equal(outcome.kind, "OUTCOME");
|
|
169
|
-
assert.equal(outcome.status, "active");
|
|
170
|
-
assert.equal(outcome.target, 3);
|
|
171
|
-
assert.equal(outcome.tolerance, 0.2);
|
|
172
|
-
assert.equal(outcome.cadence, "weekly");
|
|
173
|
-
assert.equal(outcome.sensor.capability, "crm_list_deals");
|
|
174
|
-
assert.equal(outcome.sensor.source, "method");
|
|
175
|
-
// The provenance edge hq now enforces at adopt time rides all the way here.
|
|
176
|
-
assert.equal(outcome.source.charter_section, "sec_pillar");
|
|
177
|
-
// Funded from `Employee.payBasis.meteredBudget`, apportioned by weight.
|
|
178
|
-
assert.equal(outcome.budget_cents_per_period, 25000);
|
|
179
|
-
|
|
180
|
-
// Its measure cadence comes with it — an OUTCOME nobody reads is decoration.
|
|
181
|
-
const measure = plan.obligations.find((o) => o.key === `schedule.measure.${KEY}`);
|
|
182
|
-
assert.ok(measure);
|
|
183
|
-
assert.equal(measure.guard_module, "lib/goals/loop.mjs");
|
|
184
|
-
assert.deepEqual(measure.uses, ["crm_list_deals"]);
|
|
185
|
-
|
|
186
|
-
assert.equal(plan.counts.OUTCOME, 1);
|
|
187
|
-
assert.equal(plan.counts.adoptedObjectives, 1);
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// ---------------------------------------------------------------------------
|
|
191
|
-
// 2+3. measure through a real sensor, then admit a proactive backlog item
|
|
192
|
-
// ---------------------------------------------------------------------------
|
|
193
|
-
|
|
194
|
-
test("a method-sensor measurement opens a gap that ADMITS a proactive backlog item", async () => {
|
|
195
|
-
const root = mkdtempSync(join(tmpdir(), "maestro-adopt-e2e-"));
|
|
196
|
-
mkdirSync(join(root, "state"), { recursive: true });
|
|
197
|
-
writeCache(root, SNAPSHOT, { now: () => "2026-08-12T08:00:00.000Z" });
|
|
198
|
-
|
|
199
|
-
const NOW = Date.parse("2026-08-12T09:00:00.000Z");
|
|
200
|
-
const log = [];
|
|
201
|
-
let sensorCalls = 0;
|
|
202
|
-
|
|
203
|
-
const report = await runGoalSteward({
|
|
204
|
-
agentRoot: root,
|
|
205
|
-
memberId: OWNER,
|
|
206
|
-
now: () => NOW,
|
|
207
|
-
log: (level, msg) => log.push(`${level} ${msg}`),
|
|
208
|
-
reachable: new Set(["crm_list_deals", "board_ready", "board_claim", "task_update"]),
|
|
209
|
-
// A REAL sensor: the same shape `lib/kpi-sensors.mjs` registers, reducing a
|
|
210
|
-
// protocol read to one number. Stubbed at the transport, not at the sample —
|
|
211
|
-
// the point is that the value arrives as `source:"method"` because the agent
|
|
212
|
-
// WENT AND LOOKED, which is exactly what the honesty gate turns on.
|
|
213
|
-
sensors: {
|
|
214
|
-
crm_list_deals: async ({ params, objective }) => {
|
|
215
|
-
sensorCalls += 1;
|
|
216
|
-
assert.equal(objective.key, KEY);
|
|
217
|
-
assert.deepEqual(params, {});
|
|
218
|
-
return { value: 1.6, rowCount: 41, detail: { metric: "open_pipeline_coverage", deals: 41 } };
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
remainingCents: 25000,
|
|
222
|
-
// ACTIVE, not observe: the claim is that a backlog ITEM gets created, and
|
|
223
|
-
// an observe-only run would only record that one would have been.
|
|
224
|
-
enforcement: "active",
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// --- measured, through the sensor, as `method` ----------------------------
|
|
228
|
-
assert.equal(sensorCalls, 1, "the sensor actually ran");
|
|
229
|
-
assert.equal(report.measured.length, 1);
|
|
230
|
-
assert.deepEqual(
|
|
231
|
-
{ ...report.measured[0], recorded: undefined },
|
|
232
|
-
{ objectiveKey: KEY, value: 1.6, window: "2026-W33", source: "method", recorded: undefined }
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
// --- the gap ---------------------------------------------------------------
|
|
236
|
-
const gap = report.gaps[0];
|
|
237
|
-
assert.equal(gap.objectiveKey, KEY);
|
|
238
|
-
assert.equal(gap.value, 1.6);
|
|
239
|
-
assert.equal(gap.target, 3);
|
|
240
|
-
assert.equal(+gap.gap.toFixed(6), 1.4);
|
|
241
|
-
assert.equal(gap.withinTolerance, false);
|
|
242
|
-
assert.equal(gap.source, "method");
|
|
243
|
-
|
|
244
|
-
// --- the decision + the admission -----------------------------------------
|
|
245
|
-
assert.deepEqual(report.decisions[0], {
|
|
246
|
-
objectiveKey: KEY,
|
|
247
|
-
action: "create",
|
|
248
|
-
reason: "gap exceeds tolerance and nothing is in flight",
|
|
249
|
-
coverage: 0,
|
|
250
|
-
});
|
|
251
|
-
assert.equal(report.admitted.length, 1, `expected one admitted item; rejected: ${JSON.stringify(report.rejected)}`);
|
|
252
|
-
const admitted = report.admitted[0];
|
|
253
|
-
assert.equal(admitted.objectiveKey, KEY);
|
|
254
|
-
assert.match(admitted.title, /pipeline_coverage_x/);
|
|
255
|
-
assert.equal(report.created, 1, "a real backlog item was written, not merely contemplated");
|
|
256
|
-
|
|
257
|
-
// --- the item on the queue, with its provenance ---------------------------
|
|
258
|
-
const queue = yaml.load(readFileSync(join(root, GOALS_QUEUE_REL), "utf-8"));
|
|
259
|
-
assert.equal(queue.items.length, 1);
|
|
260
|
-
const item = queue.items[0];
|
|
261
|
-
assert.deepEqual(item.advances, [KEY]);
|
|
262
|
-
assert.equal(item.obligation_key, `outcome.${KEY}`);
|
|
263
|
-
assert.equal(item.why, "kpi-gap");
|
|
264
|
-
assert.equal(+Number(item.gap).toFixed(6), 1.4);
|
|
265
|
-
// The provenance an operator needs to answer "why did the agent do that?"
|
|
266
|
-
// offline: the charter clause it advances and who stood behind the number.
|
|
267
|
-
assert.equal(item.charter_clause, "sec_pillar");
|
|
268
|
-
assert.equal(item.adopted_by, "agent_1");
|
|
269
|
-
assert.notEqual(item.adopted_by, OWNER, "and the adopter is never the owner");
|
|
270
|
-
|
|
271
|
-
// --- and the gates that passed it, named ----------------------------------
|
|
272
|
-
// Re-run `admit` over the same inputs so the proof carries the gate ledger,
|
|
273
|
-
// not just the verdict. A candidate admitted for a reason nobody can read is
|
|
274
|
-
// the same failure as one rejected for a reason nobody can read.
|
|
275
|
-
const series = readSeries(root, KEY);
|
|
276
|
-
const verdict = admit(
|
|
277
|
-
{
|
|
278
|
-
title: item.title,
|
|
279
|
-
advances: [KEY],
|
|
280
|
-
why: { reason: "kpi-gap" },
|
|
281
|
-
estCents: 50,
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
objective: SNAPSHOT.body.objectives[0],
|
|
285
|
-
gap: gapFor(SNAPSHOT.body.objectives[0], series, { now: () => NOW }),
|
|
286
|
-
latestSample: series[series.length - 1],
|
|
287
|
-
openItems: [],
|
|
288
|
-
admittedThisRun: 0,
|
|
289
|
-
remainingCents: 25000,
|
|
290
|
-
staleness: { outcome: "full" },
|
|
291
|
-
}
|
|
292
|
-
);
|
|
293
|
-
assert.equal(verdict.admitted, true, `${verdict.gate}: ${verdict.reason}`);
|
|
294
|
-
assert.deepEqual(
|
|
295
|
-
verdict.checks.map((c) => c.gate),
|
|
296
|
-
["freshness", "adoption", "honesty", "provenance", "dedupe", "trend", "wip", "budget"]
|
|
297
|
-
);
|
|
298
|
-
assert.ok(verdict.checks.every((c) => c.ok));
|
|
299
|
-
assert.match(verdict.checks.find((c) => c.gate === "honesty").detail, /method-sourced/);
|
|
300
|
-
assert.match(verdict.checks.find((c) => c.gate === "adoption").detail, /is active/);
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// ---------------------------------------------------------------------------
|
|
304
|
-
// 4. the counterfactuals — what "0 of 35 adopted" actually produced
|
|
305
|
-
// ---------------------------------------------------------------------------
|
|
306
|
-
|
|
307
|
-
test("the SAME objective left PROPOSED compiles no OUTCOME and admits nothing", async () => {
|
|
308
|
-
const body = withObjective({ state: "proposed", adoptedById: null, adoptedAt: null });
|
|
309
|
-
const plan = compile(body);
|
|
310
|
-
assert.equal(plan.counts.OUTCOME, 0, "a proposal is a request, not a mandate");
|
|
311
|
-
assert.equal(plan.obligations.some((o) => o.key.startsWith("outcome.")), false);
|
|
312
|
-
|
|
313
|
-
const root = mkdtempSync(join(tmpdir(), "maestro-adopt-e2e-prop-"));
|
|
314
|
-
writeCache(root, { ...SNAPSHOT, body }, { now: () => "2026-08-12T08:00:00.000Z" });
|
|
315
|
-
const report = await runGoalSteward({
|
|
316
|
-
agentRoot: root,
|
|
317
|
-
memberId: OWNER,
|
|
318
|
-
now: () => Date.parse("2026-08-12T09:00:00.000Z"),
|
|
319
|
-
log: () => {},
|
|
320
|
-
reachable: new Set(["crm_list_deals"]),
|
|
321
|
-
sensors: { crm_list_deals: async () => ({ value: 1.6 }) },
|
|
322
|
-
});
|
|
323
|
-
assert.equal(report.admitted.length, 0);
|
|
324
|
-
assert.equal(report.skipped, "no adopted objectives");
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
test("a SELF-ADOPTED objective compiles nothing and is reported as drift, not silently dropped", () => {
|
|
328
|
-
// The offline half of the anti-Goodhart law. hq refuses self-adoption at the
|
|
329
|
-
// handler, but a partitioned agent replaying a cached body — or a hand-edited
|
|
330
|
-
// state file — must not be able to grade itself either. Before this, the
|
|
331
|
-
// compiler trusted `state === "active"` and nothing about who set it.
|
|
332
|
-
const body = withObjective({ adoptedById: OWNER });
|
|
333
|
-
const notes = [];
|
|
334
|
-
const plan = compile(body, (level, msg) => notes.push(`${level} ${msg}`));
|
|
335
|
-
|
|
336
|
-
assert.equal(plan.counts.OUTCOME, 0);
|
|
337
|
-
const drift = plan.drift.find((d) => d.kind === "self_adopted");
|
|
338
|
-
assert.ok(drift, `expected self_adopted drift; got ${JSON.stringify(plan.drift.map((d) => d.kind))}`);
|
|
339
|
-
assert.equal(drift.key, `outcome.${KEY}`);
|
|
340
|
-
// FAIL-OPEN IS FINE; SILENT IS NOT.
|
|
341
|
-
assert.ok(notes.some((n) => /compiles NOTHING/.test(n) && /a seat cannot define, measure and be graded/.test(n)));
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
test("an objective with NO adoptedById compiles nothing either — the law fails CLOSED", () => {
|
|
345
|
-
// The cheaper tamper, and the one that used to work. The stated threat model is
|
|
346
|
-
// "an agent handed a hand-edited state file"; forging a plausible supervisor id
|
|
347
|
-
// is work, DELETING the field is one keystroke — and `isSelfAdopted` returned
|
|
348
|
-
// false for a missing field, so the row compiled a live graded OUTCOME with
|
|
349
|
-
// nobody on record as having handed the seat the number.
|
|
350
|
-
const withProvenance = withObjective({ adoptedById: "M-SUPERVISOR" });
|
|
351
|
-
const objs = withProvenance.objectives.map((o) => {
|
|
352
|
-
if (o.kind === "PILLAR") return o;
|
|
353
|
-
const { adoptedById, ...rest } = o;
|
|
354
|
-
return rest;
|
|
355
|
-
});
|
|
356
|
-
const notes = [];
|
|
357
|
-
const plan = compile({ ...withProvenance, objectives: objs }, (level, msg) => notes.push(`${level} ${msg}`));
|
|
358
|
-
|
|
359
|
-
assert.equal(plan.counts.OUTCOME, 0);
|
|
360
|
-
const drift = plan.drift.find((d) => d.kind === "missing_adoption_provenance");
|
|
361
|
-
assert.ok(drift, `expected missing_adoption_provenance drift; got ${JSON.stringify(plan.drift.map((d) => d.kind))}`);
|
|
362
|
-
assert.ok(notes.some((n) => /compiles NOTHING/.test(n) && /NO adoptedById/.test(n)));
|
|
363
|
-
|
|
364
|
-
// Control: the SAME body with the column present compiles the obligation.
|
|
365
|
-
assert.equal(compile(withProvenance, () => {}).counts.OUTCOME, 1);
|
|
366
|
-
});
|