@getmarrow/install 0.1.9 → 0.1.11

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 CHANGED
@@ -11,7 +11,7 @@ npx @getmarrow/install --repair
11
11
  npx @getmarrow/install doctor
12
12
  ```
13
13
 
14
- ## What's New in v0.1.9
14
+ ## What's New in v0.1.10
15
15
 
16
16
  - First-run output now explains the value in agent/user language: your agent is no longer starting from zero.
17
17
  - Self-test prints first proof: setup decision captured, outcome closed, runtime gate active, and risky work now gets a pre-action brief.
@@ -50,7 +50,8 @@ Expected result:
50
50
  - Marrow writes the safest detected MCP/SDK/agent config.
51
51
  - A harmless setup decision is created and its outcome is committed.
52
52
  - `/v1/agent/status` confirms capture health and missing hooks.
53
- - `/v1/agent/runtime` verifies the one-call runtime gate.
53
+ - `/v1/agent/runtime` verifies the one-call runtime gate and returns the before-action intervention contract.
54
+ - `/v1/agent/first-value` returns the five-minute proof payload used by installer, SDK, and MCP clients.
54
55
  - The installer prints: "Your agent is no longer starting from zero."
55
56
  - Fresh accounts get a first useful action to try immediately.
56
57
  - Accounts with history get proof such as avoided mistakes, reused winning decisions, prevented risky actions, or estimated time/token savings.
@@ -63,7 +64,7 @@ After install, ask the agent:
63
64
  I am about to deploy to production. What should I check first?
64
65
  ```
65
66
 
66
- Marrow should answer with a pre-action risk gate, required proof, and matching fleet lessons before the agent acts. This is the first product moment: not just "hooks installed", but "the agent is being warned before risky work."
67
+ 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."
67
68
 
68
69
  ## What It Detects
69
70
 
@@ -131,6 +132,13 @@ npm install @getmarrow/sdk
131
132
 
132
133
  The generated runtime now fails soft with an explicit warning if the SDK package is missing, so onboarding does not crash a user process.
133
134
 
135
+
136
+ ## Trust and Data Boundaries
137
+
138
+ Marrow is tenant-aware by design. Private account, fleet, memory, workflow, and proof-pack data stays scoped to the authenticated account and authorized agent-bound keys. Shared/hive learning uses visibility-controlled, sanitized aggregate signals; it is not raw cross-customer decision sharing.
139
+
140
+ For business pilots, review the live trust notes before production rollout: https://getmarrow.ai/docs#trust-boundaries
141
+
134
142
  ## Trust Model
135
143
 
136
144
  This package is intended to be open source and auditable. It prints every file it will touch, requires `--yes` to write, does not store API keys in project files, and supports MCP-only, SDK-only, both, and markdown-only setups.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getmarrow/install",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Universal installer for Marrow passive agent setup.",
5
5
  "bin": {
6
6
  "marrow-install": "bin/marrow-install.js"
package/src/installer.js CHANGED
@@ -283,7 +283,7 @@ Marrow should run passively after install:
283
283
 
284
284
  - Use MCP hooks when available: \`npx -y @getmarrow/mcp setup\`.
285
285
  - Use SDK passive runtime in owned Node processes: \`createPassiveRuntime().install()\`.
286
- - Before risky work, use Marrow's decision brief or passive prompt hook.
286
+ - Before risky work, use Marrow's before-action intervention from \`GET /v1/agent/status\` or \`POST /v1/agent/runtime\`.
287
287
  - After meaningful work, record the outcome so future agents learn from it.
288
288
  - Check health with \`marrow_agent_status\` or \`GET /v1/agent/status\`.
289
289
 
@@ -610,8 +610,25 @@ async function runSelfTest(options) {
610
610
  ok: false,
611
611
  error: error instanceof Error ? error.message : String(error),
612
612
  }));
613
- const firstValueSignal = buildFirstValueSignal(status, runtime, performance);
614
- const installValueMoment = buildInstallValueMoment(firstValueSignal, status, runtime, performance);
613
+ const firstValue = await requestJson(`${baseUrl}/v1/agent/first-value`, {
614
+ method: 'POST',
615
+ headers,
616
+ body: JSON.stringify({
617
+ action: 'I am about to deploy to production. What should I check first?',
618
+ type: 'deploy',
619
+ role: 'deploy',
620
+ surfaces: ['production', 'deploy'],
621
+ proof: {
622
+ checks: ['installer first-value self-test'],
623
+ outcome: 'first-value endpoint reached',
624
+ },
625
+ }),
626
+ }).catch((error) => ({
627
+ ok: false,
628
+ error: error instanceof Error ? error.message : String(error),
629
+ }));
630
+ const firstValueSignal = buildFirstValueSignal(status, runtime, performance, firstValue);
631
+ const installValueMoment = buildInstallValueMoment(firstValueSignal, status, runtime, performance, firstValue);
615
632
  return {
616
633
  skipped: false,
617
634
  decision_id: decisionId,
@@ -623,7 +640,9 @@ async function runSelfTest(options) {
623
640
  auto_outcome_closure: status.auto_outcome_closure || null,
624
641
  runtime_active: Boolean(runtime && runtime.ok !== false),
625
642
  runtime_exact_next_action: runtime.exact_next_action || null,
626
- runtime_before_you_act: runtime.before_you_act || null,
643
+ runtime_before_you_act: runtime.intervention?.agent_copy || runtime.intervention?.before_action || runtime.before_you_act || null,
644
+ runtime_intervention: runtime.intervention || null,
645
+ first_value: firstValue && firstValue.ok !== false ? firstValue : null,
627
646
  first_value_signal: firstValueSignal,
628
647
  install_value_moment: installValueMoment,
629
648
  performance_proof: performance && performance.ok !== false ? {
@@ -637,10 +656,23 @@ async function runSelfTest(options) {
637
656
  };
638
657
  }
639
658
 
640
- function buildInstallValueMoment(firstValueSignal = {}, status = {}, runtime = {}, performance = {}) {
659
+ function buildInstallValueMoment(firstValueSignal = {}, status = {}, runtime = {}, performance = {}, firstValue = {}) {
660
+ if (firstValue && firstValue.ok !== false && firstValue.first_value) {
661
+ return {
662
+ headline: firstValue.headline || firstValue.first_value.headline || 'Your agent is no longer starting from zero.',
663
+ proof: Array.isArray(firstValue.first_value.proof) ? firstValue.first_value.proof : [],
664
+ fleet_signal: firstValue.history_signal?.summary || 'Fresh account: Marrow will build fleet memory from this first captured outcome.',
665
+ try_this_now: firstValue.first_value.try_this_now || 'Ask your agent: "I am about to deploy to production. What should I check first?"',
666
+ 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.',
667
+ first_lesson: firstValue.first_value.first_lesson || null,
668
+ };
669
+ }
670
+
641
671
  const proof = firstValueSignal.value_proof || [];
642
672
  const hasFleetSignal = proof.length > 0;
643
- const runtimeLesson = runtime.before_you_act
673
+ const runtimeLesson = runtime.intervention?.agent_copy
674
+ || runtime.intervention?.before_action
675
+ || runtime.before_you_act
644
676
  || runtime.before_you_act_injection?.message
645
677
  || runtime.exact_next_action
646
678
  || firstValueSignal.first_lesson;
@@ -651,18 +683,36 @@ function buildInstallValueMoment(firstValueSignal = {}, status = {}, runtime = {
651
683
  'Captured this setup decision',
652
684
  'Closed the outcome successfully',
653
685
  'Runtime gate is ' + (firstValueSignal.active ? 'active' : 'installed'),
654
- runtimeLesson ? 'Future risky work now gets a pre-action brief' : 'Future risky work now gets checked before action',
686
+ 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',
655
687
  ],
656
688
  fleet_signal: hasFleetSignal
657
689
  ? 'Marrow already found signal: ' + proof.join('; ') + '.'
658
690
  : 'Fresh account: Marrow will start building fleet memory from this first captured outcome.',
659
691
  try_this_now: 'Ask your agent: "I am about to deploy to production. What should I check first?"',
660
- expected_response: 'Marrow should answer with a risk gate, required proof, and any matching fleet lessons before the agent acts.',
661
- first_lesson: runtimeLesson || 'Marrow will surface prior lessons before risky or repeated work.',
692
+ expected_response: 'Marrow should answer with proceed/warn/block, required proof, and any matching prior lesson/playbook before the agent acts.',
693
+ first_lesson: runtimeLesson || 'Marrow will stop agents before risky or repeated work and surface the prior lesson/playbook.',
662
694
  };
663
695
  }
664
696
 
665
- function buildFirstValueSignal(status, runtime, performance) {
697
+ function buildFirstValueSignal(status, runtime, performance, firstValue = {}) {
698
+ if (firstValue && firstValue.ok !== false && firstValue.first_value) {
699
+ const capture = firstValue.capture || {};
700
+ const proof = firstValue.value_proof || {};
701
+ const proofBits = [];
702
+ if (Number(proof.avoided_mistakes || 0) > 0) proofBits.push(`${proof.avoided_mistakes} avoided mistake(s)`);
703
+ if (Number(proof.reused_winning_decisions || 0) > 0) proofBits.push(`${proof.reused_winning_decisions} reused winning decision(s)`);
704
+ if (Number(proof.prevented_bad_actions || 0) > 0) proofBits.push(`${proof.prevented_bad_actions} prevented risky action(s)`);
705
+ if (Number(proof.estimated_tokens_saved || 0) > 0) proofBits.push(`~${proof.estimated_tokens_saved} tokens saved`);
706
+ return {
707
+ active: Boolean(firstValue.active),
708
+ headline: `Marrow active: ${(capture.surfaces || ['decisions']).join(', ')} captured.`,
709
+ captured: capture.surfaces || ['decisions'],
710
+ first_lesson: firstValue.first_value.first_lesson || runtime?.intervention?.agent_copy,
711
+ value_proof: proofBits,
712
+ next_action: firstValue.next_action?.reason || 'Keep working; Marrow will capture outcomes and reuse lessons automatically.',
713
+ };
714
+ }
715
+
666
716
  const capture = status.capture_coverage || {};
667
717
  const closure = status.auto_outcome_closure || {};
668
718
  const captured = [];