@getmarrow/install 0.1.20 → 0.1.21

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.
Files changed (3) hide show
  1. package/README.md +42 -101
  2. package/package.json +1 -3
  3. package/src/installer.js +62 -21
package/README.md CHANGED
@@ -9,65 +9,24 @@ npx @getmarrow/install --dry-run
9
9
  npx @getmarrow/install --yes
10
10
  npx @getmarrow/install --repair
11
11
  npx @getmarrow/install doctor
12
- npx @getmarrow/install fleet
13
12
  ```
14
13
 
15
- ## What's New in v0.1.20
14
+ ## What's New in v0.1.21
16
15
 
17
- v0.1.20 adds the Fleet Operator TUI for teams running multiple agents under one Marrow account.
16
+ v0.1.21 makes token value proof part of the default install path.
18
17
 
19
- - `npx @getmarrow/install fleet` opens a terminal operator view when run in a real TTY.
20
- - CI/headless agents can use `npx @getmarrow/install fleet --no-interactive` for a stable text snapshot or `--json` for machine-readable status.
21
- - The view shows live agents, active workflows, risky actions waiting for proof, failed/stale outcomes, backpressure/capacity status, recent decisions, degraded hooks, and deploy/publish/merge gate posture.
22
- - Operators can press Enter to inspect an agent and print the exact fix command when hooks, outcome closure, or status coverage is degraded.
23
- - The command reads existing Marrow account endpoints and degrades gracefully when a route is unavailable, so it is safe to use during incidents.
18
+ - Generated passive runtimes enable compact model-usage capture by default with `captureModelUsage`.
19
+ - First-run self-test calls `/v1/agent/value/proof` and prints a `Token value proof` block.
20
+ - Fresh accounts show token capture as active and warming up; accounts with observed model calls show calls, tokens, estimated savings, confidence, and next action.
21
+ - Provider usage capture stores compact metadata only: provider, model, token counts, latency, cost estimate, workflow/decision linkage, and Marrow intervention type.
22
+ - Marrow does not store prompts, completions, tool stdout/stderr, plaintext API keys, or raw model output for this feature.
23
+ - Disable only when required with `MARROW_PASSIVE_TOKEN_USAGE=false`.
24
24
 
25
- Example:
25
+ Business value: new users should see from day one whether Marrow is capturing the signals needed to prove token/time savings over workflows, tasks, and builds.
26
26
 
27
- ```bash
28
- MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install fleet
29
- MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install fleet --no-interactive
30
- MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install fleet --json
31
- ```
32
-
33
- ## What's New in v0.1.14
34
-
35
- v0.1.14 adds adaptive governance mode recommendations without silent auto-switching.
36
-
37
- - `npx @getmarrow/install govern` now detects project signals such as `package.json`, deploy/publish scripts, `wrangler` config, GitHub workflows, migrations, Cursor/Codex/Claude files, and MCP config.
38
- - When `MARROW_API_KEY` is present, the TUI asks Marrow for a recommended mode: `passive`, `pilot`, or `enforce`.
39
- - The TUI shows the exact reasons, confidence, and selected command before the user applies anything.
40
- - User choice is explicit. Marrow logs whether the recommendation was accepted or overridden, but it does not silently switch modes.
41
- - Policy profiles are supported by the backend/SDK/MCP so businesses can define rules like local=passive, staging=pilot, production deploys=enforce.
42
-
43
- Example recommendation:
44
-
45
- ```text
46
- Recommended mode: pilot
47
- Reason:
48
- - Node project detected
49
- - Cloudflare Worker detected
50
- - GitHub workflow detected
51
- - No owner approval policy configured yet
52
- ```
53
-
54
- ## What's New in v0.1.13
55
-
56
- v0.1.13 turns `npx @getmarrow/install govern` into an interactive terminal setup flow when run in a real TTY.
57
-
58
- - Select Codex, Claude Code, Cursor, OpenCode, OpenClaw, CI scripts, or a custom command with arrow keys.
59
- - Choose passive setup, governed pilot mode, or governed enforce mode.
60
- - Run passive setup + self-test from the TUI after explicit confirmation.
61
- - Check Marrow status and test the before-action gate from the same screen.
62
- - Print the exact command for the selected harness/mode so users know what to run next.
63
- - Exit cleanly with `q`, `Esc`, or `Ctrl+C`.
64
- - CI/non-TTY usage remains stable with `npx @getmarrow/install govern --no-interactive`.
27
+ ## Governed Runner
65
28
 
66
- This keeps Marrow passive-first: install once, verify Marrow is active, then let agents use the runtime/gate path automatically for risky work.
67
-
68
- ## What's New in v0.1.12
69
-
70
- v0.1.12 adds the Marrow governed runner for businesses that want agent governance without replacing their existing harness.
29
+ The Marrow governed runner is for businesses that want agent governance without replacing their existing harness.
71
30
 
72
31
  - `npx @getmarrow/install govern` prints a setup panel for detected harnesses and recommended protected commands.
73
32
  - `npx @getmarrow/install run --agent <agent-id> -- <command>` wraps existing agent, deploy, merge, publish, migration, and verification commands with Marrow's pre-action runtime gate.
@@ -86,12 +45,6 @@ Preview the detected harnesses and protected command examples:
86
45
  npx @getmarrow/install govern
87
46
  ```
88
47
 
89
- In a real terminal, this opens the interactive setup flow. In CI or scripts, use:
90
-
91
- ```bash
92
- npx @getmarrow/install govern --no-interactive
93
- ```
94
-
95
48
  Run a harmless command through Marrow:
96
49
 
97
50
  ```bash
@@ -117,15 +70,6 @@ MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install run \
117
70
 
118
71
  Use `--policy warn` for pilot mode and `--fail-open` only for non-production local workflows where Marrow should never block execution.
119
72
 
120
- ## What's New in v0.1.10
121
-
122
- - First-run output now explains the value in agent/user language: your agent is no longer starting from zero.
123
- - Self-test prints first proof: setup decision captured, outcome closed, runtime gate active, and risky work now gets a pre-action brief.
124
- - Fresh accounts get a guided prompt to try immediately: "I am about to deploy to production. What should I check first?"
125
- - Existing accounts/fleets show stronger proof when available: avoided mistakes, reused winning decisions, prevented risky actions, and token/time savings.
126
- - Generated SDK passive runtime now fails soft if `@getmarrow/sdk` is missing and the installer prints the exact dependency fix.
127
- - Docs now make the universal installer the default path; SDK and MCP are advanced/manual integration paths.
128
-
129
73
  ## Which Install Path Should I Use?
130
74
 
131
75
  Start here unless you already know you need a lower-level integration:
@@ -158,7 +102,9 @@ Expected result:
158
102
  - `/v1/agent/status` confirms capture health and missing hooks.
159
103
  - `/v1/agent/runtime` verifies the one-call runtime gate and returns the before-action intervention contract.
160
104
  - `/v1/agent/first-value` returns the five-minute proof payload used by installer, SDK, and MCP clients.
105
+ - `/v1/agent/value/proof` returns token value proof from passive model-usage capture.
161
106
  - The installer prints: "Your agent is no longer starting from zero."
107
+ - The installer prints: "Token value proof" with capture status, observed model calls, token totals, estimated savings, confidence, and exact next action.
162
108
  - Fresh accounts get a first useful action to try immediately.
163
109
  - Accounts with history get proof such as avoided mistakes, reused winning decisions, prevented risky actions, or estimated time/token savings.
164
110
 
@@ -172,39 +118,6 @@ I am about to deploy to production. What should I check first?
172
118
 
173
119
  Marrow should answer with `proceed`, `warn`, `block`, or `owner_approval_required`, plus required proof and matching fleet lessons/playbooks before the agent acts. This is the first product moment: not just "hooks installed", but "the agent is being warned before risky work."
174
120
 
175
- ## Fleet Scale Startup Guidance
176
-
177
- For business fleets, agents can read `GET /v1/agent/scale/capacity-contract` after install or during startup. The capacity contract tells the agent whether the account is under backpressure, when low-risk runtime guidance can be reused, when high-risk actions must still call Marrow, and how to batch low-risk telemetry through `/v1/agent/ingest/batch`.
178
-
179
- This keeps Marrow passive without making it chatty. The current contract models the common `50 businesses x 50 agents = 2,500 agents` rollout shape and gives agents an exact next action: cache low-risk runtime guidance briefly, batch command/tool telemetry, and preserve proof-gated checks for deploys, publishes, merges, migrations, secrets, billing, and destructive work.
180
-
181
- ## Fleet Operator TUI
182
-
183
- Use the operator TUI when a human owner or orchestrator agent needs to understand fleet health before acting:
184
-
185
- ```bash
186
- MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install fleet
187
- ```
188
-
189
- It shows:
190
-
191
- - live agents and selected agent inspection
192
- - active workflows
193
- - risky actions waiting for proof
194
- - failed or stale outcomes
195
- - backpressure and capacity guidance
196
- - recent decisions
197
- - degraded hooks
198
- - deploy, publish, and merge gate status
199
- - exact fix commands for common degraded states
200
-
201
- For automated reports or headless agents:
202
-
203
- ```bash
204
- MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install fleet --no-interactive
205
- MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install fleet --json
206
- ```
207
-
208
121
  ## What It Detects
209
122
 
210
123
  - OpenClaw-style workspaces
@@ -237,7 +150,7 @@ npx @getmarrow/install --md --dry-run
237
150
 
238
151
  ## Self-Test
239
152
 
240
- When `MARROW_API_KEY` is present, the installer creates a harmless test decision, commits the outcome, reads `/v1/agent/status`, calls the one-call runtime, and prints the first useful Marrow signal.
153
+ When `MARROW_API_KEY` is present, the installer creates a harmless test decision, commits the outcome, reads `/v1/agent/status`, calls the one-call runtime, reads `/v1/agent/value/proof`, and prints the first useful Marrow signal plus token value proof.
241
154
 
242
155
  ```bash
243
156
  MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install --yes
@@ -271,6 +184,34 @@ npm install @getmarrow/sdk
271
184
 
272
185
  The generated runtime now fails soft with an explicit warning if the SDK package is missing, so onboarding does not crash a user process.
273
186
 
187
+ ## Passive Token Value Proof
188
+
189
+ Token value proof is default-on when the installer writes `.marrow/passive-runtime.mjs`.
190
+
191
+ In supported Node/TypeScript agents, the SDK passive runtime wraps outbound model-provider `fetch` responses and captures compact `usage` blocks when providers return them. MCP and harness integrations can also attach `model_usage` to `marrow_commit` or call `marrow_model_usage` when the harness exposes usage metadata.
192
+
193
+ Captured fields are intentionally narrow:
194
+
195
+ - provider and model
196
+ - input, output, cached, and total token counts
197
+ - optional cost and latency estimates
198
+ - agent, workflow, session, and decision linkage
199
+ - Marrow intervention type, such as `runtime_gate`, `proof_pack`, or `before_you_act`
200
+
201
+ Marrow does not capture prompt text, completion text, raw tool output, command output, full environment values, or plaintext secrets for token value proof.
202
+
203
+ Disable capture only when a project requires it:
204
+
205
+ ```bash
206
+ MARROW_PASSIVE_TOKEN_USAGE=false
207
+ ```
208
+
209
+ Day-one behavior:
210
+
211
+ - Fresh install: `Token usage capture is ready; no model calls have been reported yet.`
212
+ - After observed usage: Marrow reports model calls, total tokens, estimated tokens saved, confidence, trend, and next action.
213
+ - After workflows complete: agents should show the returned `token_value_signal` or value proof in owner updates so users see savings without opening a dashboard.
214
+
274
215
 
275
216
  ## Trust and Data Boundaries
276
217
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getmarrow/install",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Universal installer for Marrow passive agent setup.",
5
5
  "bin": {
6
6
  "marrow-install": "bin/marrow-install.js"
@@ -15,8 +15,6 @@
15
15
  "marrow",
16
16
  "mcp",
17
17
  "installer",
18
- "governance",
19
- "runner",
20
18
  "passive-runtime"
21
19
  ],
22
20
  "repository": {
package/src/installer.js CHANGED
@@ -105,12 +105,6 @@ function findUp(startDir, names, maxDepth = 8) {
105
105
  }
106
106
 
107
107
  function projectRoot(startDir) {
108
- const resolved = path.resolve(startDir);
109
- if (path.basename(resolved) === '.marrow') return path.dirname(resolved);
110
- if (path.basename(resolved) === 'env' && path.basename(path.dirname(resolved)) === '.marrow') {
111
- return path.dirname(path.dirname(resolved));
112
- }
113
- if (exists(path.join(resolved, '.marrow'))) return resolved;
114
108
  const marker = findUp(startDir, ['package.json', 'pyproject.toml', 'requirements.txt', '.git', 'AGENTS.md', 'CLAUDE.md']);
115
109
  return marker ? path.dirname(marker) : path.resolve(startDir);
116
110
  }
@@ -289,7 +283,8 @@ Marrow should run passively after install:
289
283
 
290
284
  - Use MCP hooks when available: \`npx -y @getmarrow/mcp setup\`.
291
285
  - Use SDK passive runtime in owned Node processes: \`createPassiveRuntime().install()\`.
292
- - Before risky work, use Marrow's before-action intervention from \`GET /v1/agent/status\` or \`POST /v1/agent/runtime\`.
286
+ - Keep passive token/model usage proof enabled so Marrow can show token, cost, latency, and workflow savings after real work completes.
287
+ - Before risky work, use Marrow's decision brief or passive prompt hook.
293
288
  - After meaningful work, record the outcome so future agents learn from it.
294
289
  - Check health with \`marrow_agent_status\` or \`GET /v1/agent/status\`.
295
290
 
@@ -297,6 +292,7 @@ Required environment:
297
292
 
298
293
  - \`MARROW_API_KEY\`
299
294
  - Optional: \`MARROW_BASE_URL\`, \`MARROW_FLEET_AGENT_ID\`
295
+ - Optional: \`MARROW_PASSIVE_TOKEN_USAGE=false\` disables compact provider usage capture when needed.
300
296
  ${MARROW_BLOCK_END}`;
301
297
  }
302
298
 
@@ -318,6 +314,7 @@ if (apiKey && !globalThis.__MARROW_PASSIVE_RUNTIME__) {
318
314
  useAgentRuntime: process.env.MARROW_AGENT_RUNTIME !== 'false',
319
315
  useWorkflowGate: process.env.MARROW_WORKFLOW_GATE !== 'false',
320
316
  requireOutcomeClosure: process.env.MARROW_REQUIRE_OUTCOME_CLOSURE !== 'false',
317
+ captureModelUsage: process.env.MARROW_PASSIVE_TOKEN_USAGE !== 'false',
321
318
  });
322
319
 
323
320
  runtime.install();
@@ -339,6 +336,7 @@ MARROW_PASSIVE_VALUE_REPORT=true
339
336
  MARROW_AGENT_RUNTIME=true
340
337
  MARROW_WORKFLOW_GATE=true
341
338
  MARROW_REQUIRE_OUTCOME_CLOSURE=true
339
+ MARROW_PASSIVE_TOKEN_USAGE=true
342
340
  `;
343
341
  }
344
342
 
@@ -633,8 +631,14 @@ async function runSelfTest(options) {
633
631
  ok: false,
634
632
  error: error instanceof Error ? error.message : String(error),
635
633
  }));
636
- const firstValueSignal = buildFirstValueSignal(status, runtime, performance, firstValue);
637
- const installValueMoment = buildInstallValueMoment(firstValueSignal, status, runtime, performance, firstValue);
634
+ const valueProof = await requestJson(`${baseUrl}/v1/agent/value/proof?period_days=30`, { headers })
635
+ .catch((error) => ({
636
+ ok: false,
637
+ error: error instanceof Error ? error.message : String(error),
638
+ }));
639
+ const tokenValueProof = buildTokenValueProof(valueProof);
640
+ const firstValueSignal = buildFirstValueSignal(status, runtime, performance, firstValue, tokenValueProof);
641
+ const installValueMoment = buildInstallValueMoment(firstValueSignal, status, runtime, performance, firstValue, tokenValueProof);
638
642
  return {
639
643
  skipped: false,
640
644
  decision_id: decisionId,
@@ -646,11 +650,11 @@ async function runSelfTest(options) {
646
650
  auto_outcome_closure: status.auto_outcome_closure || null,
647
651
  runtime_active: Boolean(runtime && runtime.ok !== false),
648
652
  runtime_exact_next_action: runtime.exact_next_action || null,
649
- runtime_before_you_act: runtime.intervention?.agent_copy || runtime.intervention?.before_action || runtime.before_you_act || null,
650
- runtime_intervention: runtime.intervention || null,
653
+ runtime_before_you_act: runtime.before_you_act || null,
651
654
  first_value: firstValue && firstValue.ok !== false ? firstValue : null,
652
655
  first_value_signal: firstValueSignal,
653
656
  install_value_moment: installValueMoment,
657
+ token_value_proof: tokenValueProof,
654
658
  performance_proof: performance && performance.ok !== false ? {
655
659
  avoided_mistakes: performance.avoided_mistakes ?? performance.avoided_repeated_mistakes ?? 0,
656
660
  reused_winning_decisions: performance.reused_winning_decisions ?? 0,
@@ -662,11 +666,30 @@ async function runSelfTest(options) {
662
666
  };
663
667
  }
664
668
 
665
- function buildInstallValueMoment(firstValueSignal = {}, status = {}, runtime = {}, performance = {}, firstValue = {}) {
669
+ function buildTokenValueProof(valueProof = {}) {
670
+ const modelUsage = valueProof && valueProof.ok !== false
671
+ ? valueProof.model_usage || valueProof.token_value_signal || valueProof
672
+ : null;
673
+ if (!modelUsage || typeof modelUsage !== 'object') {
674
+ return {
675
+ enabled: true,
676
+ capture_default: 'on_when_sdk_mcp_or_installer_hooks_available',
677
+ observed: { model_calls: 0, tokens: { total: 0 } },
678
+ savings: { estimated_tokens_saved: 0, estimated_minutes_saved: 0, confidence: 'none', method: 'warming_up' },
679
+ proof_line: 'Token usage capture is ready; no model calls have been reported yet.',
680
+ exact_next_action: 'Keep passive token capture enabled so Marrow can attach usage proof after real model calls complete.',
681
+ };
682
+ }
683
+ return modelUsage;
684
+ }
685
+
686
+ function buildInstallValueMoment(firstValueSignal = {}, status = {}, runtime = {}, performance = {}, firstValue = {}, tokenValueProof = null) {
666
687
  if (firstValue && firstValue.ok !== false && firstValue.first_value) {
688
+ const proof = Array.isArray(firstValue.first_value.proof) ? [...firstValue.first_value.proof] : [];
689
+ if (tokenValueProof?.proof_line && !proof.includes(tokenValueProof.proof_line)) proof.push(tokenValueProof.proof_line);
667
690
  return {
668
691
  headline: firstValue.headline || firstValue.first_value.headline || 'Your agent is no longer starting from zero.',
669
- proof: Array.isArray(firstValue.first_value.proof) ? firstValue.first_value.proof : [],
692
+ proof,
670
693
  fleet_signal: firstValue.history_signal?.summary || 'Fresh account: Marrow will build fleet memory from this first captured outcome.',
671
694
  try_this_now: firstValue.first_value.try_this_now || 'Ask your agent: "I am about to deploy to production. What should I check first?"',
672
695
  expected_response: firstValue.first_value.expected_response || 'Marrow should answer with a risk gate, required proof, and any matching fleet lessons before the agent acts.',
@@ -676,9 +699,7 @@ function buildInstallValueMoment(firstValueSignal = {}, status = {}, runtime = {
676
699
 
677
700
  const proof = firstValueSignal.value_proof || [];
678
701
  const hasFleetSignal = proof.length > 0;
679
- const runtimeLesson = runtime.intervention?.agent_copy
680
- || runtime.intervention?.before_action
681
- || runtime.before_you_act
702
+ const runtimeLesson = runtime.before_you_act
682
703
  || runtime.before_you_act_injection?.message
683
704
  || runtime.exact_next_action
684
705
  || firstValueSignal.first_lesson;
@@ -689,18 +710,19 @@ function buildInstallValueMoment(firstValueSignal = {}, status = {}, runtime = {
689
710
  'Captured this setup decision',
690
711
  'Closed the outcome successfully',
691
712
  'Runtime gate is ' + (firstValueSignal.active ? 'active' : 'installed'),
692
- runtime.intervention?.must_use_before_action ? 'Before-action intervention is active for risky work' : runtimeLesson ? 'Future risky work now gets a pre-action brief' : 'Future risky work now gets checked before action',
713
+ runtimeLesson ? 'Future risky work now gets a pre-action brief' : 'Future risky work now gets checked before action',
714
+ tokenValueProof?.proof_line || 'Token usage proof is active and warming up after the first model call',
693
715
  ],
694
716
  fleet_signal: hasFleetSignal
695
717
  ? 'Marrow already found signal: ' + proof.join('; ') + '.'
696
718
  : 'Fresh account: Marrow will start building fleet memory from this first captured outcome.',
697
719
  try_this_now: 'Ask your agent: "I am about to deploy to production. What should I check first?"',
698
- expected_response: 'Marrow should answer with proceed/warn/block, required proof, and any matching prior lesson/playbook before the agent acts.',
699
- first_lesson: runtimeLesson || 'Marrow will stop agents before risky or repeated work and surface the prior lesson/playbook.',
720
+ expected_response: 'Marrow should answer with a risk gate, required proof, and any matching fleet lessons before the agent acts.',
721
+ first_lesson: runtimeLesson || 'Marrow will surface prior lessons before risky or repeated work.',
700
722
  };
701
723
  }
702
724
 
703
- function buildFirstValueSignal(status, runtime, performance, firstValue = {}) {
725
+ function buildFirstValueSignal(status, runtime, performance, firstValue = {}, tokenValueProof = null) {
704
726
  if (firstValue && firstValue.ok !== false && firstValue.first_value) {
705
727
  const capture = firstValue.capture || {};
706
728
  const proof = firstValue.value_proof || {};
@@ -709,11 +731,13 @@ function buildFirstValueSignal(status, runtime, performance, firstValue = {}) {
709
731
  if (Number(proof.reused_winning_decisions || 0) > 0) proofBits.push(`${proof.reused_winning_decisions} reused winning decision(s)`);
710
732
  if (Number(proof.prevented_bad_actions || 0) > 0) proofBits.push(`${proof.prevented_bad_actions} prevented risky action(s)`);
711
733
  if (Number(proof.estimated_tokens_saved || 0) > 0) proofBits.push(`~${proof.estimated_tokens_saved} tokens saved`);
734
+ if (Number(tokenValueProof?.savings?.estimated_tokens_saved || 0) > 0) proofBits.push(`~${tokenValueProof.savings.estimated_tokens_saved} measured model tokens saved`);
735
+ else if (tokenValueProof?.proof_line) proofBits.push(tokenValueProof.proof_line);
712
736
  return {
713
737
  active: Boolean(firstValue.active),
714
738
  headline: `Marrow active: ${(capture.surfaces || ['decisions']).join(', ')} captured.`,
715
739
  captured: capture.surfaces || ['decisions'],
716
- first_lesson: firstValue.first_value.first_lesson || runtime?.intervention?.agent_copy,
740
+ first_lesson: firstValue.first_value.first_lesson,
717
741
  value_proof: proofBits,
718
742
  next_action: firstValue.next_action?.reason || 'Keep working; Marrow will capture outcomes and reuse lessons automatically.',
719
743
  };
@@ -736,6 +760,8 @@ function buildFirstValueSignal(status, runtime, performance, firstValue = {}) {
736
760
  if (Number(proof.prevented_bad_actions || 0) > 0) proofBits.push(`${proof.prevented_bad_actions} prevented risky action(s)`);
737
761
  const tokens = proof.token_time_saved_estimate?.estimated_tokens_saved || 0;
738
762
  if (tokens > 0) proofBits.push(`~${tokens} tokens saved`);
763
+ if (Number(tokenValueProof?.savings?.estimated_tokens_saved || 0) > 0) proofBits.push(`~${tokenValueProof.savings.estimated_tokens_saved} measured model tokens saved`);
764
+ else if (tokenValueProof?.proof_line) proofBits.push(tokenValueProof.proof_line);
739
765
 
740
766
  const firstLesson = runtime.before_you_act
741
767
  || runtime.before_you_act_injection?.message
@@ -799,6 +825,20 @@ function printReport(report) {
799
825
  process.stdout.write(`- Next: ${report.selfTest.first_value_signal.next_action}\n`);
800
826
  }
801
827
  }
828
+ if (report.selfTest.token_value_proof) {
829
+ const proof = report.selfTest.token_value_proof;
830
+ const observed = proof.observed || {};
831
+ const savings = proof.savings || {};
832
+ const tokens = observed.tokens || {};
833
+ process.stdout.write('\nToken value proof:\n');
834
+ process.stdout.write(`- passive capture: ${proof.enabled ? 'on' : 'unknown'}\n`);
835
+ process.stdout.write(`- model calls observed: ${observed.model_calls || 0}\n`);
836
+ process.stdout.write(`- tokens observed: ${tokens.total || 0}\n`);
837
+ process.stdout.write(`- estimated tokens saved: ${savings.estimated_tokens_saved || 0}\n`);
838
+ if (savings.confidence) process.stdout.write(`- confidence: ${savings.confidence}\n`);
839
+ if (proof.proof_line) process.stdout.write(`- proof: ${proof.proof_line}\n`);
840
+ if (proof.exact_next_action) process.stdout.write(`- next: ${proof.exact_next_action}\n`);
841
+ }
802
842
  }
803
843
 
804
844
  if (report.remediation) {
@@ -949,4 +989,5 @@ module.exports = {
949
989
  inspectNpmTokenConfig,
950
990
  inspectSdkDependency,
951
991
  buildInstallValueMoment,
992
+ buildTokenValueProof,
952
993
  };