@intentic/sandbox-contract 1.248.0 → 1.249.0
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/README.md +18 -15
- package/dist/chores/chores.d.ts.map +1 -1
- package/dist/chores/chores.js.map +1 -1
- package/dist/chores/digest.d.ts.map +1 -1
- package/dist/chores/digest.js.map +1 -1
- package/dist/chores/extension-update.d.ts.map +1 -1
- package/dist/chores/extension-update.js.map +1 -1
- package/dist/chores/fix-deps.d.ts.map +1 -1
- package/dist/chores/fix-deps.js.map +1 -1
- package/dist/chores/index.d.ts +2 -2
- package/dist/chores/index.d.ts.map +1 -1
- package/dist/chores/index.js +1 -1
- package/dist/chores/index.js.map +1 -1
- package/dist/chores/probes.d.ts.map +1 -1
- package/dist/chores/probes.js.map +1 -1
- package/dist/chores/prompt.d.ts.map +1 -1
- package/dist/chores/prompt.js.map +1 -1
- package/dist/chores/stack.d.ts.map +1 -1
- package/dist/chores/stack.js.map +1 -1
- package/dist/chores/verdict.d.ts +7 -1
- package/dist/chores/verdict.d.ts.map +1 -1
- package/dist/chores/verdict.js +8 -0
- package/dist/chores/verdict.js.map +1 -1
- package/dist/contracts/accounts.contract.d.ts.map +1 -1
- package/dist/contracts/accounts.contract.js.map +1 -1
- package/dist/contracts/activity.contract.d.ts +1 -0
- package/dist/contracts/activity.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.d.ts +12 -205
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.js +2 -1
- package/dist/contracts/agent.contract.js.map +1 -1
- package/dist/contracts/agents.contract.d.ts +228 -54
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +11 -2
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/automations.contract.d.ts +35 -17
- package/dist/contracts/automations.contract.d.ts.map +1 -1
- package/dist/contracts/automations.contract.js +10 -1
- package/dist/contracts/automations.contract.js.map +1 -1
- package/dist/contracts/capabilities.contract.d.ts +0 -12
- package/dist/contracts/capabilities.contract.d.ts.map +1 -1
- package/dist/contracts/capabilities.contract.js +1 -1
- package/dist/contracts/capabilities.contract.js.map +1 -1
- package/dist/contracts/chores.contract.d.ts.map +1 -1
- package/dist/contracts/chores.contract.js.map +1 -1
- package/dist/contracts/ci.contract.d.ts +9 -0
- package/dist/contracts/ci.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.js.map +1 -1
- package/dist/contracts/exit.contract.d.ts.map +1 -1
- package/dist/contracts/exit.contract.js +1 -1
- package/dist/contracts/exit.contract.js.map +1 -1
- package/dist/contracts/extensions.contract.d.ts.map +1 -1
- package/dist/contracts/extensions.contract.js.map +1 -1
- package/dist/contracts/git.contract.d.ts +45 -6
- package/dist/contracts/git.contract.d.ts.map +1 -1
- package/dist/contracts/git.contract.js +9 -9
- package/dist/contracts/git.contract.js.map +1 -1
- package/dist/contracts/host.contract.d.ts +2 -0
- package/dist/contracts/host.contract.d.ts.map +1 -1
- package/dist/contracts/host.contract.js.map +1 -1
- package/dist/contracts/intentic.contract.js +1 -1
- package/dist/contracts/intentic.contract.js.map +1 -1
- package/dist/contracts/logs.contract.d.ts.map +1 -1
- package/dist/contracts/logs.contract.js.map +1 -1
- package/dist/contracts/loops.contract.d.ts.map +1 -1
- package/dist/contracts/loops.contract.js.map +1 -1
- package/dist/contracts/personas.contract.d.ts +1 -0
- package/dist/contracts/personas.contract.d.ts.map +1 -1
- package/dist/contracts/personas.contract.js +1 -1
- package/dist/contracts/personas.contract.js.map +1 -1
- package/dist/contracts/providers.contract.d.ts.map +1 -1
- package/dist/contracts/providers.contract.js.map +1 -1
- package/dist/contracts/runner.contract.d.ts +97 -171
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/runner.contract.js +2 -2
- package/dist/contracts/runner.contract.js.map +1 -1
- package/dist/contracts/safety.contract.d.ts.map +1 -1
- package/dist/contracts/safety.contract.js +1 -1
- package/dist/contracts/safety.contract.js.map +1 -1
- package/dist/contracts/secrets.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.js.map +1 -1
- package/dist/contracts/sessions.contract.d.ts +2 -41
- package/dist/contracts/sessions.contract.d.ts.map +1 -1
- package/dist/contracts/sessions.contract.js +1 -1
- package/dist/contracts/sessions.contract.js.map +1 -1
- package/dist/contracts/settings.contract.d.ts +8 -18
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.js.map +1 -1
- package/dist/contracts/share.contract.d.ts.map +1 -1
- package/dist/contracts/share.contract.js.map +1 -1
- package/dist/contracts/skills.contract.d.ts.map +1 -1
- package/dist/contracts/skills.contract.js.map +1 -1
- package/dist/contracts/system.contract.d.ts +49 -73
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.js +12 -2
- package/dist/contracts/system.contract.js.map +1 -1
- package/dist/contracts/usage.contract.d.ts.map +1 -1
- package/dist/contracts/usage.contract.js.map +1 -1
- package/dist/contracts/vpn.contract.d.ts.map +1 -1
- package/dist/contracts/vpn.contract.js +1 -1
- package/dist/contracts/vpn.contract.js.map +1 -1
- package/dist/contracts/webext.contract.d.ts.map +1 -1
- package/dist/contracts/webext.contract.js.map +1 -1
- package/dist/contracts/workflows.contract.d.ts +7 -6
- package/dist/contracts/workflows.contract.d.ts.map +1 -1
- package/dist/contracts/workflows.contract.js +12 -3
- package/dist/contracts/workflows.contract.js.map +1 -1
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.js.map +1 -1
- package/dist/events/agent-events.d.ts +1237 -0
- package/dist/events/agent-events.d.ts.map +1 -0
- package/dist/events/agent-events.js +226 -0
- package/dist/events/agent-events.js.map +1 -0
- package/dist/events/cards.d.ts +404 -0
- package/dist/events/cards.d.ts.map +1 -0
- package/dist/events/cards.js +179 -0
- package/dist/events/cards.js.map +1 -0
- package/dist/events/resume.d.ts +23 -0
- package/dist/events/resume.d.ts.map +1 -0
- package/dist/events/resume.js +31 -0
- package/dist/events/resume.js.map +1 -0
- package/dist/events/system-events.d.ts +615 -0
- package/dist/events/system-events.d.ts.map +1 -0
- package/dist/events/system-events.js +64 -0
- package/dist/events/system-events.js.map +1 -0
- package/dist/events/transcript.d.ts +1755 -0
- package/dist/events/transcript.d.ts.map +1 -0
- package/dist/events/transcript.js +205 -0
- package/dist/events/transcript.js.map +1 -0
- package/dist/ids/conversation-ids.d.ts +8 -0
- package/dist/ids/conversation-ids.d.ts.map +1 -0
- package/dist/{conversation-ids.js → ids/conversation-ids.js} +13 -0
- package/dist/ids/conversation-ids.js.map +1 -0
- package/dist/ids/hostnames.d.ts.map +1 -0
- package/dist/ids/hostnames.js.map +1 -0
- package/dist/ids/session-names.d.ts.map +1 -0
- package/dist/ids/session-names.js.map +1 -0
- package/dist/ids/share-paths.d.ts.map +1 -0
- package/dist/ids/share-paths.js.map +1 -0
- package/dist/{tunnel-ids.d.ts → ids/tunnel-ids.d.ts} +1 -0
- package/dist/ids/tunnel-ids.d.ts.map +1 -0
- package/dist/{tunnel-ids.js → ids/tunnel-ids.js} +1 -0
- package/dist/ids/tunnel-ids.js.map +1 -0
- package/dist/index.d.ts +423 -450
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -46
- package/dist/index.js.map +1 -1
- package/dist/{agent-catalog.d.ts → models/agent-catalog.d.ts} +2 -2
- package/dist/models/agent-catalog.d.ts.map +1 -0
- package/dist/models/agent-catalog.js.map +1 -0
- package/dist/models/agent-runtimes.d.ts.map +1 -0
- package/dist/models/agent-runtimes.js.map +1 -0
- package/dist/{fast-tier.d.ts → models/fast-tier.d.ts} +1 -1
- package/dist/models/fast-tier.d.ts.map +1 -0
- package/dist/models/fast-tier.js.map +1 -0
- package/dist/models/model-order.d.ts.map +1 -0
- package/dist/models/model-order.js.map +1 -0
- package/dist/{model-pins.d.ts → models/model-pins.d.ts} +1 -1
- package/dist/models/model-pins.d.ts.map +1 -0
- package/dist/models/model-pins.js.map +1 -0
- package/dist/{model-roles.d.ts → models/model-roles.d.ts} +0 -33
- package/dist/models/model-roles.d.ts.map +1 -0
- package/dist/{model-roles.js → models/model-roles.js} +0 -35
- package/dist/models/model-roles.js.map +1 -0
- package/dist/{plan-pools.d.ts → models/plan-pools.d.ts} +1 -1
- package/dist/models/plan-pools.d.ts.map +1 -0
- package/dist/models/plan-pools.js.map +1 -0
- package/dist/models/prompt-complexity.d.ts.map +1 -0
- package/dist/models/prompt-complexity.js.map +1 -0
- package/dist/models/provider-specs.d.ts.map +1 -0
- package/dist/models/provider-specs.js.map +1 -0
- package/dist/policy/approvals-execution.d.ts.map +1 -0
- package/dist/policy/approvals-execution.js.map +1 -0
- package/dist/{batch-runs.d.ts → policy/batch-runs.d.ts} +5 -1
- package/dist/policy/batch-runs.d.ts.map +1 -0
- package/dist/{batch-runs.js → policy/batch-runs.js} +10 -7
- package/dist/policy/batch-runs.js.map +1 -0
- package/dist/policy/capability-env.d.ts.map +1 -0
- package/dist/policy/capability-env.js.map +1 -0
- package/dist/policy/capability-secrets.d.ts.map +1 -0
- package/dist/policy/capability-secrets.js.map +1 -0
- package/dist/{card-status.d.ts → policy/card-status.d.ts} +2 -2
- package/dist/policy/card-status.d.ts.map +1 -0
- package/dist/{card-status.js → policy/card-status.js} +1 -5
- package/dist/policy/card-status.js.map +1 -0
- package/dist/{command-classes.d.ts → policy/command-classes.d.ts} +6 -2
- package/dist/policy/command-classes.d.ts.map +1 -0
- package/dist/{command-classes.js → policy/command-classes.js} +48 -11
- package/dist/policy/command-classes.js.map +1 -0
- package/dist/{command-run.d.ts → policy/command-run.d.ts} +1 -1
- package/dist/policy/command-run.d.ts.map +1 -0
- package/dist/policy/command-run.js.map +1 -0
- package/dist/policy/control-scopes.d.ts +16 -0
- package/dist/policy/control-scopes.d.ts.map +1 -0
- package/dist/policy/control-scopes.js +26 -0
- package/dist/policy/control-scopes.js.map +1 -0
- package/dist/policy/credential-material.d.ts.map +1 -0
- package/dist/policy/credential-material.js.map +1 -0
- package/dist/policy/needs-action.d.ts.map +1 -0
- package/dist/policy/needs-action.js.map +1 -0
- package/dist/policy/output-fields.d.ts.map +1 -0
- package/dist/policy/output-fields.js.map +1 -0
- package/dist/policy/overlay-lint.d.ts.map +1 -0
- package/dist/policy/overlay-lint.js.map +1 -0
- package/dist/policy/owner-ticket.d.ts.map +1 -0
- package/dist/{owner-ticket.js → policy/owner-ticket.js} +1 -1
- package/dist/policy/owner-ticket.js.map +1 -0
- package/dist/{safety-policy.d.ts → policy/safety-policy.d.ts} +6 -5
- package/dist/policy/safety-policy.d.ts.map +1 -0
- package/dist/{safety-policy.js → policy/safety-policy.js} +12 -12
- package/dist/policy/safety-policy.js.map +1 -0
- package/dist/policy/search-globs.d.ts.map +1 -0
- package/dist/policy/search-globs.js.map +1 -0
- package/dist/protocol/container-requirements.d.ts +20 -0
- package/dist/protocol/container-requirements.d.ts.map +1 -0
- package/dist/protocol/container-requirements.js +23 -0
- package/dist/protocol/container-requirements.js.map +1 -0
- package/dist/{host-protocol.d.ts → protocol/host-protocol.d.ts} +1 -0
- package/dist/protocol/host-protocol.d.ts.map +1 -0
- package/dist/{host-protocol.js → protocol/host-protocol.js} +1 -0
- package/dist/protocol/host-protocol.js.map +1 -0
- package/dist/protocol/ingress-contract.d.ts.map +1 -0
- package/dist/{ingress-contract.js → protocol/ingress-contract.js} +1 -1
- package/dist/protocol/ingress-contract.js.map +1 -0
- package/dist/protocol/ingress-protocol.d.ts.map +1 -0
- package/dist/protocol/ingress-protocol.js.map +1 -0
- package/dist/protocol/listener-protocol.d.ts.map +1 -0
- package/dist/{listener-protocol.js → protocol/listener-protocol.js} +1 -1
- package/dist/protocol/listener-protocol.js.map +1 -0
- package/dist/{peer-dial.d.ts → protocol/peer-dial.d.ts} +4 -1
- package/dist/protocol/peer-dial.d.ts.map +1 -0
- package/dist/{peer-dial.js → protocol/peer-dial.js} +51 -10
- package/dist/protocol/peer-dial.js.map +1 -0
- package/dist/protocol/peer-mcp-server.d.ts.map +1 -0
- package/dist/protocol/peer-mcp-server.js.map +1 -0
- package/dist/protocol/request-id.d.ts.map +1 -0
- package/dist/protocol/request-id.js.map +1 -0
- package/dist/protocol/routes.d.ts.map +1 -0
- package/dist/protocol/routes.js.map +1 -0
- package/dist/{runner-protocol.d.ts → protocol/runner-protocol.d.ts} +1 -0
- package/dist/protocol/runner-protocol.d.ts.map +1 -0
- package/dist/{runner-protocol.js → protocol/runner-protocol.js} +2 -1
- package/dist/protocol/runner-protocol.js.map +1 -0
- package/dist/protocol/sse.d.ts.map +1 -0
- package/dist/protocol/sse.js.map +1 -0
- package/dist/{terminal-protocol.d.ts → protocol/terminal-protocol.d.ts} +1 -3
- package/dist/protocol/terminal-protocol.d.ts.map +1 -0
- package/dist/protocol/terminal-protocol.js.map +1 -0
- package/dist/protocol/webext-links.d.ts.map +1 -0
- package/dist/protocol/webext-links.js.map +1 -0
- package/dist/{webext-protocol.d.ts → protocol/webext-protocol.d.ts} +1 -0
- package/dist/protocol/webext-protocol.d.ts.map +1 -0
- package/dist/{webext-protocol.js → protocol/webext-protocol.js} +1 -0
- package/dist/protocol/webext-protocol.js.map +1 -0
- package/dist/schemas/activity.d.ts +2 -0
- package/dist/schemas/activity.d.ts.map +1 -1
- package/dist/schemas/activity.js +4 -0
- package/dist/schemas/activity.js.map +1 -1
- package/dist/schemas/agent.d.ts +16 -4
- package/dist/schemas/agent.d.ts.map +1 -1
- package/dist/schemas/agent.js +21 -4
- package/dist/schemas/agent.js.map +1 -1
- package/dist/schemas/agents.d.ts +17 -4
- package/dist/schemas/agents.d.ts.map +1 -1
- package/dist/schemas/agents.js +15 -4
- package/dist/schemas/agents.js.map +1 -1
- package/dist/schemas/approvals.d.ts.map +1 -1
- package/dist/schemas/approvals.js.map +1 -1
- package/dist/schemas/automations.d.ts +54 -28
- package/dist/schemas/automations.d.ts.map +1 -1
- package/dist/schemas/automations.js +26 -8
- package/dist/schemas/automations.js.map +1 -1
- package/dist/schemas/capabilities.d.ts +0 -8
- package/dist/schemas/capabilities.d.ts.map +1 -1
- package/dist/schemas/capabilities.js +0 -4
- package/dist/schemas/capabilities.js.map +1 -1
- package/dist/schemas/ci.d.ts +10 -0
- package/dist/schemas/ci.d.ts.map +1 -1
- package/dist/schemas/ci.js +9 -1
- package/dist/schemas/ci.js.map +1 -1
- package/dist/schemas/codebase-health.d.ts.map +1 -1
- package/dist/schemas/codebase-health.js.map +1 -1
- package/dist/schemas/devices.d.ts +90 -0
- package/dist/schemas/devices.d.ts.map +1 -1
- package/dist/schemas/devices.js +10 -1
- package/dist/schemas/devices.js.map +1 -1
- package/dist/schemas/engines.d.ts.map +1 -1
- package/dist/schemas/engines.js.map +1 -1
- package/dist/schemas/environment.d.ts.map +1 -1
- package/dist/schemas/environment.js.map +1 -1
- package/dist/schemas/exit.d.ts.map +1 -1
- package/dist/schemas/exit.js.map +1 -1
- package/dist/schemas/extension-updates.d.ts.map +1 -1
- package/dist/schemas/extension-updates.js.map +1 -1
- package/dist/schemas/git-history.d.ts.map +1 -1
- package/dist/schemas/git-history.js.map +1 -1
- package/dist/schemas/git.d.ts +80 -16
- package/dist/schemas/git.d.ts.map +1 -1
- package/dist/schemas/git.js +37 -25
- package/dist/schemas/git.js.map +1 -1
- package/dist/schemas/history.d.ts.map +1 -1
- package/dist/schemas/history.js.map +1 -1
- package/dist/schemas/hosts.d.ts.map +1 -1
- package/dist/schemas/hosts.js.map +1 -1
- package/dist/schemas/inventory.d.ts.map +1 -1
- package/dist/schemas/inventory.js.map +1 -1
- package/dist/schemas/issues.d.ts +0 -1
- package/dist/schemas/issues.d.ts.map +1 -1
- package/dist/schemas/issues.js +0 -1
- package/dist/schemas/issues.js.map +1 -1
- package/dist/schemas/logs.d.ts.map +1 -1
- package/dist/schemas/logs.js.map +1 -1
- package/dist/schemas/loops.d.ts.map +1 -1
- package/dist/schemas/loops.js +1 -1
- package/dist/schemas/loops.js.map +1 -1
- package/dist/schemas/maintenance.d.ts.map +1 -1
- package/dist/schemas/maintenance.js.map +1 -1
- package/dist/schemas/marketplace.d.ts +0 -4
- package/dist/schemas/marketplace.d.ts.map +1 -1
- package/dist/schemas/panels.d.ts.map +1 -1
- package/dist/schemas/panels.js.map +1 -1
- package/dist/schemas/personas.d.ts +2 -1
- package/dist/schemas/personas.d.ts.map +1 -1
- package/dist/schemas/personas.js +6 -2
- package/dist/schemas/personas.js.map +1 -1
- package/dist/schemas/plan-limits.d.ts +2 -4
- package/dist/schemas/plan-limits.d.ts.map +1 -1
- package/dist/schemas/plan-limits.js +5 -8
- package/dist/schemas/plan-limits.js.map +1 -1
- package/dist/schemas/ports.d.ts.map +1 -1
- package/dist/schemas/ports.js.map +1 -1
- package/dist/schemas/provider-oauth.d.ts.map +1 -1
- package/dist/schemas/provider-oauth.js.map +1 -1
- package/dist/schemas/provider-subscriptions.d.ts +1 -1
- package/dist/schemas/provider-subscriptions.d.ts.map +1 -1
- package/dist/schemas/provider-subscriptions.js +1 -1
- package/dist/schemas/provider-subscriptions.js.map +1 -1
- package/dist/schemas/public.d.ts.map +1 -1
- package/dist/schemas/public.js.map +1 -1
- package/dist/schemas/push.d.ts.map +1 -1
- package/dist/schemas/push.js.map +1 -1
- package/dist/schemas/secrets.d.ts.map +1 -1
- package/dist/schemas/secrets.js.map +1 -1
- package/dist/schemas/settings.d.ts +6 -9
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +16 -5
- package/dist/schemas/settings.js.map +1 -1
- package/dist/schemas/share.d.ts.map +1 -1
- package/dist/schemas/share.js.map +1 -1
- package/dist/schemas/shared.d.ts +4 -0
- package/dist/schemas/shared.d.ts.map +1 -1
- package/dist/schemas/shared.js +3 -0
- package/dist/schemas/shared.js.map +1 -1
- package/dist/schemas/system.d.ts +6 -0
- package/dist/schemas/system.d.ts.map +1 -1
- package/dist/schemas/system.js +10 -0
- package/dist/schemas/system.js.map +1 -1
- package/dist/schemas/terminal.d.ts.map +1 -1
- package/dist/schemas/terminal.js.map +1 -1
- package/dist/schemas/usage.d.ts.map +1 -1
- package/dist/schemas/usage.js.map +1 -1
- package/dist/schemas/vpn.d.ts.map +1 -1
- package/dist/schemas/vpn.js.map +1 -1
- package/dist/schemas/webext.d.ts.map +1 -1
- package/dist/schemas/webext.js.map +1 -1
- package/dist/schemas/workflows.d.ts +66 -9
- package/dist/schemas/workflows.d.ts.map +1 -1
- package/dist/schemas/workflows.js +6 -5
- package/dist/schemas/workflows.js.map +1 -1
- package/dist/schemas/workspace-repos.d.ts.map +1 -1
- package/dist/schemas/workspace-repos.js.map +1 -1
- package/dist/schemas/workspace-search.d.ts.map +1 -1
- package/dist/schemas/workspace-search.js.map +1 -1
- package/dist/schemas/workspace-setup.d.ts.map +1 -1
- package/dist/schemas/workspace-setup.js.map +1 -1
- package/dist/schemas/workspace-tree.d.ts.map +1 -1
- package/dist/schemas/workspace-tree.js.map +1 -1
- package/dist/state/arrival.d.ts.map +1 -0
- package/dist/{arrival.js → state/arrival.js} +1 -1
- package/dist/state/arrival.js.map +1 -0
- package/dist/state/contract-lock.d.ts.map +1 -0
- package/dist/{contract-lock.js → state/contract-lock.js} +1 -1
- package/dist/state/contract-lock.js.map +1 -0
- package/dist/{definition.d.ts → state/definition.d.ts} +21 -17
- package/dist/state/definition.d.ts.map +1 -0
- package/dist/{definition.js → state/definition.js} +4 -4
- package/dist/state/definition.js.map +1 -0
- package/dist/state/history-state.d.ts.map +1 -0
- package/dist/{history-state.js → state/history-state.js} +1 -0
- package/dist/state/history-state.js.map +1 -0
- package/dist/state/runtime-state.d.ts.map +1 -0
- package/dist/state/runtime-state.js.map +1 -0
- package/dist/state/starter.d.ts.map +1 -0
- package/dist/state/starter.js.map +1 -0
- package/dist/state/state-portability.d.ts.map +1 -0
- package/dist/state/state-portability.js.map +1 -0
- package/dist/state/versions.d.ts.map +1 -0
- package/dist/state/versions.js.map +1 -0
- package/dist/{workspace-state.d.ts → state/workspace-state.d.ts} +8 -0
- package/dist/state/workspace-state.d.ts.map +1 -0
- package/dist/{workspace-state.js → state/workspace-state.js} +25 -0
- package/dist/state/workspace-state.js.map +1 -0
- package/dist/{documents.d.ts → text/documents.d.ts} +1 -1
- package/dist/text/documents.d.ts.map +1 -0
- package/dist/{documents.js → text/documents.js} +1 -1
- package/dist/text/documents.js.map +1 -0
- package/dist/text/embed.d.ts.map +1 -0
- package/dist/text/embed.js.map +1 -0
- package/dist/text/mentions.d.ts.map +1 -0
- package/dist/text/mentions.js.map +1 -0
- package/dist/text/model-answer.d.ts +3 -0
- package/dist/text/model-answer.d.ts.map +1 -0
- package/dist/text/model-answer.js +3 -0
- package/dist/text/model-answer.js.map +1 -0
- package/dist/text/path-refs.d.ts.map +1 -0
- package/dist/text/path-refs.js.map +1 -0
- package/dist/{shell-regions.d.ts → text/shell-regions.d.ts} +1 -1
- package/dist/text/shell-regions.d.ts.map +1 -0
- package/dist/text/shell-regions.js.map +1 -0
- package/dist/text/title.d.ts.map +1 -0
- package/dist/text/title.js.map +1 -0
- package/dist/{transcript-fold.d.ts → text/transcript-fold.d.ts} +2 -1
- package/dist/text/transcript-fold.d.ts.map +1 -0
- package/dist/{transcript-fold.js → text/transcript-fold.js} +2 -16
- package/dist/text/transcript-fold.js.map +1 -0
- package/dist/text/whisper.d.ts +3 -0
- package/dist/text/whisper.d.ts.map +1 -0
- package/dist/text/whisper.js +11 -0
- package/dist/text/whisper.js.map +1 -0
- package/dist/{workflow-faults.d.ts → text/workflow-faults.d.ts} +1 -1
- package/dist/text/workflow-faults.d.ts.map +1 -0
- package/dist/{workflow-faults.js → text/workflow-faults.js} +1 -1
- package/dist/text/workflow-faults.js.map +1 -0
- package/package.json +70 -70
- package/src/chores/chores.test.ts +4 -10
- package/src/chores/chores.ts +148 -392
- package/src/chores/digest.ts +8 -28
- package/src/chores/extension-update.ts +3 -8
- package/src/chores/fix-deps.ts +4 -18
- package/src/chores/index.ts +2 -2
- package/src/chores/probes.test.ts +7 -43
- package/src/chores/probes.ts +62 -167
- package/src/chores/prompt.ts +10 -34
- package/src/chores/stack.test.ts +6 -45
- package/src/chores/stack.ts +27 -118
- package/src/chores/verdict.test.ts +101 -80
- package/src/chores/verdict.ts +54 -99
- package/src/contracts/accounts.contract.ts +4 -19
- package/src/contracts/agent.contract.ts +7 -22
- package/src/contracts/agents.contract.ts +25 -71
- package/src/contracts/automations.contract.ts +14 -30
- package/src/contracts/capabilities.contract.ts +8 -35
- package/src/contracts/chores.contract.ts +4 -15
- package/src/contracts/endpoints.contract.ts +5 -22
- package/src/contracts/exit.contract.ts +7 -30
- package/src/contracts/extensions.contract.ts +8 -30
- package/src/contracts/git.contract.ts +25 -49
- package/src/contracts/host.contract.ts +9 -44
- package/src/contracts/intentic.contract.ts +1 -1
- package/src/contracts/logs.contract.ts +3 -13
- package/src/contracts/loops.contract.ts +9 -40
- package/src/contracts/personas.contract.ts +10 -35
- package/src/contracts/providers.contract.ts +4 -17
- package/src/contracts/runner.contract.ts +12 -39
- package/src/contracts/safety.contract.ts +5 -14
- package/src/contracts/secrets.contract.ts +4 -22
- package/src/contracts/sessions.contract.ts +1 -1
- package/src/contracts/settings.contract.ts +4 -10
- package/src/contracts/share.contract.ts +3 -9
- package/src/contracts/skills.contract.ts +4 -15
- package/src/contracts/system.contract.ts +26 -52
- package/src/contracts/usage.contract.ts +7 -21
- package/src/contracts/vpn.contract.ts +9 -16
- package/src/contracts/webext.contract.ts +9 -25
- package/src/contracts/workflows.contract.ts +34 -58
- package/src/contracts/workspace.contract.ts +19 -50
- package/src/events/agent-events.ts +345 -0
- package/src/events/cards.ts +286 -0
- package/src/{events.test.ts → events/resume.test.ts} +4 -19
- package/src/events/resume.ts +60 -0
- package/src/events/system-events.ts +139 -0
- package/src/events/transcript.ts +320 -0
- package/src/{conversation-ids.test.ts → ids/conversation-ids.test.ts} +25 -13
- package/src/ids/conversation-ids.ts +178 -0
- package/src/ids/hostnames.ts +129 -0
- package/src/ids/session-names.ts +29 -0
- package/src/ids/share-paths.ts +43 -0
- package/src/{tunnel-ids.test.ts → ids/tunnel-ids.test.ts} +1 -14
- package/src/ids/tunnel-ids.ts +29 -0
- package/src/index.ts +71 -87
- package/src/{agent-catalog.test.ts → models/agent-catalog.test.ts} +19 -93
- package/src/models/agent-catalog.ts +174 -0
- package/src/models/agent-runtimes.ts +201 -0
- package/src/models/capability-ledger.test.ts +84 -0
- package/src/{fast-tier.test.ts → models/fast-tier.test.ts} +7 -18
- package/src/models/fast-tier.ts +36 -0
- package/src/{model-order.test.ts → models/model-order.test.ts} +19 -40
- package/src/models/model-order.ts +163 -0
- package/src/{model-pins.test.ts → models/model-pins.test.ts} +12 -46
- package/src/models/model-pins.ts +57 -0
- package/src/models/model-roles.test.ts +38 -0
- package/src/models/model-roles.ts +180 -0
- package/src/{plan-pools.test.ts → models/plan-pools.test.ts} +6 -11
- package/src/models/plan-pools.ts +65 -0
- package/src/{prompt-complexity.test.ts → models/prompt-complexity.test.ts} +8 -60
- package/src/models/prompt-complexity.ts +215 -0
- package/src/{provider-specs.test.ts → models/provider-specs.test.ts} +18 -47
- package/src/models/provider-specs.ts +272 -0
- package/src/policy/approvals-execution.ts +58 -0
- package/src/{batch-runs.test.ts → policy/batch-runs.test.ts} +4 -20
- package/src/policy/batch-runs.ts +137 -0
- package/src/policy/capability-secrets.ts +5 -0
- package/src/{card-status.ts → policy/card-status.ts} +11 -26
- package/src/{command-classes.test.ts → policy/command-classes.test.ts} +11 -118
- package/src/policy/command-classes.ts +395 -0
- package/src/policy/command-run.ts +65 -0
- package/src/policy/control-scopes.ts +38 -0
- package/src/{credential-material.test.ts → policy/credential-material.test.ts} +4 -26
- package/src/policy/credential-material.ts +91 -0
- package/src/policy/needs-action.ts +5 -0
- package/src/policy/output-fields.ts +86 -0
- package/src/policy/overlay-lint.ts +100 -0
- package/src/{owner-ticket.test.ts → policy/owner-ticket.test.ts} +1 -1
- package/src/{owner-ticket.ts → policy/owner-ticket.ts} +9 -31
- package/src/policy/safety-policy.test.ts +84 -0
- package/src/policy/safety-policy.ts +142 -0
- package/src/policy/search-globs.ts +60 -0
- package/src/protocol/container-requirements.test.ts +72 -0
- package/src/protocol/container-requirements.ts +58 -0
- package/src/protocol/host-protocol.ts +29 -0
- package/src/protocol/ingress-contract.ts +103 -0
- package/src/{ingress-protocol.test.ts → protocol/ingress-protocol.test.ts} +25 -90
- package/src/protocol/ingress-protocol.ts +441 -0
- package/src/protocol/listener-protocol.ts +75 -0
- package/src/{peer-dial.test.ts → protocol/peer-dial.test.ts} +52 -1
- package/src/protocol/peer-dial.ts +207 -0
- package/src/{peer-mcp-server.ts → protocol/peer-mcp-server.ts} +16 -41
- package/src/protocol/request-id.ts +5 -0
- package/src/{routes.test.ts → protocol/routes.test.ts} +14 -22
- package/src/protocol/routes.ts +159 -0
- package/src/protocol/runner-protocol.ts +197 -0
- package/src/protocol/terminal-protocol.ts +13 -0
- package/src/protocol/webext-links.ts +50 -0
- package/src/protocol/webext-protocol.ts +24 -0
- package/src/schemas/activity.ts +22 -30
- package/src/schemas/agent.ts +130 -238
- package/src/schemas/agents.ts +165 -483
- package/src/schemas/approvals.ts +23 -71
- package/src/schemas/automations.ts +142 -250
- package/src/schemas/capabilities.ts +127 -414
- package/src/schemas/ci.ts +56 -108
- package/src/schemas/codebase-health.ts +7 -11
- package/src/schemas/devices.ts +98 -321
- package/src/schemas/engines.ts +16 -44
- package/src/schemas/environment.ts +41 -91
- package/src/schemas/exit.ts +24 -81
- package/src/schemas/extension-updates.ts +42 -87
- package/src/schemas/git-history.ts +30 -84
- package/src/schemas/git.ts +141 -256
- package/src/schemas/history.ts +14 -40
- package/src/schemas/hosts.ts +9 -15
- package/src/schemas/inventory.ts +8 -10
- package/src/schemas/issues.ts +66 -134
- package/src/schemas/logs.ts +15 -34
- package/src/schemas/loops.ts +46 -163
- package/src/schemas/maintenance.ts +47 -172
- package/src/schemas/panels.ts +20 -45
- package/src/schemas/personas.ts +50 -200
- package/src/schemas/plan-limits.ts +58 -197
- package/src/schemas/ports.ts +14 -32
- package/src/schemas/provider-oauth.ts +23 -76
- package/src/schemas/provider-subscriptions.ts +4 -13
- package/src/schemas/public.ts +4 -15
- package/src/schemas/push.ts +8 -36
- package/src/schemas/secrets.ts +20 -64
- package/src/schemas/settings.ts +175 -600
- package/src/schemas/share.ts +14 -32
- package/src/schemas/shared.ts +14 -13
- package/src/schemas/system.ts +46 -78
- package/src/schemas/terminal.ts +41 -120
- package/src/schemas/usage.ts +44 -233
- package/src/schemas/version-seam.test.ts +9 -26
- package/src/schemas/vpn.ts +27 -64
- package/src/schemas/webext.ts +22 -53
- package/src/schemas/workflows.ts +57 -183
- package/src/schemas/workspace-repos.ts +12 -24
- package/src/schemas/workspace-search.ts +17 -35
- package/src/schemas/workspace-setup.ts +4 -11
- package/src/schemas/workspace-tree.ts +32 -91
- package/src/state/arrival.ts +109 -0
- package/src/state/contract-lock.test.ts +17 -0
- package/src/state/contract-lock.ts +49 -0
- package/src/state/definition.ts +143 -0
- package/src/state/history-state.ts +103 -0
- package/src/{runtime-state.test.ts → state/runtime-state.test.ts} +3 -10
- package/src/state/runtime-state.ts +62 -0
- package/src/state/starter.ts +5 -0
- package/src/state/state-portability.ts +27 -0
- package/src/state/versions.ts +26 -0
- package/src/{workspace-state.test.ts → state/workspace-state.test.ts} +65 -172
- package/src/state/workspace-state.ts +669 -0
- package/src/{documents.test.ts → text/documents.test.ts} +1 -1
- package/src/text/documents.ts +42 -0
- package/src/text/embed.ts +132 -0
- package/src/text/mentions.ts +21 -0
- package/src/text/model-answer.ts +9 -0
- package/src/text/path-refs.ts +39 -0
- package/src/text/shell-regions.ts +224 -0
- package/src/{title.test.ts → text/title.test.ts} +13 -32
- package/src/text/title.ts +202 -0
- package/src/{transcript-fold.test.ts → text/transcript-fold.test.ts} +5 -83
- package/src/{transcript-fold.ts → text/transcript-fold.ts} +65 -170
- package/src/text/whisper.test.ts +19 -0
- package/src/text/whisper.ts +17 -0
- package/src/{workflow-faults.test.ts → text/workflow-faults.test.ts} +6 -24
- package/src/{workflow-faults.ts → text/workflow-faults.ts} +20 -60
- package/dist/agent-catalog.d.ts.map +0 -1
- package/dist/agent-catalog.js.map +0 -1
- package/dist/agent-runtimes.d.ts.map +0 -1
- package/dist/agent-runtimes.js.map +0 -1
- package/dist/approvals-execution.d.ts.map +0 -1
- package/dist/approvals-execution.js.map +0 -1
- package/dist/arrival.d.ts.map +0 -1
- package/dist/arrival.js.map +0 -1
- package/dist/batch-runs.d.ts.map +0 -1
- package/dist/batch-runs.js.map +0 -1
- package/dist/capability-env.d.ts.map +0 -1
- package/dist/capability-env.js.map +0 -1
- package/dist/capability-secrets.d.ts.map +0 -1
- package/dist/capability-secrets.js.map +0 -1
- package/dist/card-status.d.ts.map +0 -1
- package/dist/card-status.js.map +0 -1
- package/dist/command-classes.d.ts.map +0 -1
- package/dist/command-classes.js.map +0 -1
- package/dist/command-run.d.ts.map +0 -1
- package/dist/command-run.js.map +0 -1
- package/dist/contract-lock.d.ts.map +0 -1
- package/dist/contract-lock.js.map +0 -1
- package/dist/conversation-ids.d.ts +0 -4
- package/dist/conversation-ids.d.ts.map +0 -1
- package/dist/conversation-ids.js.map +0 -1
- package/dist/credential-material.d.ts.map +0 -1
- package/dist/credential-material.js.map +0 -1
- package/dist/definition.d.ts.map +0 -1
- package/dist/definition.js.map +0 -1
- package/dist/documents.d.ts.map +0 -1
- package/dist/documents.js.map +0 -1
- package/dist/embed.d.ts.map +0 -1
- package/dist/embed.js.map +0 -1
- package/dist/events.d.ts +0 -4336
- package/dist/events.d.ts.map +0 -1
- package/dist/events.js +0 -725
- package/dist/events.js.map +0 -1
- package/dist/fast-tier.d.ts.map +0 -1
- package/dist/fast-tier.js.map +0 -1
- package/dist/history-state.d.ts.map +0 -1
- package/dist/history-state.js.map +0 -1
- package/dist/host-protocol.d.ts.map +0 -1
- package/dist/host-protocol.js.map +0 -1
- package/dist/hostnames.d.ts.map +0 -1
- package/dist/hostnames.js.map +0 -1
- package/dist/ingress-contract.d.ts.map +0 -1
- package/dist/ingress-contract.js.map +0 -1
- package/dist/ingress-protocol.d.ts.map +0 -1
- package/dist/ingress-protocol.js.map +0 -1
- package/dist/listener-protocol.d.ts.map +0 -1
- package/dist/listener-protocol.js.map +0 -1
- package/dist/mentions.d.ts.map +0 -1
- package/dist/mentions.js.map +0 -1
- package/dist/model-order.d.ts.map +0 -1
- package/dist/model-order.js.map +0 -1
- package/dist/model-pins.d.ts.map +0 -1
- package/dist/model-pins.js.map +0 -1
- package/dist/model-roles.d.ts.map +0 -1
- package/dist/model-roles.js.map +0 -1
- package/dist/needs-action.d.ts.map +0 -1
- package/dist/needs-action.js.map +0 -1
- package/dist/output-fields.d.ts.map +0 -1
- package/dist/output-fields.js.map +0 -1
- package/dist/overlay-lint.d.ts.map +0 -1
- package/dist/overlay-lint.js.map +0 -1
- package/dist/owner-ticket.d.ts.map +0 -1
- package/dist/owner-ticket.js.map +0 -1
- package/dist/path-refs.d.ts.map +0 -1
- package/dist/path-refs.js.map +0 -1
- package/dist/peer-dial.d.ts.map +0 -1
- package/dist/peer-dial.js.map +0 -1
- package/dist/peer-mcp-server.d.ts.map +0 -1
- package/dist/peer-mcp-server.js.map +0 -1
- package/dist/plan-pools.d.ts.map +0 -1
- package/dist/plan-pools.js.map +0 -1
- package/dist/prompt-complexity.d.ts.map +0 -1
- package/dist/prompt-complexity.js.map +0 -1
- package/dist/provider-specs.d.ts.map +0 -1
- package/dist/provider-specs.js.map +0 -1
- package/dist/request-id.d.ts.map +0 -1
- package/dist/request-id.js.map +0 -1
- package/dist/routes.d.ts.map +0 -1
- package/dist/routes.js.map +0 -1
- package/dist/runner-protocol.d.ts.map +0 -1
- package/dist/runner-protocol.js.map +0 -1
- package/dist/runtime-state.d.ts.map +0 -1
- package/dist/runtime-state.js.map +0 -1
- package/dist/safety-policy.d.ts.map +0 -1
- package/dist/safety-policy.js.map +0 -1
- package/dist/search-globs.d.ts.map +0 -1
- package/dist/search-globs.js.map +0 -1
- package/dist/session-names.d.ts.map +0 -1
- package/dist/session-names.js.map +0 -1
- package/dist/share-paths.d.ts.map +0 -1
- package/dist/share-paths.js.map +0 -1
- package/dist/shell-regions.d.ts.map +0 -1
- package/dist/shell-regions.js.map +0 -1
- package/dist/sse.d.ts.map +0 -1
- package/dist/sse.js.map +0 -1
- package/dist/starter.d.ts.map +0 -1
- package/dist/starter.js.map +0 -1
- package/dist/state-portability.d.ts.map +0 -1
- package/dist/state-portability.js.map +0 -1
- package/dist/terminal-protocol.d.ts.map +0 -1
- package/dist/terminal-protocol.js.map +0 -1
- package/dist/title.d.ts.map +0 -1
- package/dist/title.js.map +0 -1
- package/dist/transcript-fold.d.ts.map +0 -1
- package/dist/transcript-fold.js.map +0 -1
- package/dist/tunnel-ids.d.ts.map +0 -1
- package/dist/tunnel-ids.js.map +0 -1
- package/dist/versions.d.ts.map +0 -1
- package/dist/versions.js.map +0 -1
- package/dist/webext-links.d.ts.map +0 -1
- package/dist/webext-links.js.map +0 -1
- package/dist/webext-protocol.d.ts.map +0 -1
- package/dist/webext-protocol.js.map +0 -1
- package/dist/workflow-faults.d.ts.map +0 -1
- package/dist/workflow-faults.js.map +0 -1
- package/dist/workspace-state.d.ts.map +0 -1
- package/dist/workspace-state.js.map +0 -1
- package/src/agent-catalog.ts +0 -316
- package/src/agent-runtimes.ts +0 -419
- package/src/approvals-execution.ts +0 -96
- package/src/arrival.ts +0 -160
- package/src/batch-runs.ts +0 -188
- package/src/capability-ledger.test.ts +0 -140
- package/src/capability-secrets.ts +0 -20
- package/src/command-classes.ts +0 -617
- package/src/command-run.ts +0 -78
- package/src/contract-lock.test.ts +0 -23
- package/src/contract-lock.ts +0 -66
- package/src/conversation-ids.ts +0 -207
- package/src/credential-material.ts +0 -181
- package/src/definition.ts +0 -207
- package/src/documents.ts +0 -67
- package/src/embed.ts +0 -164
- package/src/events.ts +0 -1870
- package/src/fast-tier.ts +0 -72
- package/src/history-state.ts +0 -174
- package/src/host-protocol.ts +0 -36
- package/src/hostnames.ts +0 -180
- package/src/ingress-contract.ts +0 -157
- package/src/ingress-protocol.ts +0 -625
- package/src/listener-protocol.ts +0 -96
- package/src/mentions.ts +0 -25
- package/src/model-order.ts +0 -262
- package/src/model-pins.ts +0 -132
- package/src/model-roles.test.ts +0 -52
- package/src/model-roles.ts +0 -320
- package/src/needs-action.ts +0 -14
- package/src/output-fields.ts +0 -111
- package/src/overlay-lint.ts +0 -116
- package/src/path-refs.ts +0 -59
- package/src/peer-dial.ts +0 -163
- package/src/plan-pools.ts +0 -92
- package/src/prompt-complexity.ts +0 -334
- package/src/provider-specs.ts +0 -432
- package/src/request-id.ts +0 -41
- package/src/routes.ts +0 -219
- package/src/runner-protocol.ts +0 -239
- package/src/runtime-state.ts +0 -140
- package/src/safety-policy.test.ts +0 -88
- package/src/safety-policy.ts +0 -258
- package/src/search-globs.ts +0 -76
- package/src/session-names.ts +0 -44
- package/src/share-paths.ts +0 -68
- package/src/shell-regions.ts +0 -289
- package/src/starter.ts +0 -13
- package/src/state-portability.ts +0 -56
- package/src/terminal-protocol.ts +0 -16
- package/src/title.ts +0 -267
- package/src/tunnel-ids.ts +0 -57
- package/src/versions.ts +0 -48
- package/src/webext-links.ts +0 -90
- package/src/webext-protocol.ts +0 -27
- package/src/workspace-state.ts +0 -1090
- /package/dist/{hostnames.d.ts → ids/hostnames.d.ts} +0 -0
- /package/dist/{hostnames.js → ids/hostnames.js} +0 -0
- /package/dist/{session-names.d.ts → ids/session-names.d.ts} +0 -0
- /package/dist/{session-names.js → ids/session-names.js} +0 -0
- /package/dist/{share-paths.d.ts → ids/share-paths.d.ts} +0 -0
- /package/dist/{share-paths.js → ids/share-paths.js} +0 -0
- /package/dist/{agent-catalog.js → models/agent-catalog.js} +0 -0
- /package/dist/{agent-runtimes.d.ts → models/agent-runtimes.d.ts} +0 -0
- /package/dist/{agent-runtimes.js → models/agent-runtimes.js} +0 -0
- /package/dist/{fast-tier.js → models/fast-tier.js} +0 -0
- /package/dist/{model-order.d.ts → models/model-order.d.ts} +0 -0
- /package/dist/{model-order.js → models/model-order.js} +0 -0
- /package/dist/{model-pins.js → models/model-pins.js} +0 -0
- /package/dist/{plan-pools.js → models/plan-pools.js} +0 -0
- /package/dist/{prompt-complexity.d.ts → models/prompt-complexity.d.ts} +0 -0
- /package/dist/{prompt-complexity.js → models/prompt-complexity.js} +0 -0
- /package/dist/{provider-specs.d.ts → models/provider-specs.d.ts} +0 -0
- /package/dist/{provider-specs.js → models/provider-specs.js} +0 -0
- /package/dist/{approvals-execution.d.ts → policy/approvals-execution.d.ts} +0 -0
- /package/dist/{approvals-execution.js → policy/approvals-execution.js} +0 -0
- /package/dist/{capability-env.d.ts → policy/capability-env.d.ts} +0 -0
- /package/dist/{capability-env.js → policy/capability-env.js} +0 -0
- /package/dist/{capability-secrets.d.ts → policy/capability-secrets.d.ts} +0 -0
- /package/dist/{capability-secrets.js → policy/capability-secrets.js} +0 -0
- /package/dist/{command-run.js → policy/command-run.js} +0 -0
- /package/dist/{credential-material.d.ts → policy/credential-material.d.ts} +0 -0
- /package/dist/{credential-material.js → policy/credential-material.js} +0 -0
- /package/dist/{needs-action.d.ts → policy/needs-action.d.ts} +0 -0
- /package/dist/{needs-action.js → policy/needs-action.js} +0 -0
- /package/dist/{output-fields.d.ts → policy/output-fields.d.ts} +0 -0
- /package/dist/{output-fields.js → policy/output-fields.js} +0 -0
- /package/dist/{overlay-lint.d.ts → policy/overlay-lint.d.ts} +0 -0
- /package/dist/{overlay-lint.js → policy/overlay-lint.js} +0 -0
- /package/dist/{owner-ticket.d.ts → policy/owner-ticket.d.ts} +0 -0
- /package/dist/{search-globs.d.ts → policy/search-globs.d.ts} +0 -0
- /package/dist/{search-globs.js → policy/search-globs.js} +0 -0
- /package/dist/{ingress-contract.d.ts → protocol/ingress-contract.d.ts} +0 -0
- /package/dist/{ingress-protocol.d.ts → protocol/ingress-protocol.d.ts} +0 -0
- /package/dist/{ingress-protocol.js → protocol/ingress-protocol.js} +0 -0
- /package/dist/{listener-protocol.d.ts → protocol/listener-protocol.d.ts} +0 -0
- /package/dist/{peer-mcp-server.d.ts → protocol/peer-mcp-server.d.ts} +0 -0
- /package/dist/{peer-mcp-server.js → protocol/peer-mcp-server.js} +0 -0
- /package/dist/{request-id.d.ts → protocol/request-id.d.ts} +0 -0
- /package/dist/{request-id.js → protocol/request-id.js} +0 -0
- /package/dist/{routes.d.ts → protocol/routes.d.ts} +0 -0
- /package/dist/{routes.js → protocol/routes.js} +0 -0
- /package/dist/{sse.d.ts → protocol/sse.d.ts} +0 -0
- /package/dist/{sse.js → protocol/sse.js} +0 -0
- /package/dist/{terminal-protocol.js → protocol/terminal-protocol.js} +0 -0
- /package/dist/{webext-links.d.ts → protocol/webext-links.d.ts} +0 -0
- /package/dist/{webext-links.js → protocol/webext-links.js} +0 -0
- /package/dist/{arrival.d.ts → state/arrival.d.ts} +0 -0
- /package/dist/{contract-lock.d.ts → state/contract-lock.d.ts} +0 -0
- /package/dist/{history-state.d.ts → state/history-state.d.ts} +0 -0
- /package/dist/{runtime-state.d.ts → state/runtime-state.d.ts} +0 -0
- /package/dist/{runtime-state.js → state/runtime-state.js} +0 -0
- /package/dist/{starter.d.ts → state/starter.d.ts} +0 -0
- /package/dist/{starter.js → state/starter.js} +0 -0
- /package/dist/{state-portability.d.ts → state/state-portability.d.ts} +0 -0
- /package/dist/{state-portability.js → state/state-portability.js} +0 -0
- /package/dist/{versions.d.ts → state/versions.d.ts} +0 -0
- /package/dist/{versions.js → state/versions.js} +0 -0
- /package/dist/{embed.d.ts → text/embed.d.ts} +0 -0
- /package/dist/{embed.js → text/embed.js} +0 -0
- /package/dist/{mentions.d.ts → text/mentions.d.ts} +0 -0
- /package/dist/{mentions.js → text/mentions.js} +0 -0
- /package/dist/{path-refs.d.ts → text/path-refs.d.ts} +0 -0
- /package/dist/{path-refs.js → text/path-refs.js} +0 -0
- /package/dist/{shell-regions.js → text/shell-regions.js} +0 -0
- /package/dist/{title.d.ts → text/title.d.ts} +0 -0
- /package/dist/{title.js → text/title.js} +0 -0
- /package/src/{hostnames.test.ts → ids/hostnames.test.ts} +0 -0
- /package/src/{share-paths.test.ts → ids/share-paths.test.ts} +0 -0
- /package/src/{capability-env.ts → policy/capability-env.ts} +0 -0
- /package/src/{overlay-lint.test.ts → policy/overlay-lint.test.ts} +0 -0
- /package/src/{search-globs.test.ts → policy/search-globs.test.ts} +0 -0
- /package/src/{ingress-contract.test.ts → protocol/ingress-contract.test.ts} +0 -0
- /package/src/{peer-mcp-server.test.ts → protocol/peer-mcp-server.test.ts} +0 -0
- /package/src/{sse.ts → protocol/sse.ts} +0 -0
- /package/src/{versions.test.ts → state/versions.test.ts} +0 -0
- /package/src/{embed.test.ts → text/embed.test.ts} +0 -0
- /package/src/{mentions.test.ts → text/mentions.test.ts} +0 -0
- /package/src/{path-refs.test.ts → text/path-refs.test.ts} +0 -0
package/src/schemas/settings.ts
CHANGED
|
@@ -1,41 +1,25 @@
|
|
|
1
1
|
// settings: per-sandbox agent settings (.intentic/config/settings.json)
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { CommandJudgeModeSchema } from "../safety-policy.js";
|
|
4
|
-
import { ModelRoleSchema } from "../model-roles.js";
|
|
3
|
+
import { CommandJudgeModeSchema } from "../policy/safety-policy.js";
|
|
4
|
+
import { ModelRoleSchema } from "../models/model-roles.js";
|
|
5
5
|
import { AdmissionPolicySchema, AdmissionRuleSchema, ModelPinSchema } from "./agent.js";
|
|
6
|
-
// Which prompt the agent
|
|
7
|
-
//
|
|
8
|
-
// than inline in the settings object because both sides of the wire branch on it, the daemon to build the
|
|
9
|
-
// turn, the browser to decide which base it can show you.
|
|
6
|
+
// Which prompt base the agent runs before this turn composes anything on top: Intentic's own (default), Claude Code's
|
|
7
|
+
// preset, or the owner's text. Declared out here since both the daemon and the browser branch on it.
|
|
10
8
|
export const SystemPromptModeSchema = z.enum(["intentic", "claude", "custom"]);
|
|
11
9
|
export type SystemPromptMode = z.infer<typeof SystemPromptModeSchema>;
|
|
12
|
-
//
|
|
13
|
-
// whatever they have already typed into the settings field.
|
|
10
|
+
// Excludes "custom": there is nothing to fetch, it's whatever the owner already typed into the settings field.
|
|
14
11
|
export const BuiltinPromptSchema = z.object({ base: z.enum(["intentic", "claude"]) });
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// whether to consult the successor list, what the notice may say) and the browser branches on it to draw the
|
|
18
|
-
// row: a bare inline enum would have each of those spelling the literals for itself.
|
|
12
|
+
// Declared out here because the daemon branches on it in three places (whether to wire the hook, consult the successor
|
|
13
|
+
// list, what the notice says) and the browser branches on it too.
|
|
19
14
|
export const DependencyFreshnessSchema = z.enum(["off", "versions", "full"]);
|
|
20
15
|
export type DependencyFreshness = z.infer<typeof DependencyFreshnessSchema>;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* three settings that were the same idea built three ways, ask for proof before a turn ends, run a command
|
|
25
|
-
* before a push, hold or release finished work, and the point of replacing them is that a FOURTH is now a row
|
|
26
|
-
* in this table rather than a release.
|
|
27
|
-
*
|
|
28
|
-
* The moments are named to sit in one family with WorkspaceEventKind (`turn.settled`, `agent.landed`), because
|
|
29
|
-
* chores already wake on those and folding them into this table later must not mean renaming what users wrote.
|
|
30
|
-
*/
|
|
16
|
+
// Rules: "at this moment, if this is true, do this" — one table replacing three settings that were the same idea built
|
|
17
|
+
// three ways; a fourth is now a row here, not a release. Moments are named to match `WorkspaceEventKind`, so folding
|
|
18
|
+
// chores in later won't rename what users wrote.
|
|
31
19
|
|
|
32
|
-
//
|
|
33
|
-
// names those decisions rather than inventing new ones.
|
|
20
|
+
// Four places the daemon already stops to decide something; this names those decisions rather than inventing new ones.
|
|
34
21
|
export const RuleMomentSchema = z.enum([
|
|
35
|
-
//
|
|
36
|
-
// command here runs on that one file (`{file}` in the command is its path) and what it prints on a non-zero
|
|
37
|
-
// exit rides back with the edit's own result, while the file is still in mind. The cheapest moment a defect
|
|
38
|
-
// can be caught at, and the one the per-edit linter and byte scan stand at.
|
|
22
|
+
// A command here runs on the just-written file (`{file}` is its path); the cheapest moment to catch a defect.
|
|
39
23
|
"file.edited",
|
|
40
24
|
// The assistant is about to stop. A rule here can send it back to work, which is the only moment that can.
|
|
41
25
|
"turn.ending",
|
|
@@ -45,36 +29,24 @@ export const RuleMomentSchema = z.enum([
|
|
|
45
29
|
"agent.finished",
|
|
46
30
|
]);
|
|
47
31
|
export type RuleMoment = z.infer<typeof RuleMomentSchema>;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* tracks what a turn edited against what it ran, which is not a shell command and never will be.
|
|
60
|
-
*/
|
|
61
|
-
/* The named behaviours a rule can invoke. Each reads a record only the daemon keeps, which is what makes them
|
|
62
|
-
* built-ins rather than commands: `verify-edits` weighs what a turn edited against what it ran,
|
|
63
|
-
* `verify-removals` weighs what a turn DELETED against what the repository's history says about those lines,
|
|
64
|
-
* which is a question `git log` answers and no shell one-liner an owner could type would, and
|
|
65
|
-
* `verify-ui-edits` weighs the rendered surfaces a turn changed against whether it ever looked at one, the one
|
|
66
|
-
* question a passing suite is structurally unable to answer, and `verify-tests` weighs the test files a turn
|
|
67
|
-
* touched against two things a green suite cannot say: whether their assertions got weaker than the same files
|
|
68
|
-
* at HEAD, and whether a test the turn wrote would have passed before the change it covers. */
|
|
32
|
+
// What a rule does; the split is functional since the three settings this table replaces each needed a different shape.
|
|
33
|
+
// command: runs a shell command; its exit code is the verdict.
|
|
34
|
+
// instruct: says something to the assistant before it finishes.
|
|
35
|
+
// verdict: allows or holds what is about to happen (a pass with nothing to run, told which way to go).
|
|
36
|
+
// builtin: invokes a named daemon behaviour the table has no business expressing itself.
|
|
37
|
+
// Each reads a record only the daemon keeps, which is what makes it a built-in rather than a command.
|
|
38
|
+
// verify-edits: what a turn edited, against what it ran.
|
|
39
|
+
// verify-removals: what a turn deleted, against the repo's own history (a `git log` question, not a shell one-liner).
|
|
40
|
+
// verify-ui-edits: rendered surfaces a turn changed, against whether it ever looked at one.
|
|
41
|
+
// verify-tests: whether a touched test's assertions got weaker than at HEAD, or would have passed before its own
|
|
42
|
+
// change.
|
|
69
43
|
export const RuleBuiltinSchema = z.enum(["verify-edits", "verify-removals", "verify-ui-edits", "verify-tests"]);
|
|
70
44
|
export type RuleBuiltin = z.infer<typeof RuleBuiltinSchema>;
|
|
71
45
|
export const RuleActionSchema = z.discriminatedUnion("kind", [
|
|
72
46
|
z.object({
|
|
73
47
|
kind: z.literal("command"),
|
|
74
48
|
command: z.string().max(500),
|
|
75
|
-
//
|
|
76
|
-
// Never a pass: a command that did not finish has said nothing, and a green light nobody earned is the
|
|
77
|
-
// one outcome a check exists to prevent.
|
|
49
|
+
// Past this, the process group is killed and the run is `failed`, never a silent pass.
|
|
78
50
|
timeoutMs: z.number().min(60_000).max(3_600_000).default(900_000),
|
|
79
51
|
}),
|
|
80
52
|
z.object({ kind: z.literal("instruct"), text: z.string().min(1).max(4000) }),
|
|
@@ -82,16 +54,12 @@ export const RuleActionSchema = z.discriminatedUnion("kind", [
|
|
|
82
54
|
z.object({ kind: z.literal("builtin"), name: RuleBuiltinSchema }),
|
|
83
55
|
]);
|
|
84
56
|
export type RuleAction = z.infer<typeof RuleActionSchema>;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
* land: the model was told, answered, and the last run still failed. It is named separately because a landing
|
|
88
|
-
* rule has to be able to speak about it, and because its default is not the others': work in that state is HELD
|
|
89
|
-
* unless a rule names `checks-failed` and says allow (rules/rules.ts landingVerdict). */
|
|
57
|
+
// `checks-failed` is a clean turn whose `turn.ending` check went red on the tree about to land; unlike the others, it
|
|
58
|
+
// defaults to HELD unless a rule explicitly allows it.
|
|
90
59
|
export const RuleOutcomeSchema = z.enum(["clean", "error", "conflict", "checks-failed"]);
|
|
91
60
|
export type RuleOutcome = z.infer<typeof RuleOutcomeSchema>;
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
// absent ⇒ the rule always matches at its moment, which is what the three replaced settings each did.
|
|
61
|
+
// Three keys covering "only this repo" and "skip docs-only changes" without a query language; every key absent means
|
|
62
|
+
// the rule always matches.
|
|
95
63
|
export const RuleConditionSchema = z.object({
|
|
96
64
|
// A workspace repo id, or "root". Absent ⇒ any.
|
|
97
65
|
repo: z.string().min(1).optional(),
|
|
@@ -99,16 +67,12 @@ export const RuleConditionSchema = z.object({
|
|
|
99
67
|
paths: z.array(z.string().min(1)).max(20).optional(),
|
|
100
68
|
// How the turn ended. Absent/empty ⇒ any, except that `checks-failed` never lands by omission.
|
|
101
69
|
outcome: z.array(RuleOutcomeSchema).optional(),
|
|
70
|
+
// The fraction of occasions a rule fires on, at moments that draw one (turn.ending); absent ⇒ every occasion.
|
|
71
|
+
sample: z.number().gt(0).lt(1).optional(),
|
|
102
72
|
});
|
|
103
73
|
export type RuleCondition = z.infer<typeof RuleConditionSchema>;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
*
|
|
107
|
-
* WHICH ACTIONS FIT WHICH MOMENT is checked here rather than left to the consumer, because the alternative is
|
|
108
|
-
* a rule that saves cleanly and then quietly does nothing, the failure mode a settings screen can least
|
|
109
|
-
* afford. A verdict at `turn.ending` has nothing to decide; a command at `agent.finished` has no defined place
|
|
110
|
-
* in the landing pass and would be a promise this stage cannot keep; an instruction at `file.edited` would be
|
|
111
|
-
* repeated on every save, which is noise by the third one. */
|
|
74
|
+
// `id` is stable and owner-visible, so a rename doesn't orphan the firing history. Which actions fit which moment is
|
|
75
|
+
// validated here, not left to the consumer — the alternative is a rule that saves cleanly and silently does nothing.
|
|
112
76
|
const MOMENT_ACTIONS: Record<RuleMoment, readonly RuleAction["kind"][]> = {
|
|
113
77
|
"file.edited": ["command"],
|
|
114
78
|
"turn.ending": ["builtin", "instruct", "command"],
|
|
@@ -129,95 +93,64 @@ export const RuleSchema = z
|
|
|
129
93
|
path: ["action"],
|
|
130
94
|
});
|
|
131
95
|
export type Rule = z.infer<typeof RuleSchema>;
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
// writing the owner's config on every push would make every run a settings save.
|
|
96
|
+
// Kept out of the settings object on purpose: a firing is not an edit, and writing config on every push would make
|
|
97
|
+
// every run a settings save.
|
|
135
98
|
export const RuleFiringsSchema = z.record(z.string(), z.number());
|
|
136
99
|
export type RuleFirings = z.infer<typeof RuleFiringsSchema>;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
*
|
|
147
|
-
* builtin this image ships it, a baked tool's cheatsheet, or a core feature's
|
|
148
|
-
* own the owner wrote it (.intentic/config/skills/), and only these are editable here
|
|
149
|
-
* capability something connected brought it: a CLI tool, a machine, a browser account, a VPN
|
|
150
|
-
* extension an installed extension ships it inside its checkout
|
|
151
|
-
* plugin a plugin capability cloned a repo that holds it
|
|
152
|
-
* persona one card's own kit carries it, and only turns wearing that card ever see it
|
|
153
|
-
* dropped it is simply sitting in the loaded folder, put there by hand, or by the agent itself
|
|
154
|
-
*
|
|
155
|
-
* `persona` is the one origin that is not on for everybody, which is why it needs its own word rather than
|
|
156
|
-
* being filed under `own`: it says "the agent knows this when it is wearing that card", and a list that showed
|
|
157
|
-
* it as an ordinary skill of the owner's would be claiming it applies to every chat.
|
|
158
|
-
*
|
|
159
|
-
* `dropped` is the honest bottom of the list rather than a category anything creates on purpose: the promise
|
|
160
|
-
* this surface makes is that it shows EVERYTHING the agent knows, so a file nothing else claims has to list as
|
|
161
|
-
* the loose file it is instead of being quietly left out.
|
|
162
|
-
*
|
|
163
|
-
* Deliberately NOT a capability kind. A capability holds a credential, can be broken right now, and wants a
|
|
164
|
-
* status light; a skill either exists or it does not. See _sandbox/sandbox/src/settings/skill-inventory.ts. */
|
|
100
|
+
// Where a skill came from, the fact that decides everything else about its row.
|
|
101
|
+
// builtin: this image ships it.
|
|
102
|
+
// own: the owner wrote it (.intentic/config/skills/); only these are editable here.
|
|
103
|
+
// capability: something connected brought it (a CLI tool, a machine, a browser account, a VPN).
|
|
104
|
+
// extension: an installed extension ships it inside its checkout.
|
|
105
|
+
// plugin: a plugin capability cloned a repo that holds it.
|
|
106
|
+
// persona: one card's own kit carries it; only turns wearing that card see it.
|
|
107
|
+
// dropped: sitting in the loaded folder by hand or by the agent, claimed by nothing else.
|
|
108
|
+
// Not a capability kind: a capability can be broken and wants a status light, a skill either exists or it doesn't.
|
|
165
109
|
export const SkillOriginSchema = z.enum(["builtin", "own", "capability", "extension", "plugin", "persona", "dropped"]);
|
|
166
110
|
export type SkillOrigin = z.infer<typeof SkillOriginSchema>;
|
|
167
|
-
|
|
168
|
-
|
|
111
|
+
// Same slug shape the SDK's loader accepts, checked here so a bad name is a refused save, not a skill that silently
|
|
112
|
+
// never loads.
|
|
169
113
|
export const SkillNameSchema = z.string().regex(/^[a-z0-9][a-z0-9-]*$/, "a skill name is lowercase letters, digits and dashes");
|
|
170
114
|
export const SkillSummarySchema = z.object({
|
|
171
|
-
|
|
172
|
-
* so names there are already unique); one that belongs to something else is `<origin>:<owner>:<name>`,
|
|
173
|
-
* because two plugins may each ship a `review` and the list has to be able to tell them apart. */
|
|
115
|
+
// Qualified as `<origin>:<owner>:<name>` for anything not `own`/`builtin`.
|
|
174
116
|
id: z
|
|
175
117
|
.string()
|
|
176
118
|
.describe(
|
|
177
119
|
"Its handle, which reading and deleting take. A skill of your own is simply its name; one belonging to something else is qualified, because two packages may each ship a review.",
|
|
178
120
|
),
|
|
179
121
|
name: z.string().describe("Its name."),
|
|
180
|
-
// The frontmatter line the agent routes on, empty when a shipped skill declares none, which is worth
|
|
181
|
-
// showing as the blank it is rather than papering over: a skill with no description is rarely picked.
|
|
182
122
|
description: z
|
|
183
123
|
.string()
|
|
184
124
|
.describe(
|
|
185
125
|
"What it is for, which is the line the agent reads to decide whether to reach for it. Empty when the skill declares none, which is worth showing as the blank it is: a skill with no description is rarely picked.",
|
|
186
126
|
),
|
|
187
127
|
origin: SkillOriginSchema.describe("Where it came from."),
|
|
188
|
-
//
|
|
128
|
+
// e.g. an extension's title, a plugin capability's id, a setting's name.
|
|
189
129
|
owner: z.string().optional().describe("Who ships it, as the row would name them."),
|
|
190
130
|
enabled: z.boolean().describe("Whether the agent can reach it."),
|
|
191
|
-
|
|
192
|
-
* tools and the owner's own): everything else is on because its extension, its plugin or another setting is,
|
|
193
|
-
* and a switch here that silently did nothing would be worse than no switch at all, the row names its
|
|
194
|
-
* owner instead. */
|
|
131
|
+
// True only for the skills the settings `skills` list itself governs (baked tools, the owner's own).
|
|
195
132
|
switchable: z
|
|
196
133
|
.boolean()
|
|
197
134
|
.describe(
|
|
198
135
|
"Whether this surface can switch it. Everything else is on because its extension or its plugin is, and a switch here that silently did nothing would be worse than none, so the row names its owner instead.",
|
|
199
136
|
),
|
|
200
|
-
// Whether the owner may rewrite the text here. Their own skills only, a shipped one is its author's, and
|
|
201
|
-
// editing it in place would be undone the next time the thing that ships it reconciles.
|
|
202
137
|
editable: z
|
|
203
138
|
.boolean()
|
|
204
139
|
.describe(
|
|
205
140
|
"Whether it can be rewritten here. Your own only: editing somebody else's in place would be undone the next time the thing that ships it catches up.",
|
|
206
141
|
),
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
* absolutely theirs to clear out, and with no switch and no owning extension there would otherwise be no way
|
|
210
|
-
* to get rid of it short of the file tree. */
|
|
142
|
+
// Wider than `editable` by one case: a dropped skill isn't the owner's to edit, but is theirs to remove, with no
|
|
143
|
+
// other way to short of the file tree.
|
|
211
144
|
removable: z.boolean(),
|
|
212
145
|
});
|
|
213
146
|
export type SkillSummary = z.infer<typeof SkillSummarySchema>;
|
|
214
147
|
export const SkillsListSchema = z.array(SkillSummarySchema);
|
|
215
|
-
//
|
|
216
|
-
//
|
|
148
|
+
// Its own route, not a field on the summary: bodies run to thousands of words, too costly to include in a list of
|
|
149
|
+
// one-line rows.
|
|
217
150
|
export const SkillBodySchema = z.object({
|
|
218
151
|
id: z.string().describe("The skill's id, which can carry the owner it came from."),
|
|
219
152
|
name: z.string().describe("Its name."),
|
|
220
|
-
// Everything after the frontmatter
|
|
153
|
+
// Everything after the frontmatter.
|
|
221
154
|
body: z.string().describe("The instructions themselves, as written."),
|
|
222
155
|
});
|
|
223
156
|
export type SkillBody = z.infer<typeof SkillBodySchema>;
|
|
@@ -229,10 +162,8 @@ export const SkillIdSchema = z.object({
|
|
|
229
162
|
"Which skill. It travels in the query rather than the address, because an id can name the owner it came from and that will not fit in a path.",
|
|
230
163
|
),
|
|
231
164
|
});
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
* be one the loader skips over. `description` is required for the reason above: it is the only part the model
|
|
235
|
-
* reads before deciding whether to open the rest. */
|
|
165
|
+
// Three fields because a skill is three things: name, when to reach for it, what to do. The daemon assembles
|
|
166
|
+
// frontmatter from the first two, so a saved skill can never be one the loader skips.
|
|
236
167
|
export const SkillDraftSchema = z.object({
|
|
237
168
|
name: SkillNameSchema.describe("What to call it. Saving over an existing name rewrites it, which is also how one is renamed."),
|
|
238
169
|
description: z.string().min(1).max(1024).describe("What it is for, which is what the agent reads to decide whether to reach for it."),
|
|
@@ -242,62 +173,10 @@ export type SkillDraft = z.infer<typeof SkillDraftSchema>;
|
|
|
242
173
|
export const SkillRemoveSchema = z.object({
|
|
243
174
|
name: SkillNameSchema.describe("Which skill to delete. The text and the enabled list are both updated, so nothing is left half done."),
|
|
244
175
|
});
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
// skills , names of baked-tool skills to load into .agents/skills so the agent reaches for them
|
|
250
|
-
// (e.g. "lsp". TS rename + diagnostics over the language service); a name absent ⇒ its
|
|
251
|
-
// skill file isn't written, so the agent doesn't reach for it. Data-driven: a new baked
|
|
252
|
-
// tool is one daemon-side registry entry, not a new settings field.
|
|
253
|
-
// hashlineEdits , swaps the native Read/Edit/Write for hash-anchored edits on the Claude path (stale-file
|
|
254
|
-
// guard + fewer output tokens); off ⇒ the native file tools.
|
|
255
|
-
// systemPromptMode , which base the agent's prompt is: "intentic" (default), "claude", or "custom".
|
|
256
|
-
// systemPrompt , the owner's own prompt text, used only by "custom" mode, where it is the ENTIRE system
|
|
257
|
-
// prompt and nothing the daemon would otherwise append rides with it, see its own note.
|
|
258
|
-
// iqSearch , loads the image-baked iq Claude Code plugin (skill + SessionStart nudge) so the agent
|
|
259
|
-
// prefers the iq CLI over grep/find/Glob; off ⇒ plugin not loaded, native search tools
|
|
260
|
-
// only. Opt-in (default off); the browser Search box uses iq regardless.
|
|
261
|
-
// iqSearchHoldout , conversation-level measurement control for iqSearch (UsageTurn.iqSearchArm). The arm
|
|
262
|
-
// stays fixed because teaching already loaded into a session cannot be removed next turn.
|
|
263
|
-
// workspaceMap , computes an AREA index of the project a run starts in and prepends it to the
|
|
264
|
-
// conversation's opening message, so the turn does not have to buy its own orientation
|
|
265
|
-
// with a directory listing. Generated from the filesystem every time, never stored.
|
|
266
|
-
// workspaceMapHoldout, conversation-level measurement control for workspaceMap (UsageTurn.mapArm), judged on
|
|
267
|
-
// the directory listings the opening turn ran rather than on its searches.
|
|
268
|
-
// sidecars , the background pass converging a markdown shadow of every binary workspace file
|
|
269
|
-
// (docx/pdf/images/audio → .intentic/local/cache/derived/) the moment it lands, via
|
|
270
|
-
// the baked fileq CLI, so reasoning-time reads are pre-derived. The CLI itself is
|
|
271
|
-
// always available; this gates only the eager watcher-driven derivation.
|
|
272
|
-
// dependencyFreshness, whether a version the agent is about to pin is checked against the package's own
|
|
273
|
-
// registry before it lands, and what the check is allowed to say: "off" (no hook is
|
|
274
|
-
// wired at all), "versions" (registry-derivable facts only), "full" (also names a
|
|
275
|
-
// maintained successor, where one is known and the registry corroborates it).
|
|
276
|
-
// outputCleaners , the Bash output-cleaner spec (agent-output-filter): "off" = filter disabled,
|
|
277
|
-
// "" = all cleaners on (default), else an iq-style allow-list / default-minus
|
|
278
|
-
// spec ("git,pnpm" = only those; "-cap" = all except). Threaded to the filter via env.
|
|
279
|
-
// outputHoldout , measurement control: a fraction [0,1] of Bash commands whose output bypasses cleaning
|
|
280
|
-
// (recorded raw as `heldOut`), so the savings report compares a real cleaned-vs-raw
|
|
281
|
-
// population instead of an estimate. 0 = no holdout (default).
|
|
282
|
-
// rules , the standing "at this moment, if this is true, do this" table (RuleSchema): what proves
|
|
283
|
-
// a turn's work, what runs before a push, whether finished work lands by itself. Empty
|
|
284
|
-
// (the default) means none of those happen, which is the shape a fresh sandbox has.
|
|
285
|
-
// automationFailureLimit, consecutive `error` runs after which an automation is disabled rather than left
|
|
286
|
-
// firing forever; 0 (default) ⇒ never.
|
|
287
|
-
// subagentsAtOnce / subagentsPerTurn / subagentDepth, the harness's own ceilings on delegation, raised or
|
|
288
|
-
// lowered from one place; each defaults to what the CLI enforces on its own.
|
|
289
|
-
// The booleans default off, outputCleaners defaults "" (cleaning on) and outputHoldout 0; iqSearch stays off
|
|
290
|
-
// until the owner enables it. `skills` is the exception and defaults to the
|
|
291
|
-
// baked tools worth having on: a skill file is the ONLY thing that tells the agent a baked binary exists, and
|
|
292
|
-
// with the list empty `lsp` went used once in 866 sessions, not declined, never learned about.
|
|
293
|
-
//
|
|
294
|
-
// Every field carries that default IN THE SCHEMA, so a settings object written before a field existed still
|
|
295
|
-
// parses, the absent key reads as its default. That is not a compatibility layer, it is the seam this shape
|
|
296
|
-
// spans: the browser ships with the platform while the daemon ships inside the user's sandbox image, so a web
|
|
297
|
-
// build is routinely NEWER than the daemon answering it. Requiring the key instead makes the whole settings
|
|
298
|
-
// surface fail to parse the moment a toggle is added, which reaches the user as a page of switches that are
|
|
299
|
-
// silently dead, not as an error. It also means an older on-disk manifest keeps the owner's other picks rather
|
|
300
|
-
// than being discarded whole.
|
|
176
|
+
// Opt-in settings the /settings routes edit and streamAgent reads, defaulting off so each can be A/B tested (`skills`
|
|
177
|
+
// defaults on for the baked tools worth having, since a skill file is the only thing that tells the agent a baked
|
|
178
|
+
// binary exists). Every default lives in the schema, so an older settings file still parses and keeps the owner's other
|
|
179
|
+
// picks rather than failing whole.
|
|
301
180
|
|
|
302
181
|
export const SandboxSettingsSchema = z.object({
|
|
303
182
|
stableSystemPrompt: z
|
|
@@ -307,21 +186,14 @@ export const SandboxSettingsSchema = z.object({
|
|
|
307
186
|
"Keep the instructions identical between turns so the provider can cache them, moving anything that varies into the message instead. Cheaper, at the cost of some flexibility.",
|
|
308
187
|
),
|
|
309
188
|
skills: z.array(z.string()).default(["lsp", "fileq"]).describe("Which skills are switched on."),
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
* off — never asked. A chat wears the persona the user picked, or none.
|
|
314
|
-
* suggest — asked, and the answer is a chip on the composer that the user presses to apply. The default:
|
|
315
|
-
* a persona takes accounts and repositories AWAY from a chat, and the first time that happens
|
|
316
|
-
* it should happen because somebody pressed it.
|
|
317
|
-
* auto — the answer is applied when the message is sent, unless the chip was dismissed first.
|
|
318
|
-
* Attended chats only, whatever this says: a wake nobody is watching names its persona on its own form,
|
|
319
|
-
* and routing one onto a card would GRANT it accounts the owner never named for it. */
|
|
189
|
+
// Router reads the sent message and one line per card, once per chat, between send and the first turn
|
|
190
|
+
// (persona-router.ts / model-roles.ts). Never asked of a draft: only a sent message is a finished one.
|
|
191
|
+
// Attended chats only: routing onto a card would grant an unwatched wake accounts nobody named for it.
|
|
320
192
|
personaRouting: z
|
|
321
|
-
.
|
|
322
|
-
.default(
|
|
193
|
+
.boolean()
|
|
194
|
+
.default(true)
|
|
323
195
|
.describe(
|
|
324
|
-
"Whether a new chat is matched to one of your personas from its first message.
|
|
196
|
+
"Whether a new chat is matched to one of your personas from its first message. The message is read once it is sent, by the model on the persona-routing list, and the chat says in its own transcript what was asked and which persona it landed on. Never applies to unwatched runs, which name their persona themselves.",
|
|
325
197
|
),
|
|
326
198
|
hashlineEdits: z
|
|
327
199
|
.boolean()
|
|
@@ -329,27 +201,15 @@ export const SandboxSettingsSchema = z.object({
|
|
|
329
201
|
.describe(
|
|
330
202
|
"Have the agent edit files by line number rather than by quoting the text it wants replaced. Cheaper on large files, and less forgiving of a stale read.",
|
|
331
203
|
),
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
* picking it tracks whatever the installed CLI's prompt is rather than freezing at a snapshot.
|
|
337
|
-
* custom , `systemPrompt` below, and nothing else at all.
|
|
338
|
-
*
|
|
339
|
-
* The first two are peers: both get the harness's own guidance appended (the AskUserQuestion/plan blocks
|
|
340
|
-
* the chat's cards need, the checklist guidance behind the todo panel, the browser-tool guidance), plus the
|
|
341
|
-
* delegation note. `custom` is the one that does not, by the owner's explicit choice, see the field below. */
|
|
204
|
+
// intentic: this product's own prompt (intentic-prompt.ts), tuned for this harness. Default.
|
|
205
|
+
// claude: Claude Code's preset, read live from the installed CLI, not a stored copy — tracks whatever prompt ships
|
|
206
|
+
// with it.
|
|
207
|
+
// custom: `systemPrompt` below, and nothing else.
|
|
342
208
|
systemPromptMode: SystemPromptModeSchema.default("intentic").describe(
|
|
343
209
|
"Which instructions the agent starts from: intentic's own, the ones the installed Claude Code carries, or your own. The first two both get this product's own guidance added on top; your own gets nothing added, which is the point of it.",
|
|
344
210
|
),
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
* the widget guidance the chat's cards are driven by. That is the price of total control, and the UI states
|
|
348
|
-
* it at the moment of the edit rather than letting the
|
|
349
|
-
* widgets go quietly dark. Only the cross-provider delegation note survives, because it has a home outside
|
|
350
|
-
* the system prompt already (the user-message preamble stableSystemPrompt puts it in).
|
|
351
|
-
*
|
|
352
|
-
* Cap is roomy, the bases it stands in for are ~6.8k characters, but finite, because every turn pays it. */
|
|
211
|
+
// The delegation note still survives (it lives in the user-message preamble, not here). Cap is roomy but finite —
|
|
212
|
+
// every turn pays for it.
|
|
353
213
|
systemPrompt: z
|
|
354
214
|
.string()
|
|
355
215
|
.max(20000)
|
|
@@ -361,10 +221,6 @@ export const SandboxSettingsSchema = z.object({
|
|
|
361
221
|
.boolean()
|
|
362
222
|
.default(false)
|
|
363
223
|
.describe("Teach the agent how to use this workspace's own search tool, rather than leaving it to grep around."),
|
|
364
|
-
/* Measurement control for the iq search teaching, at CONVERSATION level. A fraction [0,1] of conversations
|
|
365
|
-
* run without the plugin/instruction and stamp that stable arm on every turn. Per-turn randomization is not
|
|
366
|
-
* a valid control here: once the teaching enters a provider session, withholding it from the next request
|
|
367
|
-
* does not make the model forget it. 0 ⇒ no measurement and every conversation receives the teaching. */
|
|
368
224
|
iqSearchHoldout: z
|
|
369
225
|
.number()
|
|
370
226
|
.min(0)
|
|
@@ -373,35 +229,16 @@ export const SandboxSettingsSchema = z.object({
|
|
|
373
229
|
.describe(
|
|
374
230
|
"What share of conversations to run without that teaching, so the two can be compared. Whole conversations rather than individual turns, because once the teaching is in a session, withholding it from the next request does not make the model forget it.",
|
|
375
231
|
),
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
*
|
|
379
|
-
* It answers the question every first turn has whatever it was asked, "what is this and where am I in
|
|
380
|
-
* it", which across a hundred sessions of this workspace was being bought with a directory listing in two
|
|
381
|
-
* turns out of five, and with ~5.3k tokens of tool results before the job was touched.
|
|
382
|
-
*
|
|
383
|
-
* ROOTED AT THE RUN'S STARTING FOLDER rather than at the workspace: a persona's start folder, an isolated
|
|
384
|
-
* conversation's worktree, or wherever the turn's cwd is. It maps the project containing that folder and
|
|
385
|
-
* names the rest of the workspace on one line, because a run three levels inside one project is not asking
|
|
386
|
-
* about the others.
|
|
387
|
-
*
|
|
388
|
-
* REGENERATED, NEVER STORED, which is the whole reason it is a mechanism rather than a paragraph in the
|
|
389
|
-
* system prompt or a hand-written CLAUDE.md: in the ten days that motivated it this repo's two busiest
|
|
390
|
-
* top-level directories stopped existing, and every written-down copy of the layout was wrong by the end of
|
|
391
|
-
* the window. Off by default, it spends its tokens on the opening message of every conversation. */
|
|
232
|
+
// Rooted at the run's own starting folder (a persona's, an isolated conversation's worktree), not the workspace
|
|
233
|
+
// root — it maps the project containing that folder.
|
|
392
234
|
workspaceMap: z
|
|
393
235
|
.boolean()
|
|
394
236
|
.default(false)
|
|
395
237
|
.describe(
|
|
396
238
|
"Open every conversation with a map of the project it starts in: what is in it, what each part is for, and where the agent is standing. Worked out fresh each time rather than written down anywhere, because a written layout is wrong within a fortnight. Off by default, since it spends tokens on the first message of every conversation.",
|
|
397
239
|
),
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
* per-turn flip would call eleven treated turns controls.
|
|
401
|
-
*
|
|
402
|
-
* Judged on `UsageTurn.openingListings` and read on each conversation's opening turn (usage/turn-experiments.ts),
|
|
403
|
-
* because that is the turn the note was sent to and averaging it across a long conversation divides the
|
|
404
|
-
* effect by the conversation's length. 0 ⇒ no measurement and every conversation receives the map. */
|
|
240
|
+
// Judged on the opening turn's own directory listings, not averaged across the conversation, or a twelve-turn
|
|
241
|
+
// conversation would divide the effect by twelve.
|
|
405
242
|
workspaceMapHoldout: z
|
|
406
243
|
.number()
|
|
407
244
|
.min(0)
|
|
@@ -410,46 +247,18 @@ export const SandboxSettingsSchema = z.object({
|
|
|
410
247
|
.describe(
|
|
411
248
|
"What share of conversations to open without the map, so the two can be compared. Whole conversations rather than individual turns, because the map is sent once and stays in the conversation's history afterwards.",
|
|
412
249
|
),
|
|
413
|
-
|
|
414
|
-
* `fileq` CLI an agent runs mid-task — is always on PATH and gated only by its skill; this switch is
|
|
415
|
-
* about the BACKGROUND pass: the daemon watching /work and converging a sidecar under
|
|
416
|
-
* .intentic/local/cache/derived/ for every docx/xlsx/pptx/pdf/image/audio file the moment it lands or
|
|
417
|
-
* changes, so reasoning-time reads hit a shadow that already exists. Off by default like every boolean
|
|
418
|
-
* here: it spends CPU unasked, on every file that lands, which is the owner's call to make. */
|
|
250
|
+
// Only the eager background pass; the `fileq` CLI itself is always on PATH regardless, gated only by its own skill.
|
|
419
251
|
sidecars: z
|
|
420
252
|
.boolean()
|
|
421
253
|
.default(false)
|
|
422
254
|
.describe(
|
|
423
255
|
"Keep an up-to-date markdown rendering of every document, image and audio file in the workspace, made in the background as files land, so the agent reads a pre-derived text instead of paying to parse the file mid-task. Costs background CPU on a document-heavy workspace, so it is a switch rather than a default.",
|
|
424
256
|
),
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
* release at the moment they were typed, and a third were written without any registry ever being asked.
|
|
431
|
-
* Nothing downstream catches it either — a stale pin installs cleanly, type-checks, and passes the suite,
|
|
432
|
-
* so every gate this sandbox already has says yes to it.
|
|
433
|
-
*
|
|
434
|
-
* THREE STATES, and the middle one is the whole feature. The two halves of "this dependency choice is
|
|
435
|
-
* behind" are different KINDS of claim:
|
|
436
|
-
* versions, a measurement. The registry publishes what the newest release is and when; comparing is
|
|
437
|
-
* arithmetic, it works for any package, and there is nothing to keep current.
|
|
438
|
-
* full , a measurement plus an opinion. Naming `date-fns` as what to reach for instead of `moment`
|
|
439
|
-
* is a judgement somebody made, and judgements rot. An owner is entitled to take the facts
|
|
440
|
-
* and decline the opinions, which is exactly what the two settings are.
|
|
441
|
-
* The successor list never asserts staleness on its own: an entry surfaces only where the registry
|
|
442
|
-
* corroborates it (deprecated, or nothing published in eighteen months), so the curation supplies the
|
|
443
|
-
* NAME of the replacement and the measurement supplies the reason. That split is what stops it decaying
|
|
444
|
-
* into a list of last year's preferences.
|
|
445
|
-
*
|
|
446
|
-
* IT INFORMS, IT NEVER BLOCKS, and that is not timidity. Matching a version the workspace already pins is
|
|
447
|
-
* the common case and it is CORRECT: a new package inside a monorepo should take the catalog's
|
|
448
|
-
* `typescript`, not the newest one on the registry. A gate that refused would fight legitimate work
|
|
449
|
-
* several times for every mistake it caught, so the fact rides back as context and the model decides.
|
|
450
|
-
*
|
|
451
|
-
* Off by default like every other flag here, and off means genuinely nothing: no hook is wired, and the
|
|
452
|
-
* sandbox makes no network call it would not otherwise have made. */
|
|
257
|
+
// versions: a measurement only (the registry's own newest release).
|
|
258
|
+
// full: also the name of a successor, but only where the registry itself corroborates it (deprecated, or nothing
|
|
259
|
+
// published in 18 months) — curation supplies the name, measurement supplies the reason.
|
|
260
|
+
// Informs, never blocks: matching a version the workspace already pins is usually correct, and a gate would fight
|
|
261
|
+
// legitimate work more than it caught mistakes.
|
|
453
262
|
dependencyFreshness: DependencyFreshnessSchema.default("off").describe(
|
|
454
263
|
"Whether a version the agent is about to pin is checked against the package's own registry first. Facts only, or facts plus the name of a maintained replacement where the registry agrees the current choice has been abandoned. It tells the agent and lets it decide rather than refusing, because matching a version your project already uses is usually the right answer and a gate would fight it.",
|
|
455
264
|
),
|
|
@@ -463,54 +272,18 @@ export const SandboxSettingsSchema = z.object({
|
|
|
463
272
|
.max(1)
|
|
464
273
|
.default(0)
|
|
465
274
|
.describe("What share of commands to leave untrimmed, so the saving can be measured against a real comparison rather than estimated."),
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
* settings page, the resolver and the daemon's lookup all follow without a schema change. Seventeen named
|
|
471
|
-
* fields here would be the same table written a fourth time, in the one place where getting it out of step
|
|
472
|
-
* spends somebody's money.
|
|
473
|
-
*
|
|
474
|
-
* IT REPLACED THREE BUNDLED KEYS — `quickModel`, `agentRunModels` and `commandJudgeModels` — and the reason
|
|
475
|
-
* is worth keeping: the first two were grouped by assumed INTENSITY, not by job. "Quick" covered commit
|
|
476
|
-
* messages, session titles and loop verdicts at once, so an owner who wanted better commit subjects could
|
|
477
|
-
* not ask for them without also moving every session title onto the same model; "agent runs" covered a
|
|
478
|
-
* production incident and a documentation sweep with one tier. An intensity is a guess about work its owner
|
|
479
|
-
* knows better, and neither the configuration nor the UI was actually saving anyone anything by making it.
|
|
480
|
-
*
|
|
481
|
-
* EACH LIST IS AN ORDERED LADDER of pins, tried top to bottom, because the interesting failure is a model
|
|
482
|
-
* that is connected and will not answer today: the account's allowance went on the chat, and one spent
|
|
483
|
-
* provider takes that job down for hours while the others sit idle.
|
|
484
|
-
*
|
|
485
|
-
* AN ABSENT OR EMPTY LIST IS THE JOB SWITCHED OFF, and nothing is derived to fill it. A one-shot helper
|
|
486
|
-
* used to fall to an "Auto ladder" worked out from whatever was connected, which meant a sandbox nobody
|
|
487
|
-
* had configured still spent an account on every commit subject, every session title and every safety
|
|
488
|
-
* verdict, on a ranking this repo invented and re-ranked whenever an account was added. Not set now means
|
|
489
|
-
* not set: no auto-selection and no recommendation. A one-shot with no list does not run; a whole session
|
|
490
|
-
* with no list opens on the model the owner picked for their own chat, which is a choice they made rather
|
|
491
|
-
* than one this schema guessed. */
|
|
492
|
-
// `partialRecord`, not `record`: an exhaustive one would make every role a required key, so a settings file
|
|
493
|
-
// that has never been touched would have to spell out seventeen empty arrays to be valid, and adding a role
|
|
494
|
-
// would invalidate every settings file in existence. An absent key IS the answer "this role has no list".
|
|
275
|
+
// One key, not one field per role: a role catalog entry (`model-roles.ts`) makes a new job configurable without a
|
|
276
|
+
// schema change here.
|
|
277
|
+
// `partialRecord`, not `record`: an exhaustive one would force every settings file to list every role, and adding
|
|
278
|
+
// one would invalidate them all. Absent IS "no list".
|
|
495
279
|
modelRoles: z
|
|
496
280
|
.partialRecord(ModelRoleSchema, z.array(ModelPinSchema).max(10))
|
|
497
281
|
.default({})
|
|
498
282
|
.describe(
|
|
499
283
|
"Which models do which job, one ordered list per job: commit messages, session titles, the safety judge, pipeline fixes, and every other place this sandbox picks a model for you. Tried in order, so one spent account does not take a job down. Nothing is chosen for you: a one-shot job with no list does not run, and a whole session with no list opens on whatever your own chat is set to.",
|
|
500
284
|
),
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
*
|
|
504
|
-
* A LIST OF REPOS RATHER THAN A FLAG, and EMPTY BY DEFAULT, because this daemon runs on the user's repos
|
|
505
|
-
* rather than on ours. The commit drafter's one standing rule is that house style is INFERRED, never
|
|
506
|
-
* prescribed, it reads the last handful of subjects and matches them, so a repo that spells its commits
|
|
507
|
-
* some other way is never argued with. A note trailer is the one thing that cannot be inferred that way: a
|
|
508
|
-
* repo which has never written one gives the model nothing to copy, so asking for it has to be somebody's
|
|
509
|
-
* explicit decision. Empty means every repo behaves exactly as it did before this existed.
|
|
510
|
-
*
|
|
511
|
-
* Named by repo id ("root", or the root-relative dir discoverRepos reports), because a workspace holds
|
|
512
|
-
* several repos and a commit can span them: the trailer is written when the commit touches a repo that
|
|
513
|
-
* asked for one, and a repo that did not ask never gets a line it has to explain to its reviewers. */
|
|
285
|
+
// Named by repo id ("root" or discoverRepos's dir); a commit spanning repos gets the trailer only where one was
|
|
286
|
+
// asked for.
|
|
514
287
|
changelogRepos: z
|
|
515
288
|
.array(z.string())
|
|
516
289
|
.max(50)
|
|
@@ -518,60 +291,24 @@ export const SandboxSettingsSchema = z.object({
|
|
|
518
291
|
.describe(
|
|
519
292
|
"Which repositories keep a changelog, and so get a user-facing note written alongside each merge. A list rather than a switch, and empty by default, because the commit writer's standing rule is to copy the house style rather than impose one, and a repository that has never written such a note gives it nothing to copy.",
|
|
520
293
|
),
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
* THREE STATES RATHER THAN A TOGGLE, because the middle one is the only honest way to reach the third.
|
|
525
|
-
* Nobody, this repo included, can name a sensible cutoff for "easy enough" without traffic to fit it
|
|
526
|
-
* against, and a routing threshold guessed in advance is how a cost feature quietly becomes a quality
|
|
527
|
-
* regression. So:
|
|
528
|
-
* off — the judge never runs. Nothing is scored, nothing is recorded, turns run on the user's pick.
|
|
529
|
-
* shadow — the judge runs and its verdict is written to the spend ledger beside what the turn actually
|
|
530
|
-
* cost, and NOTHING IS ROUTED. This is the default: it spends no tokens, changes no behaviour,
|
|
531
|
-
* and is the only thing that can turn the weights in prompt-complexity.ts from a hypothesis
|
|
532
|
-
* into a measurement.
|
|
533
|
-
* on — a turn judged fast runs on the cheap rung (fast-tier.ts), when the provider publishes one.
|
|
534
|
-
*
|
|
535
|
-
* IT CAN ONLY EVER ROUTE DOWN. There is no "which model is the standard tier" setting because the standard
|
|
536
|
-
* tier is the model the user already chose, so the worst case of a wrong verdict is one turn's quality on a
|
|
537
|
-
* model they can see on the card and correct, never a bill they did not ask for. That asymmetry is why this
|
|
538
|
-
* can default to shadow rather than to off: shadow costs nothing and `on` cannot overspend. */
|
|
294
|
+
// off: the judge never runs.
|
|
295
|
+
// shadow (default): the judge scores every turn to the ledger; nothing is routed.
|
|
296
|
+
// on: a turn judged fast runs on the cheap rung, where the provider publishes one.
|
|
539
297
|
autoTier: z
|
|
540
298
|
.enum(["off", "shadow", "on"])
|
|
541
299
|
.default("shadow")
|
|
542
300
|
.describe(
|
|
543
301
|
"Whether an easy-looking turn may run on a cheaper model from the same provider. Three states rather than a switch, because the middle one is the only honest road to the third: it scores every turn and routes nothing, so the guess can become a measurement before it changes anything. It can only ever route down, so the worst case is one turn's quality rather than a bill nobody asked for.",
|
|
544
302
|
),
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
*
|
|
548
|
-
* Three named stops rather than a number, because the number means nothing to anyone who has not read the
|
|
549
|
-
* weights, while "only the unmistakable" / "the default" / "an easy question about real code too" are three
|
|
550
|
-
* sentences an owner can actually hold an opinion about (FAST_CEILINGS spells out each). It moves the
|
|
551
|
-
* cutoff and nothing else: the rule that a downgrade needs something POSITIVE to have been said holds at
|
|
552
|
-
* every stop, so no setting of this can start downgrading short vague requests.
|
|
553
|
-
*
|
|
554
|
-
* `balanced` is the default and is what every verdict recorded before this existed was judged against, so
|
|
555
|
-
* the shadow history stays comparable across the change rather than silently becoming two populations. */
|
|
303
|
+
// `balanced` is what every verdict recorded before this setting existed was judged against, so shadow history stays
|
|
304
|
+
// comparable.
|
|
556
305
|
autoTierEagerness: z
|
|
557
306
|
.enum(["cautious", "balanced", "eager"])
|
|
558
307
|
.default("balanced")
|
|
559
308
|
.describe(
|
|
560
309
|
"How readily a turn counts as simple enough for the cheaper model. It moves only the cutoff: at every setting a turn still has to say something positively easy, so nothing here can downgrade a short vague request.",
|
|
561
310
|
),
|
|
562
|
-
|
|
563
|
-
* (modelPinKey), or EMPTY for Auto.
|
|
564
|
-
*
|
|
565
|
-
* Empty is the default and the interesting case, exactly as a one-shot role's is: Auto is the cheapest row the
|
|
566
|
-
* turn's own provider publishes, read through the same cheap-end order (compareCheapestFirst), so the two
|
|
567
|
-
* features can never disagree about which rung is the cheap one, and connecting an account tomorrow
|
|
568
|
-
* improves the answer by itself.
|
|
569
|
-
*
|
|
570
|
-
* A LIST, so a sandbox working across several providers can name the rung it wants on each. But unlike the
|
|
571
|
-
* two lists above this one is NOT a failure ladder: entries naming a provider other than the turn's own are
|
|
572
|
-
* dropped rather than tried, because switching provider retires the conversation's session (turnRequest.ts
|
|
573
|
-
* `resumes`), and starting the conversation over to save a fraction of a cent is not a saving. The first
|
|
574
|
-
* entry that names this provider AND is genuinely cheaper than the pick wins; if none does, Auto answers. */
|
|
311
|
+
// Auto uses the same cheap-end order as this list (`compareCheapestFirst`), so the two can never disagree.
|
|
575
312
|
autoFastModels: z
|
|
576
313
|
.array(z.string())
|
|
577
314
|
.max(10)
|
|
@@ -579,10 +316,6 @@ export const SandboxSettingsSchema = z.object({
|
|
|
579
316
|
.describe(
|
|
580
317
|
"Which cheaper model a downgraded turn lands on. A list so a sandbox spanning providers can name a rung on each, but not a fallback ladder: an entry naming a different provider than the turn is on is skipped rather than tried, because switching provider retires the conversation and starting over to save a fraction of a penny is not a saving. Empty picks the cheapest the turn's own provider publishes.",
|
|
581
318
|
),
|
|
582
|
-
// How long a finished agent stays on the board before it is archived automatically (days; 0 ⇒ never).
|
|
583
|
-
// Unlike every other flag here this one defaults ON, because the lane it governs is the board's only
|
|
584
|
-
// terminal state: without a sweep the Finished lane grows for the life of the sandbox, and each card it
|
|
585
|
-
// holds is a live worktree checkout, not just a row.
|
|
586
319
|
agentRetentionDays: z
|
|
587
320
|
.number()
|
|
588
321
|
.min(0)
|
|
@@ -591,77 +324,48 @@ export const SandboxSettingsSchema = z.object({
|
|
|
591
324
|
.describe(
|
|
592
325
|
"How many days a finished conversation stays on the board before being put away. Zero means never. The one setting here that defaults on, because each card left behind is a real working copy on disk, not just a row.",
|
|
593
326
|
),
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
* attempts are spent".
|
|
597
|
-
*
|
|
598
|
-
* A DEFAULT, not the whole answer: any one conversation may override it (AgentSummarySchema
|
|
599
|
-
* .resumeAfterOutage), and the chat's own offer at the moment of failure writes THAT rather than this.
|
|
600
|
-
* This toggle is the standing policy for every agent that has not said otherwise, which is why it lives in
|
|
601
|
-
* settings and is not reachable by a single press from inside one chat, flipping how the whole board
|
|
602
|
-
* behaves should be a thing somebody went to do.
|
|
603
|
-
*
|
|
604
|
-
* OFF by default, on the same reasoning that keeps a spent usage limit out of this pair entirely: a resume
|
|
605
|
-
* re-runs a turn the user sent once, on their own allowance, and only they can say whether the turn was
|
|
606
|
-
* worth paying for twice. Starting off costs nothing, because the failed turn is remembered whatever the
|
|
607
|
-
* toggle says (recordOutageFailure), the failure frame reports an "available" resume and the chat's offer
|
|
608
|
-
* arms that very turn the moment it is armed for that conversation. Worth turning ON for a sandbox whose
|
|
609
|
-
* turns mostly have nobody in the room (automation wakes, Discord, webhooks), which is the case no browser
|
|
610
|
-
* could rescue and the case a per-conversation press cannot reach. */
|
|
327
|
+
// Off still records the failure, so the per-conversation resume offer arms normally; nothing is lost, just not
|
|
328
|
+
// automatic.
|
|
611
329
|
resumeAfterOutage: z
|
|
612
330
|
.boolean()
|
|
613
331
|
.default(false)
|
|
614
332
|
.describe(
|
|
615
333
|
"Whether a turn killed by the model provider failing is re-run automatically, backing off between attempts. The sandbox-wide default; any one conversation can say otherwise. Off to begin with, because a retry spends your allowance on a turn you sent once and only you can say whether it was worth paying for twice. Worth turning on for a sandbox whose work mostly happens with nobody in the room.",
|
|
616
334
|
),
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
*
|
|
620
|
-
* The one automatic resume here that WAITS FOR A PUBLISHED INSTANT rather than guessing. Its neighbour above
|
|
621
|
-
* escalates a backoff at a provider nobody can predict; this one sleeps until the hour the provider itself
|
|
622
|
-
* named and fires once, at it. A limit that publishes no instant (Grok, Cursor) is never fired for at all,
|
|
623
|
-
* because there is nothing to wait for and a guess would be spending the user's money on arithmetic.
|
|
624
|
-
*
|
|
625
|
-
* OFF by default, and this is the setting the default matters most for. Every other blocker in this pair
|
|
626
|
-
* clears at nobody's expense, while this one clears into an allowance the user may have been holding back
|
|
627
|
-
* deliberately, so the shipped behaviour is to say when it reopens and let them decide. What arming it buys
|
|
628
|
-
* is the case a press cannot reach: the 2am wall on a board nobody is watching, where the alternative is a
|
|
629
|
-
* card that sat waiting eight hours for a press that was always going to come. */
|
|
335
|
+
// The one resume that waits for a published instant rather than guessing; a limit with no published reset (Grok,
|
|
336
|
+
// Cursor) never fires this way at all.
|
|
630
337
|
resumeAfterLimit: z
|
|
631
338
|
.boolean()
|
|
632
339
|
.default(false)
|
|
633
340
|
.describe(
|
|
634
341
|
"Whether a turn a spent usage limit refused is sent again by itself once the allowance reopens. The sandbox-wide default; any one conversation can say otherwise. Off to begin with, because the allowance is your budget and a turn that spends it the second it comes back is not a decision to make for you. Worth turning on for a sandbox whose work mostly happens with nobody in the room.",
|
|
635
342
|
),
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
343
|
+
// Same provider only; a different provider would retire the session for a saving that isn't one. Composes with
|
|
344
|
+
// `resumeAfterLimit` into four postures: hold, wait for reset, move-or-hold, move-or-wait.
|
|
345
|
+
moveAfterLimit: z
|
|
346
|
+
.boolean()
|
|
347
|
+
.default(false)
|
|
348
|
+
.describe(
|
|
349
|
+
"Whether a turn a spent usage limit refused is moved to another connected account of the same provider that still has room, as soon as the refusal lands. The sandbox-wide default; any one conversation can say otherwise. Off to begin with, because it spends a second account on your behalf. With no account that has room the turn waits as the setting above says.",
|
|
350
|
+
),
|
|
351
|
+
limitMoveCarryUnder: z
|
|
352
|
+
.number()
|
|
353
|
+
.int()
|
|
354
|
+
.min(0)
|
|
355
|
+
.default(100_000)
|
|
356
|
+
.describe(
|
|
357
|
+
"When a spent usage limit moves a turn to another account, carry the provider session (the model keeps everything, and re-reads all of it once on the other account) while the conversation's context is under this many tokens; at or above it, start a fresh session with the sandbox's measured brief instead. Zero always starts fresh.",
|
|
358
|
+
),
|
|
359
|
+
// Worth it since the container is recreated on every update or environment approval — otherwise approving a
|
|
360
|
+
// Dockerfile change costs the run that asked for it.
|
|
646
361
|
autoResumeOnRestart: z
|
|
647
362
|
.boolean()
|
|
648
363
|
.default(false)
|
|
649
364
|
.describe(
|
|
650
365
|
"Whether a turn killed by the sandbox restarting is re-run once it comes back. Off to begin with, for the same reason: it would spend your allowance on work you are not watching and edit files while you are still waiting for the sandbox to return. Either way the interruption is recorded rather than silently lost.",
|
|
651
366
|
),
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
* add next. See RuleSchema for the shape and for why the four action kinds are four.
|
|
655
|
-
*
|
|
656
|
-
* EMPTY IS THE DEFAULT, and it is exactly the behaviour a fresh sandbox had when these were three separate
|
|
657
|
-
* flags: no proof is asked for, no command runs at a push, and finished work waits on its branch. That is
|
|
658
|
-
* not a coincidence to preserve by hand, each of those defaults is what "no rule matched" means at its
|
|
659
|
-
* moment, so the empty table IS the old default rather than a reconstruction of it.
|
|
660
|
-
*
|
|
661
|
-
* Rules live here, in the owner's own settings, rather than in the workspace: a rule can hold work back and
|
|
662
|
-
* gate a push, so the first version answers to the person whose sandbox it is and to nobody else. Repo-
|
|
663
|
-
* committed and extension-contributed rules are worth having and are deliberately not here yet, they need
|
|
664
|
-
* the question of what a rule from somewhere else may WIDEN answered first. */
|
|
367
|
+
// Lives in the owner's own settings, not the workspace: a rule can hold work and gate a push, so it answers to the
|
|
368
|
+
// sandbox owner alone. Repo- or extension-contributed rules aren't supported yet.
|
|
665
369
|
rules: z
|
|
666
370
|
.array(RuleSchema)
|
|
667
371
|
.max(50)
|
|
@@ -669,19 +373,6 @@ export const SandboxSettingsSchema = z.object({
|
|
|
669
373
|
.describe(
|
|
670
374
|
"Standing instructions you give the sandbox about its own work: ask for proof before a turn ends, run something before a push, hold or release finished work. Empty is the default and is exactly the behaviour of a fresh sandbox, because each of those defaults is what no rule matched means at its own moment.",
|
|
671
375
|
),
|
|
672
|
-
/* STOP AN AUTOMATION THAT ONLY EVER FAILS. After this many consecutive `error` runs the scheduler disables
|
|
673
|
-
* it and says so on the row, instead of firing a job that has proven it cannot succeed every minute until
|
|
674
|
-
* someone notices. 0 ⇒ never, which is the default.
|
|
675
|
-
*
|
|
676
|
-
* Off by default because quarantining edits the USER'S OWN configuration, and the failure it reacts to is
|
|
677
|
-
* not always the automation's fault: an hourly poll against an API having a bad afternoon is broken for
|
|
678
|
-
* three fires and fine on the fourth, and a job disabled at 3 a.m. is one nobody re-enables until they
|
|
679
|
-
* notice it stopped. So the mechanism exists for the case it is unambiguously right for, a misconfigured
|
|
680
|
-
* job burning a turn's worth of tokens on every tick, and the owner is the one who decides their
|
|
681
|
-
* automations are the kind that should be stopped rather than retried.
|
|
682
|
-
*
|
|
683
|
-
* Only `error` counts. A `skipped` run is a guard doing its job, and an `interrupted` one means the daemon
|
|
684
|
-
* died mid-fire, which says nothing about the automation, counting either would quarantine healthy jobs. */
|
|
685
376
|
automationFailureLimit: z
|
|
686
377
|
.number()
|
|
687
378
|
.min(0)
|
|
@@ -690,70 +381,30 @@ export const SandboxSettingsSchema = z.object({
|
|
|
690
381
|
.describe(
|
|
691
382
|
"How many failures in a row before an automation switches itself off. Zero means never, which is the default, because the failure is not always the automation's fault and a job disabled at three in the morning is one nobody re-enables. Only real errors count: a guard deciding there was nothing to do, or the sandbox dying mid-run, say nothing about the automation.",
|
|
692
383
|
),
|
|
693
|
-
|
|
694
|
-
* Defaults all-allow, so a fresh sandbox behaves exactly as before the floor existed and the per-automation
|
|
695
|
-
* `requireApproval` stays the way most owners meet holds. */
|
|
384
|
+
// Defaults all-allow, so a fresh sandbox behaves as it did before this floor existed.
|
|
696
385
|
admission: AdmissionPolicySchema.prefault({}).describe(
|
|
697
386
|
"Whether work started from outside may run, per kind of trigger: let it, hold it for approval, or refuse it. Composes with each automation's own setting, and the stricter of the two wins, so holding every visitor's message needs no edit to each automation.",
|
|
698
387
|
),
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
* live call and points the agent at the approvals queue, which IS the held form of a send.
|
|
704
|
-
*
|
|
705
|
-
* The CHILD-AGENT surface reads the same book: `agents.spawn` covers starting, steering and answering
|
|
706
|
-
* child agents on every provider, `agents.spawn.<provider>` singles one out (the specific key wins), and
|
|
707
|
-
* the daemon's own taint floor holds a spawn from a turn that has taken in outside content unless the
|
|
708
|
-
* owner wrote an explicit allow (guard/actions.ts childSpawn). "hold" refuses with the owner named, the
|
|
709
|
-
* same translation a send gets. */
|
|
388
|
+
// Keyed by `<provider>.<type>` ("discord.message.send"), or `<provider>.*` as a wildcard — exact key wins;
|
|
389
|
+
// unconfigured is allowed. "hold" can't park a live call: it refuses and points to the approvals queue. The
|
|
390
|
+
// child-agent surface (`agents.spawn`/`agents.spawn.<provider>`) reads the same book, plus its own taint floor for
|
|
391
|
+
// spawns from tainted turns.
|
|
710
392
|
actionRules: z
|
|
711
393
|
.record(z.string(), AdmissionRuleSchema)
|
|
712
394
|
.default({})
|
|
713
395
|
.describe("What an agent may do out in the world, per kind of action: go ahead, ask first, or never."),
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
* decided whether a card carried a sentence; both are gone, and the reason is the whole safety redesign
|
|
717
|
-
* (safety-policy.ts argues it). A regex verdict per class asked about `echo "rm -rf /"` and an actual delete
|
|
718
|
-
* in the same words, and no setting of six switches fixes that, because telling the two apart is an act of
|
|
719
|
-
* understanding rather than a threshold. What replaced them is the owner's written policy at
|
|
720
|
-
* .intentic/config/safety.md, read by a judge that also sees what the daemon knows about the turn, plus one
|
|
721
|
-
* typed hard rule the judge cannot waive. The Safety page edits that document; what a command may DO is
|
|
722
|
-
* settled there and nowhere in this object.
|
|
723
|
-
*
|
|
724
|
-
* WHETHER THE JUDGE RUNS AT ALL is a different question, and one this object has to answer, because it is
|
|
725
|
-
* the only tier of the design that spends money and interrupts people. An owner who does not want either is
|
|
726
|
-
* entitled to say so, and before this they could not: the old rulebook could be set to allow everything, and
|
|
727
|
-
* the redesign quietly made itself the one part of the sandbox you could only opt further into.
|
|
728
|
-
*
|
|
729
|
-
* WHICH MODEL judges is not answered here: it is the `safety-judge` role in `modelRoles`, like every other
|
|
730
|
-
* job in this sandbox that picks one. It used to need its own key, on the argument that a verdict is worth a
|
|
731
|
-
* different model than a commit message — true, and the fact that it had to be argued for one job at a time
|
|
732
|
-
* is exactly what the role catalog replaced. */
|
|
396
|
+
// Command policy itself lives at .intentic/config/safety.md (edited by the Safety page), not here; this only says
|
|
397
|
+
// whether the judge runs at all. Which model judges is the `safety-judge` role in `modelRoles`, not a field here.
|
|
733
398
|
commandJudge: CommandJudgeModeSchema.default("on").describe(
|
|
734
399
|
"Whether a model reads your safety policy before a flagged command runs. Off judges nothing and asks about nothing; Watch judges everything and records it without ever interrupting you, which is how you find out what your policy actually does before you let it stop anything; On lets the verdict decide. Wiping a disk or deleting under /history asks at every setting — that rule is typed rather than judged, and cannot be turned off.",
|
|
735
400
|
),
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
* They are three settings rather than one because they stop different things, and a fan-out that clears one
|
|
740
|
-
* lands on the next: `subagentsAtOnce` is the parallel width of a single fan-out, `subagentsPerTurn` is the
|
|
741
|
-
* lifetime budget of one conversation, and `subagentDepth` is how far a child may itself delegate. Raising
|
|
742
|
-
* the width alone is what makes a wide sweep hit the lifetime cap two rounds later, which reads to the user
|
|
743
|
-
* as the same wall in a new place.
|
|
744
|
-
*
|
|
745
|
-
* Each default is what the CLI does with no env set, so a sandbox that has never opened this group behaves
|
|
746
|
-
* exactly as it always did, these are not our numbers, they are the harness's, restated so they can move.
|
|
747
|
-
* The ceilings are ours: an agent is told to stop and NOT retry when it hits one, so the cost of a number
|
|
748
|
-
* set too high is a real fleet of models running at once, and the cost of one set too low is a wall.
|
|
749
|
-
*
|
|
750
|
-
* The refusal an agent sees names the env var (`ask them to raise CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`),
|
|
751
|
-
* which is why these three exist as settings at all: without them the only answer to that ask is editing
|
|
752
|
-
* the container's environment and restarting the daemon. */
|
|
401
|
+
// Three separate ceilings since they stop different things: width (parallel fan-out), lifetime (per conversation),
|
|
402
|
+
// depth (how far a child may delegate) — raising width alone just hits the lifetime cap sooner. Defaults mirror the
|
|
403
|
+
// CLI's own unset behavior; hitting one stops the agent rather than retrying.
|
|
753
404
|
subagentsAtOnce: z.number().min(1).max(200).default(20).describe("How many subagents may work at the same time."),
|
|
754
405
|
subagentsPerTurn: z.number().min(1).max(2000).default(200).describe("How many a single turn may start in total."),
|
|
755
|
-
// Depth 1
|
|
756
|
-
//
|
|
406
|
+
// Depth 1 means an agent may delegate but its children may not; unlike the other two, a runaway here is
|
|
407
|
+
// multiplicative, not merely wide.
|
|
757
408
|
subagentDepth: z
|
|
758
409
|
.number()
|
|
759
410
|
.min(1)
|
|
@@ -762,34 +413,20 @@ export const SandboxSettingsSchema = z.object({
|
|
|
762
413
|
.describe("How many levels deep the delegation may go, since a subagent can start subagents of its own."),
|
|
763
414
|
});
|
|
764
415
|
export type SandboxSettings = z.infer<typeof SandboxSettingsSchema>;
|
|
765
|
-
//
|
|
766
|
-
//
|
|
767
|
-
// shows behind "View" and drops into the editor behind "Edit a copy".
|
|
768
|
-
//
|
|
769
|
-
// `version` is the CLI build a captured preset came from, so the UI can say WHICH text the user is looking at:
|
|
770
|
-
// a custom prompt forked from an older build is a snapshot, and the version is the only honest way to tell.
|
|
771
|
-
// Empty for Intentic's prompt, which ships with the app and has no version of its own to report.
|
|
416
|
+
// Read live from the installed CLI (preset-prompt.ts), not a stored transcription. `version` is the CLI build it came
|
|
417
|
+
// from, so a fork from an older build reads as a snapshot; empty for Intentic's own prompt.
|
|
772
418
|
export const BuiltinPromptTextSchema = z.object({ text: z.string(), version: z.string() });
|
|
773
419
|
export type BuiltinPromptText = z.infer<typeof BuiltinPromptTextSchema>;
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
* Input-side savings: shell output the cleaners trimmed before the model ever saw it. Both sides of the
|
|
777
|
-
* comparison come off the SAME command (raw in, emitted out), so the counterfactual is observed rather than
|
|
778
|
-
* estimated: exact, per command, no sample size to argue about.
|
|
779
|
-
*/
|
|
420
|
+
// What each token-reduction mechanism actually saved. Input-side: both sides of the comparison come off the same
|
|
421
|
+
// command (raw in, emitted out), so the counterfactual is observed, not estimated — exact, per command.
|
|
780
422
|
|
|
781
|
-
//
|
|
782
|
-
//
|
|
783
|
-
// be drawn as one stacked bar. It is NOT "what turning this cleaner off would cost you": the cap downstream
|
|
784
|
-
// would have eaten some of the same lines. `commands` is how many commands the stage ran on. Negative for the
|
|
785
|
-
// `footer` stage, which adds the retrieval pointer back, a cost on the same ledger as what it bought.
|
|
423
|
+
// Sequential attribution (sums exactly to raw − emitted, drawable as a stacked bar); not what disabling this stage
|
|
424
|
+
// would save, since downstream would eat some of the same lines. Negative for `footer`, which adds cost back.
|
|
786
425
|
export const SavingsStageSchema = z.object({ id: z.string(), commands: z.number(), savedTokens: z.number() });
|
|
787
|
-
//
|
|
788
|
-
//
|
|
789
|
-
// calendar (the UTC day each command ran), so the reader's date range and the figures above it agree.
|
|
426
|
+
// Aggregated from historyRoot/logs/filter-stats.jsonl (one row per Bash command). Windowed on the ledger's own UTC-day
|
|
427
|
+
// calendar, so the reader's date range and these figures agree.
|
|
790
428
|
export const InputSavingsSchema = z.object({
|
|
791
|
-
//
|
|
792
|
-
// freshness it doesn't have. Absent when the ledger has never been written.
|
|
429
|
+
// Epoch ms of the ledger's last command, so the card can show its age rather than implying freshness.
|
|
793
430
|
updatedAt: z.number().optional(),
|
|
794
431
|
commands: z.number(),
|
|
795
432
|
rawTokens: z.number(),
|
|
@@ -797,133 +434,73 @@ export const InputSavingsSchema = z.object({
|
|
|
797
434
|
savedPct: z.number(),
|
|
798
435
|
// Per-stage attribution, biggest first.
|
|
799
436
|
perCleaner: z.array(SavingsStageSchema),
|
|
800
|
-
// The measured control
|
|
801
|
-
// for the pipeline as a whole rather than an estimate, and the only whole-pipeline counterfactual there is.
|
|
437
|
+
// The measured control (raw vs. cleaned); the only real whole-pipeline counterfactual, not an estimate.
|
|
802
438
|
holdout: z.object({ cleaned: z.number(), heldOut: z.number(), measuredSavedPct: z.number().optional() }),
|
|
803
|
-
|
|
804
|
-
* command text, `commands` is how many times it ran and `tokens` their total, because the question this
|
|
805
|
-
* list is read for is "what is worth a handler", and a handler is worth writing for a command that costs
|
|
806
|
-
* 5k twenty times over, not for the single 60k outlier that happened to sort first. */
|
|
439
|
+
// Grouped by command text: worth a handler is judged by total tokens across runs, not one outlier's size.
|
|
807
440
|
gaps: z.array(z.object({ command: z.string(), commands: z.number(), tokens: z.number() })),
|
|
808
441
|
});
|
|
809
442
|
export type InputSavings = z.infer<typeof InputSavingsSchema>;
|
|
810
|
-
// One arm of a turn-level experiment
|
|
811
|
-
// without it. A mean PER TURN, because the arms never hold the same number of turns.
|
|
443
|
+
// One arm of a turn-level experiment; mean is per turn, since the two arms never hold the same count.
|
|
812
444
|
export const SavingsArmSchema = z.object({ turns: z.number(), mean: z.number() });
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
* what the map hands over and what its note tells the turn not to go and fetch.
|
|
821
|
-
* callsBeforeTarget, the map again, on value rather than compliance: how far the turn walked before
|
|
822
|
-
* touching a file it went on to edit.
|
|
823
|
-
* Neither mechanism may be judged on COST. Cost is a whole turn's work, both of these move one part of it, and
|
|
824
|
-
* the part sits inside the noise of the rest. The map's whole payload is about 200 tokens, so a cost reading
|
|
825
|
-
* would be measuring a quantity two orders of magnitude under its own error bar. */
|
|
445
|
+
// One metric's reading of a turn-level experiment (the two arms, plus the arithmetic over them). `metric` says what
|
|
446
|
+
// `mean`/`deltaPct` count:
|
|
447
|
+
// searchCalls: searches a turn ran (the search teaching).
|
|
448
|
+
// openingSearches: same, narrowed to before the turn first touched a file.
|
|
449
|
+
// openingListings: directory listings a turn ran to orient itself (the project map).
|
|
450
|
+
// callsBeforeTarget: how far a turn walked before touching a file it went on to edit.
|
|
451
|
+
// Never cost: each mechanism moves one small part of a turn's work, inside the noise of the rest.
|
|
826
452
|
export const TurnMetricReadingSchema = z.object({
|
|
827
453
|
metric: z.enum(["searchCalls", "openingSearches", "openingListings", "callsBeforeTarget"]),
|
|
828
454
|
on: SavingsArmSchema,
|
|
829
455
|
off: SavingsArmSchema,
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
*
|
|
834
|
-
* It is aimed at a FIXED resolution rather than at today's delta on purpose. Sized against the observed
|
|
835
|
-
* effect it reported fourteen more turns for an experiment that had gone nine days without resolving, an
|
|
836
|
-
* estimate divided by noise inherits the noise and promises an answer next week indefinitely. Against a
|
|
837
|
-
* fixed target the same ledger asks for a few hundred, which is the fact the reader needs: this holdout is
|
|
838
|
-
* not close, and waiting is not the move.
|
|
839
|
-
*
|
|
840
|
-
* An order-of-magnitude figure, and it reads as one, the point is telling "a few more days" apart from
|
|
841
|
-
* "not at this holdout", which is a decision, where "measuring…" forever is not.
|
|
842
|
-
*
|
|
843
|
-
* Absent ⇒ nothing to wait for: the arms are under `minTurns`, the delta is published, or the resolution is
|
|
844
|
-
* already good enough and the effect is simply smaller than it. */
|
|
456
|
+
// Additional control turns to reach a fixed target resolution, not today's delta (which inherits noise and always
|
|
457
|
+
// promises "next week"). Absent means nothing to wait for: under `minTurns`, already published, or already resolved
|
|
458
|
+
// enough.
|
|
845
459
|
controlTurnsNeeded: z.number().optional(),
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
* this mechanism does, it is smaller than ±35 points" is a true and useful thing to be told, it is the
|
|
849
|
-
* reading that says to keep collecting rather than to act. */
|
|
460
|
+
// ± percentage points at 95% (Welch); present once both arms clear `minTurns`, even when `deltaPct` is withheld —
|
|
461
|
+
// "smaller than ±35 points" is still a useful, true answer.
|
|
850
462
|
marginPct: z.number().optional(),
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
* teaching run crossed its thirtieth control turn and immediately reported +31.2% ± 35.1pp: a confidence interval
|
|
856
|
-
* running from −3.4% to +66.7%, which is to say no effect was measured at all, rendered as an alarming
|
|
857
|
-
* number pointing the wrong way. Thirty turns is where the normal approximation starts to hold, not where
|
|
858
|
-
* this much per-turn spread resolves an effect; requiring the interval to exclude zero is the same
|
|
859
|
-
* withhold-until-it-means-something rule applied to the thing that actually decides whether it does.
|
|
860
|
-
* deltaPct, change in the metric's mean per turn under the mechanism; negative is a saving.
|
|
861
|
-
* saved , what the delta is worth over the turns that actually ran with it, in this window, in the
|
|
862
|
-
* metric's own unit (searches). */
|
|
463
|
+
// Present only once the margin excludes zero — clearing `minTurns` alone isn't enough, or a wide, unresolved swing
|
|
464
|
+
// reads as a real number.
|
|
465
|
+
// deltaPct: change in the metric's mean per turn; negative is a saving.
|
|
466
|
+
// saved: what that delta was worth over the turns that ran with it, in the metric's own unit.
|
|
863
467
|
deltaPct: z.number().optional(),
|
|
864
468
|
saved: z.number().optional(),
|
|
865
469
|
});
|
|
866
470
|
export type TurnMetricReading = z.infer<typeof TurnMetricReadingSchema>;
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
* ONE COIN FLIP, SEVERAL READINGS. `metrics` is a list because the search teaching is judged on two, the
|
|
870
|
-
* searches a turn ran, and the ones it ran before touching a file, and they are two readings of the SAME
|
|
871
|
-
* experiment, not two experiments. Splitting them into separate entries would duplicate the arm assignment and
|
|
872
|
-
* let a screen show a turn count on one that disagrees with the other. Headline first: the screens read
|
|
873
|
-
* `metrics[0]` for the big number and the rest as supporting lines. */
|
|
471
|
+
// One coin flip, several readings: `metrics` is a list since splitting readings into separate entries would duplicate
|
|
472
|
+
// the arm assignment. Screens read `metrics[0]` as the headline, the rest as supporting lines.
|
|
874
473
|
export const TurnExperimentSchema = z.object({
|
|
875
|
-
// A head and a tail
|
|
876
|
-
//
|
|
877
|
-
// "there is always a headline" a fact the type carries instead of a check every screen repeats. (`.nonempty()`
|
|
878
|
-
// would not do it, in zod 4 it adds a min-length rule and leaves the inferred type a plain array.)
|
|
474
|
+
// A head and a tail, not a plain array, so "always a headline" is a type fact, not a check every screen repeats.
|
|
475
|
+
// `.nonempty()` doesn't do this in zod 4 (a runtime check, still typed as a plain array).
|
|
879
476
|
metrics: z.tuple([TurnMetricReadingSchema], TurnMetricReadingSchema),
|
|
880
|
-
//
|
|
881
|
-
//
|
|
882
|
-
// reading: they are the same turns counted differently, so they clear it together.
|
|
477
|
+
// Carried on the wire so "measuring…" reflects the daemon's real threshold, not a guess; shared across every
|
|
478
|
+
// reading, since they're the same turns.
|
|
883
479
|
minTurns: z.number(),
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
*
|
|
887
|
-
* "opening turns" is the third case and belongs to a treatment sent ONCE: the project map rides the first
|
|
888
|
-
* message and nothing after it, so the sample is one turn per conversation rather than an average over
|
|
889
|
-
* the conversation's turns. The distinction is not cosmetic. Averaging a first-turn treatment across a
|
|
890
|
-
* twelve-turn conversation divides its effect by twelve and reports the remainder as noise. */
|
|
480
|
+
// Turn mechanisms randomize by turn; session-loaded teaching randomizes whole conversations; a once-sent treatment
|
|
481
|
+
// (the map) samples one turn per conversation, not an average, or its effect divides by the conversation's length.
|
|
891
482
|
sampleUnit: z.enum(["turns", "conversations", "opening turns"]).optional(),
|
|
892
|
-
// Content-addressed treatment version
|
|
893
|
-
// one experiment
|
|
483
|
+
// Content-addressed treatment version; the reader filters to the latest so two instruction revisions don't blur
|
|
484
|
+
// into one experiment.
|
|
894
485
|
cohort: z.string().optional(),
|
|
895
486
|
});
|
|
896
487
|
export type TurnExperiment = z.infer<typeof TurnExperimentSchema>;
|
|
897
|
-
//
|
|
898
|
-
//
|
|
899
|
-
//
|
|
900
|
-
|
|
901
|
-
* and friends) over the requested window. The three numbers docs/model-routing-design.md §4 says the feature
|
|
902
|
-
* cannot be defended without, plus the veto count, and nothing else: no counterfactual "you would have saved
|
|
903
|
-
* $X", because the ledger holds what turns COST, not what they would have cost on a model they never ran.
|
|
904
|
-
*
|
|
905
|
-
* NOT a TurnExperiment, deliberately. The experiments compare two randomized arms of one population; this is a
|
|
906
|
-
* tally of what one mechanism observed and did. Dressing it in arms and margins would claim a control group that
|
|
907
|
-
* does not exist (routing follows the settings mode, which follows time, not a coin flip).
|
|
908
|
-
*
|
|
909
|
-
* The whole section is absent when no turn in the window was judged at all (autoTier "off" throughout), which a
|
|
910
|
-
* screen renders as absence: "not measured" is the truth, zeros would read as "measured, found nothing". */
|
|
488
|
+
// Absent when the experiment isn't running (flag off, or no holdout set); absence reads as "not measured", not as zero.
|
|
489
|
+
// Read off the spend ledger's tier fields over the window; no counterfactual $ saved, since the ledger holds only what
|
|
490
|
+
// turns cost. Not a `TurnExperiment`: there's no randomized control, routing follows the settings mode over time, not a
|
|
491
|
+
// coin flip. Absent (no turn judged, autoTier off) reads as "not measured", not "measured, found nothing".
|
|
911
492
|
export const TierReportSchema = z.object({
|
|
912
493
|
// Turns the judge ran on in the window, the denominator under everything below.
|
|
913
494
|
judged: z.number(),
|
|
914
495
|
// …of which landed at or below FAST_CEILING: the turns that looked simple. fast ÷ judged is the fast share.
|
|
915
496
|
fast: z.number(),
|
|
916
|
-
|
|
917
|
-
* pointing at. An upper bound on any saving, never an estimate of one: moving those turns to the cheap rung
|
|
918
|
-
* would have cost something too, and this schema refuses to guess how much. */
|
|
497
|
+
// Upper bound on any saving, never an estimate: moving these turns to the cheap rung would have cost something too.
|
|
919
498
|
atStakeUsd: z.number(),
|
|
920
499
|
// Turns that actually ran the cheap rung, and what they cost there. Realized, not projected.
|
|
921
500
|
routed: z.number(),
|
|
922
501
|
routedUsd: z.number(),
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
* signal the ledger can carry (§4's first calibration row). Past a few percent of `fast`, the judge is
|
|
926
|
-
* costing more in retries and trust than it saves in tokens. */
|
|
502
|
+
// The guardrail: fast-judged turns whose very next ledger row asked for a dearer model. Past a few percent of
|
|
503
|
+
// `fast`, the judge costs more in trust than it saves.
|
|
927
504
|
escalated: z.number(),
|
|
928
505
|
// Fast-judged turns the user vetoed outright (UsageTurn.tierDenied): the same signal, said even louder.
|
|
929
506
|
denied: z.number(),
|
|
@@ -932,9 +509,7 @@ export type TierReport = z.infer<typeof TierReportSchema>;
|
|
|
932
509
|
export const SavingsReportSchema = z.object({
|
|
933
510
|
input: InputSavingsSchema,
|
|
934
511
|
search: TurnExperimentSchema.optional(),
|
|
935
|
-
|
|
936
|
-
* same rule as `search`: the switch is off, or no holdout is set, and a section that is not there reads as
|
|
937
|
-
* "not measured", which is the truth, where zeros would read as "measured, worth nothing". */
|
|
512
|
+
// Same absence rule as `search`: not measured, never zero.
|
|
938
513
|
map: TurnExperimentSchema.optional(),
|
|
939
514
|
// Automatic tier selection's readout, see TierReportSchema. Absent ⇒ nothing was judged in the window.
|
|
940
515
|
tier: TierReportSchema.optional(),
|