@cohortapp/agent-sdk 2.17.0 → 2.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +18 -0
- package/.env.example +18 -5
- package/README.md +1 -0
- package/bin/maestro.mjs +62 -0
- package/docs/guides/billing-console-keys.md +60 -0
- package/docs/guides/front-door-session.md +54 -9
- package/docs/guides/mac-mini.md +20 -25
- package/docs/guides/setup-wizard.md +1 -1
- package/docs/runbooks/fleet-rollout.md +156 -0
- package/docs/runbooks/mac-mini-bootstrap.md +12 -14
- package/lib/action-executor.js +19 -3
- package/lib/budget-guard.mjs +279 -3
- package/lib/channels/base-adapter.mjs +3 -1
- package/lib/channels/contract.mjs +2 -1
- package/lib/channels/inbox-item.mjs +8 -0
- package/lib/claude-bin.mjs +5 -6
- package/lib/cli/doctor-checks.mjs +141 -10
- package/lib/cli/global-setup-extras.mjs +5 -1
- package/lib/cli/inbox.mjs +100 -15
- package/lib/cli/seat-auth.mjs +463 -0
- package/lib/cli/session.mjs +80 -12
- package/lib/collective/capture.mjs +8 -6
- package/lib/collective/global-config.mjs +63 -1
- package/lib/collective/presence.mjs +142 -5
- package/lib/comms/send-gate.mjs +559 -1
- package/lib/diagnostics/alerts.mjs +49 -0
- package/lib/diagnostics/cadence-output-freshness.mjs +288 -0
- package/lib/engine/agents/definitions.mjs +343 -0
- package/lib/engine/agents/persist.mjs +275 -0
- package/lib/engine/agents/runtime.mjs +748 -0
- package/lib/engine/agents/usage.mjs +95 -0
- package/lib/engine/auth-status.mjs +139 -0
- package/lib/engine/budget.mjs +194 -0
- package/lib/engine/cli.mjs +1204 -0
- package/lib/engine/commands/index.mjs +269 -0
- package/lib/engine/context/budget.mjs +219 -0
- package/lib/engine/context/cache.mjs +125 -0
- package/lib/engine/context/child-env.mjs +215 -0
- package/lib/engine/context/compaction.mjs +342 -0
- package/lib/engine/context/images.mjs +90 -0
- package/lib/engine/context/instructions.mjs +327 -0
- package/lib/engine/context/lazy-instructions.mjs +169 -0
- package/lib/engine/context/manager.mjs +182 -0
- package/lib/engine/context/real-path.mjs +91 -0
- package/lib/engine/context/secret-values.mjs +163 -0
- package/lib/engine/context/settings.mjs +274 -0
- package/lib/engine/context/stream-input.mjs +159 -0
- package/lib/engine/guard.mjs +152 -0
- package/lib/engine/hooks.mjs +713 -0
- package/lib/engine/loop.mjs +560 -0
- package/lib/engine/mcp/client.mjs +254 -0
- package/lib/engine/mcp/config.mjs +301 -0
- package/lib/engine/mcp/http.mjs +201 -0
- package/lib/engine/mcp/index.mjs +146 -0
- package/lib/engine/mcp/jsonrpc.mjs +147 -0
- package/lib/engine/mcp/naming.mjs +66 -0
- package/lib/engine/mcp/resources.mjs +89 -0
- package/lib/engine/mcp/results.mjs +133 -0
- package/lib/engine/mcp/stdio.mjs +137 -0
- package/lib/engine/mcp/supervisor.mjs +116 -0
- package/lib/engine/messages.mjs +104 -0
- package/lib/engine/output/json.mjs +164 -0
- package/lib/engine/output/stream-json.mjs +266 -0
- package/lib/engine/permissions.mjs +845 -0
- package/lib/engine/process-identity.mjs +164 -0
- package/lib/engine/process-tree.mjs +551 -0
- package/lib/engine/prompt.mjs +60 -0
- package/lib/engine/session/store.mjs +299 -0
- package/lib/engine/session-runtime/args.mjs +97 -0
- package/lib/engine/session-runtime/host.mjs +143 -0
- package/lib/engine/session-runtime/inbox.mjs +122 -0
- package/lib/engine/session-runtime/notifications.mjs +129 -0
- package/lib/engine/session-runtime/registry.mjs +328 -0
- package/lib/engine/session-runtime/runner.mjs +344 -0
- package/lib/engine/session-runtime/socket.mjs +212 -0
- package/lib/engine/session-runtime/wakeup.mjs +115 -0
- package/lib/engine/skills/index.mjs +321 -0
- package/lib/engine/tools/bash-background.mjs +533 -0
- package/lib/engine/tools/bash.mjs +216 -0
- package/lib/engine/tools/edit.mjs +97 -0
- package/lib/engine/tools/glob.mjs +81 -0
- package/lib/engine/tools/grep.mjs +224 -0
- package/lib/engine/tools/index.mjs +84 -0
- package/lib/engine/tools/list-agents.mjs +32 -0
- package/lib/engine/tools/ls.mjs +127 -0
- package/lib/engine/tools/monitor.mjs +82 -0
- package/lib/engine/tools/notebook-edit.mjs +218 -0
- package/lib/engine/tools/read.mjs +103 -0
- package/lib/engine/tools/schedule-wakeup.mjs +45 -0
- package/lib/engine/tools/schema.mjs +144 -0
- package/lib/engine/tools/send-message.mjs +77 -0
- package/lib/engine/tools/session.mjs +70 -0
- package/lib/engine/tools/todo.mjs +144 -0
- package/lib/engine/tools/toolsearch.mjs +217 -0
- package/lib/engine/tools/walk.mjs +193 -0
- package/lib/engine/tools/web-switch.mjs +31 -0
- package/lib/engine/tools/webfetch-html.mjs +387 -0
- package/lib/engine/tools/webfetch-net.mjs +340 -0
- package/lib/engine/tools/webfetch.mjs +198 -0
- package/lib/engine/tools/websearch.mjs +91 -0
- package/lib/engine/tools/workflow.mjs +95 -0
- package/lib/engine/tools/write.mjs +76 -0
- package/lib/engine/tui/line-editor.mjs +137 -0
- package/lib/engine/tui/render.mjs +86 -0
- package/lib/engine/tui/tui.mjs +274 -0
- package/lib/engine/wire/anthropic-messages.mjs +263 -0
- package/lib/engine/wire/effort.mjs +36 -0
- package/lib/engine/wire/errors.mjs +496 -0
- package/lib/engine/wire/http.mjs +441 -0
- package/lib/engine/wire/index.mjs +76 -0
- package/lib/engine/wire/openai-chat.mjs +332 -0
- package/lib/engine/wire/prompt-cache.mjs +79 -0
- package/lib/engine/wire/search.mjs +140 -0
- package/lib/engine/wire/sse.mjs +114 -0
- package/lib/engine/wire/stall.mjs +349 -0
- package/lib/engine/wire/token-provider.mjs +175 -0
- package/lib/engine/wire/usage.mjs +192 -0
- package/lib/engine/workflow/host.mjs +524 -0
- package/lib/engine/workflow/journal.mjs +188 -0
- package/lib/engine/workflow/json-schema.mjs +171 -0
- package/lib/engine/workflow/meta.mjs +329 -0
- package/lib/engine/workflow/notifications.mjs +52 -0
- package/lib/engine/workflow/runtime.mjs +447 -0
- package/lib/engine/workflow/sandbox.mjs +534 -0
- package/lib/engine/workflow/worker.mjs +141 -0
- package/lib/engine/workflow/worktree.mjs +74 -0
- package/lib/execution/disposition.mjs +1 -1
- package/lib/execution/intake.mjs +10 -0
- package/lib/execution/surface-policy.mjs +15 -0
- package/lib/learning/curator.mjs +8 -6
- package/lib/learning/reflect.mjs +8 -6
- package/lib/model-router/catalog/cohort.yaml +137 -0
- package/lib/model-router/catalog.mjs +118 -1
- package/lib/model-router/failover.mjs +67 -16
- package/lib/model-router/llm-task.mjs +39 -3
- package/lib/model-router/resolve.mjs +89 -3
- package/lib/model-router/spawn.mjs +46 -47
- package/lib/model-router/taxonomy.mjs +126 -4
- package/lib/org/cost-sync.mjs +141 -11
- package/lib/org/inbound/broadcast.mjs +289 -0
- package/lib/org/inbound/collective.mjs +375 -0
- package/lib/org/inbound/directedness.mjs +96 -8
- package/lib/org/inbound/facts.mjs +78 -2
- package/lib/org/inbound/project.mjs +22 -0
- package/lib/org/inbound/surfaces.mjs +14 -0
- package/lib/org/llm-token.mjs +879 -0
- package/lib/org/mesh.mjs +61 -0
- package/lib/org/messaging.mjs +3 -1
- package/lib/org/protocol.checksum +1 -1
- package/lib/org/protocol.mjs +15 -0
- package/lib/org/quota.mjs +520 -0
- package/lib/org/tool-surface.mjs +104 -16
- package/lib/org/ui-parity.mjs +16 -1
- package/lib/org/work-ledger.mjs +37 -6
- package/lib/rate-guard.mjs +114 -1
- package/lib/resource-governor.mjs +41 -6
- package/lib/runtime/adapter.mjs +823 -0
- package/lib/runtime/child-env.mjs +191 -0
- package/lib/runtime/legacy-shell-guard.mjs +97 -0
- package/lib/runtime/seat-engine.mjs +162 -0
- package/lib/session/ask-ledger.mjs +271 -0
- package/lib/session/current-work.mjs +676 -0
- package/lib/session/feed-core.mjs +40 -3
- package/lib/session/launch-args.mjs +56 -4
- package/lib/session/status-summary.mjs +26 -9
- package/lib/session/upgrade-notice.mjs +42 -0
- package/lib/setup/claude-probe.mjs +117 -13
- package/lib/setup/enrich.mjs +13 -10
- package/lib/setup/sections/model.mjs +39 -13
- package/lib/telemetry/collect.mjs +208 -9
- package/lib/upgrade/ignored-drift.mjs +105 -0
- package/lib/voice/post-call-brief.mjs +30 -17
- package/package.json +13 -3
- package/plugins/maestro-skills/skills/board-work.md +5 -0
- package/plugins/maestro-skills/skills/inbound-triage.md +56 -15
- package/plugins/maestro-skills/skills/main-session.md +18 -7
- package/scripts/ci/check-tarball-fidelity.mjs +126 -2
- package/scripts/ci/run-tests.mjs +47 -19
- package/scripts/cohort-llm/api-key-helper.mjs +92 -0
- package/scripts/collective/hook-runner.mjs +29 -2
- package/scripts/continuous-monitor.sh +13 -0
- package/scripts/cost/track-claude-usage.mjs +15 -0
- package/scripts/daemon/agent-daemon.mjs +408 -20
- package/scripts/daemon/assurance.mjs +48 -12
- package/scripts/daemon/cadence-consumer.mjs +218 -68
- package/scripts/daemon/cadence-handlers.mjs +73 -4
- package/scripts/daemon/classifier.mjs +75 -26
- package/scripts/daemon/context-compiler.mjs +51 -37
- package/scripts/daemon/deliver.mjs +30 -1
- package/scripts/daemon/dispatcher.mjs +595 -149
- package/scripts/daemon/health.mjs +14 -1
- package/scripts/daemon/maestro-daemon.mjs +11 -0
- package/scripts/daemon/prompt-builder.mjs +24 -0
- package/scripts/daemon/responder.mjs +246 -79
- package/scripts/daemon/sdk-version.mjs +98 -16
- package/scripts/eval/probe-gateway.mjs +635 -0
- package/scripts/eval/replay/extract.mjs +270 -0
- package/scripts/eval/replay/grade.mjs +260 -0
- package/scripts/eval/replay/lib/config.mjs +50 -0
- package/scripts/eval/replay/lib/effects.mjs +65 -0
- package/scripts/eval/replay/lib/fixture.mjs +188 -0
- package/scripts/eval/replay/lib/judge.mjs +72 -0
- package/scripts/eval/replay/lib/redact.mjs +136 -0
- package/scripts/eval/replay/lib/sandbox.mjs +170 -0
- package/scripts/eval/replay/lib/schema-check.mjs +63 -0
- package/scripts/eval/replay/lib/transcript.mjs +76 -0
- package/scripts/eval/replay/mcp-replay-stub.mjs +101 -0
- package/scripts/eval/replay/report.mjs +185 -0
- package/scripts/eval/replay/run.mjs +404 -0
- package/scripts/fleet/rollout.mjs +1094 -0
- package/scripts/hooks/pre-send-audit.sh +36 -245
- package/scripts/hooks/pre-write-yaml-validate.mjs +275 -0
- package/scripts/hooks/validate-state-yaml.sh +190 -0
- package/scripts/huddle/huddle-llm.mjs +361 -0
- package/scripts/huddle/huddle-server.mjs +46 -121
- package/scripts/local-triggers/autoupdate.sh +448 -78
- package/scripts/local-triggers/run-trigger.sh +13 -0
- package/scripts/maintenance/pin-integrity.mjs +364 -0
- package/scripts/poll-slack-events.sh +41 -9
- package/scripts/poller/slack-socket-mode.mjs +28 -3
- package/scripts/session/supervisor.mjs +80 -13
- package/scripts/spawn-session.sh +13 -0
- package/bin/maestro.test.mjs +0 -1574
- package/lib/action-executor.test.mjs +0 -871
- package/lib/archetype.test.mjs +0 -132
- package/lib/assurance/plan-note.test.mjs +0 -234
- package/lib/assurance/room-budget.test.mjs +0 -486
- package/lib/assurance/tier.test.mjs +0 -174
- package/lib/autonomy.test.mjs +0 -66
- package/lib/backlog.test.mjs +0 -302
- package/lib/backup/policy.test.mjs +0 -305
- package/lib/budget-escalate.test.mjs +0 -232
- package/lib/budget-guard.envelope.test.mjs +0 -476
- package/lib/budget-guard.test.mjs +0 -427
- package/lib/cadence-bus-requeue.test.mjs +0 -83
- package/lib/cadence-bus-schedule.test.mjs +0 -194
- package/lib/cadence-bus.test.mjs +0 -720
- package/lib/cadences.test.mjs +0 -230
- package/lib/capability/inventory.test.mjs +0 -232
- package/lib/capability.test.mjs +0 -78
- package/lib/channels/base-adapter.test.mjs +0 -590
- package/lib/channels/channels.test.mjs +0 -371
- package/lib/channels/contract.test.mjs +0 -162
- package/lib/channels/inbox-item.test.mjs +0 -368
- package/lib/channels/orgmail/adapter.test.mjs +0 -448
- package/lib/channels/pairing.test.mjs +0 -270
- package/lib/channels/repeat-suppressor.test.mjs +0 -134
- package/lib/channels/slack-adapter.test.mjs +0 -212
- package/lib/channels/telegram-adapter.test.mjs +0 -306
- package/lib/channels/voice/adapter.test.mjs +0 -278
- package/lib/channels/whatsapp/adapter-baileys.test.mjs +0 -359
- package/lib/channels/whatsapp/baileys-typing.test.mjs +0 -154
- package/lib/charter.test.mjs +0 -89
- package/lib/claude-bin.test.mjs +0 -131
- package/lib/cli/board.test.mjs +0 -227
- package/lib/cli/design.test.mjs +0 -270
- package/lib/cli/doctor-checks.test.mjs +0 -336
- package/lib/cli/global-setup-extras.test.mjs +0 -462
- package/lib/cli/inbox.test.mjs +0 -230
- package/lib/cli/session-ack.test.mjs +0 -63
- package/lib/cli/session.test.mjs +0 -613
- package/lib/collective/capture.test.mjs +0 -121
- package/lib/collective/cards.test.mjs +0 -114
- package/lib/collective/config.test.mjs +0 -123
- package/lib/collective/global-config.test.mjs +0 -220
- package/lib/collective/global-skills.test.mjs +0 -126
- package/lib/collective/presence.test.mjs +0 -95
- package/lib/collective/recall.test.mjs +0 -116
- package/lib/collective/vendor-skills.test.mjs +0 -306
- package/lib/comms/send-gate.test.mjs +0 -770
- package/lib/comms.test.mjs +0 -41
- package/lib/context/budget.test.mjs +0 -252
- package/lib/context/history-scope.test.mjs +0 -79
- package/lib/cost/ledger-row.test.mjs +0 -183
- package/lib/design/design-md.test.mjs +0 -318
- package/lib/design/fixtures/DESIGN.golden.md +0 -238
- package/lib/design/fixtures/PRODUCT.golden.md +0 -67
- package/lib/design/fixtures/foundation.json +0 -133
- package/lib/design/refresh-gate.test.mjs +0 -144
- package/lib/design/write.test.mjs +0 -241
- package/lib/diagnostics/alerts.test.mjs +0 -318
- package/lib/diagnostics/backup-freshness.test.mjs +0 -185
- package/lib/diagnostics/counters.test.mjs +0 -206
- package/lib/diagnostics/events.test.mjs +0 -290
- package/lib/diagnostics/otel.test.mjs +0 -196
- package/lib/diagnostics/trace.test.mjs +0 -251
- package/lib/env-compat.test.mjs +0 -104
- package/lib/execution/disposition.test.mjs +0 -553
- package/lib/execution/drive.test.mjs +0 -270
- package/lib/execution/effects.test.mjs +0 -344
- package/lib/execution/intake.test.mjs +0 -389
- package/lib/execution/journal.test.mjs +0 -261
- package/lib/execution/match.test.mjs +0 -235
- package/lib/execution/pipeline.test.mjs +0 -392
- package/lib/execution/route.test.mjs +0 -186
- package/lib/execution/surface-policy.test.mjs +0 -162
- package/lib/fs-atomic.test.mjs +0 -72
- package/lib/fs-ownership.test.mjs +0 -158
- package/lib/goals/admission.test.mjs +0 -164
- package/lib/goals/classify.test.mjs +0 -167
- package/lib/goals/collaborate.test.mjs +0 -336
- package/lib/goals/gaps.test.mjs +0 -284
- package/lib/goals/loop.test.mjs +0 -845
- package/lib/hooks/bus.test.mjs +0 -387
- package/lib/identity/persona.test.mjs +0 -142
- package/lib/kpi-sensors.test.mjs +0 -278
- package/lib/kpi.test.mjs +0 -244
- package/lib/learning/config.test.mjs +0 -75
- package/lib/learning/counters.test.mjs +0 -69
- package/lib/learning/curator-consolidate.test.mjs +0 -238
- package/lib/learning/curator.test.mjs +0 -106
- package/lib/learning/reflect.test.mjs +0 -0
- package/lib/learning/session-index.test.mjs +0 -125
- package/lib/learning/skill-writer.test.mjs +0 -210
- package/lib/mandate/audit.test.mjs +0 -195
- package/lib/mandate/contract.test.mjs +0 -185
- package/lib/mandate/derive.test.mjs +0 -274
- package/lib/mandate/model.test.mjs +0 -164
- package/lib/mandate/refresh.test.mjs +0 -389
- package/lib/mcp/server.test.mjs +0 -426
- package/lib/model-router/auth-profiles.test.mjs +0 -580
- package/lib/model-router/catalog.test.mjs +0 -385
- package/lib/model-router/economics.test.mjs +0 -438
- package/lib/model-router/failover.test.mjs +0 -439
- package/lib/model-router/health.test.mjs +0 -338
- package/lib/model-router/integration-coverage.test.mjs +0 -831
- package/lib/model-router/integration.test.mjs +0 -564
- package/lib/model-router/ledger.test.mjs +0 -415
- package/lib/model-router/llm-task.test.mjs +0 -392
- package/lib/model-router/org-credentials.test.mjs +0 -265
- package/lib/model-router/pricing-refresh.test.mjs +0 -286
- package/lib/model-router/reconcile.test.mjs +0 -316
- package/lib/model-router/repair.test.mjs +0 -180
- package/lib/model-router/spawn.test.mjs +0 -446
- package/lib/model-router/taxonomy.test.mjs +0 -410
- package/lib/model-router.test.mjs +0 -1207
- package/lib/org/activity.test.mjs +0 -134
- package/lib/org/approvals.test.mjs +0 -216
- package/lib/org/awareness.test.mjs +0 -159
- package/lib/org/board-mine-cache.test.mjs +0 -53
- package/lib/org/board.test.mjs +0 -187
- package/lib/org/bootstrap-context.test.mjs +0 -153
- package/lib/org/client.test.mjs +0 -1206
- package/lib/org/cohort-client.test.mjs +0 -126
- package/lib/org/cost-sync.test.mjs +0 -153
- package/lib/org/doctor.test.mjs +0 -346
- package/lib/org/engagement-ledger.test.mjs +0 -112
- package/lib/org/engagement.test.mjs +0 -739
- package/lib/org/handoff.test.mjs +0 -269
- package/lib/org/inbound/directedness.test.mjs +0 -668
- package/lib/org/inbound/facts.test.mjs +0 -471
- package/lib/org/inbound/hydrate.test.mjs +0 -908
- package/lib/org/inbound/index.test.mjs +0 -429
- package/lib/org/inbound/project.test.mjs +0 -287
- package/lib/org/integration-tools.test.mjs +0 -160
- package/lib/org/keys.test.mjs +0 -92
- package/lib/org/knowledge.test.mjs +0 -326
- package/lib/org/leases.test.mjs +0 -235
- package/lib/org/mesh-directives.test.mjs +0 -110
- package/lib/org/mesh-integration.test.mjs +0 -127
- package/lib/org/mesh.test.mjs +0 -400
- package/lib/org/messaging.test.mjs +0 -471
- package/lib/org/param-contract.test.mjs +0 -477
- package/lib/org/policy.test.mjs +0 -237
- package/lib/org/protocol.checksum.test.mjs +0 -90
- package/lib/org/protocol.test.mjs +0 -323
- package/lib/org/push.test.mjs +0 -792
- package/lib/org/registry.test.mjs +0 -100
- package/lib/org/resource-tools.test.mjs +0 -361
- package/lib/org/tool-access.test.mjs +0 -144
- package/lib/org/tool-surface-integration.test.mjs +0 -120
- package/lib/org/tool-surface.test.mjs +0 -1268
- package/lib/org/typing.test.mjs +0 -291
- package/lib/org/ui-parity.test.mjs +0 -560
- package/lib/org/verify.test.mjs +0 -194
- package/lib/org/work-ledger.test.mjs +0 -273
- package/lib/plan/adoption-e2e.test.mjs +0 -366
- package/lib/plan/budget-enforcement.test.mjs +0 -400
- package/lib/plan/compile.test.mjs +0 -382
- package/lib/plan/emit.test.mjs +0 -269
- package/lib/plan/explain.test.mjs +0 -188
- package/lib/prompts/parallelism.test.mjs +0 -177
- package/lib/rag/rag.test.mjs +0 -505
- package/lib/rate-guard.test.mjs +0 -272
- package/lib/reactive-gate.test.mjs +0 -57
- package/lib/render.test.mjs +0 -68
- package/lib/resource-governor.test.mjs +0 -488
- package/lib/scheduling/dynamic-jobs.test.mjs +0 -344
- package/lib/scheduling/jitter.test.mjs +0 -140
- package/lib/secrets/broker.test.mjs +0 -280
- package/lib/secrets/providers.test.mjs +0 -274
- package/lib/security/audit-engine.test.mjs +0 -424
- package/lib/security/coerce-args.test.mjs +0 -281
- package/lib/security/dangerous-tools.test.mjs +0 -68
- package/lib/security/external-content.test.mjs +0 -84
- package/lib/security/redact.test.mjs +0 -441
- package/lib/security/secret-equal.test.mjs +0 -55
- package/lib/session/config.test.mjs +0 -92
- package/lib/session/feed-core.test.mjs +0 -198
- package/lib/session/first-run.test.mjs +0 -121
- package/lib/session/frontdoor.test.mjs +0 -205
- package/lib/session/handoffs.test.mjs +0 -183
- package/lib/session/identity.test.mjs +0 -180
- package/lib/session/inbox-claims.test.mjs +0 -286
- package/lib/session/launch-args.test.mjs +0 -157
- package/lib/session/liveness.test.mjs +0 -100
- package/lib/session/status-summary.test.mjs +0 -118
- package/lib/session-permissions.test.mjs +0 -120
- package/lib/setup/claude-probe.test.mjs +0 -187
- package/lib/setup/completeness.test.mjs +0 -110
- package/lib/setup/context-pack.test.mjs +0 -89
- package/lib/setup/enrich.test.mjs +0 -115
- package/lib/setup/enroll-from-cohort.test.mjs +0 -300
- package/lib/setup/integration.test.mjs +0 -162
- package/lib/setup/io.test.mjs +0 -77
- package/lib/setup/runner.test.mjs +0 -132
- package/lib/setup/sections/identity.test.mjs +0 -234
- package/lib/setup/sections/inventory.test.mjs +0 -198
- package/lib/setup/sections/learning.test.mjs +0 -81
- package/lib/setup/sections/mandate.test.mjs +0 -388
- package/lib/setup/sections/messaging.test.mjs +0 -127
- package/lib/setup/sections/model.test.mjs +0 -240
- package/lib/setup/sections/org.test.mjs +0 -346
- package/lib/setup/sections/orgmail.test.mjs +0 -118
- package/lib/setup/sections/recovery.test.mjs +0 -98
- package/lib/setup/sections/subagents.test.mjs +0 -429
- package/lib/setup/sections/verify.test.mjs +0 -175
- package/lib/setup/sot.test.mjs +0 -81
- package/lib/setup/state.test.mjs +0 -115
- package/lib/singleton.test.mjs +0 -151
- package/lib/subagents/cli.test.mjs +0 -389
- package/lib/subagents/client.test.mjs +0 -309
- package/lib/subagents/gap.test.mjs +0 -234
- package/lib/subagents/lock.test.mjs +0 -248
- package/lib/subagents/manifest.test.mjs +0 -175
- package/lib/subagents/refs.test.mjs +0 -204
- package/lib/subagents/resolve.test.mjs +0 -422
- package/lib/subagents/schema.test.mjs +0 -328
- package/lib/telemetry/alerts.test.mjs +0 -109
- package/lib/telemetry/collect.test.mjs +0 -1274
- package/lib/tool-definitions-integration.test.mjs +0 -83
- package/lib/tool-definitions.test.mjs +0 -437
- package/lib/upgrade/global-refresh.test.mjs +0 -65
- package/lib/upgrade/launchd-reconcile.test.mjs +0 -272
- package/lib/upgrade/post-steps.test.mjs +0 -200
- package/lib/upgrade/verify.test.mjs +0 -164
- package/lib/util/fetch-timeout.test.mjs +0 -202
- package/lib/util/reconnect.test.mjs +0 -369
- package/lib/util/unhandled.test.mjs +0 -216
- package/lib/voice/outbound.test.mjs +0 -69
- package/lib/voice/session-rotation.test.mjs +0 -114
- package/lib/voice/stt.test.mjs +0 -226
- package/lib/voice/voice.test.mjs +0 -990
- package/scripts/cadence/enqueue-cadence-tick.test.mjs +0 -187
- package/scripts/ci/check-docs-accuracy.test.mjs +0 -409
- package/scripts/ci/check-durable-write-seam.test.mjs +0 -90
- package/scripts/ci/check-no-build-artifacts.test.mjs +0 -71
- package/scripts/ci/check-no-residual-identity.test.mjs +0 -202
- package/scripts/ci/check-skill-packs.test.mjs +0 -495
- package/scripts/ci/check-subagent-frontmatter.test.mjs +0 -124
- package/scripts/ci/check.test.mjs +0 -194
- package/scripts/ci/conformance-org-api.test.mjs +0 -425
- package/scripts/cloud-relay/voice/relay-identity.test.mjs +0 -96
- package/scripts/collective/hook-runner.test.mjs +0 -173
- package/scripts/cost/fleet-digest.test.mjs +0 -207
- package/scripts/cost/track-claude-usage-pricing.test.mjs +0 -183
- package/scripts/cost/track-claude-usage.test.mjs +0 -148
- package/scripts/daemon/agent-daemon-board-mine.test.mjs +0 -96
- package/scripts/daemon/agent-daemon-design.test.mjs +0 -238
- package/scripts/daemon/agent-daemon-frontdoor.test.mjs +0 -60
- package/scripts/daemon/agent-daemon.test.mjs +0 -995
- package/scripts/daemon/assurance-e2e.test.mjs +0 -613
- package/scripts/daemon/assurance.test.mjs +0 -1791
- package/scripts/daemon/board-mirror.test.mjs +0 -165
- package/scripts/daemon/cadence-consumer-frontdoor.test.mjs +0 -393
- package/scripts/daemon/cadence-consumer-governance.test.mjs +0 -276
- package/scripts/daemon/cadence-consumer.test.mjs +0 -776
- package/scripts/daemon/cadence-handlers.test.mjs +0 -837
- package/scripts/daemon/classifier-identity.test.mjs +0 -137
- package/scripts/daemon/classifier.test.mjs +0 -266
- package/scripts/daemon/classify-kind.test.mjs +0 -40
- package/scripts/daemon/context-compiler.test.mjs +0 -406
- package/scripts/daemon/deliver.test.mjs +0 -564
- package/scripts/daemon/dispatcher-cooldown.test.mjs +0 -122
- package/scripts/daemon/dispatcher-governance.test.mjs +0 -1013
- package/scripts/daemon/dispatcher-resume.test.mjs +0 -166
- package/scripts/daemon/dispatcher-session-continuity.test.mjs +0 -365
- package/scripts/daemon/execution-ladder.test.mjs +0 -470
- package/scripts/daemon/goal-steward-cadence.test.mjs +0 -312
- package/scripts/daemon/inbox-deferral-session.test.mjs +0 -49
- package/scripts/daemon/inbox-deferral.test.mjs +0 -336
- package/scripts/daemon/inbox-wake.test.mjs +0 -199
- package/scripts/daemon/integration.test.mjs +0 -149
- package/scripts/daemon/lib/self-echo.test.mjs +0 -153
- package/scripts/daemon/lib/session-router.test.mjs +0 -554
- package/scripts/daemon/prompt-builder-preamble.test.mjs +0 -210
- package/scripts/daemon/prompt-builder.test.mjs +0 -556
- package/scripts/daemon/responder-cost.test.mjs +0 -68
- package/scripts/daemon/responder-history.test.mjs +0 -221
- package/scripts/daemon/sdk-version.test.mjs +0 -31
- package/scripts/daemon/session-lock.test.mjs +0 -252
- package/scripts/daemon/session-outcomes.test.mjs +0 -533
- package/scripts/daemon/typing-registry.test.mjs +0 -102
- package/scripts/hooks/pre-send-audit.test.mjs +0 -354
- package/scripts/huddle/huddle-prompt.test.mjs +0 -176
- package/scripts/local-triggers/autoupdate.test.mjs +0 -518
- package/scripts/local-triggers/generate-plists.test.mjs +0 -456
- package/scripts/media-generation/brand-clause.test.mjs +0 -135
- package/scripts/org/send-orgmail.first-contact.test.mjs +0 -102
- package/scripts/poller/inbox-privilege-injection.test.mjs +0 -167
- package/scripts/poller/inbox-scan-poller.test.mjs +0 -295
- package/scripts/poller/lib/cloud-relay-dedup.test.mjs +0 -133
- package/scripts/poller/slack-socket-mode.test.mjs +0 -805
- package/scripts/poller-launchd/install.test.mjs +0 -243
- package/scripts/restore-from-backup.test.mjs +0 -181
- package/scripts/session/feed.test.mjs +0 -196
- package/scripts/session/supervisor-sh.test.mjs +0 -218
- package/scripts/session/supervisor.test.mjs +0 -482
- package/scripts/setup/configure-macos.test.mjs +0 -306
- package/scripts/setup/gen-subagent-manifest.test.mjs +0 -124
- package/scripts/setup/generate-agent-package-json.test.mjs +0 -143
- package/scripts/setup/generate-capability.test.mjs +0 -134
- package/scripts/setup/init-agent.test.mjs +0 -370
- package/scripts/setup/init-skill-marketplace.test.mjs +0 -193
- package/scripts/vendor/sync-skill-packs.test.mjs +0 -103
- package/scripts/watchdog/memory-watchdog.test.mjs +0 -64
|
@@ -183,7 +183,9 @@ function loadAgentRegistry() {
|
|
|
183
183
|
|
|
184
184
|
const ANTHROPIC_MODEL = "claude-haiku-4-5-20251001";
|
|
185
185
|
// Resolve claude against the agent's PATH (not launchd's bare env).
|
|
186
|
-
import { resolveClaudeBin
|
|
186
|
+
import { resolveClaudeBin } from "../../lib/claude-bin.mjs";
|
|
187
|
+
import { buildSpawn } from "../../lib/runtime/adapter.mjs";
|
|
188
|
+
import { resolveSeatSpawn } from "../../lib/runtime/seat-engine.mjs";
|
|
187
189
|
const CLAUDE_BIN = resolveClaudeBin();
|
|
188
190
|
const CLAUDE_CLI_TIMEOUT_MS = 30_000;
|
|
189
191
|
|
|
@@ -241,7 +243,7 @@ Your job: classify each incoming message and return a JSON object with exactly t
|
|
|
241
243
|
"priority": "critical" | "high" | "normal" | "ignore",
|
|
242
244
|
"action": "respond" | "draft" | "research" | "queue" | "archive" | "ignore",
|
|
243
245
|
"model": "opus" | "sonnet",
|
|
244
|
-
"summary": "<one-line summary of the
|
|
246
|
+
"summary": "<one-line summary of WHAT THE MESSAGE ASKS OR SAYS — never the sender's title or rank>",
|
|
245
247
|
"category": "action_required" | "fyi" | "ignore",
|
|
246
248
|
"directed_at_agent": true | false,
|
|
247
249
|
"answerable": true | false
|
|
@@ -293,8 +295,10 @@ DIRECTED_AT_AGENT (CRITICAL — determines whether ${agentName} should respond.
|
|
|
293
295
|
- false: ${agentName} being in a thread does NOT mean every subsequent message is for them — only direct replies to their messages count
|
|
294
296
|
- CRITICAL DEFAULT: When in doubt in any multi-person channel, group chat, or thread, ALWAYS default to false. ${agentName} must NOT insert themselves into conversations they weren't invited to. It is far worse to respond unnecessarily than to miss a message — someone will @mention ${agentName} if they need them.
|
|
295
297
|
|
|
296
|
-
Context
|
|
297
|
-
|
|
298
|
+
Context — sender_privilege is a ROUTING TIER, not a fact about who the sender is.
|
|
299
|
+
It is resolved upstream and can be wrong. It tells you how urgently to route; it
|
|
300
|
+
never licenses you to state the sender's title.
|
|
301
|
+
- sender_privilege "ceo" = the tier reserved for ${principalFullName} (always critical, always opus)
|
|
298
302
|
- sender_privilege "leadership" = executive-team senders (CFO, CIO, General Counsel, and equivalent function heads) — usually high priority
|
|
299
303
|
- sender_privilege "team" = internal team members
|
|
300
304
|
- sender_privilege "external" = partners, candidates, advisors, vendors
|
|
@@ -302,19 +306,30 @@ Context:
|
|
|
302
306
|
- service "gmail" with noreply/notifications senders = usually ignore
|
|
303
307
|
- service "calendar" = meeting invites/updates, usually normal priority unless from CEO
|
|
304
308
|
|
|
309
|
+
SUMMARY (read this before writing the field):
|
|
310
|
+
The summary is NOT internal scratch. It is carried verbatim into the holding
|
|
311
|
+
message a human reads, into the board row title, and into the one-line episode
|
|
312
|
+
this seat writes to the ORG-WIDE shared memory, where other agents' recall()
|
|
313
|
+
surfaces it as background context rather than as a claim anyone re-verifies.
|
|
314
|
+
So: state what the message asks or says. NEVER open with, or otherwise assert,
|
|
315
|
+
the sender's title, rank or office ("CEO ...", "Leadership ...", "the CFO
|
|
316
|
+
asking ..."). Name the sender if you have their name; otherwise describe the
|
|
317
|
+
ask. A rank you did not verify becomes a false statement about this
|
|
318
|
+
organisation's governance the moment it leaves this process.
|
|
319
|
+
|
|
305
320
|
Examples:
|
|
306
321
|
|
|
307
|
-
Input:
|
|
308
|
-
Output: {"priority":"critical","action":"respond","model":"opus","summary":"
|
|
322
|
+
Input: DM on Slack from ${principalFullName}: "Can you send the board resolution to Jordan?"
|
|
323
|
+
Output: {"priority":"critical","action":"respond","model":"opus","summary":"${principalName} requesting the board resolution be sent to GC Jordan","category":"action_required","directed_at_agent":true,"answerable":false}
|
|
309
324
|
|
|
310
|
-
Input:
|
|
311
|
-
Output: {"priority":"critical","action":"respond","model":"opus","summary":"
|
|
325
|
+
Input: DM on Slack from ${principalFullName}: "what kind of machine are you running on?"
|
|
326
|
+
Output: {"priority":"critical","action":"respond","model":"opus","summary":"${principalName} asking what machine/infrastructure the agent runs on","category":"action_required","directed_at_agent":true,"answerable":true}
|
|
312
327
|
|
|
313
328
|
Input: GitHub notification email about a merged PR
|
|
314
329
|
Output: {"priority":"ignore","action":"ignore","model":"sonnet","summary":"GitHub PR merge notification","category":"ignore","directed_at_agent":false,"answerable":false}
|
|
315
330
|
|
|
316
331
|
Input: Leadership Slack: "We need the the regulator gap analysis updated by Thursday"
|
|
317
|
-
Output: {"priority":"high","action":"draft","model":"opus","summary":"
|
|
332
|
+
Output: {"priority":"high","action":"draft","model":"opus","summary":"Request for the regulator gap analysis update by Thursday deadline","category":"action_required","directed_at_agent":true,"answerable":false}
|
|
318
333
|
|
|
319
334
|
Input: Team member: "Standup notes from today's sync"
|
|
320
335
|
Output: {"priority":"normal","action":"archive","model":"sonnet","summary":"Team standup notes shared","category":"fyi","directed_at_agent":false,"answerable":false}
|
|
@@ -325,8 +340,8 @@ Output: {"priority":"normal","action":"respond","model":"sonnet","summary":"Exte
|
|
|
325
340
|
Input: Channel message from Jacob: "@${agentName} can you check the engine deployment?"
|
|
326
341
|
Output: {"priority":"normal","action":"respond","model":"sonnet","summary":"Jacob asking ${agentName} to check engine deployment","category":"action_required","directed_at_agent":true,"answerable":false}
|
|
327
342
|
|
|
328
|
-
Input: Channel message from
|
|
329
|
-
Output: {"priority":"normal","action":"archive","model":"sonnet","summary":"
|
|
343
|
+
Input: Channel message from ${principalFullName}: "@AnotherAgent can you review the agentic libraries in this channel?"
|
|
344
|
+
Output: {"priority":"normal","action":"archive","model":"sonnet","summary":"${principalName} asking another agent to review agentic libraries — not directed at ${agentName}","category":"fyi","directed_at_agent":false,"answerable":false}
|
|
330
345
|
|
|
331
346
|
Input: Channel message from Sam to Jordan: "Jordan, did you file the compliance response yet?"
|
|
332
347
|
Output: {"priority":"normal","action":"archive","model":"sonnet","summary":"Sam asking Jordan about compliance response filing","category":"fyi","directed_at_agent":false,"answerable":false}
|
|
@@ -450,22 +465,44 @@ export function parseClassification(text) {
|
|
|
450
465
|
// • Any failure (non-zero exit, timeout, unparseable output) throws so
|
|
451
466
|
// the Tier-2 llmTask fallback engages exactly as before.
|
|
452
467
|
|
|
468
|
+
/**
|
|
469
|
+
* The classifier lane's spawn from the runtime adapter (lane "classifier"):
|
|
470
|
+
* --print <permissions> <bare MCP> --model <m> --append-system-prompt <sys>,
|
|
471
|
+
* prompt on stdin; stock env posture (stale ANTHROPIC_API_KEY/AUTH_TOKEN
|
|
472
|
+
* stripped, PATH augmented).
|
|
473
|
+
*
|
|
474
|
+
* W4-E1 (CF-44): `seat` is the seat's engine resolved once for this spawn. A
|
|
475
|
+
* claude seat adds no fields (unchanged); an engine-cohort seat runs `cli.mjs run`.
|
|
476
|
+
* @param {{systemPrompt:string, userPrompt:string, env?:object, bin?:string, seat?:{fields:object}}} o
|
|
477
|
+
*/
|
|
478
|
+
export function classifierSpawn({ systemPrompt, userPrompt, env = process.env, bin = CLAUDE_BIN, seat = { fields: {} } }) {
|
|
479
|
+
return buildSpawn({
|
|
480
|
+
lane: "classifier",
|
|
481
|
+
bin,
|
|
482
|
+
model: ANTHROPIC_MODEL,
|
|
483
|
+
systemPrompt,
|
|
484
|
+
prompt: userPrompt,
|
|
485
|
+
permissions: sessionPermissionArgs({ source: "classifier" }),
|
|
486
|
+
mcp: { source: "classifier" },
|
|
487
|
+
env,
|
|
488
|
+
...seat.fields,
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
|
|
453
492
|
async function runClaudeCLI(systemPrompt, userPrompt) {
|
|
493
|
+
// W4-E1: the seat's engine, once per spawn (a claude seat reads config/agent.json only).
|
|
494
|
+
const seat = await resolveSeatSpawn(agentDir());
|
|
454
495
|
return new Promise((resolvePromise, rejectPromise) => {
|
|
455
|
-
const
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
const proc = spawn(CLAUDE_BIN, args, {
|
|
496
|
+
const spawnSpec = classifierSpawn({ systemPrompt, userPrompt, seat });
|
|
497
|
+
if (!spawnSpec.ok) {
|
|
498
|
+
// Throw-path parity: a rejection engages the Tier-2 llmTask fallback.
|
|
499
|
+
rejectPromise(new Error(`claude CLI unavailable: ${spawnSpec.error.message}`));
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const proc = spawn(spawnSpec.bin, spawnSpec.argv, {
|
|
464
504
|
stdio: ["pipe", "pipe", "pipe"],
|
|
465
|
-
|
|
466
|
-
// stale ANTHROPIC_API_KEY/AUTH_TOKEN inherited from the daemon env.
|
|
467
|
-
// Augment PATH so spawned subsessions find homebrew/nvm binaries.
|
|
468
|
-
env: { ...process.env, PATH: augmentedPath(), ANTHROPIC_API_KEY: "", ANTHROPIC_AUTH_TOKEN: "" },
|
|
505
|
+
env: spawnSpec.env,
|
|
469
506
|
});
|
|
470
507
|
|
|
471
508
|
let stdout = "";
|
|
@@ -671,12 +708,24 @@ function classifyWithRules(item) {
|
|
|
671
708
|
const directed = isDirectedAtAgent(item);
|
|
672
709
|
|
|
673
710
|
// CEO → critical, opus (but in channels, respect directed check)
|
|
711
|
+
//
|
|
712
|
+
// The summary deliberately does NOT name the tier ("CEO message from …").
|
|
713
|
+
// sender_privilege is a routing tier resolved upstream and it has been wrong
|
|
714
|
+
// fleet-wide: the answerItem() call site (now resolveSenderPrivilege() in
|
|
715
|
+
// agent-daemon.mjs) once read the unparenthesised
|
|
716
|
+
// `a || b ? "ceo" : "unknown"`, which stamped every sender "ceo". The
|
|
717
|
+
// summary is carried verbatim into holding text, board rows and org-wide
|
|
718
|
+
// memory, so a tier name here becomes an asserted fact about the sender's
|
|
719
|
+
// office that nothing downstream re-verifies. Route on the tier; never
|
|
720
|
+
// narrate it. (The rules-path sweep covered every summary below: the
|
|
721
|
+
// urgent-keyword limb's "Urgent message from …" names the message's own
|
|
722
|
+
// content, not a rank, and is kept as is.)
|
|
674
723
|
if (item.sender_privilege === "ceo") {
|
|
675
724
|
return {
|
|
676
725
|
priority: "critical",
|
|
677
726
|
action: directed ? "respond" : "archive",
|
|
678
727
|
model: "opus",
|
|
679
|
-
summary: `
|
|
728
|
+
summary: `Message from ${item.sender}`,
|
|
680
729
|
category: directed ? "action_required" : "fyi",
|
|
681
730
|
directed_at_agent: directed,
|
|
682
731
|
};
|
|
@@ -688,7 +737,7 @@ function classifyWithRules(item) {
|
|
|
688
737
|
priority: "high",
|
|
689
738
|
action: directed ? "respond" : "archive",
|
|
690
739
|
model: "opus",
|
|
691
|
-
summary: `
|
|
740
|
+
summary: `Message from ${item.sender}`,
|
|
692
741
|
category: directed ? "action_required" : "fyi",
|
|
693
742
|
directed_at_agent: directed,
|
|
694
743
|
};
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Single export: compileContext(item, classResult, options)
|
|
6
6
|
*
|
|
7
7
|
* Assembles sender profile, disclosure boundaries, conversation history,
|
|
8
|
-
*
|
|
8
|
+
* current work (this agent's sessions on the machine), and sent-message
|
|
9
|
+
* registry into a single context block.
|
|
9
10
|
* Filters history entries by information barrier domains.
|
|
10
11
|
*
|
|
11
12
|
* Adaptive token budget: 12K for critical/high, 8K for normal, 4K for low.
|
|
@@ -17,6 +18,7 @@ import { isEnabled as orgEnabled, loadOrgConfig } from "../../lib/org/client.mjs
|
|
|
17
18
|
import { recall as orgRecall } from "../../lib/org/knowledge.mjs";
|
|
18
19
|
import { isPrivateConversation, historyDirNames } from "../../lib/context/history-scope.mjs";
|
|
19
20
|
import { fitSections } from "../../lib/context/budget.mjs";
|
|
21
|
+
import { currentWorkBlock, audienceForItem } from "../../lib/session/current-work.mjs";
|
|
20
22
|
|
|
21
23
|
const AGENT_REPO_DIR = process.env.__TEST_AGENT_DIR || process.env.AGENT_DIR || join(new URL(".", import.meta.url).pathname, "../..");
|
|
22
24
|
const SESSION_DIR = process.env.__TEST_SESSION_DIR || join(AGENT_REPO_DIR, "state", "sessions");
|
|
@@ -168,6 +170,24 @@ function matchesForbiddenDomain(text, forbiddenDomains, domainKeywords) {
|
|
|
168
170
|
return false;
|
|
169
171
|
}
|
|
170
172
|
|
|
173
|
+
/**
|
|
174
|
+
* The information-barrier predicate for a sender: `text → true` when the text
|
|
175
|
+
* trips 2+ keywords of a domain that sender may not see. This is the SAME test
|
|
176
|
+
* `loadConversationHistory` applies to each history turn, exported so the
|
|
177
|
+
* current-work block gets it on BOTH reply paths (the quick path has no
|
|
178
|
+
* barrier machinery of its own and imports this). Fail-closed on a sender we
|
|
179
|
+
* cannot evaluate: `forbiddenDomains` for an unknown sender is every domain.
|
|
180
|
+
*
|
|
181
|
+
* @param {string|null} senderSlug
|
|
182
|
+
* @returns {(text:string)=>boolean}
|
|
183
|
+
*/
|
|
184
|
+
export function forbidsTextFor(senderSlug) {
|
|
185
|
+
const { forbiddenDomains } = loadDisclosureBoundaries(senderSlug, ALLOC.boundaries);
|
|
186
|
+
if (!forbiddenDomains || forbiddenDomains.length === 0) return () => false;
|
|
187
|
+
const domainKeywords = buildDomainKeywords();
|
|
188
|
+
return (text) => matchesForbiddenDomain(String(text || ""), forbiddenDomains, domainKeywords);
|
|
189
|
+
}
|
|
190
|
+
|
|
171
191
|
/**
|
|
172
192
|
* Load disclosure boundaries for a sender.
|
|
173
193
|
* Returns { boundariesSection, forbiddenDomains }.
|
|
@@ -337,44 +357,37 @@ function loadConversationHistory(senderSlug, channelId, budgetTokens, forbiddenD
|
|
|
337
357
|
return fitted.text ? fitted.text : null;
|
|
338
358
|
}
|
|
339
359
|
|
|
340
|
-
// ──
|
|
360
|
+
// ── Current work (the agent's own sessions on this machine) ────────
|
|
341
361
|
|
|
342
362
|
/**
|
|
343
|
-
*
|
|
363
|
+
* The bounded "what am I doing right now" block — lib/session/current-work.
|
|
364
|
+
*
|
|
365
|
+
* This used to read `active.json` alone: the daemon's own `--print` children,
|
|
366
|
+
* summary + model + sender, nothing else. A human asking "what are you doing
|
|
367
|
+
* right now, across sessions on your machine?" was answered from a list that
|
|
368
|
+
* did not contain the front door, its peers, the board items in progress, or
|
|
369
|
+
* the fact that a person had an interactive session open. The block now
|
|
370
|
+
* carries all of those (and names the board item where one is linked), under
|
|
371
|
+
* the same token allocation, and reports a human's session as EXISTING only.
|
|
372
|
+
*
|
|
373
|
+
* SCOPED TO THE AUDIENCE. The old list put every live session's summary —
|
|
374
|
+
* the classifier's restatement of some other person's message — into any
|
|
375
|
+
* reply's context. The block is now rendered for `item`'s conversation
|
|
376
|
+
* (`audienceForItem`): a session from another conversation is reported as
|
|
377
|
+
* existing only, and what is disclosable passes the same information-barrier
|
|
378
|
+
* keyword filter the history above it does (`forbiddenDomains`).
|
|
344
379
|
*/
|
|
345
|
-
function
|
|
380
|
+
async function loadCurrentWork(budgetTokens, item, forbiddenDomains) {
|
|
346
381
|
try {
|
|
347
|
-
const
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const
|
|
353
|
-
if (
|
|
354
|
-
|
|
355
|
-
const lines = [];
|
|
382
|
+
const domainKeywords = forbiddenDomains && forbiddenDomains.length > 0 ? buildDomainKeywords() : null;
|
|
383
|
+
const audience = audienceForItem(item, {
|
|
384
|
+
isPrivate: isPrivateConversation(item),
|
|
385
|
+
forbidsText: domainKeywords ? (t) => matchesForbiddenDomain(t, forbiddenDomains, domainKeywords) : undefined,
|
|
386
|
+
});
|
|
387
|
+
const block = await currentWorkBlock(AGENT_REPO_DIR, { activePath: join(SESSION_DIR, "active.json"), audience });
|
|
388
|
+
if (!block) return null;
|
|
356
389
|
const charBudget = budgetTokens * CHARS_PER_TOKEN;
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
for (const sess of sessions) {
|
|
360
|
-
const id = sess.sessionId || sess.id || "unknown";
|
|
361
|
-
const summary = sess.summary || sess.task || "no summary";
|
|
362
|
-
const model = sess.model || "unknown";
|
|
363
|
-
const sender = sess.sender || sess.owner || "unknown";
|
|
364
|
-
const started = sess.startTime || sess.started_at || "";
|
|
365
|
-
let age = "";
|
|
366
|
-
if (started) {
|
|
367
|
-
const ms = Date.now() - new Date(started).getTime();
|
|
368
|
-
const mins = Math.round(ms / 60000);
|
|
369
|
-
age = `${mins}m ago`;
|
|
370
|
-
}
|
|
371
|
-
const line = `- ${id}: ${summary} (model=${model}, sender=${sender}${age ? ", " + age : ""})`;
|
|
372
|
-
if (totalChars + line.length > charBudget) break;
|
|
373
|
-
lines.push(line);
|
|
374
|
-
totalChars += line.length;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
return lines.length > 0 ? lines.join("\n") : null;
|
|
390
|
+
return block.length > charBudget ? block.slice(0, charBudget) : block;
|
|
378
391
|
} catch {
|
|
379
392
|
return null;
|
|
380
393
|
}
|
|
@@ -555,8 +568,9 @@ export async function compileContext(item, classResult, options = {}) {
|
|
|
555
568
|
isPrivateConversation(item),
|
|
556
569
|
);
|
|
557
570
|
|
|
558
|
-
// Step 5 —
|
|
559
|
-
|
|
571
|
+
// Step 5 — Current work (this agent's sessions on this machine, bounded,
|
|
572
|
+
// scoped to this item's conversation and the sender's barrier)
|
|
573
|
+
const sessionsText = await loadCurrentWork(ALLOC.active_sessions, item, forbiddenDomains);
|
|
560
574
|
|
|
561
575
|
// Step 6 — Sent registry
|
|
562
576
|
const sentText = loadSentRegistry(channelId, ALLOC.sent_registry);
|
|
@@ -599,7 +613,7 @@ export async function compileContext(item, classResult, options = {}) {
|
|
|
599
613
|
sections.push("");
|
|
600
614
|
|
|
601
615
|
if (sessionsText) {
|
|
602
|
-
|
|
616
|
+
// The block carries its own "## Current Work" header.
|
|
603
617
|
sections.push(sessionsText);
|
|
604
618
|
sections.push("");
|
|
605
619
|
}
|
|
@@ -118,7 +118,10 @@ export function resolveSlackChannel(item) {
|
|
|
118
118
|
*/
|
|
119
119
|
|
|
120
120
|
/** Surfaces that genuinely live in a Cohort room — these reply with a message. */
|
|
121
|
-
|
|
121
|
+
// `broadcast` is a room message like a mention: the roll-call answer posts
|
|
122
|
+
// into the space it was asked in. Without this entry the reply has no
|
|
123
|
+
// transport, `canDeliverTo` says no, and the surface is dark at the last step.
|
|
124
|
+
const CHANNEL_SURFACES = Object.freeze(["dm", "mention", "broadcast", "thread_reply", "call"]);
|
|
122
125
|
|
|
123
126
|
/**
|
|
124
127
|
* Error frame codes a retry cannot change.
|
|
@@ -624,6 +627,26 @@ async function sendCohortEntityComment(route, text, o = {}) {
|
|
|
624
627
|
// The one public entry point
|
|
625
628
|
// ---------------------------------------------------------------------------
|
|
626
629
|
|
|
630
|
+
// Refuse any outbound body carrying raw scaffold markup. A closing </thinking>,
|
|
631
|
+
// an <assistant> wrapper and a <user_message> marker have each reached a shared
|
|
632
|
+
// room, from three separate seats. The seam is the join between the daemon
|
|
633
|
+
// placeholder and the generated output; whatever the cause on a given seat,
|
|
634
|
+
// nothing carrying these markers may leave it. Permanent refusal (no retry),
|
|
635
|
+
// same shape as the persona-leak gate: the caller escalates, never re-sends.
|
|
636
|
+
const SCAFFOLD_MARKER_RE = /<\/?(thinking|assistant|user_message|user|system|antml:[a-z_]+)>/i;
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* The first raw scaffold marker in `text`, or null when it carries none.
|
|
640
|
+
* Prose that merely NAMES a marker ("the thinking tag") is not a leak — only
|
|
641
|
+
* the literal angle-bracketed form matches.
|
|
642
|
+
* @param {string} text
|
|
643
|
+
* @returns {string|null}
|
|
644
|
+
*/
|
|
645
|
+
export function scaffoldMarkerLeak(text) {
|
|
646
|
+
const m = typeof text === "string" ? text.match(SCAFFOLD_MARKER_RE) : null;
|
|
647
|
+
return m ? m[0] : null;
|
|
648
|
+
}
|
|
649
|
+
|
|
627
650
|
/**
|
|
628
651
|
* Deliver `text` to the human behind `item`. No generation, no model, no
|
|
629
652
|
* budget — only transport.
|
|
@@ -657,6 +680,12 @@ export async function deliver(item, text, o = {}) {
|
|
|
657
680
|
if (!item || !text || !String(text).trim()) {
|
|
658
681
|
return { sent: false, via: null, error: "nothing to deliver" };
|
|
659
682
|
}
|
|
683
|
+
const leak = scaffoldMarkerLeak(text);
|
|
684
|
+
if (leak) {
|
|
685
|
+
const surface = (item && item.channel_id) ? "room" : "unknown";
|
|
686
|
+
try { console.error(`[deliver] refused: raw scaffold marker ${JSON.stringify(leak)} in outbound body (permanent, not retrying)`); } catch { /* */ }
|
|
687
|
+
return { sent: false, via: null, permanent: true, channel: item && item.channel_id, surface, code: "FORBIDDEN_SCOPE", error: `FORBIDDEN_SCOPE: raw scaffold marker ${leak} in outbound body — strip the marker; never send reasoning or transcript wrappers` };
|
|
688
|
+
}
|
|
660
689
|
// `permanent` says retrying changes nothing. A caller that cannot tell the
|
|
661
690
|
// difference between "hq blipped" and "there is no transport for telegram"
|
|
662
691
|
// retries both at the same cadence, which is how an impossible send becomes an
|