@mutmutco/kilo-plugin 4.1.3 → 4.1.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/package.json +1 -1
- package/scripts/hook-run.mjs +22 -4
- package/scripts/throttle-core.mjs +8 -0
- package/skills/bootstrap/SKILL.md +7 -3
- package/skills/bootstrap/seeds/gate.template.yml +4 -5
- package/skills/browser-automation/SKILL.md +50 -23
- package/skills/epic/SKILL.md +6 -2
- package/skills/hotfix/SKILL.md +8 -1
- package/skills/mmi/SKILL.md +22 -1
- package/skills/release/SKILL.md +40 -3
- package/skills/repo-index-audit/SKILL.md +70 -0
- package/skills/stage/SKILL.md +4 -1
package/package.json
CHANGED
package/scripts/hook-run.mjs
CHANGED
|
@@ -65,6 +65,14 @@ export function parseHookArgv(argv) {
|
|
|
65
65
|
return parsed;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/** When PowerShell `--%` turns Cursor's POSIX `< payload` into argv instead of a redirect (#5580). */
|
|
69
|
+
export function stdinRedirectPath(argv) {
|
|
70
|
+
const at = argv.indexOf('<');
|
|
71
|
+
if (at === -1 || at + 1 >= argv.length) return '';
|
|
72
|
+
const path = argv[at + 1];
|
|
73
|
+
return path && !path.startsWith('-') ? path : '';
|
|
74
|
+
}
|
|
75
|
+
|
|
68
76
|
export function pluginRoot(surfaceToken, env = process.env, here = HERE) {
|
|
69
77
|
const surface = hookSurface(surfaceToken);
|
|
70
78
|
for (const name of surface.rootEnv) {
|
|
@@ -384,19 +392,29 @@ function stripUtf8Bom(input) {
|
|
|
384
392
|
return buffer[0] === 0xef && buffer[1] === 0xbb && buffer[2] === 0xbf ? buffer.subarray(3) : buffer;
|
|
385
393
|
}
|
|
386
394
|
|
|
387
|
-
function readStdin() {
|
|
395
|
+
function readStdin(argv = process.argv.slice(2)) {
|
|
388
396
|
try {
|
|
389
|
-
|
|
397
|
+
const piped = readFileSync(0);
|
|
398
|
+
if (piped.length) return piped;
|
|
390
399
|
} catch {
|
|
391
|
-
|
|
400
|
+
// fall through to a `--%`-preserved payload path
|
|
401
|
+
}
|
|
402
|
+
const redirect = stdinRedirectPath(argv);
|
|
403
|
+
if (redirect && existsSync(redirect)) {
|
|
404
|
+
try {
|
|
405
|
+
return readFileSync(redirect);
|
|
406
|
+
} catch {
|
|
407
|
+
return Buffer.alloc(0);
|
|
408
|
+
}
|
|
392
409
|
}
|
|
410
|
+
return Buffer.alloc(0);
|
|
393
411
|
}
|
|
394
412
|
|
|
395
413
|
export async function main(argv = process.argv.slice(2)) {
|
|
396
414
|
const { surface, gate } = parseHookArgv(argv);
|
|
397
415
|
let result;
|
|
398
416
|
try {
|
|
399
|
-
result = await runPolicyGate({ surface, gate, input: readStdin() });
|
|
417
|
+
result = await runPolicyGate({ surface, gate, input: readStdin(argv) });
|
|
400
418
|
} catch (error) {
|
|
401
419
|
process.stderr.write(`[mmi-hook] ${error.message}\n`);
|
|
402
420
|
process.exit(1);
|
|
@@ -225,6 +225,14 @@ export function analyzeShellDialect(command, shellFamily, platform = process.pla
|
|
|
225
225
|
+ '`>/dev/null` for stdout suppression, or Bash variables instead.',
|
|
226
226
|
);
|
|
227
227
|
}
|
|
228
|
+
// #5561: Windows device name NUL as a relative redirect creates ./NUL under Git Bash / MSYS.
|
|
229
|
+
if (/(?:^|[\s;&|])(?:\d*>+|>>)\s*NUL\b/i.test(bashCmd)) {
|
|
230
|
+
return dialectReason(
|
|
231
|
+
'shell_dialect_nul_redirect_in_bash',
|
|
232
|
+
'Redirecting to relative `NUL` creates a `./NUL` file under Git Bash / MSYS. '
|
|
233
|
+
+ 'Use `>/dev/null` (or `2>/dev/null`) instead.',
|
|
234
|
+
);
|
|
235
|
+
}
|
|
228
236
|
if (/\bSelect-Object\b/i.test(bashCmd)) {
|
|
229
237
|
return dialectReason(
|
|
230
238
|
'shell_dialect_select_object_in_bash',
|
|
@@ -531,9 +531,13 @@ variant; the runtime reads only the canonical names and declare-first rejects th
|
|
|
531
531
|
Local `/stage` is optional product-owned configuration. A repo that wants `/stage` may carry a local
|
|
532
532
|
`stage` block, but that file must not contain board, deploy, or secret registry facts.
|
|
533
533
|
|
|
534
|
-
**Stage port block:** run `mmi-cli stage port-range <Repo>` to assign
|
|
535
|
-
|
|
536
|
-
|
|
534
|
+
**Stage port block (required for central-container):** run `mmi-cli stage port-range <Repo>` to assign
|
|
535
|
+
(idempotently) the repo's local port block from the central registry. `tenant-container` and
|
|
536
|
+
`solo-container` **must** have Hub registry `portRange` — `mmi-cli devops bootstrap verify` fails without
|
|
537
|
+
it (#5539), and `mmi-cli stage` cannot derive a local preview until the block exists. `bootstrap apply
|
|
538
|
+
--execute` assigns the block automatically after DDB register for those models; for older META holes,
|
|
539
|
+
run `stage port-range` explicitly. Use `$STAGE_PORT` in `stage.up` / `healthUrl`; `/stage` then picks a
|
|
540
|
+
free port inside the block so a dev can run several projects/versions locally without collisions.
|
|
537
541
|
|
|
538
542
|
## Step 7 — seed the org-managed .gitignore block
|
|
539
543
|
|
|
@@ -22,11 +22,11 @@ name: gate
|
|
|
22
22
|
# GATE_FULL_RUN_BRANCH — train branch whose PUSHES run the full gate job (development on full/direct;
|
|
23
23
|
# main on trunk). `main` is ALWAYS included in the job `if:` below so a required-
|
|
24
24
|
# checks ruleset on main cannot be silently skipped by a future bootstrap (#4113).
|
|
25
|
-
# GATE_WINDOWS_COMPAT — `true` opts the repo into the informational windows-latest compat job
|
|
26
|
-
# (#5113: registry gate={"windowsCompat":true} or --var). Default OFF: Windows
|
|
27
|
-
# minutes cost more than Linux and the required gate stays the Linux lane.
|
|
28
25
|
# GATE_BUDGET_SHA is rendered by the CLI from its blessed run-with-budget pin — not an operator knob.
|
|
29
|
-
#
|
|
26
|
+
# Estate policy 2026-08-23: GitHub-hosted Windows (`windows-latest` / windows-*) is forbidden org-wide.
|
|
27
|
+
# Do not add a windows-compat (or any other) job that runs-on GH-hosted Windows. Linux self-hosted
|
|
28
|
+
# (mmi-live / mmi-heavy) is the only CI merge gate. Rare Windows proof stays on the owner's machine or
|
|
29
|
+
# a future self-hosted Windows runner — never windows-latest.
|
|
30
30
|
# (seed touch: keep kilo mirror + BOM digests in lockstep after classifier land.)
|
|
31
31
|
on:
|
|
32
32
|
pull_request:
|
|
@@ -118,4 +118,3 @@ jobs:
|
|
|
118
118
|
command: {{GATE_CMD}}
|
|
119
119
|
max-seconds: {{GATE_MAX_SECONDS}}
|
|
120
120
|
working-directory: {{GATE_WORKDIR}}
|
|
121
|
-
{{GATE_WINDOWS_COMPAT_JOB_YAML}}
|
|
@@ -1,43 +1,54 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: browser-automation
|
|
3
|
-
description:
|
|
3
|
+
description: Route browser work by host — JervCode lanes or Claude Code Playwright MCP.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
**Host-native invocation:** Claude `/mmi:browser-automation` · Codex `$mmi:browser-automation` · jervcode/Kimi `/skill:browser-automation` · Kilo `skill` tool. A backticked `/name` in this doc names the matching workflow (this skill or a sibling), not a literal command.
|
|
7
7
|
|
|
8
|
-
# Browser automation —
|
|
8
|
+
# Browser automation — host lanes
|
|
9
|
+
|
|
10
|
+
Org browser skill. **Choose the host lane first.** JervCode and Kimi use the native three-lane browser contract; Claude Code uses DOM-first Playwright MCP. Do not install or select Playwright MCP on JervCode.
|
|
11
|
+
|
|
12
|
+
## Host routing (non-negotiable)
|
|
13
|
+
|
|
14
|
+
| Host | Path |
|
|
15
|
+
|------|------|
|
|
16
|
+
| **JervCode / Kimi** | Three lanes below — never Playwright MCP |
|
|
17
|
+
| **Claude Code** | DOM-first Playwright MCP (Claude-only section) |
|
|
18
|
+
| Local app stack | **`/stage`** — see `skills/stage/SKILL.md` |
|
|
19
|
+
|
|
20
|
+
### JervCode / Kimi — three lanes
|
|
21
|
+
|
|
22
|
+
Authoritative for native JervCode browser work (Jerv-JervCode `product/runbooks/browser.md`, #1694). Pick by need:
|
|
23
|
+
|
|
24
|
+
| Need | Tool |
|
|
25
|
+
|------|------|
|
|
26
|
+
| Plain read (no interaction) | `fetch_content` |
|
|
27
|
+
| Public interaction (clicks/types on public pages) | `agent_browser` |
|
|
28
|
+
| Authenticated interaction | `trusted_browser` |
|
|
29
|
+
|
|
30
|
+
**Do not** install or select Playwright MCP for JervCode. Public interaction goes to `agent_browser`, not Playwright.
|
|
31
|
+
|
|
32
|
+
### Claude Code — DOM-first Playwright MCP
|
|
9
33
|
|
|
10
34
|
Org standard for agent browser work on Claude Code. **Playwright** is the engine; agents interact through **structure-first** MCP tools, not pixels-first defaults.
|
|
11
35
|
|
|
12
|
-
|
|
36
|
+
#### Doctrine (non-negotiable on Claude Code)
|
|
13
37
|
|
|
14
38
|
1. **Accessibility tree first** — semantic structure the agent can reason about (`browser_snapshot`, a11y refs).
|
|
15
39
|
2. **DOM second** — selectors, snapshots, network when the tree is not enough.
|
|
16
40
|
3. **Vision last** — screenshots only when tree + DOM cannot answer the question.
|
|
17
41
|
4. **Prefer HTTP/OpenAPI** — call APIs directly when discovery or the task allows; do not drive UI for data you can fetch.
|
|
18
42
|
|
|
19
|
-
**Never** pass `--caps=vision` (or equivalent vision-first defaults) on Playwright MCP
|
|
43
|
+
**Never** pass `--caps=vision` (or equivalent vision-first defaults) on Playwright MCP. Vision caps burn tokens, hide structure, and break on theme/layout drift.
|
|
20
44
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| Need | Use |
|
|
24
|
-
|------|-----|
|
|
25
|
-
| Local dev server + smoke on current branch | **`/stage`** — gitignored stack under `tmp/stage/`; see `skills/stage/SKILL.md` |
|
|
26
|
-
| Personal cloud dev preview of your branch | **`/stage --live`** — IP-gated dev stage; not rc/prod |
|
|
27
|
-
| Interactive UI debug, one-off flow, agent-driven clicks | **Playwright MCP** (this skill) — DOM-first, artifacts under `tmp/` |
|
|
28
|
-
| Durable hosted automation outside dev machines | **Stagehand + Browserbase** (production path) — explicit choice, not the default for every local task |
|
|
29
|
-
|
|
30
|
-
`/stage` and Playwright MCP **complement** each other. `/stage` spins the app; MCP drives the browser against a URL (often the stage URL).
|
|
31
|
-
|
|
32
|
-
## MCP configuration (no vision)
|
|
33
|
-
|
|
34
|
-
### Claude Code
|
|
45
|
+
#### MCP configuration (Claude Code, no vision)
|
|
35
46
|
|
|
36
47
|
Enable the official Playwright plugin (`playwright@claude-plugins-official`) via `/plugin`. Follow its DOM-first tools; do not enable vision-first modes for routine agent work. Point MCP output at `tmp/playwright-mcp` when the server accepts `--output-dir`.
|
|
37
48
|
|
|
38
49
|
Editor-host MCP configs (Cursor `.cursor/mcp.json`, Codex `config.toml`) are retired org surfaces (#2741/#2808) — bootstrap no longer seeds them; do not reintroduce them.
|
|
39
50
|
|
|
40
|
-
|
|
51
|
+
#### Playwright availability
|
|
41
52
|
|
|
42
53
|
Check the configured/global CLI before adding a temporary local dependency. On Windows PowerShell:
|
|
43
54
|
|
|
@@ -50,7 +61,7 @@ playwright --version
|
|
|
50
61
|
can fail while the global or editor-configured Playwright CLI works. Use the available CLI for smoke checks
|
|
51
62
|
and MCP setup. Temporary per-worktree installs are fallback-only, and should stay untracked.
|
|
52
63
|
|
|
53
|
-
|
|
64
|
+
#### Agent workflow (MCP) (Claude Code)
|
|
54
65
|
|
|
55
66
|
1. **Goal** — what observable outcome proves success?
|
|
56
67
|
2. **Navigate** — open the target URL (often from `/stage` JSON: `mmi-cli stage --json`).
|
|
@@ -65,24 +76,40 @@ Core MCP loop:
|
|
|
65
76
|
browser_navigate → browser_snapshot → browser_click / browser_type → browser_snapshot
|
|
66
77
|
```
|
|
67
78
|
|
|
68
|
-
|
|
79
|
+
#### Artifacts and hygiene (Claude Code)
|
|
69
80
|
|
|
70
81
|
- **All Playwright MCP output → `tmp/playwright-mcp/`** (pass `--output-dir tmp/playwright-mcp` when the MCP server supports it).
|
|
71
82
|
- **Never** leave traces, screenshots, or reports at the repo root.
|
|
72
83
|
- `.playwright-mcp/` at repo root is gitignored as a **safety net only** — not the canonical path.
|
|
73
84
|
- The housekeeping gate refuses tracked browser artifacts (`.playwright-mcp/`, `playwright-report/`, `test-results/`).
|
|
74
85
|
|
|
86
|
+
## When to use what
|
|
87
|
+
|
|
88
|
+
| Need | Use |
|
|
89
|
+
|------|-----|
|
|
90
|
+
| Local dev server + smoke on current branch | **`/stage`** — gitignored stack under `tmp/stage/`; see `skills/stage/SKILL.md` |
|
|
91
|
+
| Personal cloud dev preview of your branch | **`/stage --live`** — IP-gated dev stage; not rc/prod |
|
|
92
|
+
| Interactive UI on **Claude Code** | **Playwright MCP** (Claude-only section) — DOM-first, artifacts under `tmp/` |
|
|
93
|
+
| Interactive UI on **JervCode / Kimi** (public) | **`agent_browser`** |
|
|
94
|
+
| Interactive UI on **JervCode / Kimi** (authenticated) | **`trusted_browser`** |
|
|
95
|
+
| Plain page/content read on **JervCode / Kimi** | **`fetch_content`** |
|
|
96
|
+
| Durable hosted automation outside dev machines | **Stagehand + Browserbase** (production path) — explicit choice, not the default for every local task |
|
|
97
|
+
|
|
98
|
+
`/stage` and the host browser path **complement** each other. `/stage` spins the app; the host lane drives the browser against a URL (often the stage URL).
|
|
99
|
+
|
|
75
100
|
## Anti-patterns (org-wide avoid)
|
|
76
101
|
|
|
77
|
-
-
|
|
102
|
+
- Installing or selecting Playwright MCP on JervCode (use `fetch_content` / `agent_browser` / `trusted_browser`)
|
|
103
|
+
- `--caps=vision` or screenshot-first wrappers for routine Claude Code tasks
|
|
78
104
|
- Skyvern, Magnitude, LaVague, or other vision-first agent browsers as org defaults
|
|
79
105
|
- Committing `.playwright-mcp/`, `playwright-report/`, or `test-results/` from agent runs
|
|
80
|
-
- Replacing `/stage` with ad-hoc MCP servers for branch smoke (use `/stage` for the stack,
|
|
106
|
+
- Replacing `/stage` with ad-hoc MCP servers for branch smoke (use `/stage` for the stack, the host lane for the browser)
|
|
81
107
|
|
|
82
108
|
## Related
|
|
83
109
|
|
|
84
110
|
- **`/stage`** — `skills/stage/SKILL.md`
|
|
85
111
|
- **`/grind`** (optional external tool) — use DOM-first browser checks in verification when criteria need UI proof
|
|
112
|
+
- JervCode browser contract — Jerv-JervCode `product/runbooks/browser.md` (#1694)
|
|
86
113
|
|
|
87
114
|
## Retro — one check before you finish
|
|
88
115
|
|
package/skills/epic/SKILL.md
CHANGED
|
@@ -78,7 +78,10 @@ When creating through `mmi-cli vault secrets use GH_TOKEN -- …`, the `GH_TOKEN
|
|
|
78
78
|
disrupt Hub session discovery and print `board attach skipped — no Hub session token` for batch rows. That
|
|
79
79
|
warning can appear when placement is correct, but it is not harmless or proof of placement: final verification
|
|
80
80
|
must prove every intended child is linked and on the board as Todo with `mmi-cli oracle issue children
|
|
81
|
-
<owner/repo#N> --json`.
|
|
81
|
+
<owner/repo#N> --json`. `boardStatus: null` is **inconclusive** (the children walk can miss org-board
|
|
82
|
+
Status that `board show` still sees) — it is not proof the child is off the board. A non-null Status
|
|
83
|
+
(Todo / In Progress / …) is the placement proof; if Status stays null after this command, investigate
|
|
84
|
+
with `board show` rather than treating null as "not on board".
|
|
82
85
|
|
|
83
86
|
The idempotency lookup is find-before-create, not an atomic reservation. Run one batch writer at a time:
|
|
84
87
|
never submit concurrent creates with the same key. Size the calling command's wall-clock budget for the
|
|
@@ -91,7 +94,8 @@ wait for writes to quiesce, inspect the children, then retry the missing rows wi
|
|
|
91
94
|
mmi-cli oracle issue children <owner/repo#N> --json # each child: number/title/state/repo/assignee/boardStatus/linkedPrs
|
|
92
95
|
```
|
|
93
96
|
|
|
94
|
-
This JSON is the final placement authority: verify every intended child is linked and on the board as Todo
|
|
97
|
+
This JSON is the final placement authority: verify every intended child is linked and on the board as Todo
|
|
98
|
+
(`boardStatus` names Todo). `boardStatus: null` is inconclusive, not "not on board".
|
|
95
99
|
If it does not prove that placement, investigate and correct the misfire. To link a child that already existed (not
|
|
96
100
|
part of the batch), use the inverse-friendly single link:
|
|
97
101
|
|
package/skills/hotfix/SKILL.md
CHANGED
|
@@ -53,7 +53,14 @@ mmi-cli oracle org access role <owner/repo> --json
|
|
|
53
53
|
mmi-cli doctor --no-repo-writes
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
Stop on a red authority or CLI-version result.
|
|
56
|
+
Stop on a red authority or CLI-version result. **Hub hotfix release runs the same distribution fold as
|
|
57
|
+
`/release`:** if `process.cwd()` contains whitespace, stop before `hotfix start` / `hotfix release`
|
|
58
|
+
touches local `main` (#5603). Relocate the clone to a real no-space path. A subst / junction /
|
|
59
|
+
drive-letter alias that hides spaces is not a valid workaround — canonical-root containment still
|
|
60
|
+
sees the physical path, so materialization inputs resolve outside the alias root. See `/release`
|
|
61
|
+
Step 0e.
|
|
62
|
+
|
|
63
|
+
The worktree must be clean; move scratch into `tmp/` or
|
|
57
64
|
gitignore it rather than widening the hotfix diff. A TRACKED path named in a `working tree must be clean
|
|
58
65
|
before …` refusal is not scratch: read both `git status --porcelain` columns, treat every state except
|
|
59
66
|
exactly ` M` as real work to commit or stash, and for ` M` discard only when
|
package/skills/mmi/SKILL.md
CHANGED
|
@@ -16,6 +16,21 @@ universal literal command.
|
|
|
16
16
|
Status values: `Todo · In Progress · In Review · Done` (GitHub enforces who can move what — don't re-explain
|
|
17
17
|
it on every move). Closed/finished items auto-archive after they go quiet; archived ones aren't on the board.
|
|
18
18
|
|
|
19
|
+
## Hard invariants (#5552 — load before any write)
|
|
20
|
+
|
|
21
|
+
Two rules sit above every later step. Read them before claiming, filing, or guessing a CLI route:
|
|
22
|
+
|
|
23
|
+
1. **Claims are board mutations.** The only valid claim write is
|
|
24
|
+
`mmi-cli oracle board claim <ref>` (optional `--json` / `--for` / `--check`). Never infer or guess an
|
|
25
|
+
`oracle issue claim` route — that path does not exist under `oracle issue` (create/view/edit/… only).
|
|
26
|
+
If the exact write route was not already grounded in this skill or a live
|
|
27
|
+
`mmi-cli commands` / `mmi-cli explain` result, read one of those before invoking it. Do not retry a
|
|
28
|
+
guessed `issue …` spelling after a refusal; take the suggested `oracle board claim` form.
|
|
29
|
+
2. **`learning`-tagged reports are cloud-agent work.** After `mmi-cli learning report` (or
|
|
30
|
+
`learning skill-lesson`), file and forget: return to the current task immediately. Never claim, poll,
|
|
31
|
+
wait on, force-take, or duplicate implementation of the filed learning issue. Consume eventual
|
|
32
|
+
propagation separately when it lands; do not own that fix in this session.
|
|
33
|
+
|
|
19
34
|
## Step 0 — identity, greet, eager preflight when stale
|
|
20
35
|
|
|
21
36
|
`/mmi` is the dev's hello-to-work — the most common command they run. Three pacing rules before anything else:
|
|
@@ -293,7 +308,7 @@ something else* paths.)
|
|
|
293
308
|
- **Claim:** when the dev takes an item, assign them + set `In Progress` in one go. This is the only status
|
|
294
309
|
write `/mmi` makes, and only as the mechanical side of claiming — never as a standalone "move" the dev
|
|
295
310
|
is offered. Every later transition (In Review on PR open, Done on merge) flows automatically from the
|
|
296
|
-
work, not from here.
|
|
311
|
+
work, not from here. **Route (hard):** `oracle board claim` only — never `oracle issue claim` (#5552).
|
|
297
312
|
```bash
|
|
298
313
|
mmi-cli oracle board claim <owner/repo#N> --json
|
|
299
314
|
```
|
|
@@ -348,6 +363,10 @@ something else* paths.)
|
|
|
348
363
|
Hub App's own token (#263), so no MMI-Hub repo access is required to file. Never read Hub coordinates or
|
|
349
364
|
keys from a repo-local `.env`, call a repo-local report script, or POST the Hub API directly — the CLI
|
|
350
365
|
carries the endpoint and your Hub session intrinsically.
|
|
366
|
+
**Learning fire-and-forget (#5552):** the filed issue carries the `learning` label and is owned by
|
|
367
|
+
cloud agents. After a successful file (or dedup +1), print the `{number,url}` receipt if useful, then
|
|
368
|
+
**return to the current task** — do not `board claim` it, poll it, wait on a PR, force-take it, or open
|
|
369
|
+
a second implementation issue for the same friction.
|
|
351
370
|
- Surface any `gh`/`mmi-cli` error verbatim.
|
|
352
371
|
|
|
353
372
|
## Step 6 — Leverage (offer where it fits)
|
|
@@ -512,3 +531,5 @@ claimable, or a claim that moved the wrong item.) If yes, file **one** lesson an
|
|
|
512
531
|
silent (hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR —
|
|
513
532
|
never edit the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
514
533
|
`mmi-cli learning skill-lesson --skill mmi --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
534
|
+
The lesson is `learning`-tagged cloud-agent work (#5552): file it, then finish your current report —
|
|
535
|
+
do not claim, poll, or implement that lesson in this session.
|
package/skills/release/SKILL.md
CHANGED
|
@@ -108,6 +108,9 @@ breaks here: the new worktree's branch is never literally named `development`/`r
|
|
|
108
108
|
development` inside it fails outright when `development` is already checked out in the primary checkout (git
|
|
109
109
|
worktrees cannot have the same branch checked out twice). If you are in such a worktree, exit it first and
|
|
110
110
|
run the release from the primary checkout.
|
|
111
|
+
|
|
112
|
+
**Hub `/release` also refuses a checkout path that contains spaces — prove that in Step 0e before touching local `main`.** A subst/junction/alias that hides the spaces is not a workaround.
|
|
113
|
+
|
|
111
114
|
The clean-tree check rejects UNTRACKED scratch too, not just modified tracked files. When `--apply` or
|
|
112
115
|
`--resume` stops with `working tree must be clean before …`, run `git status --porcelain` on the paths it
|
|
113
116
|
named and read BOTH status columns before touching anything (#1472, #4004):
|
|
@@ -232,6 +235,12 @@ HTTP 5xx, timeout, DNS, socket, or other transport failure is **unverified**, no
|
|
|
232
235
|
missing: retry the read/preflight and repair connectivity if it persists. Never provision or rename a
|
|
233
236
|
secret from a transport-error response.
|
|
234
237
|
|
|
238
|
+
**GitHub Actions billing/spending (#5604).** Those checks do not prove a *hosted* Actions job can start.
|
|
239
|
+
The train dispatches `actions-job-start-canary.yml` on MMI-Hub (Linux hosted, not `windows-latest`) and
|
|
240
|
+
refuses to mint a tag if the canary job never starts (empty steps / billing refusal). If a tag is already
|
|
241
|
+
on origin, do **not** recut: `mmi-cli devops release --retry-publish <run-id> --apply` retries that exact
|
|
242
|
+
run.
|
|
243
|
+
|
|
235
244
|
## Step 0c — hotfix-coverage guard (fail closed, #839, #958)
|
|
236
245
|
|
|
237
246
|
Full-track repos only. Direct-track repos skip this specific guard — not because they are exposed to no
|
|
@@ -278,6 +287,33 @@ Current state is compute-at-read + the estate repo-index (`mmi-cli oracle repo-i
|
|
|
278
287
|
If shipping code made a hand-written surface wrong, fix it on `development` as an ordinary PR
|
|
279
288
|
**outside** the train — never as a release Step.
|
|
280
289
|
|
|
290
|
+
## Step 0e — Hub checkout path must not contain spaces (#5603)
|
|
291
|
+
|
|
292
|
+
**Hub `/release` only. Do this before Step 1 — before any `git checkout main`, merge, or `--apply`.**
|
|
293
|
+
The Hub fold runs `scripts/check-hook-contract.mjs`. That verifier's Cursor probe still executes the
|
|
294
|
+
adapter command through `shell: true`. An unquoted launcher path is then split at the first space
|
|
295
|
+
(`E:\AI Projects\Mutatis Mutandis\MMI-Hub` → `E:\AI`), so the fold never gets a coherent argv. Stop
|
|
296
|
+
when the checkout path contains whitespace; do not discover this after local `main` has already moved.
|
|
297
|
+
|
|
298
|
+
Prove it from the release checkout:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
node -e "const p = process.cwd(); if (/\s/.test(p)) { console.error('Hub /release: checkout path contains spaces:\\n' + p + '\\nStop. Clone or move MMI-Hub to a path with no spaces. subst/junction/alias is not a workaround.'); process.exit(1); }"
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Non-zero → **stop**. Relocate the clone to a real path without spaces (for example `C:\src\MMI-Hub` or
|
|
305
|
+
`/opt/mmi/MMI-Hub`) and re-run `/release` from that checkout. Do not reset, merge, or fold on the
|
|
306
|
+
spaced tree.
|
|
307
|
+
|
|
308
|
+
**A subst / junction / directory-junction / drive-letter alias that hides spaces is not a valid
|
|
309
|
+
workaround.** Mapping `E:\AI Projects\Mutatis Mutandis\MMI-Hub` onto `M:\` only hides spaces in the
|
|
310
|
+
*logical* cwd. Canonical-root containment still sees the physical path: the fold's materialization
|
|
311
|
+
inputs resolve through that physical location, which then sits outside the alias root and fails
|
|
312
|
+
containment. Clone or move the repository; do not alias around the spaces.
|
|
313
|
+
|
|
314
|
+
This constraint is Hub-fold specific (the hook-contract verifier). Product-repo `/release` does not
|
|
315
|
+
run that script; still prefer a no-space checkout.
|
|
316
|
+
|
|
281
317
|
## Step 1 — merge to main (never force)
|
|
282
318
|
|
|
283
319
|
Full-track repos:
|
|
@@ -324,9 +360,10 @@ What the fold bumps, by repo:
|
|
|
324
360
|
- **Hub (`hub-serverless`):** the full locked distribution set via `scripts/release-distribution.mjs
|
|
325
361
|
prepare` — spine dogfood (`scripts/spine-dogfood.mjs`: verify docs/surfaces + the managed `.gitignore` block),
|
|
326
362
|
every registry-declared version holder, adapter payload synchronization, build output, and the public
|
|
327
|
-
artifact bill of materials — then verifies the set (`verify --skip-npm-view`).
|
|
328
|
-
|
|
329
|
-
|
|
363
|
+
artifact bill of materials — then verifies the set (`verify --skip-npm-view`). That prepare path runs
|
|
364
|
+
`scripts/check-hook-contract.mjs`; Step 0e must already have passed, or the Cursor probe splits on a
|
|
365
|
+
spaced checkout. Publication and staging both derive from `surfaces.json`; there is no second package
|
|
366
|
+
list. Claude, Codex, Kimi, Cursor, and Kilo are active.
|
|
330
367
|
- **App-style repos with a root `package.json`** (most products): the manifest + lockfile version via
|
|
331
368
|
`npm version --no-git-tag-version`, kept in lockstep with the release tag.
|
|
332
369
|
- **Repos with neither:** nothing to fold — the tag is the version.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: repo-index-audit
|
|
3
|
+
description: Audit repository indexing with live probes, receipts, and lexical/semantic/hybrid round-trips.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MMI repository-index estate audit
|
|
7
|
+
|
|
8
|
+
Canonical counterpart to `jerv-memory-audit`. Each run verifies every layer live and proves every result with a receipt.
|
|
9
|
+
|
|
10
|
+
**Vision:** MMI repository orientation works across the whole registered estate without anyone managing indexes by hand.
|
|
11
|
+
|
|
12
|
+
**Mission:** End-to-end reliability audit **with remediation**. Verify every layer live, fix every approved in-scope defect, and prove each fix before closing it.
|
|
13
|
+
|
|
14
|
+
## Start here
|
|
15
|
+
|
|
16
|
+
1. Read shipped help before using a verb: `mmi-cli --help`, `mmi-cli explain oracle repo-index --json`, and `mmi-cli explain oracle find --json`.
|
|
17
|
+
2. Read `docs/Guides/repo-index-runbook.md` and `docs/Architecture/compute-at-read.md` from the current MMI-Hub checkout.
|
|
18
|
+
3. Create a dated receipt file in task-local ignored scratch. Record command, UTC time, exit code, and the bounded JSON fields that prove each verdict. Never record query text, source bodies, credentials, hostnames, vectors, or secrets.
|
|
19
|
+
4. Treat `mmi-cli oracle repo-index status --cloud --json`, live health, and each result's retrieval metadata as runtime authority. Do not carry a recalled migration state into a new audit.
|
|
20
|
+
|
|
21
|
+
## Layers — each needs a live probe this session, not a code read
|
|
22
|
+
|
|
23
|
+
1. **Cloud backend health; full estate integrity** — run `mmi-cli oracle repo-index status --cloud --json`, `mmi-cli oracle repo-index health --live --json`, and `mmi-cli doctor --json`. PASS requires: endpoint reachable; registry roster present; active and ready authorities equal the roster; `nOfN` true; lexical, semantic, and hybrid readiness ready; citation validity and embedding coverage complete; no unaccounted integrity failure. Record the active provenance token and material layout reported now, never a hard-coded expected migration state.
|
|
24
|
+
2. **`mmi-cli` command surface vs shipped help** — compare `mmi-cli commands --json` and `mmi-cli commands --all --json` with `mmi-cli oracle repo-index --help` and `mmi-cli explain` for `rebuild`, `publish`, `search`, `status`, `graph`, `health`, `gc`, `sync-estate`, and `oracle find`. Exercise `status`, `health`, `search`, and `find` as documented. PASS requires manifest, help, examples, and behavior to agree; agents can discover every supported verb and flag.
|
|
25
|
+
3. **Guidance on every shipped surface** — verify the canonical `skills/onboard/SKILL.md`, `skills/mmi-resume/SKILL.md`, README, compute-at-read guide, and materialized plugin payloads carry the current rule: `oracle find` is semantic orientation, `oracle repo-index search` is hybrid orientation, cloud is default, `--local` is explicit checkout-only, and every hit is verified against repository, indexed commit, path, symbol, and lines. PASS requires `node scripts/check-skill-payload.mjs` to succeed.
|
|
26
|
+
4. **Automated ingestion and fail-loud alarms** — run `mmi-cli harbour org schedules --json` and `gh run list --repo mutmutco/MMI-Hub --workflow repo-index-reconcile.yml --limit 20 --json databaseId,status,conclusion,createdAt,headSha`. Inspect the installed/current workflow for default-branch push dispatch plus Harbour reconcile dispatch. PASS requires: current successful push and scheduled receipts; the exact pushed commit is checked out; drift reconciliation is delta-first; failures emit a structured alarm and deduplicated board filing; no failure dies silently.
|
|
27
|
+
5. **Build → lexical-search round-trip** — in an isolated clean checkout of one registered authority, choose a fresh unique marker already present at its current default-branch commit. Run `mmi-cli oracle repo-index rebuild --json`, then `mmi-cli oracle repo-index search "<marker>" --local --lexical --json`. Local `RepoIndexHit` owns only `repo`, `path`, `kind`, `why`, `score`, and optional `symbol` — it has no commit or line fields. PASS requires those local fields intact for the expected repository and path (and symbol when the hit is kind `symbol`), then verify commit and path directly against the isolated checkout (`git rev-parse HEAD` and that the cited path exists there). Then run `mmi-cli oracle repo-index search "<marker>" --cloud --lexical --json` for a unique marker at an active authority's reported commit; PASS requires the cloud commit-pinned citation (repository, commit, path, symbol, and lines). Never publish a canary commit without the execution handshake below.
|
|
28
|
+
6. **Indexed material → semantic/hybrid round-trip** — choose a concept whose wording differs from the target symbol in an active authority. Run `mmi-cli oracle find "<concept>" --json`, `mmi-cli oracle repo-index search "<concept>" --cloud --semantic --json`, and default hybrid search with `mmi-cli oracle repo-index search "<concept>" --cloud --json`. PASS requires: semantic retrieval is used rather than silently claimed; hybrid reports its lexical and semantic retrieval/fallback metadata; citations resolve at the reported indexed commit; semantic and hybrid return a relevant cited target. A lexical fallback is evidence of degradation, not a semantic PASS.
|
|
29
|
+
7. **Structural extraction and embeddings** — run the cloud status and live-health probes from layer 1 plus the semantic query from layer 6. Compare their current authority/retrieval metadata with the checked-in v4 schema, path policy, grammar lock, and embedder model lock. PASS requires: pinned grammar/model provenance; expected dimensions; normalized embedding coverage; typed degradation when query embedding is unavailable; successful live semantic inference; the designated local/self-hosted BGE lane; no metered LLM key or developer-laptop model path. Never print environment values; record presence/absence and provider metadata only.
|
|
30
|
+
8. **Delta, layout, rollback, and reconciliation** — run `mmi-cli oracle repo-index sync-estate --plan --json`. PASS requires: no unexpected authority drift; current layout/provenance is explicit; unchanged authorities plan no rebuild; changed authorities are delta candidates where compatible; active pointers remain valid; rollback material is retained; no retired serving fallback is implied. After any separately approved rebuild or migration, require **successful snapshot verification**, not a second reconcile that is a no-op: the run completed against its chosen commits, published safely, left all authorities ready (N-of-N lexical, semantic, hybrid, and rollback verification), and recorded any later tip commits as normal next-cycle freshness work. Never FAIL or rerun solely to chase a globally motionless estate — product commits that land during or after the run are expected freshness, not failed reconciliation. Unchanged-authority rebuild idempotency is a separate defect track; do not conflate it with this gate.
|
|
31
|
+
9. **Telemetry and schedules** — verify status query-usage rollups, readiness/shadow receipts, failure alarms, and `mmi-cli harbour org schedules --json`. PASS requires: query telemetry stores only allowlisted coarse caller/source labels; readiness stores hashes rather than query text; the reconcile schedule is present, enabled, recently firing, idempotent, and has no silent death. Zero ordinary query count is valid data but must be reported as zero adoption evidence, never as proof that search is exercised.
|
|
32
|
+
|
|
33
|
+
## Round-trip rules
|
|
34
|
+
|
|
35
|
+
- Use a different marker/query pair for lexical and semantic/hybrid probes.
|
|
36
|
+
- Record retrieval mode, fallback/degraded reason, and every field the hit surface actually returns. Local hits: `repo`, `path`, `kind`, `why`, `score`, optional `symbol`, then confirm commit and path against the isolated checkout. Cloud hits: repository, indexed commit, path, symbol, and lines.
|
|
37
|
+
- For cloud citations, verify cited files against the exact indexed commit, not a moving checkout HEAD. For local citations, verify path against the isolated checkout whose HEAD you just rebuilt.
|
|
38
|
+
- Local rebuilds stay in disposable task scratch. Remove them after receipts are captured.
|
|
39
|
+
- A cloud publish, full rebuild, migration, rollback activation, schedule dispatch, or production change is an external mutation. Stop and ask for explicit approval naming the repositories and effect before running it.
|
|
40
|
+
|
|
41
|
+
## Rules
|
|
42
|
+
|
|
43
|
+
- **Evidence-first** — nothing is healthy without a current receipt.
|
|
44
|
+
- **Runtime-first** — live status and retrieval metadata outrank memory and static docs for current state.
|
|
45
|
+
- Every defect gets a named cause, severity, and either an approved in-scope fix or a board filing on MMI-Hub.
|
|
46
|
+
- Never weaken a test or accept lexical fallback as semantic success.
|
|
47
|
+
- Use bounded receipts. Keep full raw output in task-local ignored scratch, not the report.
|
|
48
|
+
|
|
49
|
+
## Done when
|
|
50
|
+
|
|
51
|
+
- Every layer has PASS-with-receipt or a filed issue.
|
|
52
|
+
- Both round-trips (build→lexical search and indexed material→semantic/hybrid search) are verified end to end.
|
|
53
|
+
- Push ingestion and the scheduled reconcile each have current firing evidence.
|
|
54
|
+
- Post-rebuild or migration layers close on successful snapshot verification (chosen-commit completion, safe publish, authorities ready), not on a motionless-estate / no-op second reconcile.
|
|
55
|
+
- The dated estate summary records N/N layers, roster N-of-N, active provenance/layout, lexical/semantic/hybrid verdicts, adoption count, schedule state, defects, fixes, issue links, and receipt paths — including any post-snapshot tip commits noted as next-cycle freshness.
|
|
56
|
+
- Save the durable summary in the owning MMI-Hub issue or audit artifact. Save only the settled cross-session lesson or handoff to JervCoding; never copy raw query or index material into memory.
|
|
57
|
+
|
|
58
|
+
## Out of scope
|
|
59
|
+
|
|
60
|
+
New index features; production mutation without approval; fresh secrets; storing source bodies, query text, vectors, credentials, or secret values in receipts.
|
|
61
|
+
|
|
62
|
+
## House rules
|
|
63
|
+
|
|
64
|
+
- Audit read-only by default. Inspection, local disposable rebuilds, and reporting are allowed; any cloud write or external dispatch needs a fresh execution handshake.
|
|
65
|
+
- Repository fixes and board filings follow the standard issue, branch, worktree, PR, and `development` landing flow.
|
|
66
|
+
|
|
67
|
+
## Retro — one check before you finish
|
|
68
|
+
|
|
69
|
+
Before the final report, ask whether this skill's instructions misfired through ambiguous wording, a misleading message, or a missing environment warning. Process only, never the user's code or task. If yes, file one lesson and move on; a clean run is silent. The retro is advisory, so note a filing failure and continue:
|
|
70
|
+
`mmi-cli learning skill-lesson --skill repo-index-audit --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/stage/SKILL.md
CHANGED
|
@@ -51,7 +51,10 @@ mmi-cli stage --json
|
|
|
51
51
|
The JSON reports `source` (`derived` / `local` / `none`) and, when derived, the local `url`. `source: none`
|
|
52
52
|
means neither a usable local recipe nor a derivable default exists — the message names the missing fact
|
|
53
53
|
(deployModel, `docker-compose.yml`, or registry `portRange`; `.env.example` is **not** required — #2655).
|
|
54
|
-
|
|
54
|
+
When the gap is a missing Hub registry `portRange`, the JSON receipt also carries `recovery` with
|
|
55
|
+
`mmi-cli stage port-range <owner/repo>` (#5539) — assign the block, then re-run `/stage`. That gap does not
|
|
56
|
+
mean the repo's Hub registry/org project setup is missing; it means local stage derivation cannot pick a
|
|
57
|
+
collision-safe port until META.portRange exists.
|
|
55
58
|
|
|
56
59
|
## Step 1 — run the stage
|
|
57
60
|
|