@deeeed/metamask-harness 0.34.3 → 0.34.4
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 +11 -0
- package/dist/adapters/mobile/source-freshness.js +51 -14
- package/package.json +1 -1
- package/scripts/site-contrast.mjs +31 -11
- package/site/assets/progress.mjs +46 -1
- package/site/assets/style.css +68 -0
- package/site/index.html +90 -30
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.34.4 - 2026-08-12
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Split the site quick start into one-time setup and task-focused workflow tabs.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Update the transitive `tar` dependency from 7.5.19 to 7.5.22.
|
|
14
|
+
- Update transitive `js-yaml`, `nanoid`, and `postcss` dependencies.
|
|
15
|
+
|
|
5
16
|
## 0.34.3 - 2026-08-12
|
|
6
17
|
|
|
7
18
|
### Added
|
|
@@ -21,20 +21,28 @@ const ENV_INPUTS = [".js.env", ".env", ".env.local"];
|
|
|
21
21
|
const BASELINE_FILE = "mobile-source-baseline.json";
|
|
22
22
|
function mobileSourceFingerprint(target) {
|
|
23
23
|
const hash = createHash("sha256");
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
...SOURCE_PATHS
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
24
|
+
const head = tryGit(target, ["rev-parse", "HEAD"]);
|
|
25
|
+
if (head === null) {
|
|
26
|
+
hash.update("non-git\0");
|
|
27
|
+
for (const relative of SOURCE_PATHS) {
|
|
28
|
+
hashPath(hash, target, relative);
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
hash.update(head);
|
|
32
|
+
hash.update(git(target, ["diff", "--no-ext-diff", "--binary", "HEAD", "--", ...SOURCE_PATHS]));
|
|
33
|
+
const untracked = git(target, [
|
|
34
|
+
"ls-files",
|
|
35
|
+
"--others",
|
|
36
|
+
"--exclude-standard",
|
|
37
|
+
"-z",
|
|
38
|
+
"--",
|
|
39
|
+
...SOURCE_PATHS
|
|
40
|
+
]).toString("utf8").split("\0").filter(Boolean).sort();
|
|
41
|
+
for (const relative of untracked) {
|
|
42
|
+
hash.update(`untracked\0${relative}\0`);
|
|
43
|
+
hash.update(fs.readFileSync(path.join(target, relative)));
|
|
44
|
+
hash.update("\0");
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
47
|
for (const relative of ENV_INPUTS) {
|
|
40
48
|
const absolute = path.join(target, relative);
|
|
@@ -84,6 +92,35 @@ function git(target, args) {
|
|
|
84
92
|
stdio: ["ignore", "pipe", "ignore"]
|
|
85
93
|
});
|
|
86
94
|
}
|
|
95
|
+
function tryGit(target, args) {
|
|
96
|
+
try {
|
|
97
|
+
return git(target, args);
|
|
98
|
+
} catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function hashPath(hash, root, relative) {
|
|
103
|
+
const absolute = path.join(root, relative);
|
|
104
|
+
if (!fs.existsSync(absolute)) {
|
|
105
|
+
hash.update(`absent\0${relative}\0`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const stat = fs.lstatSync(absolute);
|
|
109
|
+
if (stat.isDirectory()) {
|
|
110
|
+
hash.update(`directory\0${relative}\0`);
|
|
111
|
+
for (const child of fs.readdirSync(absolute).sort()) {
|
|
112
|
+
hashPath(hash, root, path.join(relative, child));
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (stat.isSymbolicLink()) {
|
|
117
|
+
hash.update(`symlink\0${relative}\0${fs.readlinkSync(absolute)}\0`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
hash.update(`file\0${relative}\0`);
|
|
121
|
+
hash.update(fs.readFileSync(absolute));
|
|
122
|
+
hash.update("\0");
|
|
123
|
+
}
|
|
87
124
|
function readBaseline(target) {
|
|
88
125
|
try {
|
|
89
126
|
const parsed = JSON.parse(
|
package/package.json
CHANGED
|
@@ -146,6 +146,7 @@ const REVEAL = String.raw`
|
|
|
146
146
|
const d = document.getElementById(l.getAttribute('aria-controls'));
|
|
147
147
|
if (d) d.hidden = false;
|
|
148
148
|
});
|
|
149
|
+
document.querySelectorAll('[role="tabpanel"][hidden]').forEach((p) => { p.hidden = false; });
|
|
149
150
|
return true;
|
|
150
151
|
})()
|
|
151
152
|
`;
|
|
@@ -331,6 +332,9 @@ async function auditPage(browserEndpoint, url) {
|
|
|
331
332
|
async function checkBehavior(browserEndpoint, port, pages) {
|
|
332
333
|
const base = `http://127.0.0.1:${port}/`;
|
|
333
334
|
await withPage(browserEndpoint, `${base}index.html`, async (page) => {
|
|
335
|
+
// Step 1 is the hero call to action; it was a collapsible before, so accept
|
|
336
|
+
// either shape. Step 2 is a tabbed set of prompts, one per kind of work —
|
|
337
|
+
// every one of them has to survive a copy, including the hidden panels.
|
|
334
338
|
const copied = await page.evaluate(String.raw`
|
|
335
339
|
(async () => {
|
|
336
340
|
Object.defineProperty(navigator, 'clipboard', {
|
|
@@ -342,22 +346,38 @@ async function checkBehavior(browserEndpoint, port, pages) {
|
|
|
342
346
|
},
|
|
343
347
|
},
|
|
344
348
|
});
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
349
|
+
async function grab(button) {
|
|
350
|
+
if (!button) throw new Error('copy button was not initialized');
|
|
351
|
+
window.__siteCopied = null;
|
|
352
|
+
button.click();
|
|
353
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
354
|
+
return window.__siteCopied;
|
|
355
|
+
}
|
|
356
|
+
const out = { setup: await grab(document.querySelector('.cmd-hero .copy, .prompt .copy')), work: [] };
|
|
357
|
+
for (const tab of document.querySelectorAll('[role="tab"]')) {
|
|
358
|
+
tab.click();
|
|
359
|
+
const panel = document.getElementById(tab.getAttribute('aria-controls'));
|
|
360
|
+
if (!panel || panel.hidden) throw new Error('tab ' + tab.id + ' did not reveal its panel');
|
|
361
|
+
out.work.push(await grab(panel.querySelector('.cmd .copy')));
|
|
362
|
+
}
|
|
363
|
+
return out;
|
|
352
364
|
})()
|
|
353
365
|
`);
|
|
354
|
-
//
|
|
355
|
-
//
|
|
356
|
-
const expected = [
|
|
357
|
-
|
|
366
|
+
// Setting up installs the harness and the skills; the work prompts invoke
|
|
367
|
+
// them by their exact installed names.
|
|
368
|
+
const expected = [
|
|
369
|
+
['npm i -g @deeeed/metamask-harness@latest', copied.setup],
|
|
370
|
+
['yarn skills', copied.setup],
|
|
371
|
+
['/mms-recipe-pr-qa-review', copied.work.join('\n')],
|
|
372
|
+
['/mms-recipe-cook', copied.work.join('\n')],
|
|
373
|
+
];
|
|
374
|
+
const missing = expected.filter(([line, text]) => !text?.includes(line)).map(([line]) => line);
|
|
358
375
|
if (missing.length) {
|
|
359
376
|
throw new Error(`copy prompt omitted ${missing.map((m) => `"${m}"`).join(', ')}`);
|
|
360
377
|
}
|
|
378
|
+
if (copied.work.length < 3) {
|
|
379
|
+
throw new Error(`expected three work prompts, copied ${copied.work.length}`);
|
|
380
|
+
}
|
|
361
381
|
|
|
362
382
|
// The landing page is the lobby: one prompt, one way onward, nothing else.
|
|
363
383
|
const lobby = await page.evaluate(String.raw`
|
package/site/assets/progress.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Shared behaviour for the getting-started site: checklist progress, copy
|
|
3
|
-
* buttons, platform filters, and the layer diagram. No dependencies, no
|
|
3
|
+
* buttons, platform filters, tabs, and the layer diagram. No dependencies, no
|
|
4
4
|
* network, no tracking. Progress lives in localStorage under
|
|
5
5
|
* `mmh.progress.<page>`, where <page> comes from body[data-progress-page].
|
|
6
6
|
* Pages that share a namespace share their state (the How it works walkthrough and the V1
|
|
@@ -235,6 +235,50 @@
|
|
|
235
235
|
select('all');
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
/* ---------- tabs ---------- */
|
|
239
|
+
|
|
240
|
+
/*
|
|
241
|
+
* One tablist per group, roving tabindex: only the selected tab is in the
|
|
242
|
+
* tab order, arrows move between them. Panels stay in the DOM so their
|
|
243
|
+
* commands remain copyable the moment a tab is shown.
|
|
244
|
+
*/
|
|
245
|
+
function initTabs() {
|
|
246
|
+
[].slice.call(document.querySelectorAll('[role="tablist"]')).forEach(function (list) {
|
|
247
|
+
var tabs = [].slice.call(list.querySelectorAll('[role="tab"]'));
|
|
248
|
+
if (!tabs.length) return;
|
|
249
|
+
|
|
250
|
+
function select(tab, focus) {
|
|
251
|
+
tabs.forEach(function (other) {
|
|
252
|
+
var on = other === tab;
|
|
253
|
+
other.setAttribute('aria-selected', String(on));
|
|
254
|
+
other.tabIndex = on ? 0 : -1;
|
|
255
|
+
var panel = document.getElementById(other.getAttribute('aria-controls'));
|
|
256
|
+
if (panel) panel.hidden = !on;
|
|
257
|
+
});
|
|
258
|
+
if (focus) tab.focus();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
tabs.forEach(function (tab, i) {
|
|
262
|
+
tab.addEventListener('click', function () { select(tab, false); });
|
|
263
|
+
tab.addEventListener('keydown', function (e) {
|
|
264
|
+
var next = null;
|
|
265
|
+
if (e.key === 'ArrowRight') next = tabs[(i + 1) % tabs.length];
|
|
266
|
+
if (e.key === 'ArrowLeft') next = tabs[(i - 1 + tabs.length) % tabs.length];
|
|
267
|
+
if (e.key === 'Home') next = tabs[0];
|
|
268
|
+
if (e.key === 'End') next = tabs[tabs.length - 1];
|
|
269
|
+
if (!next) return;
|
|
270
|
+
e.preventDefault();
|
|
271
|
+
select(next, true);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
var current = tabs.filter(function (t) {
|
|
276
|
+
return t.getAttribute('aria-selected') === 'true';
|
|
277
|
+
})[0];
|
|
278
|
+
select(current || tabs[0], false);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
238
282
|
/* ---------- layer diagram ---------- */
|
|
239
283
|
|
|
240
284
|
function initLayers() {
|
|
@@ -261,6 +305,7 @@
|
|
|
261
305
|
initCopy();
|
|
262
306
|
initCellCopy();
|
|
263
307
|
initFilters();
|
|
308
|
+
initTabs();
|
|
264
309
|
initLayers();
|
|
265
310
|
}
|
|
266
311
|
|
package/site/assets/style.css
CHANGED
|
@@ -341,6 +341,74 @@ main { padding-bottom: 6rem; }
|
|
|
341
341
|
border-color: var(--pass);
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
+
/* ---------- quick start (lobby) ----------
|
|
345
|
+
Two steps: set up once, then pick the work. Left-aligned inside the centred
|
|
346
|
+
lobby, because everything in here is read line by line. */
|
|
347
|
+
|
|
348
|
+
.qs { text-align: left; margin-top: 1.8rem; }
|
|
349
|
+
|
|
350
|
+
.qs-step + .qs-step { margin-top: 2.6rem; }
|
|
351
|
+
|
|
352
|
+
.qs-title {
|
|
353
|
+
display: flex;
|
|
354
|
+
align-items: center;
|
|
355
|
+
gap: 0.65rem;
|
|
356
|
+
font-size: 1.16rem;
|
|
357
|
+
font-weight: 640;
|
|
358
|
+
margin: 0 0 0.35rem;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.qs-num {
|
|
362
|
+
flex: none;
|
|
363
|
+
width: 1.6rem;
|
|
364
|
+
height: 1.6rem;
|
|
365
|
+
display: grid;
|
|
366
|
+
place-items: center;
|
|
367
|
+
border-radius: 50%;
|
|
368
|
+
background: var(--accent-soft);
|
|
369
|
+
border: 1px solid var(--accent-line);
|
|
370
|
+
color: var(--accent);
|
|
371
|
+
font-family: var(--mono);
|
|
372
|
+
font-size: 0.8rem;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.qs-why { color: var(--text-dim); font-size: 0.95rem; margin-bottom: 0.9rem; }
|
|
376
|
+
|
|
377
|
+
/* ---------- tabs ---------- */
|
|
378
|
+
|
|
379
|
+
.tablist {
|
|
380
|
+
display: flex;
|
|
381
|
+
flex-wrap: wrap;
|
|
382
|
+
gap: 0.4rem;
|
|
383
|
+
margin-bottom: 0.9rem;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.tab {
|
|
387
|
+
font: 560 0.9rem var(--sans);
|
|
388
|
+
color: var(--text-dim);
|
|
389
|
+
background: var(--surface);
|
|
390
|
+
border: 1px solid var(--line);
|
|
391
|
+
border-radius: 99px;
|
|
392
|
+
padding: 0.4rem 1rem;
|
|
393
|
+
cursor: pointer;
|
|
394
|
+
transition: all 0.16s var(--ease);
|
|
395
|
+
}
|
|
396
|
+
.tab:hover { color: var(--text); border-color: var(--accent-line); }
|
|
397
|
+
.tab[aria-selected="true"] {
|
|
398
|
+
color: var(--accent);
|
|
399
|
+
background: var(--accent-soft);
|
|
400
|
+
border-color: var(--accent-line);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.qs-panel[hidden] { display: none; }
|
|
404
|
+
.qs-panel:focus-visible { outline-offset: 4px; }
|
|
405
|
+
|
|
406
|
+
.qs-panel-why { color: var(--text-dim); font-size: 0.92rem; margin-bottom: 0.5rem; }
|
|
407
|
+
|
|
408
|
+
/* These prompts are the call to action too, so their copy control never hides. */
|
|
409
|
+
.qs-panel .cmd .copy { opacity: 1; }
|
|
410
|
+
.qs-panel .cmd pre { white-space: pre-wrap; word-break: break-word; font-size: 0.82rem; }
|
|
411
|
+
|
|
344
412
|
.lobby-cta { display: flex; justify-content: center; gap: 0.7rem; flex-wrap: wrap; margin-top: 1.6rem; }
|
|
345
413
|
|
|
346
414
|
.lobby-fine {
|
package/site/index.html
CHANGED
|
@@ -21,14 +21,20 @@
|
|
|
21
21
|
self-checked in the same context, then kept as a regression guard.
|
|
22
22
|
</p>
|
|
23
23
|
<p class="lobby-sub">
|
|
24
|
-
Set up, then work a real ticket.
|
|
24
|
+
Set up once, then work a real ticket.
|
|
25
25
|
</p>
|
|
26
26
|
|
|
27
|
-
<
|
|
28
|
-
work. Follow these steps in order. When a command fails, its message names the
|
|
29
|
-
exact next command — run that instead of improvising.
|
|
27
|
+
<section class="qs">
|
|
30
28
|
|
|
31
|
-
|
|
29
|
+
<div class="qs-step">
|
|
30
|
+
<h2 class="qs-title"><span class="qs-num" aria-hidden="true">1</span>Set up</h2>
|
|
31
|
+
<p class="qs-why">
|
|
32
|
+
One time per machine. Paste this into your agent inside a MetaMask checkout.
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
<div class="cmd cmd-hero" id="prompt"><pre><code>Task: set me up for recipe-backed work on MetaMask. Follow these steps in order.
|
|
36
|
+
When a command fails, its message names the exact next command — run that
|
|
37
|
+
instead of improvising.
|
|
32
38
|
|
|
33
39
|
1. Install the harness: `npm i -g @deeeed/metamask-harness@latest`, then
|
|
34
40
|
`mm-harness --version` to confirm it resolved.
|
|
@@ -74,35 +80,89 @@ PART 1 — SET UP
|
|
|
74
80
|
metamask-extension, metamask-mobile, and core. Use `--maturity experimental`
|
|
75
81
|
when listing: the default only prints stable skills, so the recipe skills
|
|
76
82
|
below do not appear without it.
|
|
77
|
-
8. Add the
|
|
78
|
-
`yarn skills --include agentic/recipe-cook --save`
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
8. Add the skills that drive recipe-backed work:
|
|
84
|
+
`yarn skills --include agentic/recipe-cook,agentic/recipe-quality,agentic/recipe-pr-qa-review --save`
|
|
85
|
+
They install as `mms-recipe-cook`, `mms-recipe-quality`, and
|
|
86
|
+
`mms-recipe-pr-qa-review`. They come from the `Consensys/skills` clone in
|
|
87
|
+
step 7 and are marked experimental, which is why the explicit `--include`
|
|
81
88
|
is required. If `yarn metamask-skills describe agentic/recipe-cook` cannot
|
|
82
89
|
find it, check `CONSENSYS_SKILLS_DIR` points at that clone, then stop and
|
|
83
90
|
tell me. Do not substitute a different skill.
|
|
91
|
+
9. Run `mm-harness actions`. That list is the ONLY set of capabilities you may
|
|
92
|
+
use, now and in every later session — never invent an action or a flag. Then
|
|
93
|
+
stop and tell me setup is done.
|
|
94
|
+
|
|
95
|
+
Not optional, from here on: evidence comes only from executed actions — never
|
|
96
|
+
fabricate a result or edit state to manufacture one. If the harness reports a
|
|
97
|
+
capability as unsupported, stop and tell me rather than working around it. If a
|
|
98
|
+
step fails twice after following its error's instructions, stop and show me the
|
|
99
|
+
exact error.</code></pre></div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<div class="qs-step">
|
|
103
|
+
<h2 class="qs-title"><span class="qs-num" aria-hidden="true">2</span>Do real work</h2>
|
|
104
|
+
<p class="qs-why">
|
|
105
|
+
Pick what you are doing. Each one runs the skill that owns that flow, and leaves a
|
|
106
|
+
rerunnable recipe behind as the proof.
|
|
107
|
+
</p>
|
|
108
|
+
|
|
109
|
+
<div class="tabs">
|
|
110
|
+
<div class="tablist" role="tablist" aria-label="Choose what to do">
|
|
111
|
+
<button type="button" role="tab" id="tab-review" class="tab" aria-controls="panel-review" aria-selected="true" tabindex="0">Review a PR</button>
|
|
112
|
+
<button type="button" role="tab" id="tab-fix" class="tab" aria-controls="panel-fix" aria-selected="false" tabindex="-1">Fix a bug</button>
|
|
113
|
+
<button type="button" role="tab" id="tab-build" class="tab" aria-controls="panel-build" aria-selected="false" tabindex="-1">Build a feature</button>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<div class="qs-panel" role="tabpanel" id="panel-review" aria-labelledby="tab-review" tabindex="0">
|
|
117
|
+
<p class="qs-panel-why">
|
|
118
|
+
<code>mms-recipe-pr-qa-review</code> — read-only. It freezes the acceptance criteria
|
|
119
|
+
before it touches the runtime, validates each one on a real build, and returns a report.
|
|
120
|
+
It never edits product code and never posts to GitHub. The PR must be in the same
|
|
121
|
+
product as your checkout.
|
|
122
|
+
</p>
|
|
123
|
+
<div class="cmd"><pre><code>/mms-recipe-pr-qa-review https://github.com/MetaMask/metamask-mobile/pull/<number>
|
|
124
|
+
|
|
125
|
+
Extract the acceptance criteria from the PR yourself and freeze them before any
|
|
126
|
+
runtime work. Validate each one against the running build, then give me the
|
|
127
|
+
per-AC verdict table, the overall verdict, and the artifact paths. Do not post
|
|
128
|
+
anything on the PR.</code></pre></div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div class="qs-panel" role="tabpanel" id="panel-fix" aria-labelledby="tab-fix" tabindex="0" hidden>
|
|
132
|
+
<p class="qs-panel-why">
|
|
133
|
+
<code>mms-recipe-cook</code>, classified as <code>fix-bug</code>. It lists the
|
|
134
|
+
compatible checklist templates and stops for your pick, then works on a local task
|
|
135
|
+
branch. No product edits until the bug is proven to reproduce.
|
|
136
|
+
</p>
|
|
137
|
+
<div class="cmd"><pre><code>/mms-recipe-cook
|
|
138
|
+
|
|
139
|
+
Fix this in the checkout I started you in — treat it as fix-bug:
|
|
140
|
+
<paste the ticket, or the broken behaviour and how to reproduce it>
|
|
141
|
+
|
|
142
|
+
Reproduce it on the real build first and keep that failing run as the baseline.
|
|
143
|
+
Then fix it and re-run the same recipe until it passes. Show me the recipe
|
|
144
|
+
status, the per-node results, and the artifact paths.</code></pre></div>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<div class="qs-panel" role="tabpanel" id="panel-build" aria-labelledby="tab-build" tabindex="0" hidden>
|
|
148
|
+
<p class="qs-panel-why">
|
|
149
|
+
<code>mms-recipe-cook</code>, classified as <code>dev</code>. Same flow: it lists the
|
|
150
|
+
compatible templates, stops for your pick, and keeps the diff uncommitted until you
|
|
151
|
+
ask it to package the PR.
|
|
152
|
+
</p>
|
|
153
|
+
<div class="cmd"><pre><code>/mms-recipe-cook
|
|
154
|
+
|
|
155
|
+
Build this in the checkout I started you in — treat it as dev:
|
|
156
|
+
<paste the ticket, or the change you want>
|
|
157
|
+
|
|
158
|
+
Plan the proof before you edit anything, implement it, then prove it with a
|
|
159
|
+
recipe that drives the real build. Show me the recipe status, the per-node
|
|
160
|
+
results, and the artifact paths.</code></pre></div>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
84
164
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
9. Discover before acting: run `mm-harness actions`. That list is the ONLY set
|
|
88
|
-
of capabilities you may use, now and in every later session. Never invent an
|
|
89
|
-
action or a flag. If you need something not listed, stop and tell me.
|
|
90
|
-
10. Ask me for a ticket or a bug to work on. Then run `/mms-recipe-cook` and
|
|
91
|
-
follow it. It classifies the task as dev, fix-bug, or review-pr, lists the
|
|
92
|
-
compatible checklist templates, and stops for my choice — do not choose for
|
|
93
|
-
me, and do not create a second task if one is already materialized.
|
|
94
|
-
11. Work the checklist it gives you. The recipe it runs is the proof: it drives
|
|
95
|
-
the real build, asserts, and writes the evidence. Show me the status from
|
|
96
|
-
summary.json, the per-node results from trace.json, and the artifact paths.
|
|
97
|
-
12. Re-run that recipe without starting a new session and confirm it still
|
|
98
|
-
passes. Checking your own work in the context you did it in is the point;
|
|
99
|
-
replay it after every change you make from here on.
|
|
100
|
-
|
|
101
|
-
Not optional: evidence comes only from executed actions — never fabricate a
|
|
102
|
-
result or edit state to manufacture one. If the harness reports a capability as
|
|
103
|
-
unsupported, stop and tell me rather than working around it. If a step fails
|
|
104
|
-
twice after following its error's instructions, stop and show me the exact
|
|
105
|
-
error.</code></pre></div>
|
|
165
|
+
</section>
|
|
106
166
|
|
|
107
167
|
<div class="lobby-cta">
|
|
108
168
|
<a class="btn btn-primary" href="how-it-works.html">How it works →</a>
|