@deeeed/metamask-harness 0.17.5 → 0.19.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/CHANGELOG.md +1059 -0
- package/README.md +91 -140
- package/adapters/core/inject.sh +1 -6
- package/adapters/extension/console-tail.mjs +55 -24
- package/adapters/extension/ensure-browser.sh +6 -1
- package/adapters/extension/inject.mjs +7 -13
- package/adapters/extension/launch-browser.cjs +7 -1
- package/adapters/extension/launch-webpack.cjs +83 -0
- package/adapters/extension/launch.sh +8 -11
- package/adapters/extension/lib/chrome-args.cjs +8 -1
- package/adapters/extension/lib/macos-focus.cjs +32 -0
- package/adapters/extension/live.sh +12 -21
- package/adapters/extension/reattach.sh +1 -0
- package/adapters/extension/seed-fixture.sh +4 -12
- package/adapters/extension/sidepanel-toggle.sh +4 -1
- package/adapters/extension/stamp-runtime-title.cjs +58 -0
- package/adapters/extension/start-watch.sh +17 -4
- package/adapters/extension/stop-viewers.sh +1 -1
- package/adapters/extension/sync-webpack-dist.cjs +107 -0
- package/adapters/extension/verify.sh +2 -2
- package/adapters/manifest.json +53 -37
- package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +16 -0
- package/adapters/mobile/bridge-runtime/console-forwarder.cjs +1 -1
- package/adapters/mobile/bridge-runtime/lib/match-bridge-target.cjs +3 -1
- package/adapters/mobile/bridge-runtime/lib/target-discovery.cjs +2 -3
- package/adapters/mobile/cleanup.sh +16 -176
- package/adapters/mobile/inject.sh +91 -671
- package/adapters/mobile/launch-console-forwarder.cjs +39 -0
- package/adapters/mobile/open-device.sh +45 -7
- package/adapters/mobile/start-console-forwarder.sh +70 -0
- package/adapters/mobile/start-metro.sh +0 -41
- package/adapters/mobile/verify.sh +34 -83
- package/adapters/mobile/wait-for-bridge.sh +22 -8
- package/adapters/shared/harness-source-fingerprint.mjs +14 -12
- package/adapters/shared/resolve-slot-ports-core.mjs +17 -6
- package/adapters/shared/resolve-slot-ports.sh +17 -5
- package/adapters/shared/update-check-worker.mjs +43 -0
- package/bin/mm-harness +21 -2
- package/dist/adapters/core/surface.js +4 -1
- package/dist/adapters/extension/console-capture.js +95 -0
- package/dist/adapters/extension/product-config.js +110 -0
- package/dist/adapters/extension/runtime-decision.js +20 -2
- package/dist/adapters/extension/surface.js +22 -3
- package/dist/adapters/harness-freshness.js +49 -0
- package/dist/adapters/mobile/perps-env.js +43 -3
- package/dist/adapters/mobile/prepare.js +39 -7
- package/dist/adapters/mobile/surface.js +5 -2
- package/dist/adapters/resolve-slot-ports.js +2 -2
- package/dist/adapters/slot-ports.js +13 -16
- package/dist/adapters.js +56 -16
- package/dist/checkout-lock.js +27 -2
- package/dist/cli-color.js +19 -0
- package/dist/cli-commands.js +1 -1
- package/dist/cli.js +7 -18
- package/dist/command-contract.js +462 -0
- package/dist/command-journal.js +263 -0
- package/dist/commands/call.js +252 -57
- package/dist/commands/check.js +10 -4
- package/dist/commands/completion-candidates.js +17 -22
- package/dist/commands/device-target.js +27 -12
- package/dist/commands/doctor.js +106 -25
- package/dist/commands/fixtures.js +142 -35
- package/dist/commands/last.js +60 -0
- package/dist/commands/launch/extension.js +40 -17
- package/dist/commands/launch/index.js +207 -63
- package/dist/commands/launch/mobile.js +2 -0
- package/dist/commands/list-executables.js +187 -29
- package/dist/commands/logs.js +8 -6
- package/dist/commands/manifest.js +286 -35
- package/dist/commands/parse-args.js +68 -4
- package/dist/commands/provision.js +10 -4
- package/dist/commands/run-engine.js +772 -264
- package/dist/commands/run-report.js +12 -3
- package/dist/commands/run.js +378 -85
- package/dist/commands/shared.js +76 -4
- package/dist/commands/status-probe.js +4 -1
- package/dist/commands/status.js +2 -1
- package/dist/commands/stop.js +7 -2
- package/dist/commands/update.js +16 -28
- package/dist/completions-cache.js +1 -1
- package/dist/doctor.js +57 -10
- package/dist/harness.js +47 -137
- package/dist/heal-bounds.js +7 -2
- package/dist/json-stream.js +57 -0
- package/dist/live-adapter-contract.js +138 -32
- package/dist/manifest.js +161 -1
- package/dist/mm-harness-cli.js +146 -73
- package/dist/paths.js +2 -5
- package/dist/recipe-security.js +178 -0
- package/dist/run-diagnostics.js +261 -0
- package/dist/run-recording.js +1 -1
- package/dist/runner.js +140 -9
- package/docs/CONTRIBUTING.md +136 -0
- package/docs/QA.md +184 -0
- package/docs/RECIPES.md +122 -0
- package/docs/SECURITY.md +88 -0
- package/library/README.md +7 -3
- package/library/actions/core/perps/_controller.mjs +43 -56
- package/library/actions/core/perps/assert_orders.mjs +6 -7
- package/library/actions/core/perps/assert_positions.mjs +6 -7
- package/library/actions/core/perps/close_orders.mjs +2 -0
- package/library/actions/core/perps/close_positions.mjs +2 -0
- package/library/actions/core/perps/ensure_orders.mjs +4 -2
- package/library/actions/core/perps/ensure_positions.mjs +4 -2
- package/library/actions/core/perps/place_order.mjs +7 -3
- package/library/actions/core/perps/read_account.mjs +2 -2
- package/library/actions/core/perps/read_orders.mjs +2 -1
- package/library/actions/core/perps/read_positions.mjs +2 -1
- package/library/actions/core/wallet/list_accounts.mjs +95 -0
- package/library/actions/extension/perps/assert_orders.mjs +2 -1
- package/library/actions/extension/perps/assert_positions.mjs +2 -1
- package/library/actions/extension/perps/perps.mjs +43 -14
- package/library/actions/extension/platform/cdp.mjs +1 -0
- package/library/actions/extension/wallet/list_accounts.mjs +41 -0
- package/library/actions/mobile/perps/assert_orders.mjs +2 -1
- package/library/actions/mobile/perps/assert_positions.mjs +2 -1
- package/library/actions/mobile/perps/perps.mjs +40 -12
- package/library/actions/mobile/wallet/list_accounts.mjs +37 -0
- package/library/library.json +1 -1
- package/library/manifests/core.action-manifest.json +1214 -396
- package/library/manifests/extension.action-manifest.json +1635 -728
- package/library/manifests/mobile.action-manifest.json +1740 -727
- package/library/recipes/app/lifecycle.android-smoke.mobile.recipe.json +63 -81
- package/library/recipes/perps/clean-market-testnet.core.recipe.json +44 -0
- package/library/recipes/perps/clean-market-testnet.recipe.json +49 -0
- package/library/recipes/perps/lifecycle.recipe.json +136 -180
- package/library/recipes/perps/order-lifecycle.core.recipe.json +71 -67
- package/library/recipes/perps/performance.background-resume.mobile.recipe.json +51 -67
- package/library/recipes/perps/performance.cold-start.mobile.recipe.json +51 -67
- package/library/recipes/perps/performance.mobile.recipe.json +37 -51
- package/library/recipes/perps/performance.warm-start.mobile.recipe.json +44 -59
- package/library/recipes/perps/read-markets.core.recipe.json +29 -31
- package/library/recipes/perps/smoke.core.recipe.json +29 -32
- package/library/recipes/perps/smoke.extension.recipe.json +41 -44
- package/library/recipes/perps/smoke.mobile.recipe.json +42 -44
- package/library/recipes/perps/trading-lifecycle.core.recipe.json +69 -65
- package/library/recipes/runner/action-validation.extension.recipe.json +312 -398
- package/library/recipes/runner/action-validation.mobile.recipe.json +316 -402
- package/library/recipes/runner/smoke.core.recipe.json +25 -0
- package/library/recipes/runner/smoke.extension.recipe.json +23 -24
- package/library/recipes/runner/smoke.mobile.recipe.json +23 -24
- package/library/recipes/wallet/smoke.extension.recipe.json +40 -0
- package/library/recipes/wallet/smoke.mobile.recipe.json +40 -0
- package/package.json +12 -5
- package/scripts/completions.sh +8 -11
- package/scripts/validate-human-outcomes.mjs +169 -0
- package/adapters/mobile/overlay/app/dev-tools/AgenticService/AgentStepHud.tsx.patch +0 -185
- package/adapters/mobile/overlay/app/dev-tools/AgenticService/AgenticService.ts.patch +0 -1662
- package/adapters/mobile/overlay/compat/README.md +0 -28
- package/adapters/mobile/overlay/compat/rn81-message-event-source.patch +0 -42
- package/adapters/shared/resolve-farmslot-ports-core.mjs +0 -3
- package/adapters/shared/resolve-farmslot-ports.mjs +0 -5
- package/adapters/shared/resolve-farmslot-ports.sh +0 -7
- package/dist/adapters/extension/harness-freshness.js +0 -39
- package/dist/commands/flows.js +0 -62
- package/docs/ADAPTER-SURFACE.md +0 -119
- package/docs/CHEATSHEET.md +0 -61
- package/docs/CLI-SPEC.md +0 -1098
- package/docs/CODE-MAP.md +0 -62
- package/docs/DEBUG-HANDOVER.md +0 -36
- package/docs/MENTAL-MODEL.md +0 -295
- package/docs/UX-PRINCIPLES.md +0 -64
- package/docs/architecture.md +0 -398
- package/docs/live-adapter-contract.md +0 -188
- package/docs/package-boundaries.md +0 -47
- package/docs/perps-flow-catalog.md +0 -235
- package/docs/recipe-libraries.md +0 -301
- package/docs/runtime-file-conventions.md +0 -36
- package/library/flows/perps.flows.json +0 -64
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Keep `mm-harness` thin: put each change in the layer that owns it and validate
|
|
4
|
+
both the machine contract and the visible human result.
|
|
5
|
+
|
|
6
|
+
## Ownership
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
bin/mm-harness
|
|
10
|
+
-> src/ typed CLI and product decisions
|
|
11
|
+
-> @farmslot/recipe-harness generic execution, UI transports, evidence
|
|
12
|
+
-> @farmslot/protocol schemas
|
|
13
|
+
-> adapters/ focused host/browser/device leaves
|
|
14
|
+
-> library/ MetaMask actions and recipes
|
|
15
|
+
-> MetaMask checkout product under test
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
| Layer | Owns |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `@farmslot/protocol` | recipe and evidence schemas |
|
|
21
|
+
| `@farmslot/recipe-harness` | generic execution, recovery, traces, artifacts, `ui.*` |
|
|
22
|
+
| `mm-harness` | MetaMask runtime control, diagnostics, durable domain actions |
|
|
23
|
+
| skills/checklists | task workflow and proof expectations |
|
|
24
|
+
| product checkout | app behavior and explicit debug hooks |
|
|
25
|
+
|
|
26
|
+
Generic bootstrap, trust, receipts, and recovery belong upstream. MetaMask
|
|
27
|
+
platform behavior and risk classification belong here. Ticket assertions stay
|
|
28
|
+
task-local.
|
|
29
|
+
|
|
30
|
+
## Repository map
|
|
31
|
+
|
|
32
|
+
| Path | Responsibility |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `bin/mm-harness` | only public executable |
|
|
35
|
+
| `src/commands/` | command behavior |
|
|
36
|
+
| `src/adapters/` | typed platform decisions and `AdapterSurface` |
|
|
37
|
+
| `adapters/<platform>/` | focused shell/Node host operations |
|
|
38
|
+
| `adapters/<platform>/inject*` | assemble the checkout overlay from shipped adapter/library files |
|
|
39
|
+
| `library/actions/` | executable MetaMask action adapters |
|
|
40
|
+
| `library/recipes/` | reusable parameterized behavior and proofs |
|
|
41
|
+
| `library/manifests/` | declared capability surface |
|
|
42
|
+
| `scripts/` | build/validation tooling and shipped completion/human-QA helpers |
|
|
43
|
+
|
|
44
|
+
All TypeScript lives under `src/`. Use `.mjs` for direct no-build Node leaves,
|
|
45
|
+
`.cjs` only for required CommonJS contexts, and shell only for host/device
|
|
46
|
+
commands. Decisions belong in TypeScript; a leaf performs one operation and
|
|
47
|
+
exits.
|
|
48
|
+
|
|
49
|
+
## Adapter surface
|
|
50
|
+
|
|
51
|
+
Commands resolve shared platform behavior through
|
|
52
|
+
`src/adapters/surface.ts`. Extend `AdapterSurface` only when all platforms need
|
|
53
|
+
the concept, implement all three adapters, and let Core report headless/N/A
|
|
54
|
+
explicitly. Do not add command-local platform ladders for surface-owned behavior.
|
|
55
|
+
|
|
56
|
+
Each checkout owns:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
temp/recipe/runtime/ ports, processes, fixture, logs, runtime identity
|
|
60
|
+
temp/recipe/harness/ installed runtime overlay
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Profiles, devices, ports, watchers, and evidence paths must resolve from that
|
|
64
|
+
checkout so slots remain isolated.
|
|
65
|
+
|
|
66
|
+
## Actions and adapters
|
|
67
|
+
|
|
68
|
+
Official `ui.*` behavior comes from the generic runtime. MetaMask-specific
|
|
69
|
+
actions are manifest-declared modules under:
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
library/actions/<platform>/<domain>/<name>.mjs
|
|
73
|
+
library/actions/shared/<domain>/<name>.mjs
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Configured libraries use the same structure. An adapter receives a JSON input
|
|
77
|
+
path, writes JSON to its `outputPath` or stdout, returns redacted trace-safe
|
|
78
|
+
output, and performs only the declared operation. It must not execute another
|
|
79
|
+
recipe graph.
|
|
80
|
+
|
|
81
|
+
The input path is argv 1 and `METAMASK_RECIPE_ADAPTER_INPUT`. Its document is:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"schemaVersion": 1,
|
|
86
|
+
"platform": "mobile|extension|core",
|
|
87
|
+
"action": "metamask.example.action",
|
|
88
|
+
"node": {},
|
|
89
|
+
"context": {
|
|
90
|
+
"nodeId": "step-id",
|
|
91
|
+
"projectRoot": "/path/to/checkout",
|
|
92
|
+
"artifactsDir": "/path/to/run/artifacts"
|
|
93
|
+
},
|
|
94
|
+
"outputPath": "/temporary/output.json"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Write JSON to `outputPath` (also `METAMASK_RECIPE_ADAPTER_OUTPUT`) or stdout.
|
|
99
|
+
Write evidence under `context.artifactsDir` and return relative artifact paths.
|
|
100
|
+
`METAMASK_RECIPE_LIVE_ADAPTER_DIR` is the explicit task-local implementation
|
|
101
|
+
root; configured libraries are the durable sharing mechanism.
|
|
102
|
+
|
|
103
|
+
Add a bundled action only when it is reusable, typed, stable, reduces inference
|
|
104
|
+
or risk, and has a real postcondition. Otherwise use a team library or task-local
|
|
105
|
+
recipe. Follow [Recipes](RECIPES.md) and [Security](SECURITY.md).
|
|
106
|
+
|
|
107
|
+
## CLI contract
|
|
108
|
+
|
|
109
|
+
- Human mode is contextual, colored only in a TTY, and teaches one exact next
|
|
110
|
+
action on failure.
|
|
111
|
+
- `--json` stdout is one stable document with no decoration.
|
|
112
|
+
- Long work acknowledges intent before blocking and streams child output.
|
|
113
|
+
- Lifecycle commands are checkout-scoped and idempotent.
|
|
114
|
+
- `doctor` is read-only; `doctor --fix` repairs without launching.
|
|
115
|
+
- No command may fabricate platform support or readiness.
|
|
116
|
+
|
|
117
|
+
When adding a command, register its behavior and human metadata, then add a
|
|
118
|
+
contract test. When a flag reaches a host leaf, both the typed composer and leaf
|
|
119
|
+
parser must accept it. Before renaming or removing a public flag, injected file,
|
|
120
|
+
or wrapper, verify real callers and retain compatibility only when one exists.
|
|
121
|
+
|
|
122
|
+
## Change gates
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
yarn test:unit
|
|
126
|
+
yarn test:coverage
|
|
127
|
+
yarn check
|
|
128
|
+
bash tests/contract/run.sh
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Runtime changes also require real affected-platform QA and a packed installation
|
|
132
|
+
test. Update `CHANGELOG.md` under `Unreleased` for user-visible behavior.
|
|
133
|
+
|
|
134
|
+
Docs describe only current behavior. History belongs in the changelog and Git;
|
|
135
|
+
do not add handovers, audits, speculative roadmaps, or duplicate command guides
|
|
136
|
+
under `docs/`.
|
package/docs/QA.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# QA
|
|
2
|
+
|
|
3
|
+
Validate the installed candidate as a human would use it. Use disposable
|
|
4
|
+
profiles and an unfunded fixture; preserve existing product source and active
|
|
5
|
+
processes.
|
|
6
|
+
|
|
7
|
+
## Candidate and provenance
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
export CANDIDATE=/path/to/mm-harness-candidate.tgz
|
|
11
|
+
export QA_HOME="$(mktemp -d "$HOME/mmh-qa.XXXXXX")"
|
|
12
|
+
export QA_PREFIX="$QA_HOME/npm"
|
|
13
|
+
HOME="$QA_HOME" npm install -g --prefix "$QA_PREFIX" "$CANDIDATE"
|
|
14
|
+
export PATH="$QA_PREFIX/bin:$PATH"
|
|
15
|
+
mm-harness --version
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- [ ] The executable and dependencies resolve inside the isolated prefix.
|
|
19
|
+
- [ ] No dependency is a symlink or resolves through a local Farmslot checkout.
|
|
20
|
+
- [ ] Record the tarball SHA-256 and product SHAs.
|
|
21
|
+
- [ ] Product trees start and finish without tracked changes.
|
|
22
|
+
|
|
23
|
+
## Common
|
|
24
|
+
|
|
25
|
+
Run inside each Extension, Mobile, and Core checkout:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
mm-harness doctor
|
|
29
|
+
mm-harness doctor --json
|
|
30
|
+
mm-harness status
|
|
31
|
+
mm-harness actions
|
|
32
|
+
mm-harness run --list
|
|
33
|
+
mm-harness run runner.smoke --describe
|
|
34
|
+
mm-harness run runner.smoke --plan
|
|
35
|
+
mm-harness run runner.smoke
|
|
36
|
+
mm-harness last --json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- [ ] Product, checkout, slot, ports, and next action are correct.
|
|
40
|
+
- [ ] Human output is concise and evidence paths are absolute.
|
|
41
|
+
- [ ] JSON output is one parseable document without color or prose on stdout.
|
|
42
|
+
- [ ] `run` chooses a checkout-local artifact directory; an explicit
|
|
43
|
+
`--artifacts-dir` still wins.
|
|
44
|
+
- [ ] Reports, trace, diagnostics, executed recipe, and manifest exist and agree.
|
|
45
|
+
- [ ] `last --json` reconstructs the run without re-executing it.
|
|
46
|
+
|
|
47
|
+
Recovery checks:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
mm-harness actions --wat
|
|
51
|
+
mm-harness run missing.recipe --describe
|
|
52
|
+
mm-harness doctor --fix
|
|
53
|
+
mm-harness verify
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- [ ] Bad input fails before runtime work with a stable code and one exact next
|
|
57
|
+
action.
|
|
58
|
+
- [ ] `doctor --fix` is idempotent and does not choose a fixture or launch.
|
|
59
|
+
- [ ] With `capture-helper` absent, Extension reports CDP screenshots and Mobile
|
|
60
|
+
reports `simctl`/ADB screenshots; video is honestly unavailable.
|
|
61
|
+
|
|
62
|
+
Run the bounded multi-platform preflight when all three checkouts are available:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
yarn qa:human \
|
|
66
|
+
--extension /path/to/metamask-extension \
|
|
67
|
+
--mobile /path/to/metamask-mobile \
|
|
68
|
+
--core /path/to/metamask-core \
|
|
69
|
+
--artifacts-dir temp/human-qa
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
It supplements the visible checks below; it does not replace them.
|
|
73
|
+
|
|
74
|
+
## Extension
|
|
75
|
+
|
|
76
|
+
Fresh MetaMask Extension needs its normal product configuration and
|
|
77
|
+
checkout-pinned Chromium. Follow the product files; do not invent values:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
cd /path/to/metamask-extension
|
|
81
|
+
cp .metamaskrc.dist .metamaskrc
|
|
82
|
+
${EDITOR:-vi} .metamaskrc
|
|
83
|
+
yarn playwright install chromium
|
|
84
|
+
mm-harness launch --verify
|
|
85
|
+
mm-harness fixtures set
|
|
86
|
+
mm-harness run wallet.smoke
|
|
87
|
+
mm-harness logs --source extension
|
|
88
|
+
mm-harness logs --source dapp
|
|
89
|
+
mm-harness logs --source webpack
|
|
90
|
+
mm-harness debug
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- [ ] Missing/placeholder Infura configuration returns
|
|
94
|
+
`EXTENSION_PRODUCT_CONFIG_REQUIRED` before build or browser startup.
|
|
95
|
+
- [ ] Missing Chromium returns `EXTENSION_BROWSER_REQUIRED` without using system
|
|
96
|
+
Chrome.
|
|
97
|
+
- [ ] Launch uses the checkout-owned profile, opens one MetaMask surface, avoids
|
|
98
|
+
keychain prompts, and preserves keyboard focus by default.
|
|
99
|
+
- [ ] A second launch reuses the watcher/profile without duplicate tabs.
|
|
100
|
+
- [ ] Two source edits rebuild incrementally; refresh shows each change; revert
|
|
101
|
+
restores a clean tree.
|
|
102
|
+
- [ ] Log sources are distinct.
|
|
103
|
+
- [ ] `debug` opens connected DevTools for the active Extension surface;
|
|
104
|
+
`location.href` returns its `chrome-extension://` URL and remains connected.
|
|
105
|
+
|
|
106
|
+
## Mobile
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cd /path/to/metamask-mobile
|
|
110
|
+
mm-harness provision runway ios
|
|
111
|
+
mm-harness launch ios --verify
|
|
112
|
+
mm-harness fixtures set
|
|
113
|
+
mm-harness call metamask.wallet.ensure_unlocked
|
|
114
|
+
mm-harness run wallet.smoke
|
|
115
|
+
mm-harness logs --source app
|
|
116
|
+
mm-harness logs --source metro
|
|
117
|
+
mm-harness debug
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- [ ] Simulator opens only when absent and does not steal focus by default.
|
|
121
|
+
- [ ] A second launch reuses the running simulator and Metro.
|
|
122
|
+
- [ ] Fixture setup and unlock show the intended redacted account without
|
|
123
|
+
mnemonic/private-key output.
|
|
124
|
+
- [ ] Status matches verified product routes: `Login`/`LockScreen` are locked;
|
|
125
|
+
`WalletView` is unlocked.
|
|
126
|
+
- [ ] App and Metro logs are separate.
|
|
127
|
+
- [ ] A JS edit rebuilds through Metro and appears after reload without a native
|
|
128
|
+
rebuild; revert restores a clean tree.
|
|
129
|
+
|
|
130
|
+
When Android/ADB is available, repeat with:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
mm-harness launch android --device <serial> --verify
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Core
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
cd /path/to/metamask-core
|
|
140
|
+
mm-harness doctor
|
|
141
|
+
mm-harness call metamask.wallet.list_accounts scope=selected
|
|
142
|
+
mm-harness run runner.smoke
|
|
143
|
+
mm-harness logs
|
|
144
|
+
mm-harness debug
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- [ ] Doctor reports a headless controller surface and no capture requirement.
|
|
148
|
+
- [ ] Account output is fixture-backed and redacted.
|
|
149
|
+
- [ ] Smoke writes the complete evidence package without launching an app.
|
|
150
|
+
- [ ] Logs/debug fail with truthful headless teaching errors.
|
|
151
|
+
|
|
152
|
+
## Trust and evidence
|
|
153
|
+
|
|
154
|
+
- [ ] An untrusted restricted plan fails with `RECIPE_TRUST_REQUIRED` and no
|
|
155
|
+
side effect.
|
|
156
|
+
- [ ] A wrong/stale digest fails with `RECIPE_APPROVAL_MISMATCH`.
|
|
157
|
+
- [ ] Only the unchanged, reviewed plan executes with its exact approval digest.
|
|
158
|
+
- [ ] Human output, JSON, reports, traces, diagnostics, and screenshots contain
|
|
159
|
+
no mnemonic, private key, seed, bearer token, or API credential.
|
|
160
|
+
- [ ] Diagnostics contain only events observed in the proof window.
|
|
161
|
+
- [ ] Screenshot provenance identifies capture-helper, CDP, simctl, or ADB
|
|
162
|
+
accurately.
|
|
163
|
+
|
|
164
|
+
## Automated and release gates
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
yarn check
|
|
168
|
+
bash tests/contract/run.sh
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Before release:
|
|
172
|
+
|
|
173
|
+
- [ ] Focused unit tests and full contract suite pass.
|
|
174
|
+
- [ ] Packed isolated installation passes the critical Extension, Mobile, and
|
|
175
|
+
Core scenarios.
|
|
176
|
+
- [ ] Independent review approves the exact final diff.
|
|
177
|
+
- [ ] Known limits are explicit: Extension requires product Infura setup;
|
|
178
|
+
Mobile requires its normal dev-client/device setup; video requires optional
|
|
179
|
+
`capture-helper`; the harness never invents funded fixtures.
|
|
180
|
+
- [ ] Existing Farmslot slots remain compatible.
|
|
181
|
+
|
|
182
|
+
When a slot manager is available, repeat `runner.smoke` in one existing managed
|
|
183
|
+
checkout per product and verify its profile/device, ports, processes, and fixture
|
|
184
|
+
remain isolated.
|
package/docs/RECIPES.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Recipes
|
|
2
|
+
|
|
3
|
+
Use the smallest durable layer that proves the task:
|
|
4
|
+
|
|
5
|
+
1. call an existing action;
|
|
6
|
+
2. compose existing recipes;
|
|
7
|
+
3. write a task-local recipe;
|
|
8
|
+
4. use a verified controller or CDP path when no stable action exists.
|
|
9
|
+
|
|
10
|
+
Discover before authoring:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
mm-harness actions <intent>
|
|
14
|
+
mm-harness actions --action <name>
|
|
15
|
+
mm-harness run --list
|
|
16
|
+
mm-harness run <name> --describe
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Discovery reports parameters, selected adapter variant, nested recipes, source,
|
|
20
|
+
and shadows. Use `--json` for exact metadata.
|
|
21
|
+
|
|
22
|
+
## Author and run
|
|
23
|
+
|
|
24
|
+
An action performs one typed operation. A recipe owns a reusable graph or a
|
|
25
|
+
task proof and may call other recipes.
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
30
|
+
"title": "Wallet readiness",
|
|
31
|
+
"description": "Proves the running wallet is reachable and unlocked.",
|
|
32
|
+
"paramsSchema": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"properties": {
|
|
35
|
+
"account": { "type": "string", "default": "Account 1" }
|
|
36
|
+
},
|
|
37
|
+
"additionalProperties": false
|
|
38
|
+
},
|
|
39
|
+
"workflow": {
|
|
40
|
+
"entry": "unlock",
|
|
41
|
+
"nodes": {
|
|
42
|
+
"unlock": {
|
|
43
|
+
"action": "metamask.wallet.ensure_unlocked",
|
|
44
|
+
"intent": "Make the fixture-backed wallet ready for use",
|
|
45
|
+
"next": "done"
|
|
46
|
+
},
|
|
47
|
+
"done": { "action": "end", "status": "pass" }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Defaults are applied before validation. Root values use `key=value`; a nested
|
|
54
|
+
recipe call uses `action: "call"`, `ref`, and `params`.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
mm-harness run recipe.json account="Account 2" --plan
|
|
58
|
+
mm-harness run recipe.json account="Account 2"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Rules:
|
|
62
|
+
|
|
63
|
+
- Validate with `--plan` before side effects.
|
|
64
|
+
- Use real product paths; never mutate hidden state to fabricate proof.
|
|
65
|
+
- Prove preparation with an independent read/assert or visible UI postcondition.
|
|
66
|
+
- Keep ticket-specific claims in task-local recipes.
|
|
67
|
+
- Parameterize repeated behavior instead of multiplying names.
|
|
68
|
+
- Keep secrets out of recipes, libraries, and evidence.
|
|
69
|
+
|
|
70
|
+
The protocol is authoritative:
|
|
71
|
+
<https://farmslot.io/docs/reference/recipe-protocol-v1>.
|
|
72
|
+
|
|
73
|
+
## Share a library
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
team-recipes/
|
|
77
|
+
library.json
|
|
78
|
+
manifests/extension.action-manifest.json
|
|
79
|
+
actions/extension/wallet/ensure_ready.mjs
|
|
80
|
+
recipes/onboarding/smoke.extension.recipe.json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"kind": "recipe-library",
|
|
86
|
+
"schema_version": 1,
|
|
87
|
+
"name": "wallet-team",
|
|
88
|
+
"owner": "wallet-team"
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
export RECIPE_LIBRARY_PATH="wallet=$HOME/shared-library/wallet-team"
|
|
94
|
+
mm-harness run --list
|
|
95
|
+
mm-harness run onboarding.smoke --describe
|
|
96
|
+
mm-harness run onboarding.smoke --plan
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Use `--library wallet=/path/to/library` for one command. Resolution follows the
|
|
100
|
+
explicit library order, then bundled MetaMask. Adapter-specific variants are
|
|
101
|
+
selected deterministically. Every run records the root recipe, exact resolved
|
|
102
|
+
dependency documents, their digests, call edges, selected sources, and shadows.
|
|
103
|
+
|
|
104
|
+
## Direct product access
|
|
105
|
+
|
|
106
|
+
The bundled library is intentionally small. A task may use a verified controller
|
|
107
|
+
or CDP path when that is clearer than adding a permanent wrapper. Confirm the
|
|
108
|
+
current source path, mutation risk, preconditions, independent postcondition,
|
|
109
|
+
and redaction. Do not infer route or controller names from memory. Repeated team
|
|
110
|
+
behavior belongs in a reviewed team recipe; only broadly reusable stable
|
|
111
|
+
capabilities belong in the bundled library.
|
|
112
|
+
|
|
113
|
+
Mobile and Extension share vocabulary where the product supports it. Core is
|
|
114
|
+
headless and must not fabricate UI state. Inspect the current surface:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
mm-harness actions --category wallet --json
|
|
118
|
+
mm-harness actions --category perps --json
|
|
119
|
+
mm-harness run --list --json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
See [Security](SECURITY.md) before enabling custom executable actions.
|
package/docs/SECURITY.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
`mm-harness` executes product code, recipes, and optional custom adapters with
|
|
4
|
+
the current user's authority. It is a proof tool, not an OS sandbox.
|
|
5
|
+
|
|
6
|
+
## Trust boundary
|
|
7
|
+
|
|
8
|
+
- Bundled actions and recipes are trusted package content.
|
|
9
|
+
- A configured library cannot declare itself trusted.
|
|
10
|
+
- Untrusted plans that request restricted capabilities stop before runtime
|
|
11
|
+
preparation or side effects with `RECIPE_TRUST_REQUIRED`.
|
|
12
|
+
- The failure reports blocked nodes, capabilities, source provenance, and one
|
|
13
|
+
exact approval command.
|
|
14
|
+
- Approval is bound to the resolved plan, implementation bundle, project root,
|
|
15
|
+
artifact directory, and execution environment.
|
|
16
|
+
- Changed code or inputs produce `RECIPE_APPROVAL_MISMATCH`; an old digest does
|
|
17
|
+
not authorize a new plan.
|
|
18
|
+
|
|
19
|
+
Never construct an approval from memory. Inspect the plan and use the exact
|
|
20
|
+
`userAction` emitted by the failed run. Review custom libraries like application
|
|
21
|
+
code because approved code retains the user's filesystem, process, and network
|
|
22
|
+
permissions.
|
|
23
|
+
|
|
24
|
+
## Product-state integrity
|
|
25
|
+
|
|
26
|
+
Proof must come from supported UI, controller, or API paths. Never write DOM,
|
|
27
|
+
React/Redux/MobX state, controller internals, or storage merely to manufacture
|
|
28
|
+
the claimed result.
|
|
29
|
+
|
|
30
|
+
Fixture setup is allowed before the proof window when it is explicit in the
|
|
31
|
+
trace. Mutating setup must finish with a real read/assert or visible UI
|
|
32
|
+
postcondition.
|
|
33
|
+
|
|
34
|
+
## Wallet fixtures
|
|
35
|
+
|
|
36
|
+
Each checkout has one canonical fixture:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
temp/recipe/runtime/wallet-fixture.json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Initialize it explicitly from an approved fixture or choose the disposable
|
|
43
|
+
`--dev` option shown in the [README](../README.md). Never fund a dev fixture.
|
|
44
|
+
|
|
45
|
+
- Never commit a fixture containing a mnemonic or private key.
|
|
46
|
+
- Never print, paste, or record mnemonic/private-key material.
|
|
47
|
+
- Use funded fixtures only in the intended isolated environment.
|
|
48
|
+
- `fixtures set` reads the password from the fixture; do not put it on the
|
|
49
|
+
command line.
|
|
50
|
+
- Human and JSON outputs may identify redacted accounts but must not expose
|
|
51
|
+
secret material.
|
|
52
|
+
|
|
53
|
+
## Evidence and journals
|
|
54
|
+
|
|
55
|
+
Recipe output may include application logs, screenshots, traces, and custom
|
|
56
|
+
action results. Before sharing it:
|
|
57
|
+
|
|
58
|
+
- verify the artifact manifest contains only intended files;
|
|
59
|
+
- search human output, JSON, traces, diagnostics, and reports for credentials;
|
|
60
|
+
- confirm screenshots use the declared provider and show no sensitive UI;
|
|
61
|
+
- keep task-local artifacts out of source control unless intentionally reviewed.
|
|
62
|
+
|
|
63
|
+
`mm-harness last --json` stores a redacted resumability record. It is not a
|
|
64
|
+
secret store.
|
|
65
|
+
|
|
66
|
+
## Runtime isolation
|
|
67
|
+
|
|
68
|
+
Extension uses a checkout-owned Chrome profile and CDP port. Mobile resolves a
|
|
69
|
+
checkout-owned simulator/device and Metro port. Core is headless. Parallel
|
|
70
|
+
checkouts must not share profiles, runtime directories, process markers, or
|
|
71
|
+
evidence directories.
|
|
72
|
+
|
|
73
|
+
On macOS, Extension Chromium uses a mock keychain so an isolated test profile
|
|
74
|
+
does not touch the operator's login keychain. Product configuration and wallet
|
|
75
|
+
fixtures remain user-owned; the harness detects missing prerequisites but never
|
|
76
|
+
invents them.
|
|
77
|
+
|
|
78
|
+
## Release checks
|
|
79
|
+
|
|
80
|
+
Security-sensitive changes require:
|
|
81
|
+
|
|
82
|
+
1. trust-boundary tests proving rejection occurs before side effects;
|
|
83
|
+
2. exact-digest success and stale-digest rejection;
|
|
84
|
+
3. redaction tests for arguments, results, journals, and evidence;
|
|
85
|
+
4. packed-install provenance with no local links;
|
|
86
|
+
5. independent review of the exact diff.
|
|
87
|
+
|
|
88
|
+
Use [QA](QA.md) for the runnable checklist.
|
package/library/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Recipe library
|
|
2
2
|
|
|
3
|
+
- An **action** performs one typed operation.
|
|
4
|
+
- A **recipe** is a parameterized, composable graph that may call actions and
|
|
5
|
+
other recipes.
|
|
6
|
+
|
|
3
7
|
- `actions/<adapter>/<group>/<name>.mjs` — executable action modules.
|
|
4
8
|
**Importing an action module RUNS it**: each ends with `runAdapter(main)` at top
|
|
5
9
|
level, which reads the live-adapter input path from the environment and executes.
|
|
@@ -9,6 +13,6 @@
|
|
|
9
13
|
- Actions load harness helpers ONLY through `actions/harness-exports.mjs` (the
|
|
10
14
|
dist-preferring bridge) — never deep-import `src/` (published installs have no
|
|
11
15
|
src/, and the entrypoint would close an import cycle through adapters.ts).
|
|
12
|
-
- `recipes/` — runnable
|
|
13
|
-
-
|
|
14
|
-
|
|
16
|
+
- `recipes/` — runnable recipes (`mm-harness run <name-or-file>`).
|
|
17
|
+
- Recipe resolution is explicit library order, then bundled MetaMask; selected
|
|
18
|
+
variants and shadows are recorded in run evidence.
|