[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M69BJ51WJSADYHSFYAGMNDK3":3,"skill-same:01M69BJ51WJSADYHSFYAGMNDK3":113},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":25,"linkOnly":26,"markdownContent":27,"markdownBody":28,"frontMatter":29,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":6,"ownerHtmlUrl":52,"ownerBlogUrl":53,"ownerDescription":54,"updatedAt":55,"install":56,"resources":68},"01M69BJ51WJSADYHSFYAGMNDK3","goal-batch",null,"Batch independent work into isolated \u002Fgoal lanes. Triggers: \"run these in parallel\", \"goal-batch\", \"launch lanes for these\", \"work these N tasks simultaneously\", \"batch these as goals\". Show the plan; require explicit user approval before launch; verify results before landing. Not for bounded per-PR edits (mass-change) or continuous refill-on-drain work (ten-lane-highway).","microsoft\u002Famplifier-app-cli","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M69BHYVWVEWQF0DY6W6TMESV",19,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Fgoal-batch\u002FSKILL.md",[],[19,20,21,22,23,24],"goal batch","launch","change","pr","tasks","run","2026-11-10 10:12:30",false,"---\nname: goal-batch\ndescription: >\n  Batch independent work into isolated \u002Fgoal lanes. Triggers: \"run these in\n  parallel\", \"goal-batch\", \"launch lanes for these\", \"work these N tasks\n  simultaneously\", \"batch these as goals\". Show the plan; require explicit\n  user approval before launch; verify results before landing. Not for bounded\n  per-PR edits (mass-change) or continuous refill-on-drain work (ten-lane-highway).\nversion: 2.0.0\nuser-invocable: true\nargument-hint: \"\u003Cthe work to batch, or where it is enumerated>\"\nallowed-tools: [bash, read_file, write_file, edit_file, grep, glob, delegate, load_skill, todo]\nmodel_role: general\nvisibility:\n  summary: \"One-shot batch of parallel \u002Fgoal lanes that launches once and drains together; for continuous refill-on-drain work use ten-lane-highway.\"\n---\n\n# Goal Batch\n\nSplit large work into lanes that cannot collide, run each as an autonomous\n`\u002Fgoal` session in its own worktree, and land the results through a merge pass\nyou verify yourself.\n\nYou are the ORCHESTRATOR. You plan, launch, watch, verify, merge, report. You do\nnot do the lanes' work — if you catch yourself editing a lane's code mid-flight,\nstop and fix the goal file or relaunch instead.\n\nEvery rule here was bought with a real failure in production use — roughly 45\nlanes across three operators. Where a rule looks fussy, it is load-bearing.\n\nShape references (plan screen, approval vocabulary, DONE.json, report) live in\n`examples\u002Fplan-and-report.md`. This file is the rules.\n\n**Invoking.** `\u002Fgoal-batch \u003Cbatch>` in the interactive TUI, or **\"Use the\ngoal-batch skill and …\"** in natural language — both load this skill reliably\n(measured). What does NOT work is a bare `\u002Fgoal-batch …` in a headless\n`amplifier run \"\u003Cprompt>\"`: the model reads the token as prose and does the work\nitself, producing plausible branches with no gate, no manifest, and no lanes.\nIn a headless one-shot, **direct the assistant in natural language** — e.g.\n`amplifier run \"Use the goal-batch skill and run this batch: …\"` — or call\n`load_skill(skill_name=\"goal-batch\", arguments=…)` outright. Naming the skill\nis what loads it; the bare slash token is not.\n\n**If `$ARGUMENTS` is empty, you have no batch.** This skill forks — the\nsub-session cannot see the parent conversation, so an `arguments`-less\n`load_skill` call arrives with nothing to plan against. That happened in a real\nrun and the whole invocation died silently. Do not produce an empty plan and do\nnot guess: reconstruct the batch from whatever context you were given, and if\nthere genuinely is none, say so in one line and ask for the work. One question,\nnot an interview.\n\n**Running the companion scripts.** `load_skill` returns `skill_directory`.\nResolve every script from it — `\u003Cskill_directory>\u002Fscripts\u002F\u003Cname>.sh` — and use\nthat absolute path. Never a bare relative path: the working directory is the\ntarget repo, not the skill, and in a bundle the skill lives under a\nhash-suffixed cache path that changes between installs. **Never copy a script\ninto the target repo** — a real run did exactly that, leaving `.amplifier\u002Fbin\u002F`\nbehind as untracked pollution in someone else's repository.\n\n**Input** — `$ARGUMENTS`: the work to batch, or a pointer to where it is\nenumerated. If lane independence is unclear, that is Phase 1's job, not a\nquestion for the user yet.\n\n---\n\n## Phase 1 — Plan\n\nRead enough to decompose honestly. Lanes each own a disjoint set of files, have\na provable outcome, and do not need a sibling to finish first.\n\nThen do the work that decides whether this batch lands:\n\n- **Collision analysis.** Map every candidate lane to the files it will touch\n  and print the intersections. Where two lanes want the same file, FOLD THEM\n  INTO ONE LANE, or assign sole ownership and have the other record its needed\n  edit as a residual. Merging two lanes that would have collided is a win.\n- **Pre-assign anything numbered** — issue IDs, task IDs, migration numbers.\n  Parallel lanes *will* both grab the next free number. Two really did take 075.\n- **Name the seams.** List files no lane owns. That is where it breaks: a\n  packaging script nobody owned shipped broken because nobody tested it. Either\n  give a lane the seam, or carry it to Phase 7 as untested.\n- **Pin the base SHA** every lane branches from, and **record current test\n  baselines** so \"no regressions\" is a number.\n\nNo lane cap. Width is bounded by the work. **That no-cap rule governs *lanes*,\nnot the resources lanes create.** Anything a lane stands up that outlives a\nprocess — containers, VMs, background servers, environments — does need a\ncumulative ceiling for the whole batch, because no single lane can enforce one:\neach lane sees only its own usage, never the total. The orchestrator is the only\nactor with the cross-lane view, so it keeps a running resource ledger for the\nbatch — beside the manifest and goal files — and holds combined usage under a\ndeclared ceiling. Unbounded lanes are fine; unbounded resource accumulation\nacross them is what exhausts the host.\n\n## Phase 2 — Review and go\n\n**Nothing is created and nothing launches before the user has seen the plan.**\n\n**Open with what the batch will NOT deliver.** The first two lines are:\n\n```\nWhen this finishes you WILL have: \u003Cthe concrete end state>\nYou will NOT have:                \u003Cwhat stays undone, and what it blocks>\n```\n\nThis is the whole point of the gate and the one thing it has actually failed at.\nIn a real run the fact that the batch *would not produce a working component*\nwas disclosed — as the third bullet, inside a code block, under a heading about\ntesting — and the user found out only after it finished: *\"So the batch had post\nwork associated with it? That was not clear to me.\"* Anything a reader would be\nupset to discover afterwards goes in line two, not in a section they will skim.\n\nThen the plan on one screen — lane table, contested files, parked items, unowned\nfiles, per-lane bounds, watching mode. Fifteen seconds to read, one sentence to\nargue with. Shape in `examples\u002F`.\n\nAsk questions ONLY where a wrong guess costs a relaunch: an ownership call you\ncannot make from the code, a repo you are not sure you may push to, a\nhuman-reserved action. Bring a plan, not a form.\n\n**Every lane must trace to something the user asked for.** State the origin of\neach lane in the table. A run once invented a lane out of the orchestrator's own\nscratch notes and got 32 minutes into the gate before the user caught it:\n*\"Lane F drafts five upstream feature requests against repos we don't own.\"\nWhat? Why are we changing other repos?* If you cannot name where a lane came\nfrom, it is not a lane.\n\n**Approval is conversational.** Accept a bare `go`, and accept a `go` carrying\noptions — reporting cadence, per-lane bounds, dropping a lane — and honor them\nwithout re-asking. Anything that is not an affirmative is feedback: revise, show\nthe diff, re-present. Never infer approval from enthusiasm, repetition, or\nsilence.\n\n**Pre-authorization is valid and must be honored.** If the invocation itself\ngrants approval — \"pre-approved\", \"don't stop and ask\", \"go ahead and run it\" —\npost the plan for the record and proceed without waiting. Users have started\npre-arguing with the gate in the same breath as the request (*\"but do NOT bug me\nabout this simple design, then launch into \u002Fgoal-batch\"*), and the cleanest run\nin the field skipped the gate entirely. The plan is always shown; stopping is\nwhat a user may waive. Waiving is theirs to do, never yours to assume.\n\n## Phase 3 — Compose the goal files\n\nLoad **goalify** and use it per lane; it owns outcome-first composition and\ntermination linting.\n\n**Commit the goal files to the base commit before Phase 4 cuts any worktree**,\nand pin `BASE_SHA` to that commit. Goal files written only into a worktree die\nwith it; goal files committed after the worktree exists are not in it, and the\nlauncher will refuse the lane.\n\nEvery goal carries:\n\n- **The disjunctive exit, close to verbatim.** The load-bearing sentence — what\n  makes lanes terminate honestly instead of spinning or declaring victory:\n\n  > Complete when **either** every item reaches a terminal state, **or** it is\n  > conclusively demonstrated the remainder cannot, naming the blocker for\n  > each. Items ending FAIL or BLOCKED are residuals, not failures of the goal.\n\n- **Terminal states** `PASS` \u002F `FAIL-named` \u002F `BLOCKED-named` \u002F `PENDING-HUMAN`.\n  `PENDING-HUMAN` is distinct on purpose: a lane that discharges a review by\n  assigning it to a person has deferred, not finished, and Phase 7 must show\n  that separately.\n- **A reachable terminal verb, when the lane must record its outcome in a\n  work-tracker** (goalify L7). `work_resolve` and `work_release` both refuse a\n  session that does not hold the item, so a lane pointed at an item a sibling\n  has already resolved cannot record anything and cannot terminate. Name\n  `work_erratum` — append-only, no claim needed — as the terminal verb for\n  that case, in every such lane's goal. (Two lanes that lacked this spent\n  **855 turns \u002F $202.91** and **~887 turns \u002F ~$184** repeating one evaluator\n  line, hours after their own PRs had merged.)\n- **Working directory + branch + base SHA.** \"Work ONLY here. Do not touch the\n  main checkout or sibling worktrees.\"\n- **File ownership** with the residual protocol: crossing into another lane's\n  files is a defect, not a courtesy — record the needed edit and stop. Draw\n  ownership around what makes the thing *work*, not around the artifact. A lane\n  owning an icon but not the packager does not own a shippable icon.\n- **Commit early, push always.** Two tmux-server crashes cost minutes instead of\n  hours because every lane pushed as it committed.\n- **Never merge to main.** The orchestrator merges.\n- **Host capability limits, stated plainly.** A lane that authors what this box\n  cannot compile ships code that breaks on someone else's first build. Live\n  shared services are read-only evidence to a lane; tests use fixtures.\n- **Non-git resources the lane provisions, enumerated with their teardown.**\n  Anything a lane stands up that outlives a process — containers, VMs,\n  background servers, external environments — must be named in the goal, and\n  tearing each one down (or an explicit, named handoff to an owner) must be part\n  of the lane's own DONE criteria. File ownership bounds the *files* a lane\n  touches and says nothing about the *resources* it starts; a lane that exits\n  with resources still running has not finished, and Phase 7 cannot verify\n  teardown for what a lane never declared.\n- **The time bound**, and that exceeding it is a terminal `BUDGET` state, not a\n  reason to rush the work or skip the commit.\n- **Add `DONE.json` to the repo's `.gitignore` before writing it.** Four of five\n  lanes in one run committed theirs and the batch's own merge pass collided on\n  that file. It is a signal, not an artifact.\n- **Write `DONE.json` in the worktree root as your final act** — the terminal\n  marker. Without it, an exited session is indistinguishable from a killed one.\n  Fields: `lane, session_id, verdict, branch, head, pushed, items[],\n  residuals[], pending_human[], resources[], suite`. `resources[]` names every\n  non-git resource the lane provisioned and whether it was torn down or handed\n  off, so Phase 7 can verify teardown instead of guessing. Shape in `examples\u002F`.\n  **`verdict` is exactly one of `COMPLETE` \u002F `BLOCKED` \u002F `PARTIAL`**, and\n  `session_id` is this lane's own — two lanes in one batch wrote `\"PASS\"` and\n  `\"success\"`, which no parser reads the same way, and a `DONE.json` without a\n  session_id cannot be told apart from one inherited through the base commit.\n- **KNOWN section** — env setup, suite commands, baselines, footguns. Speed\n  aid, not criteria.\n\n## Phase 4 — Preflight\n\nFail loud here. Never launch degraded.\n\n- **Every lane's output must be COMMITTABLE — not necessarily pushable.** A\n  local-only repo is fine: a lane commits to its own branch, and those commits\n  live in the main repo's object store, so they survive `git worktree remove`\n  and merge normally with no network at all. Verify that, not a remote.\n  - **A remote is recommended, not required.** With one, lanes push as they\n    commit and a crash costs minutes; without one, the work is still safe on\n    disk but only on this machine. Say which the user is getting, once, and\n    move on — do not block the batch.\n  - **What actually loses work is output that is never committed at all.** The\n    real 47MB loss came from a repo that *had* two remotes: the lane's entire\n    output sat under gitignored paths, so it was never committed and pushing\n    would have saved none of it. So check the thing that matters: will each\n    lane's deliverables land in a commit? If a lane's real product is a\n    gitignored artifact directory, say so at the gate — that is a batch that\n    cannot deliver, and no remote fixes it.\n- **Smoke-test the launcher once**, ~90s, thrown away, and confirm any\n  capability a lane depends on is reachable from inside a lane.\n- **Create worktrees**, skipping any that already exist rather than failing on\n  them — this path is re-entered on resume:\n  `[ -d \"$WT\" ] || git worktree add -b \u003Cbranch> \"$WT\" \u003CBASE_SHA>`\n\n**One worktree per lane is not optional.** The session workspace slug is derived\nfrom the working directory, so lanes sharing a directory share a workspace and\ntheir activity becomes unattributable.\n\n## Phase 5 — Launch and register\n\nOne tmux session per lane, via the companion script — once per lane:\n\n```bash\n\u003Cskill_directory>\u002Fscripts\u002Flaunch_lane.sh \\\n    \u003Cbatch> \u003Clane> \u003Cworktree> .amplifier\u002Fgoals\u002F\u003Clane>.md \\\n    \u003Crepo>\u002F.amplifier\u002Fgoals\u002Fmanifest.tsv [wall_s] [max_turns]\n```\n\n**The script owns the manifest. Never hand-write it.** It writes the header on\nfirst call and appends one 8-column row per lane. Both users of v1 ended up\nhand-writing manifests because the launcher emitted 5 columns while the status\nprobe read 7 — they never agreed, and no batch could use both tools as shipped.\nIf you find yourself composing a `manifest.tsv` heredoc, stop: something is\nwrong and hand-writing it will hide the failure.\n\nThe tmux session name and log path are **derived** from `\u003Cbatch>`\u002F`\u003Clane>`, so\nthe `gb__*` convention that the orphan sweep and pane-viewer match strings depend\non cannot drift.\n\nIt also enforces five things you must not reimplement by hand: the tmux command\ncarries **no user prose** (a lone apostrophe in a launch note silently truncated\na real launch — put launch notes INSIDE the goal file); logging survives; the\nlane runs under `timeout` in its own process group so a runaway dies with its\nchildren; any inherited `DONE.json` is purged before launch; and it **fails\nloud** if no session ID appears rather than writing a blank into the crash\nanchor.\n\nOne-phase launch is mandatory. Never start a bare `amplifier` TUI and `send-keys`\nthe `\u002Fgoal` into it — keystrokes sent to a busy pane get swallowed silently (one\nrun left an 8MB job with a zero-byte log), and `amplifier run` *exits* when the\ngoal loop ends while a TUI sits at a prompt forever, so one-phase is what makes\nsession death a real signal.\n\nBoth bounds are real but live at different layers: `--max-turns` is parsed by\n**`\u002Fgoal`**, not by `amplifier run`, so it rides inside the prompt string\n(`\u002Fgoal --max-turns 40 @file`); wall-clock is `timeout` around the process.\n`\u002Fgoal` is unlimited by default on purpose (ADR-0005) — a batch should set both.\n\n**Session names `gb__\u003Cbatch>__\u003Clane>`** — double underscore because lane names\ncontain hyphens. Gives `gb__*` (every lane of every batch, for the orphan sweep\nin Phase 7 and for pane-viewer match strings), `gb__\u003Cbatch>__*` (one batch),\nexact (one lane). Never use `.` or `:`: tmux silently rewrites them to `_` and\ntwo differently-named lanes can collide.\n\n**Write the manifest** — TSV, one row per lane: `lane · worktree · branch · tmux\n· goal · log · session_id`, beside the goal files. This is the crash anchor.\nWhen the tmux server dies, panes are gone but git plus this file let any session\nreconstruct the batch; without it, recovery was 40 minutes of archaeology.\n\n## Phase 6 — Watch\n\n**Every claim you make about a lane must come from a probe you just ran.** This\nis the rule; everything below serves it. Watchers that narrated from memory or\nfrom a pane's last line have fabricated in multiple runs — one declared\n`TIMEOUT: reached 95-minute max duration` at 30 minutes actual, and one reported\n`No DONE.json files written` 68 seconds before the merge collided with those\nexact files. The run with the lowest overhead measured (7% of spend) is the one\nthat probed for everything it said.\n\nThe instrument:\n\n```bash\n\u003Cskill_directory>\u002Fscripts\u002Fbatch_status.sh \u003Cmanifest.tsv> \u003CBASE_SHA>\nSHOW_LAST=1 \u003Cskill_directory>\u002Fscripts\u002Fbatch_status.sh \u003Cmanifest.tsv>\n```\n\nIts first line is `BATCH_ELAPSED`, computed from the manifest header — **that is\nthe only elapsed time that means anything.** The per-lane `LANE_IDLE` column is\nseconds since that lane last emitted an event; reading it as batch elapsed time\nis what killed a watch an hour early.\n\nFive signals are counter-intuitive and the script encodes them so you do not\nhave to reason about them:\n\n- Terminal is `DONE.json`, checked against the manifest's session_id — an\n  inherited one from the base commit otherwise reads as a finished lane.\n- Alive is `kill -0` on the lane PID, **not** tmux presence. The tmux server has\n  died mid-batch in three separate runs, leaving healthy lanes running as\n  orphans while tmux-keyed probes went blind.\n- Liveness is `events.jsonl` mtime, **not** `transcript.jsonl` mtime — the\n  transcript freezes entirely while a lane delegates to a sub-agent.\n- Progress is assistant turns from the transcript, **not**\n  `metadata.turn_count`, which is corrupt (reports 1 for a 21-turn session).\n- Pushed is `git ls-remote`, **not** `@{upstream}`, never set by an\n  explicit-refspec push.\n\n**Wait on state change, not on a clock.** Sleep between probes; do not spend a\nmodel call to decide whether to sleep again. In one run 51 of 70 monitor calls\nwere bare `sleep`, and monitoring ran 3.9× longer than the work it watched.\nLoad **monitor** if you delegate the loop — it owns the SEQUENTIAL-ONLY rule and\nthe batched-imposter check — but the loop's job here is mechanical: probe,\ncompare, sleep, repeat.\n\nReport per the mode approved in Phase 2. Interrupt regardless for: a lane\n`DIED`, a `STALE-DONE-IGNORED` verdict, a lane asking a human a question, or the\nprobe itself failing twice. Stall thresholds (120s\u002F900s) are starting guesses —\ncalibrate before letting `STALLED` justify killing anything.\n\n**Verify the watcher's verdict yourself before acting on it.** Both false-DONE\nand false-crash have happened.\n\n**Inherited artifacts are the single biggest source of false signals.** A lane's\nworktree starts as a full copy of the base commit, so every status file, every\nevidence directory, every `BLOCKED.md` that was already tracked appears to\nbelong to the lane. Three false alarms in one day came from this: a `BLOCKED.md`\nbyte-identical to main — *whose first line read \"The lane is not blocked\"* —\nread as a real block; \"23 evidence files, great progress\" where 20 were\ninherited; a monitor citing a device transcript that shipped with the branch.\nBefore reading any artifact as a lane's own output, prove the lane wrote it:\ncompare against the base commit (`git log \u003CBASE_SHA>..HEAD -- \u003Cpath>`, or a\nchecksum against base). `launch_lane.sh` purges `DONE.json` for exactly this\nreason; every other artifact is on you.\n\n**Provider rate-limit errors in a pane are healthy, not a stall.** If a lane\ndies of them, that is a model-routing problem: switch the model and relaunch.\nDo not serialize the batch.\n\n**A lane that died — crashed, or killed by its time bound — takes the same\npath:** rescue-commit anything real it banked, then relaunch the same goal with\na RESUME note naming what the prior attempt completed with SHAs, \"treat that as\nyour own prior work, do not redo it\", and what remains. Max 2 resumes. A lane\nthat hit its bound twice is a scoping problem — report it, do not extend\nforever. Never let a bounded-out lane vanish silently from the Phase 7 report.\n\n## Phase 7 — Land\n\n**Re-verify everything. Lane self-reports are hints.** Two lanes reported green\nhonestly from a suite run that predated their own last file.\n\n1. `git fetch`. Diff-stat each landed branch with **three dots** —\n   `git diff main...HEAD` — not two. Two dots compares against main's *current*\n   tip, so every commit main gained while the lane ran shows up as the lane's\n   work. That produced a near-miss ownership accusation against a lane that had\n   touched none of the files.\n2. **Read the diffs across lanes, not just within them.** File ownership does\n   not catch two lanes inventing the *same* thing at *different* paths — two\n   lanes once created separate `ThreadVisibility` singletons, one written by\n   one lane and read by the other, and **both lanes' tests passed** while the\n   behavior was silently broken. It was caught only by reading the combined\n   diff. Anything that looks like a new shared abstraction deserves a\n   cross-lane look before merging.\n2. Merge **sequentially, ascending by churn, `--no-ff`**. Run the full suite\n   yourself after EVERY merge. Verify actual test counts from result files, not\n   \"BUILD SUCCESSFUL\".\n3. On conflict: resolve per the lanes' own merge notes. If notes are missing or\n   intents genuinely conflict, stop and surface it rather than guessing.\n4. On red: fix at the cause, or revert that merge and report. Never weaken a\n   test to pass — the gate is doing its job.\n5. Push main. Then per lane: `git worktree remove`, delete branch local and\n   remote, `tmux kill-session`. Sweep for orphaned sessions: `tmux ls -F\n   '#{session_name}' | grep '^gb__\u003Cbatch>__'` must come back empty. **Then verify\n   teardown of everything the lanes provisioned** — teardown is part of landing,\n   not an afterthought. Read each lane's reported `resources[]`, confirm every\n   entry is actually gone, and extend the orphan sweep beyond tmux to whatever\n   the lanes could have started: check `docker ps`, `incus list`, or the process\n   list for survivors tied to this batch. Reconcile the total against the batch\n   resource ledger from Phase 1 — it must read zero still-running. A batch is not\n   landed while it is still holding resources open.\n6. Report verdict-first: per-lane table (shipped, SHAs, suite results), what\n   verification caught that lanes did not self-report, residuals, anything\n   `PENDING-HUMAN`, the unowned-files list from Phase 1, and new baselines.\n","# Goal Batch\n\nSplit large work into lanes that cannot collide, run each as an autonomous\n`\u002Fgoal` session in its own worktree, and land the results through a merge pass\nyou verify yourself.\n\nYou are the ORCHESTRATOR. You plan, launch, watch, verify, merge, report. You do\nnot do the lanes' work — if you catch yourself editing a lane's code mid-flight,\nstop and fix the goal file or relaunch instead.\n\nEvery rule here was bought with a real failure in production use — roughly 45\nlanes across three operators. Where a rule looks fussy, it is load-bearing.\n\nShape references (plan screen, approval vocabulary, DONE.json, report) live in\n`examples\u002Fplan-and-report.md`. This file is the rules.\n\n**Invoking.** `\u002Fgoal-batch \u003Cbatch>` in the interactive TUI, or **\"Use the\ngoal-batch skill and …\"** in natural language — both load this skill reliably\n(measured). What does NOT work is a bare `\u002Fgoal-batch …` in a headless\n`amplifier run \"\u003Cprompt>\"`: the model reads the token as prose and does the work\nitself, producing plausible branches with no gate, no manifest, and no lanes.\nIn a headless one-shot, **direct the assistant in natural language** — e.g.\n`amplifier run \"Use the goal-batch skill and run this batch: …\"` — or call\n`load_skill(skill_name=\"goal-batch\", arguments=…)` outright. Naming the skill\nis what loads it; the bare slash token is not.\n\n**If `$ARGUMENTS` is empty, you have no batch.** This skill forks — the\nsub-session cannot see the parent conversation, so an `arguments`-less\n`load_skill` call arrives with nothing to plan against. That happened in a real\nrun and the whole invocation died silently. Do not produce an empty plan and do\nnot guess: reconstruct the batch from whatever context you were given, and if\nthere genuinely is none, say so in one line and ask for the work. One question,\nnot an interview.\n\n**Running the companion scripts.** `load_skill` returns `skill_directory`.\nResolve every script from it — `\u003Cskill_directory>\u002Fscripts\u002F\u003Cname>.sh` — and use\nthat absolute path. Never a bare relative path: the working directory is the\ntarget repo, not the skill, and in a bundle the skill lives under a\nhash-suffixed cache path that changes between installs. **Never copy a script\ninto the target repo** — a real run did exactly that, leaving `.amplifier\u002Fbin\u002F`\nbehind as untracked pollution in someone else's repository.\n\n**Input** — `$ARGUMENTS`: the work to batch, or a pointer to where it is\nenumerated. If lane independence is unclear, that is Phase 1's job, not a\nquestion for the user yet.\n\n---\n\n## Phase 1 — Plan\n\nRead enough to decompose honestly. Lanes each own a disjoint set of files, have\na provable outcome, and do not need a sibling to finish first.\n\nThen do the work that decides whether this batch lands:\n\n- **Collision analysis.** Map every candidate lane to the files it will touch\n  and print the intersections. Where two lanes want the same file, FOLD THEM\n  INTO ONE LANE, or assign sole ownership and have the other record its needed\n  edit as a residual. Merging two lanes that would have collided is a win.\n- **Pre-assign anything numbered** — issue IDs, task IDs, migration numbers.\n  Parallel lanes *will* both grab the next free number. Two really did take 075.\n- **Name the seams.** List files no lane owns. That is where it breaks: a\n  packaging script nobody owned shipped broken because nobody tested it. Either\n  give a lane the seam, or carry it to Phase 7 as untested.\n- **Pin the base SHA** every lane branches from, and **record current test\n  baselines** so \"no regressions\" is a number.\n\nNo lane cap. Width is bounded by the work. **That no-cap rule governs *lanes*,\nnot the resources lanes create.** Anything a lane stands up that outlives a\nprocess — containers, VMs, background servers, environments — does need a\ncumulative ceiling for the whole batch, because no single lane can enforce one:\neach lane sees only its own usage, never the total. The orchestrator is the only\nactor with the cross-lane view, so it keeps a running resource ledger for the\nbatch — beside the manifest and goal files — and holds combined usage under a\ndeclared ceiling. Unbounded lanes are fine; unbounded resource accumulation\nacross them is what exhausts the host.\n\n## Phase 2 — Review and go\n\n**Nothing is created and nothing launches before the user has seen the plan.**\n\n**Open with what the batch will NOT deliver.** The first two lines are:\n\n```\nWhen this finishes you WILL have: \u003Cthe concrete end state>\nYou will NOT have:                \u003Cwhat stays undone, and what it blocks>\n```\n\nThis is the whole point of the gate and the one thing it has actually failed at.\nIn a real run the fact that the batch *would not produce a working component*\nwas disclosed — as the third bullet, inside a code block, under a heading about\ntesting — and the user found out only after it finished: *\"So the batch had post\nwork associated with it? That was not clear to me.\"* Anything a reader would be\nupset to discover afterwards goes in line two, not in a section they will skim.\n\nThen the plan on one screen — lane table, contested files, parked items, unowned\nfiles, per-lane bounds, watching mode. Fifteen seconds to read, one sentence to\nargue with. Shape in `examples\u002F`.\n\nAsk questions ONLY where a wrong guess costs a relaunch: an ownership call you\ncannot make from the code, a repo you are not sure you may push to, a\nhuman-reserved action. Bring a plan, not a form.\n\n**Every lane must trace to something the user asked for.** State the origin of\neach lane in the table. A run once invented a lane out of the orchestrator's own\nscratch notes and got 32 minutes into the gate before the user caught it:\n*\"Lane F drafts five upstream feature requests against repos we don't own.\"\nWhat? Why are we changing other repos?* If you cannot name where a lane came\nfrom, it is not a lane.\n\n**Approval is conversational.** Accept a bare `go`, and accept a `go` carrying\noptions — reporting cadence, per-lane bounds, dropping a lane — and honor them\nwithout re-asking. Anything that is not an affirmative is feedback: revise, show\nthe diff, re-present. Never infer approval from enthusiasm, repetition, or\nsilence.\n\n**Pre-authorization is valid and must be honored.** If the invocation itself\ngrants approval — \"pre-approved\", \"don't stop and ask\", \"go ahead and run it\" —\npost the plan for the record and proceed without waiting. Users have started\npre-arguing with the gate in the same breath as the request (*\"but do NOT bug me\nabout this simple design, then launch into \u002Fgoal-batch\"*), and the cleanest run\nin the field skipped the gate entirely. The plan is always shown; stopping is\nwhat a user may waive. Waiving is theirs to do, never yours to assume.\n\n## Phase 3 — Compose the goal files\n\nLoad **goalify** and use it per lane; it owns outcome-first composition and\ntermination linting.\n\n**Commit the goal files to the base commit before Phase 4 cuts any worktree**,\nand pin `BASE_SHA` to that commit. Goal files written only into a worktree die\nwith it; goal files committed after the worktree exists are not in it, and the\nlauncher will refuse the lane.\n\nEvery goal carries:\n\n- **The disjunctive exit, close to verbatim.** The load-bearing sentence — what\n  makes lanes terminate honestly instead of spinning or declaring victory:\n\n  > Complete when **either** every item reaches a terminal state, **or** it is\n  > conclusively demonstrated the remainder cannot, naming the blocker for\n  > each. Items ending FAIL or BLOCKED are residuals, not failures of the goal.\n\n- **Terminal states** `PASS` \u002F `FAIL-named` \u002F `BLOCKED-named` \u002F `PENDING-HUMAN`.\n  `PENDING-HUMAN` is distinct on purpose: a lane that discharges a review by\n  assigning it to a person has deferred, not finished, and Phase 7 must show\n  that separately.\n- **A reachable terminal verb, when the lane must record its outcome in a\n  work-tracker** (goalify L7). `work_resolve` and `work_release` both refuse a\n  session that does not hold the item, so a lane pointed at an item a sibling\n  has already resolved cannot record anything and cannot terminate. Name\n  `work_erratum` — append-only, no claim needed — as the terminal verb for\n  that case, in every such lane's goal. (Two lanes that lacked this spent\n  **855 turns \u002F $202.91** and **~887 turns \u002F ~$184** repeating one evaluator\n  line, hours after their own PRs had merged.)\n- **Working directory + branch + base SHA.** \"Work ONLY here. Do not touch the\n  main checkout or sibling worktrees.\"\n- **File ownership** with the residual protocol: crossing into another lane's\n  files is a defect, not a courtesy — record the needed edit and stop. Draw\n  ownership around what makes the thing *work*, not around the artifact. A lane\n  owning an icon but not the packager does not own a shippable icon.\n- **Commit early, push always.** Two tmux-server crashes cost minutes instead of\n  hours because every lane pushed as it committed.\n- **Never merge to main.** The orchestrator merges.\n- **Host capability limits, stated plainly.** A lane that authors what this box\n  cannot compile ships code that breaks on someone else's first build. Live\n  shared services are read-only evidence to a lane; tests use fixtures.\n- **Non-git resources the lane provisions, enumerated with their teardown.**\n  Anything a lane stands up that outlives a process — containers, VMs,\n  background servers, external environments — must be named in the goal, and\n  tearing each one down (or an explicit, named handoff to an owner) must be part\n  of the lane's own DONE criteria. File ownership bounds the *files* a lane\n  touches and says nothing about the *resources* it starts; a lane that exits\n  with resources still running has not finished, and Phase 7 cannot verify\n  teardown for what a lane never declared.\n- **The time bound**, and that exceeding it is a terminal `BUDGET` state, not a\n  reason to rush the work or skip the commit.\n- **Add `DONE.json` to the repo's `.gitignore` before writing it.** Four of five\n  lanes in one run committed theirs and the batch's own merge pass collided on\n  that file. It is a signal, not an artifact.\n- **Write `DONE.json` in the worktree root as your final act** — the terminal\n  marker. Without it, an exited session is indistinguishable from a killed one.\n  Fields: `lane, session_id, verdict, branch, head, pushed, items[],\n  residuals[], pending_human[], resources[], suite`. `resources[]` names every\n  non-git resource the lane provisioned and whether it was torn down or handed\n  off, so Phase 7 can verify teardown instead of guessing. Shape in `examples\u002F`.\n  **`verdict` is exactly one of `COMPLETE` \u002F `BLOCKED` \u002F `PARTIAL`**, and\n  `session_id` is this lane's own — two lanes in one batch wrote `\"PASS\"` and\n  `\"success\"`, which no parser reads the same way, and a `DONE.json` without a\n  session_id cannot be told apart from one inherited through the base commit.\n- **KNOWN section** — env setup, suite commands, baselines, footguns. Speed\n  aid, not criteria.\n\n## Phase 4 — Preflight\n\nFail loud here. Never launch degraded.\n\n- **Every lane's output must be COMMITTABLE — not necessarily pushable.** A\n  local-only repo is fine: a lane commits to its own branch, and those commits\n  live in the main repo's object store, so they survive `git worktree remove`\n  and merge normally with no network at all. Verify that, not a remote.\n  - **A remote is recommended, not required.** With one, lanes push as they\n    commit and a crash costs minutes; without one, the work is still safe on\n    disk but only on this machine. Say which the user is getting, once, and\n    move on — do not block the batch.\n  - **What actually loses work is output that is never committed at all.** The\n    real 47MB loss came from a repo that *had* two remotes: the lane's entire\n    output sat under gitignored paths, so it was never committed and pushing\n    would have saved none of it. So check the thing that matters: will each\n    lane's deliverables land in a commit? If a lane's real product is a\n    gitignored artifact directory, say so at the gate — that is a batch that\n    cannot deliver, and no remote fixes it.\n- **Smoke-test the launcher once**, ~90s, thrown away, and confirm any\n  capability a lane depends on is reachable from inside a lane.\n- **Create worktrees**, skipping any that already exist rather than failing on\n  them — this path is re-entered on resume:\n  `[ -d \"$WT\" ] || git worktree add -b \u003Cbranch> \"$WT\" \u003CBASE_SHA>`\n\n**One worktree per lane is not optional.** The session workspace slug is derived\nfrom the working directory, so lanes sharing a directory share a workspace and\ntheir activity becomes unattributable.\n\n## Phase 5 — Launch and register\n\nOne tmux session per lane, via the companion script — once per lane:\n\n```bash\n\u003Cskill_directory>\u002Fscripts\u002Flaunch_lane.sh \\\n    \u003Cbatch> \u003Clane> \u003Cworktree> .amplifier\u002Fgoals\u002F\u003Clane>.md \\\n    \u003Crepo>\u002F.amplifier\u002Fgoals\u002Fmanifest.tsv [wall_s] [max_turns]\n```\n\n**The script owns the manifest. Never hand-write it.** It writes the header on\nfirst call and appends one 8-column row per lane. Both users of v1 ended up\nhand-writing manifests because the launcher emitted 5 columns while the status\nprobe read 7 — they never agreed, and no batch could use both tools as shipped.\nIf you find yourself composing a `manifest.tsv` heredoc, stop: something is\nwrong and hand-writing it will hide the failure.\n\nThe tmux session name and log path are **derived** from `\u003Cbatch>`\u002F`\u003Clane>`, so\nthe `gb__*` convention that the orphan sweep and pane-viewer match strings depend\non cannot drift.\n\nIt also enforces five things you must not reimplement by hand: the tmux command\ncarries **no user prose** (a lone apostrophe in a launch note silently truncated\na real launch — put launch notes INSIDE the goal file); logging survives; the\nlane runs under `timeout` in its own process group so a runaway dies with its\nchildren; any inherited `DONE.json` is purged before launch; and it **fails\nloud** if no session ID appears rather than writing a blank into the crash\nanchor.\n\nOne-phase launch is mandatory. Never start a bare `amplifier` TUI and `send-keys`\nthe `\u002Fgoal` into it — keystrokes sent to a busy pane get swallowed silently (one\nrun left an 8MB job with a zero-byte log), and `amplifier run` *exits* when the\ngoal loop ends while a TUI sits at a prompt forever, so one-phase is what makes\nsession death a real signal.\n\nBoth bounds are real but live at different layers: `--max-turns` is parsed by\n**`\u002Fgoal`**, not by `amplifier run`, so it rides inside the prompt string\n(`\u002Fgoal --max-turns 40 @file`); wall-clock is `timeout` around the process.\n`\u002Fgoal` is unlimited by default on purpose (ADR-0005) — a batch should set both.\n\n**Session names `gb__\u003Cbatch>__\u003Clane>`** — double underscore because lane names\ncontain hyphens. Gives `gb__*` (every lane of every batch, for the orphan sweep\nin Phase 7 and for pane-viewer match strings), `gb__\u003Cbatch>__*` (one batch),\nexact (one lane). Never use `.` or `:`: tmux silently rewrites them to `_` and\ntwo differently-named lanes can collide.\n\n**Write the manifest** — TSV, one row per lane: `lane · worktree · branch · tmux\n· goal · log · session_id`, beside the goal files. This is the crash anchor.\nWhen the tmux server dies, panes are gone but git plus this file let any session\nreconstruct the batch; without it, recovery was 40 minutes of archaeology.\n\n## Phase 6 — Watch\n\n**Every claim you make about a lane must come from a probe you just ran.** This\nis the rule; everything below serves it. Watchers that narrated from memory or\nfrom a pane's last line have fabricated in multiple runs — one declared\n`TIMEOUT: reached 95-minute max duration` at 30 minutes actual, and one reported\n`No DONE.json files written` 68 seconds before the merge collided with those\nexact files. The run with the lowest overhead measured (7% of spend) is the one\nthat probed for everything it said.\n\nThe instrument:\n\n```bash\n\u003Cskill_directory>\u002Fscripts\u002Fbatch_status.sh \u003Cmanifest.tsv> \u003CBASE_SHA>\nSHOW_LAST=1 \u003Cskill_directory>\u002Fscripts\u002Fbatch_status.sh \u003Cmanifest.tsv>\n```\n\nIts first line is `BATCH_ELAPSED`, computed from the manifest header — **that is\nthe only elapsed time that means anything.** The per-lane `LANE_IDLE` column is\nseconds since that lane last emitted an event; reading it as batch elapsed time\nis what killed a watch an hour early.\n\nFive signals are counter-intuitive and the script encodes them so you do not\nhave to reason about them:\n\n- Terminal is `DONE.json`, checked against the manifest's session_id — an\n  inherited one from the base commit otherwise reads as a finished lane.\n- Alive is `kill -0` on the lane PID, **not** tmux presence. The tmux server has\n  died mid-batch in three separate runs, leaving healthy lanes running as\n  orphans while tmux-keyed probes went blind.\n- Liveness is `events.jsonl` mtime, **not** `transcript.jsonl` mtime — the\n  transcript freezes entirely while a lane delegates to a sub-agent.\n- Progress is assistant turns from the transcript, **not**\n  `metadata.turn_count`, which is corrupt (reports 1 for a 21-turn session).\n- Pushed is `git ls-remote`, **not** `@{upstream}`, never set by an\n  explicit-refspec push.\n\n**Wait on state change, not on a clock.** Sleep between probes; do not spend a\nmodel call to decide whether to sleep again. In one run 51 of 70 monitor calls\nwere bare `sleep`, and monitoring ran 3.9× longer than the work it watched.\nLoad **monitor** if you delegate the loop — it owns the SEQUENTIAL-ONLY rule and\nthe batched-imposter check — but the loop's job here is mechanical: probe,\ncompare, sleep, repeat.\n\nReport per the mode approved in Phase 2. Interrupt regardless for: a lane\n`DIED`, a `STALE-DONE-IGNORED` verdict, a lane asking a human a question, or the\nprobe itself failing twice. Stall thresholds (120s\u002F900s) are starting guesses —\ncalibrate before letting `STALLED` justify killing anything.\n\n**Verify the watcher's verdict yourself before acting on it.** Both false-DONE\nand false-crash have happened.\n\n**Inherited artifacts are the single biggest source of false signals.** A lane's\nworktree starts as a full copy of the base commit, so every status file, every\nevidence directory, every `BLOCKED.md` that was already tracked appears to\nbelong to the lane. Three false alarms in one day came from this: a `BLOCKED.md`\nbyte-identical to main — *whose first line read \"The lane is not blocked\"* —\nread as a real block; \"23 evidence files, great progress\" where 20 were\ninherited; a monitor citing a device transcript that shipped with the branch.\nBefore reading any artifact as a lane's own output, prove the lane wrote it:\ncompare against the base commit (`git log \u003CBASE_SHA>..HEAD -- \u003Cpath>`, or a\nchecksum against base). `launch_lane.sh` purges `DONE.json` for exactly this\nreason; every other artifact is on you.\n\n**Provider rate-limit errors in a pane are healthy, not a stall.** If a lane\ndies of them, that is a model-routing problem: switch the model and relaunch.\nDo not serialize the batch.\n\n**A lane that died — crashed, or killed by its time bound — takes the same\npath:** rescue-commit anything real it banked, then relaunch the same goal with\na RESUME note naming what the prior attempt completed with SHAs, \"treat that as\nyour own prior work, do not redo it\", and what remains. Max 2 resumes. A lane\nthat hit its bound twice is a scoping problem — report it, do not extend\nforever. Never let a bounded-out lane vanish silently from the Phase 7 report.\n\n## Phase 7 — Land\n\n**Re-verify everything. Lane self-reports are hints.** Two lanes reported green\nhonestly from a suite run that predated their own last file.\n\n1. `git fetch`. Diff-stat each landed branch with **three dots** —\n   `git diff main...HEAD` — not two. Two dots compares against main's *current*\n   tip, so every commit main gained while the lane ran shows up as the lane's\n   work. That produced a near-miss ownership accusation against a lane that had\n   touched none of the files.\n2. **Read the diffs across lanes, not just within them.** File ownership does\n   not catch two lanes inventing the *same* thing at *different* paths — two\n   lanes once created separate `ThreadVisibility` singletons, one written by\n   one lane and read by the other, and **both lanes' tests passed** while the\n   behavior was silently broken. It was caught only by reading the combined\n   diff. Anything that looks like a new shared abstraction deserves a\n   cross-lane look before merging.\n2. Merge **sequentially, ascending by churn, `--no-ff`**. Run the full suite\n   yourself after EVERY merge. Verify actual test counts from result files, not\n   \"BUILD SUCCESSFUL\".\n3. On conflict: resolve per the lanes' own merge notes. If notes are missing or\n   intents genuinely conflict, stop and surface it rather than guessing.\n4. On red: fix at the cause, or revert that merge and report. Never weaken a\n   test to pass — the gate is doing its job.\n5. Push main. Then per lane: `git worktree remove`, delete branch local and\n   remote, `tmux kill-session`. Sweep for orphaned sessions: `tmux ls -F\n   '#{session_name}' | grep '^gb__\u003Cbatch>__'` must come back empty. **Then verify\n   teardown of everything the lanes provisioned** — teardown is part of landing,\n   not an afterthought. Read each lane's reported `resources[]`, confirm every\n   entry is actually gone, and extend the orphan sweep beyond tmux to whatever\n   the lanes could have started: check `docker ps`, `incus list`, or the process\n   list for survivors tied to this batch. Reconcile the total against the batch\n   resource ledger from Phase 1 — it must read zero still-running. A batch is not\n   landed while it is still holding resources open.\n6. Report verdict-first: per-lane table (shipped, SHAs, suite results), what\n   verification caught that lanes did not self-report, residuals, anything\n   `PENDING-HUMAN`, the unowned-files list from Phase 1, and new baselines.\n",{"name":5,"version":30,"model_role":31,"visibility":32,"description":34,"allowed-tools":35,"argument-hint":45,"user-invocable":46},"2.0.0","general",{"summary":33},"One-shot batch of parallel \u002Fgoal lanes that launches once and drains together; for continuous refill-on-drain work use ten-lane-highway.","Batch independent work into isolated \u002Fgoal lanes. Triggers: \"run these in parallel\", \"goal-batch\", \"launch lanes for these\", \"work these N tasks simultaneously\", \"batch these as goals\". Show the plan; require explicit user approval before launch; verify results before landing. Not for bounded per-PR edits (mass-change) or continuous refill-on-drain work (ten-lane-highway).\n",[36,37,38,39,40,41,42,43,44],"bash","read_file","write_file","edit_file","grep","glob","delegate","load_skill","todo","\u003Cthe work to batch, or where it is enumerated>",true,"main","631c4bdbcf3dcd2da20456ad6ccef386e778c101","amplifier_app_cli\u002Fdata\u002Fskills\u002Fgoal-batch",28,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-12 01:45:24",{"source":8,"skillName":5,"commands":57,"prompt":67,"zipAvailable":46},[58,61,64],{"tool":59,"command":60},"npx","npx skills add microsoft\u002Famplifier-app-cli --skill goal-batch",{"tool":62,"command":63},"bunx","bunx skills add microsoft\u002Famplifier-app-cli --skill goal-batch",{"tool":65,"command":66},"pnpm","pnpm dlx skills add microsoft\u002Famplifier-app-cli --skill goal-batch","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Fgoal-batch\u002FSKILL.md",[69,75,81,85,89,93,97,101,105,109],{"path":70,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":73,"sourceHtmlUrl":74},"examples\u002Fplan-and-report.md","REFERENCE","参考文档",2667,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Fgoal-batch\u002Fexamples\u002Fplan-and-report.md",{"path":76,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":79,"sourceHtmlUrl":80},"scripts\u002F.gitignore","SCRIPT","脚本",13,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fawf-debug-tools\u002Fscripts\u002F.gitignore",{"path":82,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":83,"sourceHtmlUrl":84},"scripts\u002Fbatch_status.sh",6620,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Fgoal-batch\u002Fscripts\u002Fbatch_status.sh",{"path":86,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":87,"sourceHtmlUrl":88},"scripts\u002Fcommon.py",13290,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fawf-debug-tools\u002Fscripts\u002Fcommon.py",{"path":90,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":91,"sourceHtmlUrl":92},"scripts\u002Fdiagnose-awf.py",10789,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fawf-debug-tools\u002Fscripts\u002Fdiagnose-awf.py",{"path":94,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":95,"sourceHtmlUrl":96},"scripts\u002Finspect-containers.py",7111,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fawf-debug-tools\u002Fscripts\u002Finspect-containers.py",{"path":98,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":99,"sourceHtmlUrl":100},"scripts\u002Flane_turns.sh",1438,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Fgoal-batch\u002Fscripts\u002Flane_turns.sh",{"path":102,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":103,"sourceHtmlUrl":104},"scripts\u002Flaunch_lane.sh",9185,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Fgoal-batch\u002Fscripts\u002Flaunch_lane.sh",{"path":106,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":107,"sourceHtmlUrl":108},"scripts\u002Fparse-squid-logs.py",7065,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fawf-debug-tools\u002Fscripts\u002Fparse-squid-logs.py",{"path":110,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":111,"sourceHtmlUrl":112},"scripts\u002Ftest-domain.py",7519,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fawf-debug-tools\u002Fscripts\u002Ftest-domain.py",[114,127,135,143],{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":120,"publishedAt":25},"01M69BJ9BX3FSEPSFADNZFTZBA","ten-lane-highway","Become the Highway Manager: drive many parallel \u002Fgoal lanes continuously toward a defined outcome, refilling lanes on every manager cycle so none sit idle. Use when the user wants continuous parallel throughput toward an outcome: \"run the highway\", \"\u002Fhighway\", \"10-lane highway\", \"keep N lanes full\", \"keep re-feeding lanes as they drain\", \"drive this for me in parallel\", \"do them all and monitor\", \"keep the lanes full\", \"work the whole list in parallel until done\". NOT for a one-shot batch that launches once and drains together — use goal-batch. NOT for bounded edits that each end in their own PR — use mass-change. Requires git, tmux, the amplifier CLI on PATH, and the goalify and monitor skills.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Ften-lane-highway\u002FSKILL.md",[],[121,122,123,24,124,22,21,125,126],"ten lane highway","goalify","git","monitor","tmux","cli",{"skillNo":128,"name":122,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":25},"01M69BJ71F38DR2QASW4HZ8K2Q","Compose and lint a \u002Fgoal stop-condition from the current conversation, catching known termination-failure patterns before showing it to the user. Use when the user wants to turn the current task into a \u002Fgoal loop, asks to \"goalify this\", wants a stop condition for autonomous work, says \"write a goal condition\", \"make this a \u002Fgoal\", \"turn this into a goal\", or asks for help wording a condition for \u002Fgoal.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Fgoalify\u002FSKILL.md",[],[122,133,134],"help","lint",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":141,"publishedAt":25},"01M69BJ3GMC0R27M16QKP33XYZ","doctor","Diagnose an Amplifier CLI environment through the CLI doctor agent. USE WHEN a user requests CLI runtime, settings or missing-capability inspection. DO NOT USE for project bugs or other hosts.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Fdoctor\u002FSKILL.md",[],[137,142,126],"diagnose",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":149,"publishedAt":25},"01M69BJ1PV3RT2VTC0PVVXJMC1","amplifier-config","Explain, inspect, troubleshoot, and safely modify Amplifier CLI configuration — providers, settings scopes, bundles, routing, skills, and source overrides. Use when someone describes desired Amplifier CLI behavior and needs effective-value provenance, a safe change plan, implementation, or outcome-based verification.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-app-cli\u002Fblob\u002Fmain\u002Famplifier_app_cli\u002Fdata\u002Fskills\u002Famplifier-config\u002FSKILL.md",[],[150,151,126,152,21,153,154],"config","amplifier config","routing","troubleshoot","safe"]