@cohortapp/agent-sdk 2.17.0 → 2.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +18 -0
- package/.env.example +18 -5
- package/README.md +1 -0
- package/bin/maestro.mjs +62 -0
- package/docs/guides/billing-console-keys.md +60 -0
- package/docs/guides/front-door-session.md +54 -9
- package/docs/guides/mac-mini.md +20 -25
- package/docs/guides/setup-wizard.md +1 -1
- package/docs/runbooks/fleet-rollout.md +156 -0
- package/docs/runbooks/mac-mini-bootstrap.md +12 -14
- package/lib/action-executor.js +19 -3
- package/lib/budget-guard.mjs +279 -3
- package/lib/channels/base-adapter.mjs +3 -1
- package/lib/channels/contract.mjs +2 -1
- package/lib/channels/inbox-item.mjs +8 -0
- package/lib/claude-bin.mjs +5 -6
- package/lib/cli/doctor-checks.mjs +141 -10
- package/lib/cli/global-setup-extras.mjs +5 -1
- package/lib/cli/inbox.mjs +100 -15
- package/lib/cli/seat-auth.mjs +463 -0
- package/lib/cli/session.mjs +80 -12
- package/lib/collective/capture-slots.mjs +234 -0
- package/lib/collective/capture.mjs +8 -6
- package/lib/collective/config.mjs +2 -0
- package/lib/collective/global-config.mjs +63 -1
- package/lib/collective/loop-guard.mjs +155 -0
- package/lib/collective/presence.mjs +142 -5
- package/lib/comms/send-gate.mjs +559 -1
- package/lib/diagnostics/alerts.mjs +49 -0
- package/lib/diagnostics/cadence-output-freshness.mjs +288 -0
- package/lib/engine/agents/definitions.mjs +343 -0
- package/lib/engine/agents/persist.mjs +275 -0
- package/lib/engine/agents/runtime.mjs +748 -0
- package/lib/engine/agents/usage.mjs +95 -0
- package/lib/engine/auth-status.mjs +139 -0
- package/lib/engine/budget.mjs +194 -0
- package/lib/engine/cli.mjs +1204 -0
- package/lib/engine/commands/index.mjs +269 -0
- package/lib/engine/context/budget.mjs +219 -0
- package/lib/engine/context/cache.mjs +125 -0
- package/lib/engine/context/child-env.mjs +215 -0
- package/lib/engine/context/compaction.mjs +342 -0
- package/lib/engine/context/images.mjs +90 -0
- package/lib/engine/context/instructions.mjs +327 -0
- package/lib/engine/context/lazy-instructions.mjs +169 -0
- package/lib/engine/context/manager.mjs +182 -0
- package/lib/engine/context/real-path.mjs +91 -0
- package/lib/engine/context/secret-values.mjs +163 -0
- package/lib/engine/context/settings.mjs +274 -0
- package/lib/engine/context/stream-input.mjs +159 -0
- package/lib/engine/guard.mjs +152 -0
- package/lib/engine/hooks.mjs +713 -0
- package/lib/engine/loop.mjs +560 -0
- package/lib/engine/mcp/client.mjs +254 -0
- package/lib/engine/mcp/config.mjs +301 -0
- package/lib/engine/mcp/http.mjs +201 -0
- package/lib/engine/mcp/index.mjs +146 -0
- package/lib/engine/mcp/jsonrpc.mjs +147 -0
- package/lib/engine/mcp/naming.mjs +66 -0
- package/lib/engine/mcp/resources.mjs +89 -0
- package/lib/engine/mcp/results.mjs +133 -0
- package/lib/engine/mcp/stdio.mjs +137 -0
- package/lib/engine/mcp/supervisor.mjs +116 -0
- package/lib/engine/messages.mjs +104 -0
- package/lib/engine/output/json.mjs +164 -0
- package/lib/engine/output/stream-json.mjs +266 -0
- package/lib/engine/permissions.mjs +845 -0
- package/lib/engine/process-identity.mjs +164 -0
- package/lib/engine/process-tree.mjs +551 -0
- package/lib/engine/prompt.mjs +60 -0
- package/lib/engine/session/store.mjs +299 -0
- package/lib/engine/session-runtime/args.mjs +97 -0
- package/lib/engine/session-runtime/host.mjs +143 -0
- package/lib/engine/session-runtime/inbox.mjs +122 -0
- package/lib/engine/session-runtime/notifications.mjs +129 -0
- package/lib/engine/session-runtime/registry.mjs +328 -0
- package/lib/engine/session-runtime/runner.mjs +344 -0
- package/lib/engine/session-runtime/socket.mjs +212 -0
- package/lib/engine/session-runtime/wakeup.mjs +115 -0
- package/lib/engine/skills/index.mjs +321 -0
- package/lib/engine/tools/bash-background.mjs +533 -0
- package/lib/engine/tools/bash.mjs +216 -0
- package/lib/engine/tools/edit.mjs +97 -0
- package/lib/engine/tools/glob.mjs +81 -0
- package/lib/engine/tools/grep.mjs +224 -0
- package/lib/engine/tools/index.mjs +84 -0
- package/lib/engine/tools/list-agents.mjs +32 -0
- package/lib/engine/tools/ls.mjs +127 -0
- package/lib/engine/tools/monitor.mjs +82 -0
- package/lib/engine/tools/notebook-edit.mjs +218 -0
- package/lib/engine/tools/read.mjs +103 -0
- package/lib/engine/tools/schedule-wakeup.mjs +45 -0
- package/lib/engine/tools/schema.mjs +144 -0
- package/lib/engine/tools/send-message.mjs +77 -0
- package/lib/engine/tools/session.mjs +70 -0
- package/lib/engine/tools/todo.mjs +144 -0
- package/lib/engine/tools/toolsearch.mjs +217 -0
- package/lib/engine/tools/walk.mjs +193 -0
- package/lib/engine/tools/web-switch.mjs +31 -0
- package/lib/engine/tools/webfetch-html.mjs +387 -0
- package/lib/engine/tools/webfetch-net.mjs +340 -0
- package/lib/engine/tools/webfetch.mjs +198 -0
- package/lib/engine/tools/websearch.mjs +91 -0
- package/lib/engine/tools/workflow.mjs +95 -0
- package/lib/engine/tools/write.mjs +76 -0
- package/lib/engine/tui/line-editor.mjs +137 -0
- package/lib/engine/tui/render.mjs +86 -0
- package/lib/engine/tui/tui.mjs +274 -0
- package/lib/engine/wire/anthropic-messages.mjs +263 -0
- package/lib/engine/wire/effort.mjs +36 -0
- package/lib/engine/wire/errors.mjs +496 -0
- package/lib/engine/wire/http.mjs +441 -0
- package/lib/engine/wire/index.mjs +76 -0
- package/lib/engine/wire/openai-chat.mjs +332 -0
- package/lib/engine/wire/prompt-cache.mjs +79 -0
- package/lib/engine/wire/search.mjs +140 -0
- package/lib/engine/wire/sse.mjs +114 -0
- package/lib/engine/wire/stall.mjs +349 -0
- package/lib/engine/wire/token-provider.mjs +175 -0
- package/lib/engine/wire/usage.mjs +192 -0
- package/lib/engine/workflow/host.mjs +524 -0
- package/lib/engine/workflow/journal.mjs +188 -0
- package/lib/engine/workflow/json-schema.mjs +171 -0
- package/lib/engine/workflow/meta.mjs +329 -0
- package/lib/engine/workflow/notifications.mjs +52 -0
- package/lib/engine/workflow/runtime.mjs +447 -0
- package/lib/engine/workflow/sandbox.mjs +534 -0
- package/lib/engine/workflow/worker.mjs +141 -0
- package/lib/engine/workflow/worktree.mjs +74 -0
- package/lib/execution/disposition.mjs +1 -1
- package/lib/execution/intake.mjs +10 -0
- package/lib/execution/surface-policy.mjs +15 -0
- package/lib/learning/curator.mjs +8 -6
- package/lib/learning/reflect.mjs +8 -6
- package/lib/model-router/catalog/cohort.yaml +137 -0
- package/lib/model-router/catalog.mjs +118 -1
- package/lib/model-router/failover.mjs +67 -16
- package/lib/model-router/llm-task.mjs +39 -3
- package/lib/model-router/resolve.mjs +89 -3
- package/lib/model-router/spawn.mjs +46 -47
- package/lib/model-router/taxonomy.mjs +126 -4
- package/lib/org/cost-sync.mjs +141 -11
- package/lib/org/inbound/broadcast.mjs +289 -0
- package/lib/org/inbound/collective.mjs +375 -0
- package/lib/org/inbound/directedness.mjs +96 -8
- package/lib/org/inbound/facts.mjs +78 -2
- package/lib/org/inbound/project.mjs +22 -0
- package/lib/org/inbound/surfaces.mjs +14 -0
- package/lib/org/llm-token.mjs +879 -0
- package/lib/org/mesh.mjs +61 -0
- package/lib/org/messaging.mjs +3 -1
- package/lib/org/protocol.checksum +1 -1
- package/lib/org/protocol.mjs +15 -0
- package/lib/org/quota.mjs +520 -0
- package/lib/org/tool-surface.mjs +104 -16
- package/lib/org/ui-parity.mjs +16 -1
- package/lib/org/work-ledger.mjs +37 -6
- package/lib/rate-guard.mjs +114 -1
- package/lib/resource-governor.mjs +41 -6
- package/lib/runtime/adapter.mjs +833 -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 +229 -11
- package/lib/upgrade/ignored-drift.mjs +105 -0
- package/lib/voice/post-call-brief.mjs +30 -17
- package/package.json +13 -3
- package/plugins/maestro-skills/skills/board-work.md +5 -0
- package/plugins/maestro-skills/skills/inbound-triage.md +56 -15
- package/plugins/maestro-skills/skills/main-session.md +18 -7
- package/scaffold/config/collective.yaml +7 -0
- package/scripts/ci/check-durable-write-seam.mjs +3 -1
- 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 +142 -19
- package/scripts/continuous-monitor.sh +13 -0
- package/scripts/cost/track-claude-usage.mjs +15 -0
- package/scripts/daemon/agent-daemon.mjs +408 -20
- package/scripts/daemon/assurance.mjs +48 -12
- package/scripts/daemon/cadence-consumer.mjs +218 -68
- package/scripts/daemon/cadence-handlers.mjs +73 -4
- package/scripts/daemon/classifier.mjs +75 -26
- package/scripts/daemon/context-compiler.mjs +51 -37
- package/scripts/daemon/deliver.mjs +30 -1
- package/scripts/daemon/dispatcher.mjs +595 -149
- package/scripts/daemon/health.mjs +14 -1
- package/scripts/daemon/maestro-daemon.mjs +11 -0
- package/scripts/daemon/prompt-builder.mjs +24 -0
- package/scripts/daemon/responder.mjs +246 -79
- package/scripts/daemon/sdk-version.mjs +98 -16
- package/scripts/eval/probe-gateway.mjs +635 -0
- package/scripts/eval/replay/extract.mjs +270 -0
- package/scripts/eval/replay/grade.mjs +260 -0
- package/scripts/eval/replay/lib/config.mjs +50 -0
- package/scripts/eval/replay/lib/effects.mjs +65 -0
- package/scripts/eval/replay/lib/fixture.mjs +188 -0
- package/scripts/eval/replay/lib/judge.mjs +72 -0
- package/scripts/eval/replay/lib/redact.mjs +136 -0
- package/scripts/eval/replay/lib/sandbox.mjs +170 -0
- package/scripts/eval/replay/lib/schema-check.mjs +63 -0
- package/scripts/eval/replay/lib/transcript.mjs +76 -0
- package/scripts/eval/replay/mcp-replay-stub.mjs +101 -0
- package/scripts/eval/replay/report.mjs +185 -0
- package/scripts/eval/replay/run.mjs +404 -0
- package/scripts/fleet/rollout.mjs +1151 -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 +465 -81
- package/scripts/local-triggers/run-trigger.sh +13 -0
- package/scripts/maintenance/pin-integrity.mjs +364 -0
- package/scripts/poll-slack-events.sh +41 -9
- package/scripts/poller/slack-socket-mode.mjs +28 -3
- package/scripts/session/supervisor.mjs +80 -13
- package/scripts/spawn-session.sh +13 -0
- package/bin/maestro.test.mjs +0 -1574
- package/lib/action-executor.test.mjs +0 -871
- package/lib/archetype.test.mjs +0 -132
- package/lib/assurance/plan-note.test.mjs +0 -234
- package/lib/assurance/room-budget.test.mjs +0 -486
- package/lib/assurance/tier.test.mjs +0 -174
- package/lib/autonomy.test.mjs +0 -66
- package/lib/backlog.test.mjs +0 -302
- package/lib/backup/policy.test.mjs +0 -305
- package/lib/budget-escalate.test.mjs +0 -232
- package/lib/budget-guard.envelope.test.mjs +0 -476
- package/lib/budget-guard.test.mjs +0 -427
- package/lib/cadence-bus-requeue.test.mjs +0 -83
- package/lib/cadence-bus-schedule.test.mjs +0 -194
- package/lib/cadence-bus.test.mjs +0 -720
- package/lib/cadences.test.mjs +0 -230
- package/lib/capability/inventory.test.mjs +0 -232
- package/lib/capability.test.mjs +0 -78
- package/lib/channels/base-adapter.test.mjs +0 -590
- package/lib/channels/channels.test.mjs +0 -371
- package/lib/channels/contract.test.mjs +0 -162
- package/lib/channels/inbox-item.test.mjs +0 -368
- package/lib/channels/orgmail/adapter.test.mjs +0 -448
- package/lib/channels/pairing.test.mjs +0 -270
- package/lib/channels/repeat-suppressor.test.mjs +0 -134
- package/lib/channels/slack-adapter.test.mjs +0 -212
- package/lib/channels/telegram-adapter.test.mjs +0 -306
- package/lib/channels/voice/adapter.test.mjs +0 -278
- package/lib/channels/whatsapp/adapter-baileys.test.mjs +0 -359
- package/lib/channels/whatsapp/baileys-typing.test.mjs +0 -154
- package/lib/charter.test.mjs +0 -89
- package/lib/claude-bin.test.mjs +0 -131
- package/lib/cli/board.test.mjs +0 -227
- package/lib/cli/design.test.mjs +0 -270
- package/lib/cli/doctor-checks.test.mjs +0 -336
- package/lib/cli/global-setup-extras.test.mjs +0 -462
- package/lib/cli/inbox.test.mjs +0 -230
- package/lib/cli/session-ack.test.mjs +0 -63
- package/lib/cli/session.test.mjs +0 -613
- package/lib/collective/capture.test.mjs +0 -121
- package/lib/collective/cards.test.mjs +0 -114
- package/lib/collective/config.test.mjs +0 -123
- package/lib/collective/global-config.test.mjs +0 -220
- package/lib/collective/global-skills.test.mjs +0 -126
- package/lib/collective/presence.test.mjs +0 -95
- package/lib/collective/recall.test.mjs +0 -116
- package/lib/collective/vendor-skills.test.mjs +0 -306
- package/lib/comms/send-gate.test.mjs +0 -770
- package/lib/comms.test.mjs +0 -41
- package/lib/context/budget.test.mjs +0 -252
- package/lib/context/history-scope.test.mjs +0 -79
- package/lib/cost/ledger-row.test.mjs +0 -183
- package/lib/design/design-md.test.mjs +0 -318
- package/lib/design/fixtures/DESIGN.golden.md +0 -238
- package/lib/design/fixtures/PRODUCT.golden.md +0 -67
- package/lib/design/fixtures/foundation.json +0 -133
- package/lib/design/refresh-gate.test.mjs +0 -144
- package/lib/design/write.test.mjs +0 -241
- package/lib/diagnostics/alerts.test.mjs +0 -318
- package/lib/diagnostics/backup-freshness.test.mjs +0 -185
- package/lib/diagnostics/counters.test.mjs +0 -206
- package/lib/diagnostics/events.test.mjs +0 -290
- package/lib/diagnostics/otel.test.mjs +0 -196
- package/lib/diagnostics/trace.test.mjs +0 -251
- package/lib/env-compat.test.mjs +0 -104
- package/lib/execution/disposition.test.mjs +0 -553
- package/lib/execution/drive.test.mjs +0 -270
- package/lib/execution/effects.test.mjs +0 -344
- package/lib/execution/intake.test.mjs +0 -389
- package/lib/execution/journal.test.mjs +0 -261
- package/lib/execution/match.test.mjs +0 -235
- package/lib/execution/pipeline.test.mjs +0 -392
- package/lib/execution/route.test.mjs +0 -186
- package/lib/execution/surface-policy.test.mjs +0 -162
- package/lib/fs-atomic.test.mjs +0 -72
- package/lib/fs-ownership.test.mjs +0 -158
- package/lib/goals/admission.test.mjs +0 -164
- package/lib/goals/classify.test.mjs +0 -167
- package/lib/goals/collaborate.test.mjs +0 -336
- package/lib/goals/gaps.test.mjs +0 -284
- package/lib/goals/loop.test.mjs +0 -845
- package/lib/hooks/bus.test.mjs +0 -387
- package/lib/identity/persona.test.mjs +0 -142
- package/lib/kpi-sensors.test.mjs +0 -278
- package/lib/kpi.test.mjs +0 -244
- package/lib/learning/config.test.mjs +0 -75
- package/lib/learning/counters.test.mjs +0 -69
- package/lib/learning/curator-consolidate.test.mjs +0 -238
- package/lib/learning/curator.test.mjs +0 -106
- package/lib/learning/reflect.test.mjs +0 -0
- package/lib/learning/session-index.test.mjs +0 -125
- package/lib/learning/skill-writer.test.mjs +0 -210
- package/lib/mandate/audit.test.mjs +0 -195
- package/lib/mandate/contract.test.mjs +0 -185
- package/lib/mandate/derive.test.mjs +0 -274
- package/lib/mandate/model.test.mjs +0 -164
- package/lib/mandate/refresh.test.mjs +0 -389
- package/lib/mcp/server.test.mjs +0 -426
- package/lib/model-router/auth-profiles.test.mjs +0 -580
- package/lib/model-router/catalog.test.mjs +0 -385
- package/lib/model-router/economics.test.mjs +0 -438
- package/lib/model-router/failover.test.mjs +0 -439
- package/lib/model-router/health.test.mjs +0 -338
- package/lib/model-router/integration-coverage.test.mjs +0 -831
- package/lib/model-router/integration.test.mjs +0 -564
- package/lib/model-router/ledger.test.mjs +0 -415
- package/lib/model-router/llm-task.test.mjs +0 -392
- package/lib/model-router/org-credentials.test.mjs +0 -265
- package/lib/model-router/pricing-refresh.test.mjs +0 -286
- package/lib/model-router/reconcile.test.mjs +0 -316
- package/lib/model-router/repair.test.mjs +0 -180
- package/lib/model-router/spawn.test.mjs +0 -446
- package/lib/model-router/taxonomy.test.mjs +0 -410
- package/lib/model-router.test.mjs +0 -1207
- package/lib/org/activity.test.mjs +0 -134
- package/lib/org/approvals.test.mjs +0 -216
- package/lib/org/awareness.test.mjs +0 -159
- package/lib/org/board-mine-cache.test.mjs +0 -53
- package/lib/org/board.test.mjs +0 -187
- package/lib/org/bootstrap-context.test.mjs +0 -153
- package/lib/org/client.test.mjs +0 -1206
- package/lib/org/cohort-client.test.mjs +0 -126
- package/lib/org/cost-sync.test.mjs +0 -153
- package/lib/org/doctor.test.mjs +0 -346
- package/lib/org/engagement-ledger.test.mjs +0 -112
- package/lib/org/engagement.test.mjs +0 -739
- package/lib/org/handoff.test.mjs +0 -269
- package/lib/org/inbound/directedness.test.mjs +0 -668
- package/lib/org/inbound/facts.test.mjs +0 -471
- package/lib/org/inbound/hydrate.test.mjs +0 -908
- package/lib/org/inbound/index.test.mjs +0 -429
- package/lib/org/inbound/project.test.mjs +0 -287
- package/lib/org/integration-tools.test.mjs +0 -160
- package/lib/org/keys.test.mjs +0 -92
- package/lib/org/knowledge.test.mjs +0 -326
- package/lib/org/leases.test.mjs +0 -235
- package/lib/org/mesh-directives.test.mjs +0 -110
- package/lib/org/mesh-integration.test.mjs +0 -127
- package/lib/org/mesh.test.mjs +0 -400
- package/lib/org/messaging.test.mjs +0 -471
- package/lib/org/param-contract.test.mjs +0 -477
- package/lib/org/policy.test.mjs +0 -237
- package/lib/org/protocol.checksum.test.mjs +0 -90
- package/lib/org/protocol.test.mjs +0 -323
- package/lib/org/push.test.mjs +0 -792
- package/lib/org/registry.test.mjs +0 -100
- package/lib/org/resource-tools.test.mjs +0 -361
- package/lib/org/tool-access.test.mjs +0 -144
- package/lib/org/tool-surface-integration.test.mjs +0 -120
- package/lib/org/tool-surface.test.mjs +0 -1268
- package/lib/org/typing.test.mjs +0 -291
- package/lib/org/ui-parity.test.mjs +0 -560
- package/lib/org/verify.test.mjs +0 -194
- package/lib/org/work-ledger.test.mjs +0 -273
- package/lib/plan/adoption-e2e.test.mjs +0 -366
- package/lib/plan/budget-enforcement.test.mjs +0 -400
- package/lib/plan/compile.test.mjs +0 -382
- package/lib/plan/emit.test.mjs +0 -269
- package/lib/plan/explain.test.mjs +0 -188
- package/lib/prompts/parallelism.test.mjs +0 -177
- package/lib/rag/rag.test.mjs +0 -505
- package/lib/rate-guard.test.mjs +0 -272
- package/lib/reactive-gate.test.mjs +0 -57
- package/lib/render.test.mjs +0 -68
- package/lib/resource-governor.test.mjs +0 -488
- package/lib/scheduling/dynamic-jobs.test.mjs +0 -344
- package/lib/scheduling/jitter.test.mjs +0 -140
- package/lib/secrets/broker.test.mjs +0 -280
- package/lib/secrets/providers.test.mjs +0 -274
- package/lib/security/audit-engine.test.mjs +0 -424
- package/lib/security/coerce-args.test.mjs +0 -281
- package/lib/security/dangerous-tools.test.mjs +0 -68
- package/lib/security/external-content.test.mjs +0 -84
- package/lib/security/redact.test.mjs +0 -441
- package/lib/security/secret-equal.test.mjs +0 -55
- package/lib/session/config.test.mjs +0 -92
- package/lib/session/feed-core.test.mjs +0 -198
- package/lib/session/first-run.test.mjs +0 -121
- package/lib/session/frontdoor.test.mjs +0 -205
- package/lib/session/handoffs.test.mjs +0 -183
- package/lib/session/identity.test.mjs +0 -180
- package/lib/session/inbox-claims.test.mjs +0 -286
- package/lib/session/launch-args.test.mjs +0 -157
- package/lib/session/liveness.test.mjs +0 -100
- package/lib/session/status-summary.test.mjs +0 -118
- package/lib/session-permissions.test.mjs +0 -120
- package/lib/setup/claude-probe.test.mjs +0 -187
- package/lib/setup/completeness.test.mjs +0 -110
- package/lib/setup/context-pack.test.mjs +0 -89
- package/lib/setup/enrich.test.mjs +0 -115
- package/lib/setup/enroll-from-cohort.test.mjs +0 -300
- package/lib/setup/integration.test.mjs +0 -162
- package/lib/setup/io.test.mjs +0 -77
- package/lib/setup/runner.test.mjs +0 -132
- package/lib/setup/sections/identity.test.mjs +0 -234
- package/lib/setup/sections/inventory.test.mjs +0 -198
- package/lib/setup/sections/learning.test.mjs +0 -81
- package/lib/setup/sections/mandate.test.mjs +0 -388
- package/lib/setup/sections/messaging.test.mjs +0 -127
- package/lib/setup/sections/model.test.mjs +0 -240
- package/lib/setup/sections/org.test.mjs +0 -346
- package/lib/setup/sections/orgmail.test.mjs +0 -118
- package/lib/setup/sections/recovery.test.mjs +0 -98
- package/lib/setup/sections/subagents.test.mjs +0 -429
- package/lib/setup/sections/verify.test.mjs +0 -175
- package/lib/setup/sot.test.mjs +0 -81
- package/lib/setup/state.test.mjs +0 -115
- package/lib/singleton.test.mjs +0 -151
- package/lib/subagents/cli.test.mjs +0 -389
- package/lib/subagents/client.test.mjs +0 -309
- package/lib/subagents/gap.test.mjs +0 -234
- package/lib/subagents/lock.test.mjs +0 -248
- package/lib/subagents/manifest.test.mjs +0 -175
- package/lib/subagents/refs.test.mjs +0 -204
- package/lib/subagents/resolve.test.mjs +0 -422
- package/lib/subagents/schema.test.mjs +0 -328
- package/lib/telemetry/alerts.test.mjs +0 -109
- package/lib/telemetry/collect.test.mjs +0 -1274
- package/lib/tool-definitions-integration.test.mjs +0 -83
- package/lib/tool-definitions.test.mjs +0 -437
- package/lib/upgrade/global-refresh.test.mjs +0 -65
- package/lib/upgrade/launchd-reconcile.test.mjs +0 -272
- package/lib/upgrade/post-steps.test.mjs +0 -200
- package/lib/upgrade/verify.test.mjs +0 -164
- package/lib/util/fetch-timeout.test.mjs +0 -202
- package/lib/util/reconnect.test.mjs +0 -369
- package/lib/util/unhandled.test.mjs +0 -216
- package/lib/voice/outbound.test.mjs +0 -69
- package/lib/voice/session-rotation.test.mjs +0 -114
- package/lib/voice/stt.test.mjs +0 -226
- package/lib/voice/voice.test.mjs +0 -990
- package/scripts/cadence/enqueue-cadence-tick.test.mjs +0 -187
- package/scripts/ci/check-docs-accuracy.test.mjs +0 -409
- package/scripts/ci/check-durable-write-seam.test.mjs +0 -90
- package/scripts/ci/check-no-build-artifacts.test.mjs +0 -71
- package/scripts/ci/check-no-residual-identity.test.mjs +0 -202
- package/scripts/ci/check-skill-packs.test.mjs +0 -495
- package/scripts/ci/check-subagent-frontmatter.test.mjs +0 -124
- package/scripts/ci/check.test.mjs +0 -194
- package/scripts/ci/conformance-org-api.test.mjs +0 -425
- package/scripts/cloud-relay/voice/relay-identity.test.mjs +0 -96
- package/scripts/collective/hook-runner.test.mjs +0 -173
- package/scripts/cost/fleet-digest.test.mjs +0 -207
- package/scripts/cost/track-claude-usage-pricing.test.mjs +0 -183
- package/scripts/cost/track-claude-usage.test.mjs +0 -148
- package/scripts/daemon/agent-daemon-board-mine.test.mjs +0 -96
- package/scripts/daemon/agent-daemon-design.test.mjs +0 -238
- package/scripts/daemon/agent-daemon-frontdoor.test.mjs +0 -60
- package/scripts/daemon/agent-daemon.test.mjs +0 -995
- package/scripts/daemon/assurance-e2e.test.mjs +0 -613
- package/scripts/daemon/assurance.test.mjs +0 -1791
- package/scripts/daemon/board-mirror.test.mjs +0 -165
- package/scripts/daemon/cadence-consumer-frontdoor.test.mjs +0 -393
- package/scripts/daemon/cadence-consumer-governance.test.mjs +0 -276
- package/scripts/daemon/cadence-consumer.test.mjs +0 -776
- package/scripts/daemon/cadence-handlers.test.mjs +0 -837
- package/scripts/daemon/classifier-identity.test.mjs +0 -137
- package/scripts/daemon/classifier.test.mjs +0 -266
- package/scripts/daemon/classify-kind.test.mjs +0 -40
- package/scripts/daemon/context-compiler.test.mjs +0 -406
- package/scripts/daemon/deliver.test.mjs +0 -564
- package/scripts/daemon/dispatcher-cooldown.test.mjs +0 -122
- package/scripts/daemon/dispatcher-governance.test.mjs +0 -1013
- package/scripts/daemon/dispatcher-resume.test.mjs +0 -166
- package/scripts/daemon/dispatcher-session-continuity.test.mjs +0 -365
- package/scripts/daemon/execution-ladder.test.mjs +0 -470
- package/scripts/daemon/goal-steward-cadence.test.mjs +0 -312
- package/scripts/daemon/inbox-deferral-session.test.mjs +0 -49
- package/scripts/daemon/inbox-deferral.test.mjs +0 -336
- package/scripts/daemon/inbox-wake.test.mjs +0 -199
- package/scripts/daemon/integration.test.mjs +0 -149
- package/scripts/daemon/lib/self-echo.test.mjs +0 -153
- package/scripts/daemon/lib/session-router.test.mjs +0 -554
- package/scripts/daemon/prompt-builder-preamble.test.mjs +0 -210
- package/scripts/daemon/prompt-builder.test.mjs +0 -556
- package/scripts/daemon/responder-cost.test.mjs +0 -68
- package/scripts/daemon/responder-history.test.mjs +0 -221
- package/scripts/daemon/sdk-version.test.mjs +0 -31
- package/scripts/daemon/session-lock.test.mjs +0 -252
- package/scripts/daemon/session-outcomes.test.mjs +0 -533
- package/scripts/daemon/typing-registry.test.mjs +0 -102
- package/scripts/hooks/pre-send-audit.test.mjs +0 -354
- package/scripts/huddle/huddle-prompt.test.mjs +0 -176
- package/scripts/local-triggers/autoupdate.test.mjs +0 -518
- package/scripts/local-triggers/generate-plists.test.mjs +0 -456
- package/scripts/media-generation/brand-clause.test.mjs +0 -135
- package/scripts/org/send-orgmail.first-contact.test.mjs +0 -102
- package/scripts/poller/inbox-privilege-injection.test.mjs +0 -167
- package/scripts/poller/inbox-scan-poller.test.mjs +0 -295
- package/scripts/poller/lib/cloud-relay-dedup.test.mjs +0 -133
- package/scripts/poller/slack-socket-mode.test.mjs +0 -805
- package/scripts/poller-launchd/install.test.mjs +0 -243
- package/scripts/restore-from-backup.test.mjs +0 -181
- package/scripts/session/feed.test.mjs +0 -196
- package/scripts/session/supervisor-sh.test.mjs +0 -218
- package/scripts/session/supervisor.test.mjs +0 -482
- package/scripts/setup/configure-macos.test.mjs +0 -306
- package/scripts/setup/gen-subagent-manifest.test.mjs +0 -124
- package/scripts/setup/generate-agent-package-json.test.mjs +0 -143
- package/scripts/setup/generate-capability.test.mjs +0 -134
- package/scripts/setup/init-agent.test.mjs +0 -370
- package/scripts/setup/init-skill-marketplace.test.mjs +0 -193
- package/scripts/vendor/sync-skill-packs.test.mjs +0 -103
- package/scripts/watchdog/memory-watchdog.test.mjs +0 -64
|
@@ -14,6 +14,15 @@
|
|
|
14
14
|
* this isn't an agent machine or the layer is disabled. Capture runs in a
|
|
15
15
|
* DETACHED child so it never blocks session exit.
|
|
16
16
|
*
|
|
17
|
+
* Loop guard: the capture worker's own model passes are Claude Code sessions,
|
|
18
|
+
* so their hooks land here too. A session of kind `collective` (env
|
|
19
|
+
* MAESTRO_COLLECTIVE_CHILD=1), or whose transcript opens with a collective
|
|
20
|
+
* prompt, is exempt from every event — no presence, no primer, no capture —
|
|
21
|
+
* so a capture can never spawn a capture (lib/collective/loop-guard.mjs).
|
|
22
|
+
* Workers are further bounded machine-wide by slot + per-session O_EXCL locks
|
|
23
|
+
* (lib/collective/capture-slots.mjs); a worker that cannot get a slot records a
|
|
24
|
+
* skipped capture rather than running.
|
|
25
|
+
*
|
|
17
26
|
* The agent repo this feeds is the runner's own repo, overridable with
|
|
18
27
|
* MAESTRO_COLLECTIVE_ROOT (used by tests + multi-repo setups).
|
|
19
28
|
*
|
|
@@ -26,6 +35,7 @@ import { fileURLToPath } from "node:url";
|
|
|
26
35
|
import { dirname, join, basename } from "node:path";
|
|
27
36
|
import { existsSync, readFileSync } from "node:fs";
|
|
28
37
|
import { spawn } from "node:child_process";
|
|
38
|
+
import { classifyKind, captureExemption, readTranscriptHead, COLLECTIVE_CHILD_ENV } from "../../lib/collective/loop-guard.mjs";
|
|
29
39
|
|
|
30
40
|
const THIS_FILE = fileURLToPath(import.meta.url);
|
|
31
41
|
const SELF_ROOT = process.env.MAESTRO_COLLECTIVE_ROOT || join(dirname(THIS_FILE), "..", "..");
|
|
@@ -60,6 +70,7 @@ async function main() {
|
|
|
60
70
|
const cwd = input.cwd || process.cwd();
|
|
61
71
|
const sessionId = input.session_id || input.sessionId || `sess-${process.pid}`;
|
|
62
72
|
const transcriptPath = input.transcript_path || input.transcriptPath || "";
|
|
73
|
+
const kind = classifyKind(input, process.env);
|
|
63
74
|
|
|
64
75
|
let config, presence, isEnabled, isRepoDenied;
|
|
65
76
|
try {
|
|
@@ -75,9 +86,16 @@ async function main() {
|
|
|
75
86
|
const denied = isRepoDenied(cwd, config);
|
|
76
87
|
const repo = basename(cwd || "");
|
|
77
88
|
|
|
89
|
+
// The collective layer's own children: nothing on any event. A capture/
|
|
90
|
+
// reflect/curator `claude --print` must not register presence, be primed, or
|
|
91
|
+
// — above all — be captured (that is the recursion). Counted, never silent.
|
|
92
|
+
if (kind === "collective") {
|
|
93
|
+
if (event === "stop" || event === "capture") await recordExemption("collective-child-env", sessionId);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
78
97
|
if (event === "prime") {
|
|
79
|
-
|
|
80
|
-
try { presence.register(SELF_ROOT, { sessionId, cwd, repo, kind }); } catch { /* */ }
|
|
98
|
+
try { presence.register(SELF_ROOT, { sessionId, cwd, repo, kind, ...ownerFields(presence) }); } catch { /* */ }
|
|
81
99
|
if (denied) return; // never inject agent memory (or the persona) into a ring-fenced/client session
|
|
82
100
|
const parts = [];
|
|
83
101
|
try {
|
|
@@ -111,7 +129,15 @@ async function main() {
|
|
|
111
129
|
}
|
|
112
130
|
|
|
113
131
|
if (event === "beat") {
|
|
114
|
-
|
|
132
|
+
// A beat on a session with no record re-registers it: a session that was
|
|
133
|
+
// running before this hook learned to record its OWNER pid (see
|
|
134
|
+
// ownerFields) was reaped on every read, and would otherwise stay
|
|
135
|
+
// invisible until it restarts.
|
|
136
|
+
let beaten = false;
|
|
137
|
+
try { beaten = presence.heartbeat(SELF_ROOT, sessionId); } catch { beaten = false; }
|
|
138
|
+
if (!beaten) {
|
|
139
|
+
try { presence.register(SELF_ROOT, { sessionId, cwd, repo, kind, ...ownerFields(presence) }); } catch { /* */ }
|
|
140
|
+
}
|
|
115
141
|
// WS3: nudge the self-learning loop's tool-use counter. Cheap, fail-open,
|
|
116
142
|
// and only when the layer is enabled + the repo isn't denylisted.
|
|
117
143
|
if (!denied) {
|
|
@@ -125,14 +151,51 @@ async function main() {
|
|
|
125
151
|
|
|
126
152
|
if (event === "stop") {
|
|
127
153
|
try { presence.deregister(SELF_ROOT, sessionId); } catch { /* */ }
|
|
128
|
-
if (!denied)
|
|
154
|
+
if (!denied) await maybeSpawnCaptureWorker({ kind, transcriptPath, cwd, sessionId });
|
|
129
155
|
return;
|
|
130
156
|
}
|
|
131
157
|
|
|
132
158
|
if (event === "capture") {
|
|
133
|
-
if (!denied)
|
|
159
|
+
if (!denied) await maybeSpawnCaptureWorker({ kind, transcriptPath, cwd, sessionId });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Spawn a capture worker unless this session is the collective layer's own
|
|
166
|
+
* child. The env marker was handled before dispatch; this catches a child whose
|
|
167
|
+
* env did not propagate, by its transcript (the first user input is one of the
|
|
168
|
+
* collective prompts).
|
|
169
|
+
*/
|
|
170
|
+
async function maybeSpawnCaptureWorker({ kind, transcriptPath, cwd, sessionId }) {
|
|
171
|
+
const exempt = captureExemption({ kind, transcriptHead: readTranscriptHead(transcriptPath) });
|
|
172
|
+
if (exempt) {
|
|
173
|
+
await recordExemption(exempt, sessionId);
|
|
134
174
|
return;
|
|
135
175
|
}
|
|
176
|
+
spawnCaptureWorker({ transcriptPath, cwd, sessionId });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Count a capture the loop guard refused to start. Never rejects. */
|
|
180
|
+
function recordExemption(reason, sessionId) {
|
|
181
|
+
return countCapture("collective.capture_exempt", reason, sessionId);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Count a capture a worker gave up on (lock contention). Never rejects. */
|
|
185
|
+
function recordSkip(reason, sessionId, extra = {}) {
|
|
186
|
+
return countCapture("collective.capture_skipped", reason, sessionId, extra);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* One durable counter row per refused/skipped capture, in the agent's
|
|
191
|
+
* logs/diagnostics/counters stream (what doctor reads). Dynamic import so a repo
|
|
192
|
+
* that predates lib/diagnostics stays silent rather than failing the hook.
|
|
193
|
+
*/
|
|
194
|
+
async function countCapture(name, reason, sessionId, extra = {}) {
|
|
195
|
+
try {
|
|
196
|
+
const counters = await import("../../lib/diagnostics/counters.mjs");
|
|
197
|
+
counters.bump(name, { reason, sessionId: sessionId || "", ...extra }, { agentRoot: SELF_ROOT });
|
|
198
|
+
} catch { /* a counter must never break a session exit */ }
|
|
136
199
|
}
|
|
137
200
|
|
|
138
201
|
/** The identity block + status line for `prime`. "" when there is nothing to say. */
|
|
@@ -151,11 +214,23 @@ function buildFrontDoorPrimer(agentRoot) {
|
|
|
151
214
|
mod.buildPrimerContext({ agentJson, agentRoot, status: mod.readSessionStatus(agentRoot, { now: Date.now() }) }));
|
|
152
215
|
}
|
|
153
216
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
217
|
+
/**
|
|
218
|
+
* The pid, `--name` and process start of the session that RAN this hook.
|
|
219
|
+
* Without this the record carried the hook's own pid, which is dead by the
|
|
220
|
+
* time anyone reads it, so `list()` reaped every interactive session on its
|
|
221
|
+
* first read (see lib/collective/presence.mjs `owningSession`). `pid: null`
|
|
222
|
+
* when the walk finds nothing — liveness then rests on the heartbeat. The
|
|
223
|
+
* start time is the owner's `ps etime`, so a session re-registered by a late
|
|
224
|
+
* beat still says when it OPENED, not when the beat happened.
|
|
225
|
+
*/
|
|
226
|
+
function ownerFields(presence) {
|
|
227
|
+
try {
|
|
228
|
+
if (typeof presence.resolveOwner !== "function") return {};
|
|
229
|
+
const o = presence.resolveOwner();
|
|
230
|
+
return { pid: o.pid, agentName: o.name || "", ...(o.startedAt ? { startedAt: o.startedAt } : {}) };
|
|
231
|
+
} catch {
|
|
232
|
+
return {};
|
|
233
|
+
}
|
|
159
234
|
}
|
|
160
235
|
|
|
161
236
|
/** Spawn the detached capture pass and return immediately. */
|
|
@@ -170,6 +245,9 @@ function spawnCaptureWorker({ transcriptPath, cwd, sessionId }) {
|
|
|
170
245
|
MAESTRO_CAPTURE_TRANSCRIPT_PATH: transcriptPath || "",
|
|
171
246
|
MAESTRO_CAPTURE_CWD: cwd || "",
|
|
172
247
|
MAESTRO_CAPTURE_SESSION: sessionId || "",
|
|
248
|
+
// The worker's whole process tree is the collective layer: every
|
|
249
|
+
// `claude` it spawns inherits this, so their hooks exempt themselves.
|
|
250
|
+
[COLLECTIVE_CHILD_ENV]: "1",
|
|
173
251
|
},
|
|
174
252
|
});
|
|
175
253
|
child.unref();
|
|
@@ -187,23 +265,68 @@ function spawnCaptureWorker({ transcriptPath, cwd, sessionId }) {
|
|
|
187
265
|
*
|
|
188
266
|
* Both passes are independently fail-open: a throw in either is swallowed, the
|
|
189
267
|
* worker still exits 0, and the session was never blocked.
|
|
268
|
+
*
|
|
269
|
+
* Before either pass the worker takes two O_EXCL locks (lib/collective/
|
|
270
|
+
* capture-slots.mjs): the SESSION lock (one worker per session at a time — a
|
|
271
|
+
* PreCompact and the Stop after it never distil in parallel) and then one of
|
|
272
|
+
* `captureMaxConcurrent` machine-wide SLOTS, queueing up to
|
|
273
|
+
* `captureQueueWaitMs`. Either refusal ends the worker with a counted skip
|
|
274
|
+
* (`collective.capture_skipped`); an unwritable lock dir fails CLOSED the same
|
|
275
|
+
* way, because an unbounded capture is the failure this exists to prevent.
|
|
190
276
|
*/
|
|
191
277
|
async function doCaptureWorker() {
|
|
278
|
+
const transcriptPath = process.env.MAESTRO_CAPTURE_TRANSCRIPT_PATH || "";
|
|
279
|
+
const cwd = process.env.MAESTRO_CAPTURE_CWD || "";
|
|
280
|
+
const sessionId = process.env.MAESTRO_CAPTURE_SESSION || "";
|
|
281
|
+
let cfg, cap, text;
|
|
192
282
|
try {
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
283
|
+
const cfgMod = await import("../../lib/collective/config.mjs");
|
|
284
|
+
cfg = await cfgMod.loadConfig(SELF_ROOT);
|
|
285
|
+
if (!cfgMod.isEnabled(cfg)) return;
|
|
196
286
|
let raw = "";
|
|
197
287
|
if (transcriptPath && existsSync(transcriptPath)) {
|
|
198
288
|
try { raw = readFileSync(transcriptPath, "utf8"); } catch { raw = ""; }
|
|
199
289
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (!text) return;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
290
|
+
cap = await import("../../lib/collective/capture.mjs");
|
|
291
|
+
text = cap.transcriptToText(raw);
|
|
292
|
+
if (!text) return; // nothing to distil → no lock, no slot
|
|
293
|
+
} catch {
|
|
294
|
+
return; // libs unavailable / not an agent repo → nothing to capture into
|
|
295
|
+
}
|
|
296
|
+
let slots;
|
|
297
|
+
try {
|
|
298
|
+
slots = await import("../../lib/collective/capture-slots.mjs");
|
|
299
|
+
} catch {
|
|
300
|
+
await recordSkip("lock-unavailable", sessionId);
|
|
301
|
+
return; // no lock module → no ceiling → do not run
|
|
302
|
+
}
|
|
303
|
+
const dir = slots.captureLockDir(process.env);
|
|
304
|
+
const owner = { pid: process.pid, sessionId };
|
|
305
|
+
const session = slots.tryAcquireLock(slots.sessionLockPath(dir, sessionId), owner);
|
|
306
|
+
if (!session.ok) {
|
|
307
|
+
await recordSkip(session.error.code === "held" ? "session-busy" : "lock-io", sessionId);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
const max = slots.maxConcurrentFrom(cfg);
|
|
312
|
+
const slot = await slots.acquireSlotQueued(dir, max, owner, { waitMs: slots.queueWaitFrom(cfg) });
|
|
313
|
+
if (!slot.ok) {
|
|
314
|
+
await recordSkip(slot.error.code === "no-slot" ? "no-slot" : "lock-io", sessionId, { max, waitedMs: slot.waitedMs });
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
await runCapturePasses({ cfg, cap, text, transcriptPath, cwd, sessionId });
|
|
319
|
+
} finally {
|
|
320
|
+
slot.release();
|
|
321
|
+
}
|
|
322
|
+
} finally {
|
|
323
|
+
session.release();
|
|
324
|
+
}
|
|
325
|
+
}
|
|
206
326
|
|
|
327
|
+
/** Pass A + Pass B over one read of the transcript. Runs only under both locks. */
|
|
328
|
+
async function runCapturePasses({ cfg, cap, text, transcriptPath, cwd, sessionId }) {
|
|
329
|
+
try {
|
|
207
330
|
// ── Pass A — collective memory cards (existing behaviour, unchanged). ──
|
|
208
331
|
const res = await cap.captureSession({ agentRoot: SELF_ROOT, sessionId, cwd, transcriptText: text, cfg });
|
|
209
332
|
if (res.written > 0) {
|
|
@@ -9,6 +9,19 @@ set -e
|
|
|
9
9
|
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
AGENT_REPO_DIR="${AGENT_DIR:-$(dirname "$SCRIPT_DIR")}"
|
|
12
|
+
|
|
13
|
+
# Retired on engine-cohort seats (W4-E1): this lane runs claude outside the
|
|
14
|
+
# runtime adapter. The guard exits 3 with the reason when runtime.engine is cohort.
|
|
15
|
+
# Fail closed: when the guard cannot run (no node on PATH — launchd's
|
|
16
|
+
# /usr/bin:/bin — or the guard file is missing), config/agent.json is checked
|
|
17
|
+
# here and an engine-cohort seat is refused all the same.
|
|
18
|
+
LEGACY_GUARD="$(dirname "$SCRIPT_DIR")/lib/runtime/legacy-shell-guard.mjs"
|
|
19
|
+
if [ -f "$LEGACY_GUARD" ] && command -v node >/dev/null 2>&1; then
|
|
20
|
+
node "$LEGACY_GUARD" continuous-monitor.sh "$AGENT_REPO_DIR" || exit $?
|
|
21
|
+
elif [ -f "$AGENT_REPO_DIR/config/agent.json" ] && grep -Eq '"engine"[[:space:]]*:[[:space:]]*"cohort"' "$AGENT_REPO_DIR/config/agent.json"; then
|
|
22
|
+
echo "continuous-monitor.sh is retired on this seat: runtime.engine is \"cohort\", and this legacy lane runs the claude binary directly, outside the runtime adapter (the engine guard could not run: node or $LEGACY_GUARD is unavailable)." >&2
|
|
23
|
+
exit 3
|
|
24
|
+
fi
|
|
12
25
|
# Load agent identity for the LLM prompt
|
|
13
26
|
if [ -f "$AGENT_REPO_DIR/config/agent.env" ]; then
|
|
14
27
|
# shellcheck disable=SC1091
|
|
@@ -22,6 +22,13 @@
|
|
|
22
22
|
* That writes measurement:"unknown" with NULL tokens. It must never write
|
|
23
23
|
* zeros — see "MEASURED, UNKNOWN, N/A" below.
|
|
24
24
|
*
|
|
25
|
+
* A session cohort-llm served (engine cohort, or claude retargeted to the
|
|
26
|
+
* cohort provider) is already metered by the gateway; mark it so org
|
|
27
|
+
* cost-sync does not report it a second time:
|
|
28
|
+
*
|
|
29
|
+
* node scripts/cost/track-claude-usage.mjs record ... \
|
|
30
|
+
* --billed-by cohort-llm --request-ids req_1,req_2
|
|
31
|
+
*
|
|
25
32
|
* 2. `summarise` — Rollup the last N days into state/dashboards/cost-summary.yaml.
|
|
26
33
|
* Called daily (cadence: nightly-cost-rollup) and on demand.
|
|
27
34
|
*
|
|
@@ -266,6 +273,14 @@ function recordCmd(flags) {
|
|
|
266
273
|
};
|
|
267
274
|
if (unmeasuredReason) row.unmeasured_reason = unmeasuredReason;
|
|
268
275
|
if (flags["decision-id"]) row.decision_id = String(flags["decision-id"]);
|
|
276
|
+
// Who metered this session. "cohort-llm": the gateway billed it; the row is
|
|
277
|
+
// kept for the seat's own view and reconciliation, and skipped by org
|
|
278
|
+
// cost-sync (lib/org/cost-sync.mjs) so it is never counted twice.
|
|
279
|
+
if (flags["billed-by"] && flags["billed-by"] !== "true") row.billed_by = String(flags["billed-by"]);
|
|
280
|
+
if (flags["request-ids"] && flags["request-ids"] !== "true") {
|
|
281
|
+
const ids = String(flags["request-ids"]).split(",").map((x) => x.trim()).filter(Boolean);
|
|
282
|
+
if (ids.length) row.gateway_request_ids = ids;
|
|
283
|
+
}
|
|
269
284
|
|
|
270
285
|
if (measurement === "measured") {
|
|
271
286
|
// Cache tokens are billed at their own rates (read 0.1x, write 1.25x) and
|