@deeeed/metamask-harness 0.29.0 → 0.29.2
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/CHANGELOG.md +22 -0
- package/docs/RECIPES.md +26 -1
- package/docs/SECURITY.md +31 -0
- package/package.json +2 -2
- package/site/architecture.html +59 -0
- package/site/index.html +8 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.29.2 - 2026-08-01
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Upgrade `@farmslot/recipe-harness` to 0.11.1 so iOS lifecycle terminate and restart remain idempotent when Simulator reports that it found nothing to terminate.
|
|
10
|
+
|
|
11
|
+
## 0.29.1 - 2026-08-01
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Deploy the static getting-started site through GitHub Pages when its files change on `main`, with manual deployment restricted to the same `main` branch.
|
|
16
|
+
- Document the farmslot specification on the getting-started site: what it standardizes, that its schemas are published and versioned, and why one spec is what makes an engineer's run and a fleet run the same artifact. Carries the control-plane boundary — experimental, sole-maintained, and required by nothing the site teaches.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Define composition-first recipe maintenance and require failures to be classified against authoritative expectations before the owning product, recipe, runtime, or harness layer is changed and revalidated.
|
|
21
|
+
- Define the signed-deeplink canonicalization boundary, its required negative cases, and the distinction between external-ingress proof and in-app route-consumption evidence.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Correct the site's setup path: `mm-harness setup-base` shipped in 0.29.0, so the bootstrap is no longer described as unpublished.
|
|
26
|
+
|
|
5
27
|
## 0.29.0 - 2026-08-01
|
|
6
28
|
|
|
7
29
|
### Added
|
package/docs/RECIPES.md
CHANGED
|
@@ -64,8 +64,33 @@ Rules:
|
|
|
64
64
|
- Use real product paths; never mutate hidden state to fabricate proof.
|
|
65
65
|
- Prove preparation with an independent read/assert or visible UI postcondition.
|
|
66
66
|
- Keep ticket-specific claims in task-local recipes.
|
|
67
|
-
-
|
|
67
|
+
- Compose, repair, or parameterize repeated behavior instead of multiplying names.
|
|
68
68
|
- Keep secrets out of recipes, libraries, and evidence.
|
|
69
|
+
- Limit claims to the boundary actually exercised. In-app navigation cannot
|
|
70
|
+
prove external ingress, and security-boundary proofs require accepted and
|
|
71
|
+
rejected cases.
|
|
72
|
+
|
|
73
|
+
## Classify failures before changing either layer
|
|
74
|
+
|
|
75
|
+
Recipes are maintained proof assets, not immutable descriptions of the app.
|
|
76
|
+
Locators, labels, routes, and screen structure can legitimately change, so a
|
|
77
|
+
failed recipe is not by itself evidence of either recipe drift or a product
|
|
78
|
+
regression.
|
|
79
|
+
|
|
80
|
+
1. Reproduce the failing node and compare it with authoritative acceptance
|
|
81
|
+
criteria, product contracts, or known-good evidence.
|
|
82
|
+
2. Inspect the current product surface and resolved recipe source, then classify
|
|
83
|
+
the cause as product regression, recipe drift, fixture/runtime drift, or
|
|
84
|
+
harness defect.
|
|
85
|
+
3. If an accepted product change establishes recipe drift, repair the smallest
|
|
86
|
+
shared action or recipe node that owns it. Otherwise preserve the failure
|
|
87
|
+
and fix or report the owning product, runtime, or harness layer.
|
|
88
|
+
4. Rerun the repaired path and every shared recipe that composes it.
|
|
89
|
+
5. Report the classification, owning source, change, and fresh evidence together.
|
|
90
|
+
|
|
91
|
+
Do not duplicate a stale recipe to avoid maintaining it. Do not change product
|
|
92
|
+
code merely to satisfy an obsolete proof path, or update a recipe merely to
|
|
93
|
+
make a real regression pass.
|
|
69
94
|
|
|
70
95
|
Keep responsibilities narrow:
|
|
71
96
|
|
package/docs/SECURITY.md
CHANGED
|
@@ -31,6 +31,37 @@ Fixture setup is allowed before the proof window when it is explicit in the
|
|
|
31
31
|
trace. Mutating setup must finish with a real read/assert or visible UI
|
|
32
32
|
postcondition.
|
|
33
33
|
|
|
34
|
+
## Signed deeplink boundary
|
|
35
|
+
|
|
36
|
+
Treat every raw or original URL parameter as attacker-controlled. Route handlers
|
|
37
|
+
may receive only canonical parameters authorized by a valid signature and the
|
|
38
|
+
link's `sig_params` list. Never add a handler fallback to original parameters,
|
|
39
|
+
including for attribution or a destination considered read-only.
|
|
40
|
+
|
|
41
|
+
Attribution fields such as `utm_*` may pass through only when they are inside
|
|
42
|
+
the signed parameter set, explicitly allowlisted for the destination, and
|
|
43
|
+
validated for bounded length and character format before use.
|
|
44
|
+
|
|
45
|
+
A publishable signed-deeplink proof covers the whole ingress boundary:
|
|
46
|
+
|
|
47
|
+
1. a valid, signed, destination-allowlisted, format-valid, within-limit
|
|
48
|
+
attribution value reaches the destination;
|
|
49
|
+
2. an unsigned candidate parameter reaches neither handler nor destination;
|
|
50
|
+
3. tampering with a signed value causes authorization failure or interstitial
|
|
51
|
+
demotion, and no candidate parameter reaches handler or destination;
|
|
52
|
+
4. malformed `sig_params` and invalid signatures cause authorization failure or
|
|
53
|
+
interstitial demotion, and no candidate parameter reaches handler or
|
|
54
|
+
destination;
|
|
55
|
+
5. a signed attribution key outside the destination allowlist does not reach
|
|
56
|
+
the destination or attribution context;
|
|
57
|
+
6. signed attribution values with invalid characters or excessive length do
|
|
58
|
+
not reach the destination or attribution context;
|
|
59
|
+
7. handler observations for accepted links contain canonical values only.
|
|
60
|
+
|
|
61
|
+
Opening the same route from inside an already-running app proves downstream
|
|
62
|
+
navigation or analytics consumption only. It is not evidence for external link
|
|
63
|
+
parsing, signature verification, or canonicalization.
|
|
64
|
+
|
|
34
65
|
## Wallet fixtures
|
|
35
66
|
|
|
36
67
|
Each checkout has one canonical fixture:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deeeed/metamask-harness",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mm-harness": "bin/mm-harness"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@farmslot/agent-runtime": "^0.5.0",
|
|
24
24
|
"@farmslot/handoff": "^0.3.1",
|
|
25
25
|
"@farmslot/protocol": "^0.15.0",
|
|
26
|
-
"@farmslot/recipe-harness": "^0.11.
|
|
26
|
+
"@farmslot/recipe-harness": "^0.11.1",
|
|
27
27
|
"commander": "^12.0.0",
|
|
28
28
|
"es-module-lexer": "2.3.1",
|
|
29
29
|
"esbuild": "0.28.1",
|
package/site/architecture.html
CHANGED
|
@@ -135,6 +135,65 @@
|
|
|
135
135
|
</div>
|
|
136
136
|
</section>
|
|
137
137
|
|
|
138
|
+
<section class="wrap">
|
|
139
|
+
<h2 id="spec">The spec underneath</h2>
|
|
140
|
+
<p>
|
|
141
|
+
<code>mm-harness</code> implements <strong>farmslot</strong>, a versioned specification for agentic
|
|
142
|
+
proof work. The CLI is one implementation of it, not the thing itself.
|
|
143
|
+
</p>
|
|
144
|
+
|
|
145
|
+
<div class="stack">
|
|
146
|
+
<div class="layer layer-static">
|
|
147
|
+
<span class="layer-n">1</span>
|
|
148
|
+
<span class="layer-name">The specification</span>
|
|
149
|
+
<span class="layer-sub">recipes, action manifests, observations and traces, evidence, handoff</span>
|
|
150
|
+
</div>
|
|
151
|
+
<div class="arrow" aria-hidden="true">↓</div>
|
|
152
|
+
<div class="layer layer-static">
|
|
153
|
+
<span class="layer-n">2</span>
|
|
154
|
+
<span class="layer-name">mm-harness implements it</span>
|
|
155
|
+
<span class="layer-sub">for MetaMask products</span>
|
|
156
|
+
</div>
|
|
157
|
+
<div class="arrow" aria-hidden="true">↓</div>
|
|
158
|
+
<div class="layer layer-static">
|
|
159
|
+
<span class="layer-n">3</span>
|
|
160
|
+
<span class="layer-name">Skills drive it</span>
|
|
161
|
+
<span class="layer-sub">the workflows an agent follows</span>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
<p>Schemas are published and versioned. Every recipe carries the URL it validates against:</p>
|
|
166
|
+
<div class="out">"$schema": <a href="https://farmslot.io/schemas/recipe-v1.schema.json">"https://farmslot.io/schemas/recipe-v1.schema.json"</a></div>
|
|
167
|
+
<p>
|
|
168
|
+
Action manifests carry <code>action-manifest-v1</code>; evidence records its own
|
|
169
|
+
<code>schemaVersion</code> and <code>runner_protocol_version</code>. Versioning is what keeps a
|
|
170
|
+
bundle readable by tooling written after it was produced.
|
|
171
|
+
</p>
|
|
172
|
+
|
|
173
|
+
<h3>Why the spec is the scaling mechanism</h3>
|
|
174
|
+
<p>
|
|
175
|
+
The recipe you run from the CLI is the same artifact a control plane dispatches to a worker,
|
|
176
|
+
monitors, and gates — dispatch, worker, self-review, human gate, publication, each step speaking
|
|
177
|
+
these contracts. Evidence returns in the same shape either way, so a fleet result is reviewable by
|
|
178
|
+
whoever wrote the recipe. Parity is structural: one spec, both sides.
|
|
179
|
+
</p>
|
|
180
|
+
<p>The seam shows in the CLI's own help — the flags a control plane supplies:</p>
|
|
181
|
+
<div class="out">managed trust boundary (not needed for normal runs; Farmslot supplies it):
|
|
182
|
+
--source-trust, --source-kind, --source-name, --source-digest,
|
|
183
|
+
<span class="hint">--approve-plan</span> (binds approval to the exact reviewed plan)</div>
|
|
184
|
+
<p>Approve a plan and only that plan runs — which is what keeps the gate a gate.</p>
|
|
185
|
+
|
|
186
|
+
<div class="note">
|
|
187
|
+
<span class="note-title">What you actually need</span>
|
|
188
|
+
<p>
|
|
189
|
+
The farmslot control plane is <strong>experimental and sole-maintained</strong>. Nothing this site
|
|
190
|
+
teaches requires it — the harness, recipes, and skills are complete on their own, and the CLI says
|
|
191
|
+
as much: those flags are "not needed for normal runs". The specification is what you adopt; the
|
|
192
|
+
control plane is one consumer of it.
|
|
193
|
+
</p>
|
|
194
|
+
</div>
|
|
195
|
+
</section>
|
|
196
|
+
|
|
138
197
|
<section class="wrap">
|
|
139
198
|
<h2 id="loop">The improvement loop</h2>
|
|
140
199
|
<p>The stack is arranged so each run can leave the next one better informed.</p>
|
package/site/index.html
CHANGED
|
@@ -62,6 +62,10 @@
|
|
|
62
62
|
screenshots. The steps below follow <strong>discover → drive → prove</strong>, which is also the
|
|
63
63
|
order you will work in from here on.
|
|
64
64
|
</p>
|
|
65
|
+
<p>
|
|
66
|
+
<code>mm-harness</code> implements the farmslot specification —
|
|
67
|
+
<a href="architecture.html#spec">see Architecture</a>.
|
|
68
|
+
</p>
|
|
65
69
|
|
|
66
70
|
<div class="doctrine">
|
|
67
71
|
<p>
|
|
@@ -147,11 +151,11 @@ me the exact error.</code></pre></div>
|
|
|
147
151
|
<div class="path-tag">Path A — from zero</div>
|
|
148
152
|
<h4 style="margin:0 0 .5rem">No checkout yet</h4>
|
|
149
153
|
<p style="font-size:.92rem;color:var(--text-dim)">
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
154
|
+
Install below, then <code>mm-harness setup-base</code> clones the MetaMask product repos
|
|
155
|
+
into one standard layout and runs each repo's own dependency install. Use
|
|
156
|
+
<code>--dry-run</code> first to see the layout it would create.
|
|
153
157
|
</p>
|
|
154
|
-
<p style="margin-bottom:0"><span class="badge
|
|
158
|
+
<p style="margin-bottom:0"><span class="badge live">available now</span></p>
|
|
155
159
|
</div>
|
|
156
160
|
<div class="path-card">
|
|
157
161
|
<div class="path-tag">Path B — you already have a checkout</div>
|