@intentic/sandbox-contract 1.344.0 → 1.345.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 +6 -0
- package/dist/contracts/accounts.contract.d.ts +24 -0
- package/dist/contracts/accounts.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.d.ts +214 -6
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.js +13 -2
- package/dist/contracts/agent.contract.js.map +1 -1
- package/dist/contracts/agents.contract.d.ts +656 -0
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +5 -3
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/device.contract.d.ts +242 -0
- package/dist/contracts/device.contract.d.ts.map +1 -1
- package/dist/contracts/device.contract.js +5 -1
- package/dist/contracts/device.contract.js.map +1 -1
- package/dist/contracts/endpoints.contract.d.ts +2 -0
- package/dist/contracts/endpoints.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.js +1 -0
- package/dist/contracts/endpoints.contract.js.map +1 -1
- package/dist/contracts/push.contract.d.ts +11 -0
- package/dist/contracts/push.contract.d.ts.map +1 -1
- package/dist/contracts/push.contract.js +10 -1
- package/dist/contracts/push.contract.js.map +1 -1
- package/dist/contracts/runner.contract.d.ts +15 -0
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.d.ts +169 -0
- package/dist/contracts/secrets.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.js +35 -0
- package/dist/contracts/secrets.contract.js.map +1 -1
- package/dist/contracts/sessions.contract.d.ts +2 -0
- package/dist/contracts/sessions.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.d.ts +33 -0
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.d.ts +133 -30
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/translator.contract.d.ts +24 -0
- package/dist/contracts/translator.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.d.ts +11 -0
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.js +11 -1
- package/dist/contracts/workspace.contract.js.map +1 -1
- package/dist/events/agent-events.d.ts +17 -0
- package/dist/events/agent-events.d.ts.map +1 -1
- package/dist/events/agent-events.js +2 -1
- package/dist/events/agent-events.js.map +1 -1
- package/dist/events/agent-transcript.d.ts +727 -0
- package/dist/events/agent-transcript.d.ts.map +1 -0
- package/dist/events/agent-transcript.js +34 -0
- package/dist/events/agent-transcript.js.map +1 -0
- package/dist/events/agent-words.d.ts +5 -0
- package/dist/events/agent-words.d.ts.map +1 -1
- package/dist/events/agent-words.js +9 -0
- package/dist/events/agent-words.js.map +1 -1
- package/dist/events/requests.d.ts +143 -0
- package/dist/events/requests.d.ts.map +1 -1
- package/dist/events/requests.js +35 -1
- package/dist/events/requests.js.map +1 -1
- package/dist/events/sandbox-notice.d.ts +7 -0
- package/dist/events/sandbox-notice.d.ts.map +1 -1
- package/dist/events/sandbox-notice.js +1 -0
- package/dist/events/sandbox-notice.js.map +1 -1
- package/dist/events/system-events.d.ts +88 -0
- package/dist/events/system-events.d.ts.map +1 -1
- package/dist/events/transcript.d.ts +20 -720
- package/dist/events/transcript.d.ts.map +1 -1
- package/dist/events/transcript.js +17 -19
- package/dist/events/transcript.js.map +1 -1
- package/dist/events/undelivered.d.ts +4 -0
- package/dist/events/undelivered.d.ts.map +1 -1
- package/dist/events/undelivered.js +13 -0
- package/dist/events/undelivered.js.map +1 -1
- package/dist/ids/conversation-ids.d.ts +2 -0
- package/dist/ids/conversation-ids.d.ts.map +1 -1
- package/dist/ids/conversation-ids.js +2 -0
- package/dist/ids/conversation-ids.js.map +1 -1
- package/dist/ids/row-ids.d.ts +3 -0
- package/dist/ids/row-ids.d.ts.map +1 -0
- package/dist/ids/row-ids.js +11 -0
- package/dist/ids/row-ids.js.map +1 -0
- package/dist/index.d.ts +1281 -39
- package/dist/index.d.ts.map +1 -1
- package/dist/models/agent-lanes.d.ts.map +1 -1
- package/dist/models/agent-lanes.js +3 -2
- package/dist/models/agent-lanes.js.map +1 -1
- package/dist/models/agent-standing.d.ts +4 -0
- package/dist/models/agent-standing.d.ts.map +1 -1
- package/dist/models/agent-standing.js +2 -1
- package/dist/models/agent-standing.js.map +1 -1
- package/dist/models/plan-pools.d.ts +5 -1
- package/dist/models/plan-pools.d.ts.map +1 -1
- package/dist/models/plan-pools.js +57 -21
- package/dist/models/plan-pools.js.map +1 -1
- package/dist/netd/generated/wire.d.ts +5 -0
- package/dist/netd/generated/wire.d.ts.map +1 -1
- package/dist/policy/command-classes.d.ts +1 -1
- package/dist/policy/command-classes.d.ts.map +1 -1
- package/dist/policy/command-classes.js +2 -2
- package/dist/policy/command-classes.js.map +1 -1
- package/dist/policy/keyring-origins.d.ts +27 -0
- package/dist/policy/keyring-origins.d.ts.map +1 -0
- package/dist/policy/keyring-origins.js +213 -0
- package/dist/policy/keyring-origins.js.map +1 -0
- package/dist/policy/keyring-seal.d.ts +9 -0
- package/dist/policy/keyring-seal.d.ts.map +1 -1
- package/dist/policy/keyring-seal.js +18 -6
- package/dist/policy/keyring-seal.js.map +1 -1
- package/dist/policy/safety-policy.d.ts +1 -1
- package/dist/policy/safety-policy.d.ts.map +1 -1
- package/dist/policy/safety-policy.js +1 -1
- package/dist/policy/safety-policy.js.map +1 -1
- package/dist/policy/turned-away.d.ts +1 -0
- package/dist/policy/turned-away.d.ts.map +1 -1
- package/dist/policy/turned-away.js +10 -0
- package/dist/policy/turned-away.js.map +1 -1
- package/dist/protocol/doors/host-protocol.d.ts +1 -0
- package/dist/protocol/doors/host-protocol.d.ts.map +1 -1
- package/dist/protocol/doors/host-protocol.js +1 -0
- package/dist/protocol/doors/host-protocol.js.map +1 -1
- package/dist/protocol/doors/webext-links.d.ts +1 -0
- package/dist/protocol/doors/webext-links.d.ts.map +1 -1
- package/dist/protocol/doors/webext-links.js +1 -0
- package/dist/protocol/doors/webext-links.js.map +1 -1
- package/dist/protocol/peer-dial.d.ts +2 -0
- package/dist/protocol/peer-dial.d.ts.map +1 -1
- package/dist/protocol/peer-dial.js +62 -29
- package/dist/protocol/peer-dial.js.map +1 -1
- package/dist/protocol/raw/raw-json-routes.d.ts +176 -0
- package/dist/protocol/raw/raw-json-routes.d.ts.map +1 -1
- package/dist/protocol/raw/raw-json-routes.js +5 -0
- package/dist/protocol/raw/raw-json-routes.js.map +1 -1
- package/dist/protocol/raw/raw-routes.d.ts +31 -0
- package/dist/protocol/raw/raw-routes.d.ts.map +1 -1
- package/dist/protocol/raw/raw-routes.js +8 -0
- package/dist/protocol/raw/raw-routes.js.map +1 -1
- package/dist/schemas/agent-place.d.ts +10 -0
- package/dist/schemas/agent-place.d.ts.map +1 -0
- package/dist/schemas/agent-place.js +15 -0
- package/dist/schemas/agent-place.js.map +1 -0
- package/dist/schemas/agent.d.ts +116 -83
- package/dist/schemas/agent.d.ts.map +1 -1
- package/dist/schemas/agent.js +26 -39
- package/dist/schemas/agent.js.map +1 -1
- package/dist/schemas/agents-list.d.ts +38 -0
- package/dist/schemas/agents-list.d.ts.map +1 -1
- package/dist/schemas/agents.d.ts +117 -16
- package/dist/schemas/agents.d.ts.map +1 -1
- package/dist/schemas/agents.js +19 -21
- package/dist/schemas/agents.js.map +1 -1
- package/dist/schemas/attach.d.ts +8 -0
- package/dist/schemas/attach.d.ts.map +1 -0
- package/dist/schemas/attach.js +14 -0
- package/dist/schemas/attach.js.map +1 -0
- package/dist/schemas/command-admission.d.ts +71 -0
- package/dist/schemas/command-admission.d.ts.map +1 -0
- package/dist/schemas/command-admission.js +27 -0
- package/dist/schemas/command-admission.js.map +1 -0
- package/dist/schemas/conversation-links.d.ts +44 -0
- package/dist/schemas/conversation-links.d.ts.map +1 -0
- package/dist/schemas/conversation-links.js +35 -0
- package/dist/schemas/conversation-links.js.map +1 -0
- package/dist/schemas/data-protection.d.ts +1 -1
- package/dist/schemas/data-protection.d.ts.map +1 -1
- package/dist/schemas/devices.d.ts +4 -1
- package/dist/schemas/devices.d.ts.map +1 -1
- package/dist/schemas/devices.js +1 -0
- package/dist/schemas/devices.js.map +1 -1
- package/dist/schemas/hosts.d.ts +2 -0
- package/dist/schemas/hosts.d.ts.map +1 -1
- package/dist/schemas/hosts.js +2 -0
- package/dist/schemas/hosts.js.map +1 -1
- package/dist/schemas/keyring-native.d.ts +137 -0
- package/dist/schemas/keyring-native.d.ts.map +1 -0
- package/dist/schemas/keyring-native.js +69 -0
- package/dist/schemas/keyring-native.js.map +1 -0
- package/dist/schemas/keyring.d.ts +413 -0
- package/dist/schemas/keyring.d.ts.map +1 -1
- package/dist/schemas/keyring.js +139 -4
- package/dist/schemas/keyring.js.map +1 -1
- package/dist/schemas/phone-passwords.d.ts +186 -0
- package/dist/schemas/phone-passwords.d.ts.map +1 -0
- package/dist/schemas/phone-passwords.js +25 -0
- package/dist/schemas/phone-passwords.js.map +1 -0
- package/dist/schemas/providers/plan-limits.d.ts +74 -0
- package/dist/schemas/providers/plan-limits.d.ts.map +1 -1
- package/dist/schemas/providers/plan-limits.js +31 -0
- package/dist/schemas/providers/plan-limits.js.map +1 -1
- package/dist/schemas/providers/provider-oauth.d.ts +24 -0
- package/dist/schemas/providers/provider-oauth.d.ts.map +1 -1
- package/dist/schemas/providers/usage.d.ts +1 -0
- package/dist/schemas/providers/usage.d.ts.map +1 -1
- package/dist/schemas/providers/usage.js +1 -0
- package/dist/schemas/providers/usage.js.map +1 -1
- package/dist/schemas/push.d.ts +13 -0
- package/dist/schemas/push.d.ts.map +1 -1
- package/dist/schemas/push.js +11 -1
- package/dist/schemas/push.js.map +1 -1
- package/dist/schemas/sandbox-passwords.d.ts +288 -0
- package/dist/schemas/sandbox-passwords.d.ts.map +1 -0
- package/dist/schemas/sandbox-passwords.js +66 -0
- package/dist/schemas/sandbox-passwords.js.map +1 -0
- package/dist/schemas/secrets.d.ts +2 -0
- package/dist/schemas/secrets.d.ts.map +1 -1
- package/dist/schemas/secrets.js +4 -0
- package/dist/schemas/secrets.js.map +1 -1
- package/dist/schemas/settings-savings.d.ts +709 -0
- package/dist/schemas/settings-savings.d.ts.map +1 -0
- package/dist/schemas/settings-savings.js +53 -0
- package/dist/schemas/settings-savings.js.map +1 -0
- package/dist/schemas/settings.d.ts +3 -671
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +3 -50
- package/dist/schemas/settings.js.map +1 -1
- package/dist/schemas/terminal.d.ts +5 -0
- package/dist/schemas/terminal.d.ts.map +1 -1
- package/dist/schemas/terminal.js +4 -0
- package/dist/schemas/terminal.js.map +1 -1
- package/dist/schemas/work-assurance.d.ts +24 -0
- package/dist/schemas/work-assurance.d.ts.map +1 -0
- package/dist/schemas/work-assurance.js +23 -0
- package/dist/schemas/work-assurance.js.map +1 -0
- package/dist/schemas/workspace/workspace-tree.d.ts +23 -0
- package/dist/schemas/workspace/workspace-tree.d.ts.map +1 -1
- package/dist/schemas/workspace/workspace-tree.js +20 -0
- package/dist/schemas/workspace/workspace-tree.js.map +1 -1
- package/dist/state/auth-state.d.ts +4 -0
- package/dist/state/auth-state.d.ts.map +1 -0
- package/dist/state/auth-state.js +37 -0
- package/dist/state/auth-state.js.map +1 -0
- package/dist/state/definition.d.ts +4 -0
- package/dist/state/definition.d.ts.map +1 -1
- package/dist/state/history-state.d.ts.map +1 -1
- package/dist/state/history-state.js +17 -1
- package/dist/state/history-state.js.map +1 -1
- package/dist/state/runtime-state.d.ts.map +1 -1
- package/dist/state/runtime-state.js.map +1 -1
- package/dist/text/transcript-fold.js +5 -5
- package/dist/text/transcript-fold.js.map +1 -1
- package/dist/webext/index.d.ts +1 -0
- package/dist/webext/index.d.ts.map +1 -1
- package/dist/webext/index.js +1 -0
- package/dist/webext/index.js.map +1 -1
- package/package.json +6 -5
- package/src/contracts/agent.contract.ts +13 -1
- package/src/contracts/agents.contract.ts +4 -3
- package/src/contracts/device.contract.ts +16 -0
- package/src/contracts/endpoints.contract.ts +3 -0
- package/src/contracts/push.contract.ts +23 -1
- package/src/contracts/secrets.contract.ts +39 -0
- package/src/contracts/workspace.contract.ts +16 -0
- package/src/events/agent-events.ts +4 -1
- package/src/events/agent-transcript.ts +48 -0
- package/src/events/agent-words.ts +13 -0
- package/src/events/requests.ts +41 -3
- package/src/events/sandbox-notice.ts +3 -0
- package/src/events/transcript.ts +30 -28
- package/src/events/undelivered.ts +18 -0
- package/src/ids/conversation-ids.ts +7 -0
- package/src/ids/row-ids.ts +20 -0
- package/src/models/agent-lanes.ts +9 -3
- package/src/models/agent-standing.ts +9 -1
- package/src/models/plan-pools.test.ts +128 -20
- package/src/models/plan-pools.ts +114 -31
- package/src/netd/generated/netd-wire.json +25 -0
- package/src/netd/generated/wire.ts +1 -1
- package/src/policy/command-classes.ts +2 -2
- package/src/policy/keyring-origins.test.ts +132 -0
- package/src/policy/keyring-origins.ts +287 -0
- package/src/policy/keyring-seal.test.ts +37 -2
- package/src/policy/keyring-seal.ts +33 -7
- package/src/policy/safety-policy.ts +1 -1
- package/src/policy/tests/safety-policy.test.ts +1 -1
- package/src/policy/turned-away.ts +15 -0
- package/src/protocol/doors/host-protocol.ts +3 -0
- package/src/protocol/doors/webext-links.ts +3 -0
- package/src/protocol/peer-dial.test.ts +90 -4
- package/src/protocol/peer-dial.ts +83 -39
- package/src/protocol/raw/raw-json-routes.ts +13 -0
- package/src/protocol/raw/raw-routes.ts +12 -1
- package/src/schemas/agent-place.ts +22 -0
- package/src/schemas/agent.ts +42 -78
- package/src/schemas/agents.ts +41 -46
- package/src/schemas/attach.ts +23 -0
- package/src/schemas/command-admission.ts +57 -0
- package/src/schemas/conversation-links.ts +62 -0
- package/src/schemas/data-protection.ts +1 -1
- package/src/schemas/devices.ts +4 -4
- package/src/schemas/hosts.ts +4 -0
- package/src/schemas/keyring-native.test.ts +13 -0
- package/src/schemas/keyring-native.ts +101 -0
- package/src/schemas/keyring.ts +202 -4
- package/src/schemas/phone-passwords.ts +51 -0
- package/src/schemas/providers/plan-limits.ts +49 -2
- package/src/schemas/providers/usage.ts +2 -0
- package/src/schemas/push.ts +19 -3
- package/src/schemas/sandbox-passwords.ts +88 -0
- package/src/schemas/secrets.ts +4 -0
- package/src/schemas/settings-savings.ts +125 -0
- package/src/schemas/settings.ts +8 -116
- package/src/schemas/terminal.ts +8 -0
- package/src/schemas/work-assurance.ts +36 -0
- package/src/schemas/workspace/workspace-tree.ts +32 -0
- package/src/state/auth-state.ts +89 -0
- package/src/state/history-state.ts +44 -1
- package/src/state/runtime-state.ts +5 -4
- package/src/text/transcript-fold.test.ts +67 -0
- package/src/text/transcript-fold.ts +6 -6
- package/src/webext/index.ts +2 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// settings-savings: what each token-reduction mechanism saved and how the turn-level ones are measured, as the
|
|
2
|
+
// settings routes report them. Re-exported by settings.ts, whose routes carry them.
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
// What each token-reduction mechanism actually saved. Input-side: both sides of the comparison come off the same
|
|
6
|
+
// command (raw in, emitted out), so the counterfactual is observed, not estimated — exact, per command.
|
|
7
|
+
|
|
8
|
+
// Sequential attribution (sums exactly to raw − emitted, drawable as a stacked bar); not what disabling this stage
|
|
9
|
+
// would save, since downstream would eat some of the same lines. Negative for `footer`, which adds cost back.
|
|
10
|
+
export const SavingsStageSchema = z.object({ id: z.string(), commands: z.number(), savedTokens: z.number() });
|
|
11
|
+
// Aggregated from historyRoot/logs/filter-stats.jsonl (one row per Bash command). Windowed on the ledger's own UTC-day
|
|
12
|
+
// calendar, so the reader's date range and these figures agree.
|
|
13
|
+
export const InputSavingsSchema = z.object({
|
|
14
|
+
// Epoch ms of the ledger's last command, so the card can show its age rather than implying freshness.
|
|
15
|
+
updatedAt: z.number().optional(),
|
|
16
|
+
commands: z.number(),
|
|
17
|
+
rawTokens: z.number(),
|
|
18
|
+
emittedTokens: z.number(),
|
|
19
|
+
savedPct: z.number(),
|
|
20
|
+
// Per-stage attribution, biggest first.
|
|
21
|
+
perCleaner: z.array(SavingsStageSchema),
|
|
22
|
+
// The measured control (raw vs. cleaned); the only real whole-pipeline counterfactual, not an estimate.
|
|
23
|
+
holdout: z.object({ cleaned: z.number(), heldOut: z.number(), measuredSavedPct: z.number().optional() }),
|
|
24
|
+
// Grouped by command text: worth a handler is judged by total tokens across runs, not one outlier's size.
|
|
25
|
+
gaps: z.array(z.object({ command: z.string(), commands: z.number(), tokens: z.number() })),
|
|
26
|
+
});
|
|
27
|
+
export type InputSavings = z.infer<typeof InputSavingsSchema>;
|
|
28
|
+
// One arm of a turn-level experiment; mean is per turn, since the two arms never hold the same count.
|
|
29
|
+
// `mean` is over samples capped at both arms' pooled 95th percentile, so one runaway conversation cannot carry an arm.
|
|
30
|
+
// For a yes/no reading (`openedWithListing`) it is the share of yeses, 0 to 1, and uncapped.
|
|
31
|
+
export const SavingsArmSchema = z.object({ turns: z.number(), mean: z.number() });
|
|
32
|
+
// One metric's reading of a turn-level experiment (the two arms, plus the arithmetic over them). `metric` says what
|
|
33
|
+
// `mean`/`deltaPct` count:
|
|
34
|
+
// searchCalls: searches a turn ran (the search teaching).
|
|
35
|
+
// openingSearches: same, narrowed to before the turn first touched a file.
|
|
36
|
+
// openedWithListing: whether a turn listed directories to orient itself, as a share of turns (the project map).
|
|
37
|
+
// callsBeforeTarget: how far a turn walked before touching a file it went on to edit.
|
|
38
|
+
// failedCalls: tool calls that ended in error (the field notes, whose largest section is a failure taxonomy).
|
|
39
|
+
// openingPrompt: tokens a turn's first request sent (cache reads plus cache writes), which is what every later call of
|
|
40
|
+
// the turn reads again (tool search, which moves the tool schemas out of it).
|
|
41
|
+
// openingWrite: tokens a follow-up turn's first request wrote to the cache instead of reading them (the stable prompt).
|
|
42
|
+
// Every reading is the main agent's own: a subagent's calls are counted toward the turn and read for nothing.
|
|
43
|
+
// Never cost: each mechanism moves one small part of a turn's work, inside the noise of the rest. The prompt's size is
|
|
44
|
+
// the exception that proves it: it is the part every call pays again, so it is read directly rather than through cost.
|
|
45
|
+
export const TurnMetricReadingSchema = z.object({
|
|
46
|
+
metric: z.enum(["searchCalls", "openingSearches", "openedWithListing", "callsBeforeTarget", "failedCalls", "openingPrompt", "openingWrite"]),
|
|
47
|
+
on: SavingsArmSchema,
|
|
48
|
+
off: SavingsArmSchema,
|
|
49
|
+
// Additional control turns to reach a fixed target resolution, not today's delta (which inherits noise and always
|
|
50
|
+
// promises "next week"). Absent means nothing to wait for: under `minTurns`, already published, or already resolved
|
|
51
|
+
// enough.
|
|
52
|
+
controlTurnsNeeded: z.number().optional(),
|
|
53
|
+
// ± percentage points at 95% (Welch); present once both arms clear `minTurns`, even when `deltaPct` is withheld —
|
|
54
|
+
// "smaller than ±35 points" is still a useful, true answer.
|
|
55
|
+
marginPct: z.number().optional(),
|
|
56
|
+
// Present only once the margin excludes zero — clearing `minTurns` alone isn't enough, or a wide, unresolved swing
|
|
57
|
+
// reads as a real number.
|
|
58
|
+
// deltaPct: change in the metric's mean per turn; negative is a saving.
|
|
59
|
+
// saved: what that delta was worth over the turns that ran with it, in the metric's own unit.
|
|
60
|
+
deltaPct: z.number().optional(),
|
|
61
|
+
saved: z.number().optional(),
|
|
62
|
+
});
|
|
63
|
+
export type TurnMetricReading = z.infer<typeof TurnMetricReadingSchema>;
|
|
64
|
+
// One coin flip, several readings: `metrics` is a list since splitting readings into separate entries would duplicate
|
|
65
|
+
// the arm assignment. Screens read `metrics[0]` as the headline, the rest as supporting lines.
|
|
66
|
+
export const TurnExperimentSchema = z.object({
|
|
67
|
+
// A head and a tail, not a plain array, so "always a headline" is a type fact, not a check every screen repeats.
|
|
68
|
+
// `.nonempty()` doesn't do this in zod 4 (a runtime check, still typed as a plain array).
|
|
69
|
+
metrics: z.tuple([TurnMetricReadingSchema], TurnMetricReadingSchema),
|
|
70
|
+
// Carried on the wire so "measuring…" reflects the daemon's real threshold, not a guess; shared across every
|
|
71
|
+
// reading, since they're the same turns.
|
|
72
|
+
minTurns: z.number(),
|
|
73
|
+
// Turn mechanisms randomize by turn; session-loaded teaching randomizes whole conversations; a once-sent treatment
|
|
74
|
+
// (the map) samples one turn per conversation, not an average, or its effect divides by the conversation's length.
|
|
75
|
+
sampleUnit: z.enum(["turns", "conversations", "opening turns"]).optional(),
|
|
76
|
+
// Content-addressed treatment version; the reader filters to the latest so two instruction revisions don't blur
|
|
77
|
+
// into one experiment.
|
|
78
|
+
cohort: z.string().optional(),
|
|
79
|
+
// The latest earlier cohort that reached an answer, with only its answered readings (a margin, with or without a
|
|
80
|
+
// delta), so restarting a comparison does not wipe a finding off the screen while the new one is early. `from` and
|
|
81
|
+
// `to` are its first and last measured turn inside the window read, epoch ms. Absent when no earlier one answered.
|
|
82
|
+
previous: z
|
|
83
|
+
.object({ from: z.number(), to: z.number(), cohort: z.string().optional(), metrics: z.array(TurnMetricReadingSchema) })
|
|
84
|
+
.optional(),
|
|
85
|
+
// Whether the treatment was taken up at all, which no reading above can tell: the share, 0 to 1, of each group's
|
|
86
|
+
// searches that ran iq, pooled over the turns of this cohort that recorded it. `turns` is the treated group's count;
|
|
87
|
+
// absent until it reaches `minTurns`. The search teaching only.
|
|
88
|
+
uptake: z.object({ on: z.number(), off: z.number(), turns: z.number() }).optional(),
|
|
89
|
+
});
|
|
90
|
+
export type TurnExperiment = z.infer<typeof TurnExperimentSchema>;
|
|
91
|
+
// What the settings row can say about the brief without opening it: whether there is one, how much of it this budget
|
|
92
|
+
// reaches, and whether anything is scheduled to rewrite it. Read off the file and the automation store, never stored.
|
|
93
|
+
export const FieldNotesStatusSchema = z.object({
|
|
94
|
+
// False means the automation has never run (or was never set up) — the ordinary state before the first month.
|
|
95
|
+
present: z.boolean(),
|
|
96
|
+
// Epoch ms the file was last written. Absent when there is no file.
|
|
97
|
+
writtenAt: z.number().optional(),
|
|
98
|
+
// How many ranked sections the current budget reaches, out of how many the file holds. The pair is the point: "5"
|
|
99
|
+
// alone cannot tell a generous budget from a short file.
|
|
100
|
+
ranksSent: z.number().optional(),
|
|
101
|
+
ranksTotal: z.number().optional(),
|
|
102
|
+
// What the brief costs the prompt, in characters, at the current budget.
|
|
103
|
+
chars: z.number().optional(),
|
|
104
|
+
// The monthly rewrite: absent until the owner creates it from the offered template, since an automation names the
|
|
105
|
+
// models it spends and nothing chooses those for them.
|
|
106
|
+
automation: z.enum(["missing", "enabled", "disabled"]),
|
|
107
|
+
// When it next runs, epoch ms; absent when there is nothing scheduled.
|
|
108
|
+
nextRunAt: z.number().optional(),
|
|
109
|
+
// Said out loud rather than shown as "no file": a brief that exists and cannot be read is a broken automation.
|
|
110
|
+
unreadable: z.string().optional(),
|
|
111
|
+
// Blocks of the file its priority table does not rank, so no limit ever sends them. Absent when there are none.
|
|
112
|
+
unlisted: z.array(z.string()).optional(),
|
|
113
|
+
});
|
|
114
|
+
export type FieldNotesStatus = z.infer<typeof FieldNotesStatusSchema>;
|
|
115
|
+
export const SavingsReportSchema = z.object({
|
|
116
|
+
input: InputSavingsSchema,
|
|
117
|
+
search: TurnExperimentSchema.optional(),
|
|
118
|
+
// Same absence rule as `search`: not measured, never zero.
|
|
119
|
+
map: TurnExperimentSchema.optional(),
|
|
120
|
+
notes: TurnExperimentSchema.optional(),
|
|
121
|
+
toolSearch: TurnExperimentSchema.optional(),
|
|
122
|
+
stablePrompt: TurnExperimentSchema.optional(),
|
|
123
|
+
coldTrim: TurnExperimentSchema.optional(),
|
|
124
|
+
});
|
|
125
|
+
export type SavingsReport = z.infer<typeof SavingsReportSchema>;
|
package/src/schemas/settings.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { claudeExperimentSettings, iqSearchSettings } from "./settings-experimen
|
|
|
6
6
|
import { CommandJudgeModeSchema, ProjectInstallModeSchema } from "../policy/safety-policy.js";
|
|
7
7
|
import { ModelRoleSchema } from "../models/model-roles.js";
|
|
8
8
|
import { MODEL_SETUP_ID, ModelSetupSchema } from "../models/model-setups.js";
|
|
9
|
-
import { AdmissionPolicySchema, AdmissionRuleSchema } from "./
|
|
9
|
+
import { AdmissionPolicySchema, AdmissionRuleSchema } from "./command-admission.js";
|
|
10
10
|
import { KeepWarmSettingsSchema } from "./keep-warm.js";
|
|
11
11
|
import { LimitHandoffSchema } from "./providers/handoff.js";
|
|
12
12
|
import { SessionsPlacementSchema } from "./offload.js";
|
|
@@ -597,6 +597,11 @@ export const SandboxSettingsSchema = z.object({
|
|
|
597
597
|
.max(10)
|
|
598
598
|
.default(3)
|
|
599
599
|
.describe("How many levels deep the delegation may go, since a subagent can start subagents of its own."),
|
|
600
|
+
// How far off a reset a spawned child's spent turn is booked to re-run by itself (classify-failure.ts); one with fallbacks
|
|
601
|
+
// keeps 90 minutes. 2026-10-18: was a fixed 90 minutes, which ended every child behind a five-hour window.
|
|
602
|
+
childRerunHorizonHours: z.number().int().min(0).max(24).default(6).describe(
|
|
603
|
+
"How long a subagent refused for a spent allowance waits for the provider's reset before it goes again by itself. Past it, or at 0, it stops and its parent hears where else the work can go. One spawned with fallbacks waits at most 90 minutes and then moves to them.",
|
|
604
|
+
),
|
|
600
605
|
// Width again, for a team-chat automation rather than a turn: each thread a message lands in is a conversation of
|
|
601
606
|
// its own, and threads of one automation are worked on side by side up to this many (automations/scheduler.ts in
|
|
602
607
|
// the daemon); one more waits, told it is queued, until a slot frees. Read per fire, so a change holds from the next
|
|
@@ -668,121 +673,8 @@ export type TimezoneState = z.infer<typeof TimezoneStateSchema>;
|
|
|
668
673
|
// from, so a fork from an older build reads as a snapshot.
|
|
669
674
|
export const BuiltinPromptTextSchema = z.object({ text: z.string(), version: z.string() });
|
|
670
675
|
export type BuiltinPromptText = z.infer<typeof BuiltinPromptTextSchema>;
|
|
671
|
-
// What each token-reduction mechanism
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
// Sequential attribution (sums exactly to raw − emitted, drawable as a stacked bar); not what disabling this stage
|
|
675
|
-
// would save, since downstream would eat some of the same lines. Negative for `footer`, which adds cost back.
|
|
676
|
-
export const SavingsStageSchema = z.object({ id: z.string(), commands: z.number(), savedTokens: z.number() });
|
|
677
|
-
// Aggregated from historyRoot/logs/filter-stats.jsonl (one row per Bash command). Windowed on the ledger's own UTC-day
|
|
678
|
-
// calendar, so the reader's date range and these figures agree.
|
|
679
|
-
export const InputSavingsSchema = z.object({
|
|
680
|
-
// Epoch ms of the ledger's last command, so the card can show its age rather than implying freshness.
|
|
681
|
-
updatedAt: z.number().optional(),
|
|
682
|
-
commands: z.number(),
|
|
683
|
-
rawTokens: z.number(),
|
|
684
|
-
emittedTokens: z.number(),
|
|
685
|
-
savedPct: z.number(),
|
|
686
|
-
// Per-stage attribution, biggest first.
|
|
687
|
-
perCleaner: z.array(SavingsStageSchema),
|
|
688
|
-
// The measured control (raw vs. cleaned); the only real whole-pipeline counterfactual, not an estimate.
|
|
689
|
-
holdout: z.object({ cleaned: z.number(), heldOut: z.number(), measuredSavedPct: z.number().optional() }),
|
|
690
|
-
// Grouped by command text: worth a handler is judged by total tokens across runs, not one outlier's size.
|
|
691
|
-
gaps: z.array(z.object({ command: z.string(), commands: z.number(), tokens: z.number() })),
|
|
692
|
-
});
|
|
693
|
-
export type InputSavings = z.infer<typeof InputSavingsSchema>;
|
|
694
|
-
// One arm of a turn-level experiment; mean is per turn, since the two arms never hold the same count.
|
|
695
|
-
// `mean` is over samples capped at both arms' pooled 95th percentile, so one runaway conversation cannot carry an arm.
|
|
696
|
-
// For a yes/no reading (`openedWithListing`) it is the share of yeses, 0 to 1, and uncapped.
|
|
697
|
-
export const SavingsArmSchema = z.object({ turns: z.number(), mean: z.number() });
|
|
698
|
-
// One metric's reading of a turn-level experiment (the two arms, plus the arithmetic over them). `metric` says what
|
|
699
|
-
// `mean`/`deltaPct` count:
|
|
700
|
-
// searchCalls: searches a turn ran (the search teaching).
|
|
701
|
-
// openingSearches: same, narrowed to before the turn first touched a file.
|
|
702
|
-
// openedWithListing: whether a turn listed directories to orient itself, as a share of turns (the project map).
|
|
703
|
-
// callsBeforeTarget: how far a turn walked before touching a file it went on to edit.
|
|
704
|
-
// failedCalls: tool calls that ended in error (the field notes, whose largest section is a failure taxonomy).
|
|
705
|
-
// openingPrompt: tokens a turn's first request sent (cache reads plus cache writes), which is what every later call of
|
|
706
|
-
// the turn reads again (tool search, which moves the tool schemas out of it).
|
|
707
|
-
// openingWrite: tokens a follow-up turn's first request wrote to the cache instead of reading them (the stable prompt).
|
|
708
|
-
// Every reading is the main agent's own: a subagent's calls are counted toward the turn and read for nothing.
|
|
709
|
-
// Never cost: each mechanism moves one small part of a turn's work, inside the noise of the rest. The prompt's size is
|
|
710
|
-
// the exception that proves it: it is the part every call pays again, so it is read directly rather than through cost.
|
|
711
|
-
export const TurnMetricReadingSchema = z.object({
|
|
712
|
-
metric: z.enum(["searchCalls", "openingSearches", "openedWithListing", "callsBeforeTarget", "failedCalls", "openingPrompt", "openingWrite"]),
|
|
713
|
-
on: SavingsArmSchema,
|
|
714
|
-
off: SavingsArmSchema,
|
|
715
|
-
// Additional control turns to reach a fixed target resolution, not today's delta (which inherits noise and always
|
|
716
|
-
// promises "next week"). Absent means nothing to wait for: under `minTurns`, already published, or already resolved
|
|
717
|
-
// enough.
|
|
718
|
-
controlTurnsNeeded: z.number().optional(),
|
|
719
|
-
// ± percentage points at 95% (Welch); present once both arms clear `minTurns`, even when `deltaPct` is withheld —
|
|
720
|
-
// "smaller than ±35 points" is still a useful, true answer.
|
|
721
|
-
marginPct: z.number().optional(),
|
|
722
|
-
// Present only once the margin excludes zero — clearing `minTurns` alone isn't enough, or a wide, unresolved swing
|
|
723
|
-
// reads as a real number.
|
|
724
|
-
// deltaPct: change in the metric's mean per turn; negative is a saving.
|
|
725
|
-
// saved: what that delta was worth over the turns that ran with it, in the metric's own unit.
|
|
726
|
-
deltaPct: z.number().optional(),
|
|
727
|
-
saved: z.number().optional(),
|
|
728
|
-
});
|
|
729
|
-
export type TurnMetricReading = z.infer<typeof TurnMetricReadingSchema>;
|
|
730
|
-
// One coin flip, several readings: `metrics` is a list since splitting readings into separate entries would duplicate
|
|
731
|
-
// the arm assignment. Screens read `metrics[0]` as the headline, the rest as supporting lines.
|
|
732
|
-
export const TurnExperimentSchema = z.object({
|
|
733
|
-
// A head and a tail, not a plain array, so "always a headline" is a type fact, not a check every screen repeats.
|
|
734
|
-
// `.nonempty()` doesn't do this in zod 4 (a runtime check, still typed as a plain array).
|
|
735
|
-
metrics: z.tuple([TurnMetricReadingSchema], TurnMetricReadingSchema),
|
|
736
|
-
// Carried on the wire so "measuring…" reflects the daemon's real threshold, not a guess; shared across every
|
|
737
|
-
// reading, since they're the same turns.
|
|
738
|
-
minTurns: z.number(),
|
|
739
|
-
// Turn mechanisms randomize by turn; session-loaded teaching randomizes whole conversations; a once-sent treatment
|
|
740
|
-
// (the map) samples one turn per conversation, not an average, or its effect divides by the conversation's length.
|
|
741
|
-
sampleUnit: z.enum(["turns", "conversations", "opening turns"]).optional(),
|
|
742
|
-
// Content-addressed treatment version; the reader filters to the latest so two instruction revisions don't blur
|
|
743
|
-
// into one experiment.
|
|
744
|
-
cohort: z.string().optional(),
|
|
745
|
-
// The latest earlier cohort that reached an answer, with only its answered readings (a margin, with or without a
|
|
746
|
-
// delta), so restarting a comparison does not wipe a finding off the screen while the new one is early. `from` and
|
|
747
|
-
// `to` are its first and last measured turn inside the window read, epoch ms. Absent when no earlier one answered.
|
|
748
|
-
previous: z
|
|
749
|
-
.object({ from: z.number(), to: z.number(), cohort: z.string().optional(), metrics: z.array(TurnMetricReadingSchema) })
|
|
750
|
-
.optional(),
|
|
751
|
-
});
|
|
752
|
-
export type TurnExperiment = z.infer<typeof TurnExperimentSchema>;
|
|
753
|
-
// What the settings row can say about the brief without opening it: whether there is one, how much of it this budget
|
|
754
|
-
// reaches, and whether anything is scheduled to rewrite it. Read off the file and the automation store, never stored.
|
|
755
|
-
export const FieldNotesStatusSchema = z.object({
|
|
756
|
-
// False means the automation has never run (or was never set up) — the ordinary state before the first month.
|
|
757
|
-
present: z.boolean(),
|
|
758
|
-
// Epoch ms the file was last written. Absent when there is no file.
|
|
759
|
-
writtenAt: z.number().optional(),
|
|
760
|
-
// How many ranked sections the current budget reaches, out of how many the file holds. The pair is the point: "5"
|
|
761
|
-
// alone cannot tell a generous budget from a short file.
|
|
762
|
-
ranksSent: z.number().optional(),
|
|
763
|
-
ranksTotal: z.number().optional(),
|
|
764
|
-
// What the brief costs the prompt, in characters, at the current budget.
|
|
765
|
-
chars: z.number().optional(),
|
|
766
|
-
// The monthly rewrite: absent until the owner creates it from the offered template, since an automation names the
|
|
767
|
-
// models it spends and nothing chooses those for them.
|
|
768
|
-
automation: z.enum(["missing", "enabled", "disabled"]),
|
|
769
|
-
// When it next runs, epoch ms; absent when there is nothing scheduled.
|
|
770
|
-
nextRunAt: z.number().optional(),
|
|
771
|
-
// Said out loud rather than shown as "no file": a brief that exists and cannot be read is a broken automation.
|
|
772
|
-
unreadable: z.string().optional(),
|
|
773
|
-
});
|
|
774
|
-
export type FieldNotesStatus = z.infer<typeof FieldNotesStatusSchema>;
|
|
775
|
-
export const SavingsReportSchema = z.object({
|
|
776
|
-
input: InputSavingsSchema,
|
|
777
|
-
search: TurnExperimentSchema.optional(),
|
|
778
|
-
// Same absence rule as `search`: not measured, never zero.
|
|
779
|
-
map: TurnExperimentSchema.optional(),
|
|
780
|
-
notes: TurnExperimentSchema.optional(),
|
|
781
|
-
toolSearch: TurnExperimentSchema.optional(),
|
|
782
|
-
stablePrompt: TurnExperimentSchema.optional(),
|
|
783
|
-
coldTrim: TurnExperimentSchema.optional(),
|
|
784
|
-
});
|
|
785
|
-
export type SavingsReport = z.infer<typeof SavingsReportSchema>;
|
|
676
|
+
// What each token-reduction mechanism saved, and the comparisons that measure the turn-level ones, in a file of their own.
|
|
677
|
+
export * from "./settings-savings.js";
|
|
786
678
|
|
|
787
679
|
// ---- what a REPOSITORY declares for itself, at `<repo>/.intentic/checks.json` ----
|
|
788
680
|
// Here rather than in a file of its own because the line between these shapes and the settings above is authority, not
|
package/src/schemas/terminal.ts
CHANGED
|
@@ -219,6 +219,14 @@ export const SubagentVerificationSchema = z.object({
|
|
|
219
219
|
),
|
|
220
220
|
});
|
|
221
221
|
export type SubagentVerification = z.infer<typeof SubagentVerificationSchema>;
|
|
222
|
+
// Where the Claude runtime keeps an in-process subagent's own record: beside the session it ran in, under the runtime's
|
|
223
|
+
// own id for it. The daemon pairs the two while the subagent runs and writes them onto its delegation's card, so the
|
|
224
|
+
// subagent's whole run reads back from that record after a restart, when nothing in memory still knows where it is.
|
|
225
|
+
export const SubagentSdkRecordSchema = z.object({
|
|
226
|
+
sessionId: z.string().describe("The provider session the subagent ran in."),
|
|
227
|
+
agentId: z.string().describe("The runtime's own id for the subagent, which names its record beside that session."),
|
|
228
|
+
});
|
|
229
|
+
export type SubagentSdkRecord = z.infer<typeof SubagentSdkRecordSchema>;
|
|
222
230
|
export const SubagentSessionSchema = z.object({
|
|
223
231
|
id: z
|
|
224
232
|
.string()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// WHAT HAS LOOKED AT A CONVERSATION'S WORK, as its card says it: what its last turn checked of its own work, and the
|
|
4
|
+
// latest code review it reported. Both written by a turn's settle from what the turn did, never asked of the model.
|
|
5
|
+
// Re-exported by agents.ts, whose summary carries them.
|
|
6
|
+
|
|
7
|
+
// What the last turn showed of its own work, read off its tool calls and never asked of the model: the record a card
|
|
8
|
+
// badges instead of sending the turn back to prove anything. CI checks what the owner pushes (schemas/ci.ts).
|
|
9
|
+
export const TurnProofSchema = z.object({
|
|
10
|
+
at: z.number().describe("When the turn that left this ended, in milliseconds."),
|
|
11
|
+
verification: z
|
|
12
|
+
.enum(["verified", "unproven", "failing", "no-code"])
|
|
13
|
+
.describe(
|
|
14
|
+
"Verified: a check it ran passed after its last edit to code. Failing: the last one it ran failed. Unproven: it changed code and ran nothing that checked it. No-code: it changed nothing a check could speak to.",
|
|
15
|
+
),
|
|
16
|
+
check: z.string().optional().describe("The command that spoke, when one did, so a targeted test is never read as the whole suite."),
|
|
17
|
+
unviewed: z
|
|
18
|
+
.number()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("How many rendered files it changed (pages, components, styles) without looking at the result afterwards. Absent when none."),
|
|
21
|
+
});
|
|
22
|
+
export type TurnProof = z.infer<typeof TurnProofSchema>;
|
|
23
|
+
// The latest code review a conversation reported (events/review.ts), counted rather than carried: the findings stay in
|
|
24
|
+
// its chat, where the card that sends them to be fixed draws them. Kept until a later review replaces it, since a turn
|
|
25
|
+
// that reviews nothing has not undone the one before.
|
|
26
|
+
export const ReviewTallySchema = z.object({
|
|
27
|
+
at: z.number().describe("When the turn that reported it ended, in milliseconds."),
|
|
28
|
+
source: z.enum(["claude", "codex"]).describe("Which harness's reviewer reported it."),
|
|
29
|
+
findings: z.number().int().nonnegative().describe("How many findings it reported."),
|
|
30
|
+
open: z
|
|
31
|
+
.number()
|
|
32
|
+
.int()
|
|
33
|
+
.nonnegative()
|
|
34
|
+
.describe("How many of those no re-report has marked fixed or set aside yet. Equal to `findings` until the review is reported again with its fixes applied."),
|
|
35
|
+
});
|
|
36
|
+
export type ReviewTally = z.infer<typeof ReviewTallySchema>;
|
|
@@ -143,6 +143,38 @@ export const WorkspaceMediaTicketSchema = z.object({
|
|
|
143
143
|
ticket: z.string().describe("Hand this to the streaming route in the query string. It buys exactly the one file it was minted for."),
|
|
144
144
|
expiresAt: z.number().describe("When it stops working, in milliseconds, so a player can tell a dead ticket from a dead file."),
|
|
145
145
|
});
|
|
146
|
+
// The long edges a picture is re-encoded at for drawing (GET /workspace/thumb's `size=e<edge>`), smallest first. A reader
|
|
147
|
+
// asks for the smallest one at least as long as the box the picture fills on its screen, device pixels counted, the
|
|
148
|
+
// way a browser picks from a srcset. Steps of about one and a half, so a pick is never much larger than it needs, and
|
|
149
|
+
// few enough that the pictures of a folder seen at several sizes share their renditions.
|
|
150
|
+
export const PICTURE_EDGES = [384, 512, 768, 1024, 1536, 2048] as const;
|
|
151
|
+
export type PictureEdge = (typeof PICTURE_EDGES)[number];
|
|
152
|
+
|
|
153
|
+
// The box each picture or video is drawn in, asked of a folder's worth at once: a gallery lays its rows out from every
|
|
154
|
+
// picture's shape before any of them has loaded, so a row never reflows under the reader as its pictures arrive.
|
|
155
|
+
export const WORKSPACE_DIMENSIONS_MAX = 500;
|
|
156
|
+
export const WorkspaceDimensionsQuerySchema = WorkspaceScopeSchema.extend({
|
|
157
|
+
paths: z
|
|
158
|
+
.array(z.string().min(1))
|
|
159
|
+
.min(1)
|
|
160
|
+
.max(WORKSPACE_DIMENSIONS_MAX)
|
|
161
|
+
.describe("The pictures and videos to measure, as workspace paths. Anything else, or anything unreadable, is left out of the answer."),
|
|
162
|
+
});
|
|
163
|
+
export const WorkspaceDimensionSchema = z.object({
|
|
164
|
+
path: z.string().describe("The path as it was asked for."),
|
|
165
|
+
width: z.number().describe("Width in pixels, as the picture is shown: a phone photo's or a phone video's rotation is already applied."),
|
|
166
|
+
height: z.number().describe("Height in pixels, as the picture is shown."),
|
|
167
|
+
duration: z.number().optional().describe("A video's running time in seconds, where its container says."),
|
|
168
|
+
});
|
|
169
|
+
export type WorkspaceDimension = z.infer<typeof WorkspaceDimensionSchema>;
|
|
170
|
+
export const WorkspaceDimensionsSchema = z.object({
|
|
171
|
+
items: z
|
|
172
|
+
.array(WorkspaceDimensionSchema)
|
|
173
|
+
.describe(
|
|
174
|
+
"One entry per path that could be measured. A path missing here is not a picture this could read, which is an answer, not an error.",
|
|
175
|
+
),
|
|
176
|
+
});
|
|
177
|
+
export type WorkspaceDimensions = z.infer<typeof WorkspaceDimensionsSchema>;
|
|
146
178
|
// Credential for GET /workspace/download, which the browser navigates to so its own download manager streams the archive
|
|
147
179
|
// to disk. The ticket carries the whole selection, resolved when minted, so however many entries it names the URL stays
|
|
148
180
|
// short.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { STATE_DIR } from "@intentic/constants";
|
|
2
|
+
import type { StateFile } from "./state-portability.js";
|
|
3
|
+
import type { WorkspaceStatePath } from "./workspace-state.js";
|
|
4
|
+
|
|
5
|
+
// The auth root holds AI-provider logins, the sandbox's secret vaults and the trust files a turn must not edit (mode
|
|
6
|
+
// 0600, off the file routes, tree walk and search index). It lives at `.intentic/secrets/auth/` unless AGENT_AUTH_DIR
|
|
7
|
+
// moved it, and the workspace table names it once, as a `secret` directory. This table classifies what is inside, so
|
|
8
|
+
// an export does not carry this sandbox's own keys and pairings with the credentials, and does not drop the owner's
|
|
9
|
+
// restrictions with them either. auth-state-coverage.test.ts in the daemon keeps it complete.
|
|
10
|
+
//
|
|
11
|
+
// The default for a path no entry claims is `secret`, the class of the directory itself: a provider home (`claude/`,
|
|
12
|
+
// `codex/`, `cliproxy/`, `opencode/`…) is a login, and a new provider lands secret by construction.
|
|
13
|
+
//
|
|
14
|
+
// The classes follow the history table's precedent. A restriction the owner set is `carry`: a secret that travels must
|
|
15
|
+
// not arrive ungated. A yes the owner gave (a grant, a release, a widened rule) is `identity`, like the hook and extension
|
|
16
|
+
// approvals there: a trust decision the target's owner makes again.
|
|
17
|
+
|
|
18
|
+
// Where the auth root sits inside the workspace when AGENT_AUTH_DIR does not move it; a declared workspace path.
|
|
19
|
+
export const AUTH_ROOT_IN_WORKSPACE = `${STATE_DIR}/secrets/auth/` as const satisfies WorkspaceStatePath;
|
|
20
|
+
|
|
21
|
+
// Auth-root-relative paths, forward-slash, matched by prefix; a directory keeps its trailing slash.
|
|
22
|
+
export const AUTH_STATE_FILES: readonly StateFile[] = [
|
|
23
|
+
/* ---- the owner's restrictions: no credential in them, and loosened if left behind ---- */
|
|
24
|
+
|
|
25
|
+
// Which credentials need a named person's click (secrets/credential-gates.ts).
|
|
26
|
+
{ path: "credential-gates.json", portability: "carry" },
|
|
27
|
+
// Where each secret may be sent (secrets/guards/host-guards.ts).
|
|
28
|
+
{ path: "secret-hosts.json", portability: "carry" },
|
|
29
|
+
// The privacy shield's policy: whether it masks, what it looks for, which providers it trusts.
|
|
30
|
+
{ path: "privacy-shield.json", portability: "carry" },
|
|
31
|
+
// The execution boundary agents run in (workload/domain/agent-domain-policy.ts).
|
|
32
|
+
{ path: "agent-domain.json", portability: "carry" },
|
|
33
|
+
|
|
34
|
+
/* ---- credentials and what holds their values ---- */
|
|
35
|
+
|
|
36
|
+
{ path: "sandbox-secrets.json", portability: "secret" },
|
|
37
|
+
{ path: "capability-secrets.json", portability: "secret" },
|
|
38
|
+
{ path: "extension-secrets.json", portability: "secret" },
|
|
39
|
+
// The personal data the shield masked, by token, and the pictures it painted over.
|
|
40
|
+
{ path: "privacy-vault.json", portability: "secret" },
|
|
41
|
+
{ path: "privacy-images/", portability: "secret" },
|
|
42
|
+
{ path: "ssh-keys/", portability: "secret" },
|
|
43
|
+
// An update's pre-images of the files above; a vault's copy is a vault.
|
|
44
|
+
{ path: "converting/", portability: "secret" },
|
|
45
|
+
|
|
46
|
+
/* ---- yeses the owner gave here: decided again on the target ---- */
|
|
47
|
+
|
|
48
|
+
// Sandbox-wide permissions ("Always: <line>") and each conversation's own (personas/owner-grants.ts,
|
|
49
|
+
// conversation-grants.ts); a conversation's card simply asks again, so only the sandbox-wide ones carry a note.
|
|
50
|
+
{ path: "owner-grants.json", portability: "identity", note: "Give sandbox-wide permissions again from the Access tab." },
|
|
51
|
+
{ path: "conversation-grants.json", portability: "identity" },
|
|
52
|
+
// An approver's release of a gated credential for one conversation.
|
|
53
|
+
{ path: "credential-releases.json", portability: "identity" },
|
|
54
|
+
// Programs a secret may be typed into unasked; unset, every typing asks.
|
|
55
|
+
{ path: "secret-programs.json", portability: "identity", note: "Allow programs to receive secrets again from Secrets." },
|
|
56
|
+
// Per-card credential rules and raw delivery, the owner's widening of a connector's own rules.
|
|
57
|
+
{ path: "credential-policy.json", portability: "identity", note: "Set a connection's credential rules and delivery again from Capabilities." },
|
|
58
|
+
|
|
59
|
+
/* ---- this sandbox's own keys, and what it is paired with ---- */
|
|
60
|
+
|
|
61
|
+
// The keyring keypair the owner's computers pinned their shares to; only the public halves ever leave.
|
|
62
|
+
{ path: "keyring-keys.json", portability: "identity", note: "Passwords shared from your computers are shared again with the new sandbox." },
|
|
63
|
+
// What each connected computer's keyring said, the entries copied to this sandbox's key, deliveries waiting for a
|
|
64
|
+
// computer, and the needs raised to them.
|
|
65
|
+
{ path: "keyring-devices.json", portability: "identity" },
|
|
66
|
+
{ path: "keyring-copies.json", portability: "identity" },
|
|
67
|
+
{ path: "keyring-sync-mailbox.json", portability: "identity" },
|
|
68
|
+
{ path: "keyring-needs.json", portability: "identity" },
|
|
69
|
+
// The credential broker's signing key and the privacy gateway's token key, each minted on first use.
|
|
70
|
+
{ path: "broker-session.key", portability: "identity" },
|
|
71
|
+
{ path: "privacy-gateway.key", portability: "identity" },
|
|
72
|
+
// The organisation policy the platform hands this sandbox; the target's platform hands its own.
|
|
73
|
+
{ path: "org-policy.json", portability: "identity" },
|
|
74
|
+
|
|
75
|
+
/* ---- regenerated by the target ---- */
|
|
76
|
+
|
|
77
|
+
// Seat refusals the provider answered, and the model catalogs fetched for each runtime.
|
|
78
|
+
{ path: "claude/seats.json", portability: "derived" },
|
|
79
|
+
{ path: "claude/models.json", portability: "derived" },
|
|
80
|
+
{ path: "cursor/models.json", portability: "derived" },
|
|
81
|
+
{ path: "devin/models.json", portability: "derived" },
|
|
82
|
+
{ path: "gemini/models.json", portability: "derived" },
|
|
83
|
+
// Each custom endpoint's last discovered model list, fetched again from the endpoint.
|
|
84
|
+
{ path: "endpoints/", portability: "derived" },
|
|
85
|
+
// Values a computer released for one use each, for masking only; never outlive the process handed them.
|
|
86
|
+
{ path: "keyring-released.json", portability: "derived" },
|
|
87
|
+
// The shell script and socket OpenCode runs commands through, written at boot.
|
|
88
|
+
{ path: "opencode-shell/", portability: "derived" },
|
|
89
|
+
];
|
|
@@ -25,6 +25,14 @@ export const HISTORY_STATE_FILES: readonly StateFile[] = [
|
|
|
25
25
|
// The tasks this sandbox's conversations handed to linked sandboxes (links/linked-children.ts), followed until they
|
|
26
26
|
// settle: part of the conversations' own record, so it goes where they go.
|
|
27
27
|
{ path: "links/linked-children.json", portability: "carry" },
|
|
28
|
+
// One file per agent a conversation spawned (agent/subagents/spawned-children.ts): what its parent supervises it by
|
|
29
|
+
// (its run, session, last report and result), read back at boot so a restart does not orphan it. Part of the
|
|
30
|
+
// conversations' own record, so it goes where they go.
|
|
31
|
+
{ path: "spawned-children/", portability: "carry" },
|
|
32
|
+
// One file per workflow run a conversation started (agent/subagents/workflows/script-runs.ts): its script, its calls and what
|
|
33
|
+
// each handed back, so a restart picks it up where it was and a later run can resume from its finished calls. Part of
|
|
34
|
+
// the conversations' own record, so it goes where they go.
|
|
35
|
+
{ path: "script-runs/", portability: "carry" },
|
|
28
36
|
// The long tool outputs those transcripts name rather than hold, stored once by content for every record naming
|
|
29
37
|
// them; a transcript without them keeps only each output's start.
|
|
30
38
|
{ path: "blobs/", portability: "carry" },
|
|
@@ -48,6 +56,10 @@ export const HISTORY_STATE_FILES: readonly StateFile[] = [
|
|
|
48
56
|
{ path: "audit/", portability: "carry" },
|
|
49
57
|
{ path: "usage.jsonl", portability: "carry" },
|
|
50
58
|
{ path: "account-usage.json", portability: "carry" },
|
|
59
|
+
// What each provider's usage answers have been made of (their paths, and one redacted sample), so an answer that
|
|
60
|
+
// changes is noticed. Carried: the provider answers the same wherever the sandbox runs, and a fresh record would
|
|
61
|
+
// take the next changed answer as the first one.
|
|
62
|
+
{ path: "provider-answers.json", portability: "carry" },
|
|
51
63
|
// Per-account stay-away for a provider's usage endpoint. Carried, not re-earned: earning one costs the very read it
|
|
52
64
|
// holds off, and is answered with a deadline measured from that moment. Entries past their instant are inert.
|
|
53
65
|
{ path: "usage-parks.json", portability: "carry" },
|
|
@@ -71,6 +83,14 @@ export const HISTORY_STATE_FILES: readonly StateFile[] = [
|
|
|
71
83
|
{ path: "apply-events.ndjson", portability: "carry" },
|
|
72
84
|
{ path: "check-events/", portability: "carry" },
|
|
73
85
|
|
|
86
|
+
// User-started operator panels resume on this sandbox after a restart; a moved sandbox starts inert.
|
|
87
|
+
{ path: "panels.json", portability: "derived" },
|
|
88
|
+
// Receipts name kept commands lost with container-local capture storage; never replay arbitrary commands.
|
|
89
|
+
{ path: "kept-jobs/", portability: "derived" },
|
|
90
|
+
// The last hour's turns `agents message` and each link started (the daemon's store/start-window.ts), so a restart does
|
|
91
|
+
// not reopen their hourly ceilings; a moved sandbox starts its hour afresh.
|
|
92
|
+
{ path: "turn-starts.json", portability: "derived" },
|
|
93
|
+
|
|
74
94
|
/* ---- regenerated by the target ---- */
|
|
75
95
|
|
|
76
96
|
// Deliberately omitted: the branch lives in gits/, the registry in conversations.db; regenerated on the next turn.
|
|
@@ -185,7 +205,11 @@ export const HISTORY_STATE_FILES: readonly StateFile[] = [
|
|
|
185
205
|
portability: "identity",
|
|
186
206
|
note: "Re-invite collaborators from the Access tab, a grant is the platform's record, and the target enforces its own copy.",
|
|
187
207
|
},
|
|
188
|
-
{
|
|
208
|
+
{
|
|
209
|
+
path: "identity/control-tokens.json",
|
|
210
|
+
portability: "identity",
|
|
211
|
+
note: "Mint fresh control tokens, the old ones authenticate against the source sandbox.",
|
|
212
|
+
},
|
|
189
213
|
// The links other sandboxes hand this one tasks through (links/inbound-links.ts): hashed tokens like the control
|
|
190
214
|
// tokens, each minted here, and the tasks filed under them; elsewhere they would let the paired sandboxes reach the
|
|
191
215
|
// target in this one's name.
|
|
@@ -223,6 +247,9 @@ export const HISTORY_STATE_FILES: readonly StateFile[] = [
|
|
|
223
247
|
{ path: "phone-enrollments.json", portability: "identity", note: "Pair your phone again from its card: the app is still installed." },
|
|
224
248
|
{ path: "phone-pair-consumed.json", portability: "identity" },
|
|
225
249
|
{ path: "phone-wake.json", portability: "identity" },
|
|
250
|
+
// Which computers' keyrings each phone paired with for Passwords (phones/phone-pairings.ts): a shortcut over the
|
|
251
|
+
// keyrings' own pinned keys, keyed by phones paired to this sandbox, so it stays with the pairings above.
|
|
252
|
+
{ path: "phone-pairings.json", portability: "identity" },
|
|
226
253
|
// Setup-device pairing burn list; carrying it would mark another sandbox's fresh pairing as spent.
|
|
227
254
|
{ path: "host-pair-consumed.json", portability: "identity" },
|
|
228
255
|
// Lands waiting for the computer whose folder they go to, and which computer last held each attached folder
|
|
@@ -256,6 +283,11 @@ export const HISTORY_STATE_FILES: readonly StateFile[] = [
|
|
|
256
283
|
// person, since the key that signed it stays behind.
|
|
257
284
|
{ path: "automation-holds/", portability: "carry" },
|
|
258
285
|
{ path: "automation-holds.key", portability: "identity", note: "A held wake that was counting down arrives waiting for your yes instead." },
|
|
286
|
+
// What waits for an automation fire not journalled yet (the daemon's automations/durable/inbox-store.ts): a channel
|
|
287
|
+
// message in its debounce or behind a running fire, a workspace event behind its chore. Travels with the turn journal
|
|
288
|
+
// in conversations.db, which names the rows a fire already took.
|
|
289
|
+
{ path: "automation-listener-inbox.json", portability: "carry" },
|
|
290
|
+
{ path: "automation-workspace-inbox.json", portability: "carry" },
|
|
259
291
|
{ path: "local-cert/", portability: "identity" },
|
|
260
292
|
|
|
261
293
|
/* ---- the state engine's own bookkeeping (the daemon's store/evolution/state-journal.ts) ---- */
|
|
@@ -267,4 +299,15 @@ export const HISTORY_STATE_FILES: readonly StateFile[] = [
|
|
|
267
299
|
// Every conversation the import of the pre-1.308 layout settled (the daemon's conversations/registry/pre-1308-import.ts),
|
|
268
300
|
// so one deleted after its import is not brought back from the old files still on disk. About this volume only.
|
|
269
301
|
{ path: "pre-1308-import.json", portability: "derived" },
|
|
302
|
+
|
|
303
|
+
/* ---- written beside the daemon, by the image, the host's ic and the package manager ---- */
|
|
304
|
+
|
|
305
|
+
// The terminal's typed history (the image's HISTFILE, made by docker-entrypoint.sh): the owner's own, kept so its
|
|
306
|
+
// suggestions survive a rebuild. `secret`, since a typed line can hold a pasted token.
|
|
307
|
+
{ path: "shell/", portability: "secret" },
|
|
308
|
+
// ic's copy of its records for this sandbox (ic's sandbox/mirror.rs): its channel and rollback target, the machine
|
|
309
|
+
// that keeps it, its backups and repairs. About the machine it runs on, so the target's ic writes its own.
|
|
310
|
+
{ path: ".ic/", portability: "identity" },
|
|
311
|
+
// pnpm's package store for installs in a checkout under /history, kept at the top of the mount pnpm finds it on.
|
|
312
|
+
{ path: ".pnpm-store/", portability: "derived" },
|
|
270
313
|
];
|
|
@@ -53,10 +53,11 @@ const RUNTIME_DOMAINS = [
|
|
|
53
53
|
// Commit subject drafted after landing; arrives too late for the turn-end refresh, needs its own push.
|
|
54
54
|
{ domain: "landings", invalidates: [["git", "changes"]] },
|
|
55
55
|
|
|
56
|
-
// A pipeline run
|
|
57
|
-
// poll is the freshness floor, not the answer: somebody watching a run
|
|
58
|
-
// Runs only: the frame doesn't name which run moved, and re-reading every open
|
|
59
|
-
// vendor call per row.
|
|
56
|
+
// A pipeline run or one of its jobs moved: every webhook delivery, in flight or ended (2026-10-20), or the REST poll
|
|
57
|
+
// for a repo with no hook. The board's own poll is the freshness floor, not the answer: somebody watching a run
|
|
58
|
+
// must not wait out a poll interval. Runs only: the frame doesn't name which run moved, and re-reading every open
|
|
59
|
+
// row's job graph would cost a vendor call per row. An open in-flight row re-reads its own graph when the board's
|
|
60
|
+
// runs land (useRunJobs.ts); the daemon's CI-shaped watches recheck on it too (watchers.ts).
|
|
60
61
|
{ domain: "ci", invalidates: [["ci-runs"]] },
|
|
61
62
|
|
|
62
63
|
// An engine install starting or ending, whoever started it; the card's only feed, since a read costs registry calls.
|