@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 +11 -3
- package/package.json +1 -1
- package/src/installer.js +60 -10
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.
|
|
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
|
|
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
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
|
|
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
|
|
614
|
-
|
|
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.
|
|
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
|
|
661
|
-
first_lesson: runtimeLesson || 'Marrow will
|
|
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 = [];
|