Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 82 additions & 43 deletions domains/agentic/skills/recipe-cook/references/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ For MetaMask Mobile PRs, compose existing flows instead of inventing raw evals:
5. **Capture** — screenshot/video/log only after the assertion proves the screen settled.
6. **Teardown** — reset wallet/app state when a run changes balances, permissions, txs, or network.

Good Mobile recipes compose the v1 manifest's semantic actions instead of shelling to scripts. Prefer, where the installed manifest advertises them:
Good Mobile recipes compose the runner manifest's semantic actions instead of shelling to scripts. Prefer, where the installed manifest advertises them:

- `metamask.wallet.setup`, `metamask.wallet.ensure_unlocked`, `metamask.wallet.select_account`, `metamask.wallet.read_state` for wallet setup/start-state.
- `metamask.perps.start_state`, `metamask.perps.ensure_positions`, `metamask.perps.ensure_orders`, `metamask.perps.place_order`, `metamask.perps.close_positions`, `metamask.perps.read_positions`, `metamask.perps.assert_positions` for Perps flows.
- `ui.navigate`, `ui.wait_for`, `ui.press`, `ui.set_input`, `ui.scroll`, `ui.screenshot`, `app.status`, `app.hud` for the user path and evidence.

`call`/flow-catalog composition is valid only when the installed runner manifest advertises a flow catalog; do not point at in-repo flow files (the legacy `scripts/perps/agentic/teams/perps/flows/*` recipes are not part of the v1 model). When reusing an action or flow, state which proof target it covers and add only the nodes needed for the PR-specific claim.
`call`/flow-catalog composition is valid only when the installed runner manifest advertises a flow catalog; do not point at in-repo flow files (the legacy `scripts/perps/agentic/teams/perps/flows/*` recipes are not part of the runner model). When reusing an action or flow, state which proof target it covers and add only the nodes needed for the PR-specific claim.

## Mobile Direct Smoke Recipe

Expand All @@ -28,53 +28,61 @@ Use this for live-device validation of the recipe plumbing itself. It intentiona
```json
{
"schema_version": 1,
"title": "Mobile direct smoke reach a settled wallet screen",
"description": "Proves the Mobile debug app is reachable and the v1 runner can drive the bridge to a settled wallet screen. Intentionally avoids wallet-specific assertions beyond reachability.",
"title": "Mobile direct smoke \u2014 reach a settled wallet screen",
"description": "Proves the Mobile debug app is reachable and the runner can drive the bridge to a settled wallet screen. Intentionally avoids wallet-specific assertions beyond reachability.",
"validate": {
"workflow": {
"pre_conditions": ["Run from the metamask-mobile checkout", "Debug app is already running on the intended simulator"],
"pre_conditions": [
"Run from the metamask-mobile checkout",
"Debug app is already running on the intended simulator"
],
"entry": "status",
"nodes": {
"status": {
"action": "app.status",
"description": "PT-1: read app route/device/platform through the v1 app.status action",
"timeout_ms": 30000,
"next": "ensure-unlocked"
"next": "ensure-unlocked",
"intent": "PT-1: read app route/device/platform through the app.status action"
},
"ensure-unlocked": {
"action": "metamask.wallet.ensure_unlocked",
"description": "PT-1: idempotently reach an unlocked wallet",
"timeout_ms": 45000,
"next": "navigate-wallet"
"next": "navigate-wallet",
"intent": "PT-1: idempotently reach an unlocked wallet"
},
"navigate-wallet": {
"action": "ui.navigate",
"description": "PT-2: open the wallet view through the navigation layer",
"route": "WalletView",
"timeout_ms": 30000,
"next": "wait-wallet"
"next": "wait-wallet",
"intent": "PT-2: open the wallet view through the navigation layer"
},
"wait-wallet": {
"action": "ui.wait_for",
"description": "PT-2: the wallet screen is present after navigation settles",
"test_id": "wallet-screen",
"expected": "present",
"timeout_ms": 30000,
"next": "capture"
"next": "capture",
"intent": "PT-2: the wallet screen is present after navigation settles"
},
"capture": {
"action": "ui.screenshot",
"description": "PT-2: reviewer-visible settled wallet screen",
"path": "screenshots/mobile-direct-smoke-wallet.png",
"next": "index-artifacts"
"next": "index-artifacts",
"intent": "PT-2: reviewer-visible settled wallet screen"
},
"index-artifacts": {
"action": "index_artifacts",
"description": "Index the screenshot proof",
"artifacts": ["screenshots/"],
"next": "done"
"artifacts": [
"screenshots/"
],
"next": "done",
"intent": "Index the screenshot proof"
},
"done": { "action": "end", "status": "pass" }
"done": {
"action": "end",
"status": "pass"
}
},
"teardown": []
}
Expand All @@ -100,38 +108,50 @@ This pattern composes a real Mobile flow and adds a PR-specific assertion. It is
},
"validate": {
"workflow": {
"pre_conditions": ["wallet.unlocked", "perps.feature_enabled"],
"pre_conditions": [
"wallet.unlocked",
"perps.feature_enabled"
],
"entry": "open-market",
"nodes": {
"open-market": {
"action": "ui.navigate",
"description": "PT-1: open the BTC market detail through the raw Perps market route",
"route": "PerpsMarketDetails",
"params": { "market": { "symbol": "{{symbol}}" } },
"params": {
"market": {
"symbol": "{{symbol}}"
}
},
"timeout_ms": 30000,
"next": "wait-market"
"next": "wait-market",
"intent": "PT-1: open the BTC market detail through the raw Perps market route"
},
"wait-market": {
"action": "ui.wait_for",
"description": "PT-2: after navigation settles, the BTC market detail content is present",
"text": "{{symbol}}",
"expected": "present",
"timeout_ms": 30000,
"next": "capture-detail"
"next": "capture-detail",
"intent": "PT-2: after navigation settles, the BTC market detail content is present"
},
"capture-detail": {
"action": "ui.screenshot",
"description": "PT-2: reviewer-visible settled market detail screen",
"path": "screenshots/perps-btc-detail.png",
"next": "index-artifacts"
"next": "index-artifacts",
"intent": "PT-2: reviewer-visible settled market detail screen"
},
"index-artifacts": {
"action": "index_artifacts",
"description": "Index state and screenshot evidence",
"artifacts": ["screenshots/"],
"next": "done"
"artifacts": [
"screenshots/"
],
"next": "done",
"intent": "Index state and screenshot evidence"
},
"done": { "action": "end", "status": "pass" }
"done": {
"action": "end",
"status": "pass"
}
},
"teardown": []
}
Expand All @@ -151,31 +171,42 @@ Use command assertions when the PR claim is not user-facing.
"inputs": {},
"validate": {
"workflow": {
"pre_conditions": ["PR branch is checked out"],
"pre_conditions": [
"PR branch is checked out"
],
"setup": [],
"entry": "run-focused-test",
"nodes": {
"run-focused-test": {
"action": "command",
"description": "PT-1: focused unit test covers malformed metadata",
"cmd": "mkdir -p reports && yarn test --runInBand app/core/token-service/metadata.test.ts --json --outputFile reports/jest-token-metadata.json",
"timeout_ms": 120000,
"next": "assert-pass"
"next": "assert-pass",
"intent": "PT-1: focused unit test covers malformed metadata"
},
"assert-pass": {
"action": "assert_json",
"description": "PT-1: Jest reports zero failed tests",
"path": "reports/jest-token-metadata.json",
"assert": { "path": "$.numFailedTests", "operator": "eq", "value": 0 },
"next": "index-artifacts"
"assert": {
"path": "$.numFailedTests",
"operator": "eq",
"value": 0
},
"next": "index-artifacts",
"intent": "PT-1: Jest reports zero failed tests"
},
"index-artifacts": {
"action": "index_artifacts",
"description": "Index the test report",
"artifacts": ["reports/jest-token-metadata.json"],
"next": "done"
"artifacts": [
"reports/jest-token-metadata.json"
],
"next": "done",
"intent": "Index the test report"
},
"done": { "action": "end", "status": "pass" }
"done": {
"action": "end",
"status": "pass"
}
},
"teardown": []
}
Expand All @@ -193,8 +224,16 @@ Use command assertions when the PR claim is not user-facing.
"workflow": {
"entry": "test",
"nodes": {
"test": { "action": "wait", "duration_ms": 10000, "next": "done" },
"done": { "action": "end", "status": "pass" }
"test": {
"action": "wait",
"duration_ms": 10000,
"next": "done",
"intent": "Perform test for recipe proof"
},
"done": {
"action": "end",
"status": "pass"
}
}
}
}
Expand Down
22 changes: 11 additions & 11 deletions domains/agentic/skills/recipe-cook/references/recipe-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ Use this shape unless the target repo already publishes a stricter schema.
```json
{
"schema_version": 1,
"title": "Human-readable validation title",
"description": "What this recipe proves",
"inputs": {},
"proofTargets": [
{ "id": "PT-1", "claim": "The changed behavior is visible and settled." }
Expand All @@ -21,28 +19,28 @@ Use this shape unless the target repo already publishes a stricter schema.
"nodes": {
"start": {
"action": "command",
"description": "Run a project-native check",
"intent": "Run a project-native check",
"cmd": "mkdir -p logs && yarn test --runInBand path/to/test > logs/test.log 2>&1; status=$?; cat logs/test.log; exit $status",
"timeout_ms": 120000,
"next": "assert-result"
},
"assert-result": {
"action": "assert_exit_code",
"description": "Check the project-native check passed",
"intent": "Check the project-native check passed",
"expected": 0,
"next": "assert-output"
},
"assert-output": {
"action": "assert_output",
"description": "Check the project-native output looked successful",
"intent": "Check the project-native output looked successful",
"source": "start",
"stream": "stdout",
"contains": "PASS",
"next": "index-artifacts"
},
"index-artifacts": {
"action": "index_artifacts",
"description": "Write the artifact manifest",
"intent": "Write the artifact manifest",
"artifacts": ["logs/test.log"],
"next": "done"
},
Expand All @@ -57,7 +55,7 @@ Use this shape unless the target repo already publishes a stricter schema.

## Composition and start-state fields

Recipe v1 authoring should support reusable flow composition. When the installed runner publishes flow catalogs, prefer `call` nodes over repeated raw setup.
Recipe authoring should support reusable flow composition. When the installed runner publishes flow catalogs, prefer `call` nodes over repeated raw setup.

Recommended metadata:

Expand All @@ -71,6 +69,7 @@ Recommended current MetaMask setup action shape:
```json
{
"action": "metamask.perps.start_state",
"intent": "Converge Perps to the requested baseline before proof",
"phase": "start_state",
"network": "testnet",
"provider": "hyperliquid",
Expand All @@ -86,21 +85,22 @@ An `ensure_*` or `start_state` action/flow is idempotent: it inspects the curren
Minimum required fields:

- `schema_version: 1`
- `title`
- `description`
- `validate.workflow.entry`
- non-empty `validate.workflow.nodes`
- `intent` on every non-terminal executable node

Node rules:

- Every node key is a stable id.
- Every node has `action` and `description`, except a minimal terminal `end` node.
- Every non-terminal node has `action` and `intent`, except a minimal terminal `end` node.
- Every non-terminal node has `next`, `cases`, or `default`.
- Transition targets exist.
- At least one node reaches `action: "end"`.
- Assertions name the proof target they validate, either in `description` or a `proofTarget` field.
- Assertions name the proof target they validate with `proofTarget`.
- Setup/start-state flows should be declared separately from proof nodes so evidence can focus on the AC interaction.

Every non-terminal recipe node needs `intent`: one short HUD/trace line for what the agent is doing now. Do not use generic/action/node/selector/test-id/title/description/note text, and do not author sub-intent/HUD fields.

Action classes:

- Portable/base: `command`, `wait`, `assert_json`, `assert_file`, `assert_exit_code`, `assert_output`, `watch_logs`, `index_artifacts`, `end`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Prefer repo-owned browser, extension, fixture, and mock helpers over raw CDP sni

## Common Action Mapping

Use only action names declared by the installed v1 action manifest. Typical Extension mappings are:
Use only action names declared by the installed action manifest. Typical Extension mappings are:

- Launch extension: `/recipe-harness` live/verify flow or runner setup with `--launch-existing-dist`.
- Open route/popup: `ui.navigate` with a raw extension `hash` route, e.g. `{ "hash": "#/?tab=perps" }`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Do this especially on historical commits, where the checked-out runner may be st

## Common Action Mapping

Use only action names declared by the installed v1 action manifest. Typical Mobile mappings are:
Use only action names declared by the installed action manifest. Typical Mobile mappings are:

- Open app area/screen: `ui.navigate` with a raw `route` (and optional `params`), e.g. `{ "route": "PerpsMarketListView" }` or `{ "route": "PerpsMarketDetails", "params": { "market": { "symbol": "ETH" } } }`.
- Tap: `ui.press` with a stable `test_id`, text, or page-object target.
Expand Down
Loading
Loading