Skip to content
10 changes: 5 additions & 5 deletions amplifier_app_cli/data/skills/amplifier-config/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
name: amplifier-config
description: >-
Explain, inspect, troubleshoot, and safely modify Amplifier CLI configuration,
including provider selection, settings scopes, bundles, routing, skills, source
overrides, and provider-module settings composed into the CLI. Use when someone
describes desired Amplifier CLI behavior and needs effective-value provenance, a
safe change plan, implementation, or outcome-based verification.
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.
user-invocable: true
version: 0.1.0
license: MIT
Expand Down
25 changes: 14 additions & 11 deletions amplifier_app_cli/data/skills/goal-batch/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
---
name: goal-batch
description: >
Plan a batch of independent work into isolated lanes, get your approval, then
run each lane as its own autonomous /goal session — one git worktree, one
branch, one tmux session each — and verify and merge the results yourself.
Use when work decomposes into pieces that can run at the same time: "run these
in parallel", "goal-batch", "launch lanes for these", "work these N tasks
simultaneously", "batch these as goals". Nothing launches until you have seen
the lane split and said go. This is NOT fire-and-forget: the orchestrating
session re-runs the full test suite itself after every merge and never accepts
a lane's own claim that it finished. NOT for bounded edits that each end in
their own PR — use mass-change for that. Requires git, tmux, the amplifier CLI
on PATH, and the goalify and monitor skills.
Batch independent work into isolated /goal lanes — one worktree, branch, and
tmux session each — get your approval, then verify and merge every lane
yourself. Use when work decomposes into pieces that can run at the same
time: "run these in parallel", "goal-batch", "launch lanes for these",
"work these N tasks simultaneously", "batch these as goals". Nothing
launches until you've seen the lane split and said go, and this is NOT
fire-and-forget: the orchestrating session re-runs the full suite after
every merge and never accepts a lane's own claim that it finished. NOT for
bounded edits that each end in their own PR — use mass-change for that. For
continuous refill-on-drain parallel work toward an outcome, use
ten-lane-highway instead. Requires git, tmux, the amplifier CLI on PATH,
and the goalify and monitor skills.
version: 2.0.0
user-invocable: true
argument-hint: "<the work to batch, or where it is enumerated>"
allowed-tools: [bash, read_file, write_file, edit_file, grep, glob, delegate, load_skill, todo]
model_role: general
visibility:
summary: "One-shot batch of parallel /goal lanes that launches once and drains together; for continuous refill-on-drain work use ten-lane-highway."
---

# Goal Batch
Expand Down
4 changes: 2 additions & 2 deletions amplifier_app_cli/data/skills/goalify/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: goalify
description: >
Compose a /goal stop-condition from the current conversation and lint it
against known termination-failure patterns before showing it to the user.
Compose and lint a /goal 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 /goal loop, asks to
"goalify this", wants a stop condition for autonomous work, says "write a
goal condition", "make this a /goal", "turn this into a goal", or asks for
Expand Down
107 changes: 79 additions & 28 deletions amplifier_app_cli/data/skills/ten-lane-highway/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
---
name: ten-lane-highway
description: >
Become the Highway Manager: a strategist that takes a defined outcome plus
constraints and drives many parallel /goal lanes continuously toward it —
plan, get one approval, saturate to width, then verify/merge/refill on every
wake so lanes never sit idle, weaving new feedback into priorities as it
arrives. Use when the user wants continuous parallel throughput toward an
outcome: "run the highway", "/highway", "10-lane highway", "keep N lanes
full", "keep re-feeding lanes as they drain", "drive this for me in
parallel". 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.
Become the Highway Manager: drive many parallel /goal lanes continuously
toward a defined outcome, refilling lanes on every wake so none sit idle.
Use when the user wants continuous parallel throughput toward an outcome:
"run the highway", "/highway", "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.
version: 1.0.0
user-invocable: true
shortcut: highway
argument-hint: "<the outcome to drive, constraints/deadline, and where the work lives>"
model_role: general
visibility:
summary: "Drive many parallel /goal lanes continuously toward an outcome — refill on drain, verify by evidence, close per completion intent."
# Deliberately NOT `context: fork`: the approval gate, mid-flight steering, and
# conflict questions must happen in THIS conversation across many turns. A fork
# is call-and-return; a highway manager is a standing conversation partner.
Expand All @@ -36,6 +37,16 @@ capacity. Never wait for a batch. Continuously decide what the best available
use of each unit is." You are doing agent capacity management — closer to OS
scheduling than to a task list.

## First run (~15 minutes)

New to the highway? Do a throwaway run first — a scratch repo you can break,
**width 2**. Invoke `/highway` with a small outcome + that repo + "width 2";
approve at the Phase 3 gate (nothing launches before you say go); then watch
**gate → 2 lanes → watchdog → merges**, refilling until the queue drains. Stop
everything with `tmux -L hw kill-session -t hw-watchdog__<batch>` (plus any
`hw__<batch>__*` lane sessions), then delete `BATCH_DIR`. Full command sequence
and expected output: `examples/first-run.md`.

## You are the Highway Manager — a strategist, not an intake clerk

You take the user's **outcome/goal**, their **constraints** (time, authority,
Expand Down Expand Up @@ -78,10 +89,12 @@ repo** (a real run left `.amplifier/bin/` behind as untracked pollution).
| `launch_lane.sh BATCH_DIR LANE REPO GOAL [BASE_REF]` | Worktree + branch + tmux + `/goal` session, idempotent; the ONLY writer of `manifest.tsv` | Hand-written manifests diverged on column count and broke a real batch |
| `verify_lane.sh BATCH_DIR LANE` | Git-facts probe for one landed lane (DONE.json, ahead-count, three-dot diffstat, uncommitted work) | "Ground truth from git and the filesystem, not from what any session said about itself" |
| `highway_watchdog.sh BATCH_DIR WIDTH SESSION_ID [INTERVAL] [MAX_HOURS]` | Detached tmux loop that re-wakes THIS session (`amplifier run --resume`) on lane-end / under-width / stale heartbeat | The highway once froze overnight because the manager stopped monitoring the moment it reported status |
| `infra_ledger.sh BATCH_DIR add TYPE ID DESTROY_CMD...` / `infra_ledger.sh BATCH_DIR sweep` | Records any infrastructure a lane OR the manager stands up (DTU, gitea instance, container, service, background process) into `infra.tsv` at creation, each with its teardown command; `sweep` runs those commands and exits non-zero until nothing is left standing | A run closed with a DTU and a gitea container still live — nothing the highway stands up should outlive it (Rule 14) |

State lives in `BATCH_DIR` (create one per highway, e.g. `~/dev/hw-<name>`):
`manifest.tsv` (scripts write), `HIGHWAY.md` (you write), `lanes/` (worktrees),
`.manager-heartbeat`, `wake-needed`, `watchdog.log`.
`manifest.tsv` (scripts write), `HIGHWAY.md` (you write), `goals/` (pre-composed
goal files), `lanes/` (worktrees), `.width` (authoritative width), `infra.tsv`
(the infra ledger), `.manager-heartbeat`, `wake-needed`, `watchdog.log`.

## Phase 1 — Intake

Expand Down Expand Up @@ -121,8 +134,20 @@ strategic value toward the outcome — not arrival order. Mark
investment/speculative candidates (recon, spikes, de-risking) to backfill idle
capacity later.

**Pre-compose the whole queue now.** `load_skill("goalify")` **inline — never
delegated** (goalify reads the live transcript; a sub-agent cannot) and write a
goal file per queued item up front into `BATCH_DIR/goals/<item>.md`, each with a
disjunctive exit and per-item residuals. This makes every later refill a bare
`launch_lane.sh` call, never compose-then-launch (idle capacity is the enemy —
Phase 5 invariant); an item arriving at weave-in gets its goal file composed
when it enters the queue, not at refill. Each goal file MUST instruct its lane to
register any infrastructure it stands up — DTU, gitea instance, container,
service, background process — with `infra_ledger.sh <BATCH_DIR> add <type> <id>
<destroy-cmd…>` at creation (Rule 14).

**Success criteria**: a priority queue in `HIGHWAY.md` with a one-line
rationale per item tied to the outcome/constraints.
rationale per item tied to the outcome/constraints, and a pre-composed goal file
in `BATCH_DIR/goals/` for every item in it.

## Phase 3 — Approval gate `[human]`

Expand All @@ -136,11 +161,10 @@ approval from enthusiasm or silence.

## Phase 4 — Saturate

For each lane in the first wave:
1. `load_skill("goalify")` **inline — never delegated** (goalify reads the
live transcript; a sub-agent cannot) and compose the lane's stop-condition
with a disjunctive exit and per-item residuals.
2. `launch_lane.sh BATCH_DIR <lane> <repo> <goal-file> [base]`.
For each lane in the first wave, launch from the goal file Phase 2 already
pre-composed in `BATCH_DIR/goals/` — no goalify here:

- `launch_lane.sh BATCH_DIR <lane> <repo> BATCH_DIR/goals/<item>.md [base]`.

Then start the watchdog. **`<BATCH_DIR>`, `<WIDTH>`, `<SESSION_ID>` below are
documentation placeholders — substitute literal values; they do not exist as
Expand All @@ -150,17 +174,27 @@ not depend on context:

```bash
printf '%s\n' "<SESSION_ID>" > <BATCH_DIR>/.session-id
printf '%s\n' "<WIDTH>" > <BATCH_DIR>/.width # authoritative width — the single
# source of truth the scripts read
touch <BATCH_DIR>/.manager-heartbeat # BEFORE the watchdog starts, so it never
# sees an absent heartbeat and wakes a
# concurrent instance mid-saturation
BATCH=$(printf '%s' "$(basename <BATCH_DIR>)" | tr -c 'A-Za-z0-9_-' '_') # same sanitization the scripts use
tmux new-session -d -s "hw-watchdog__${BATCH}" \
tmux -L hw new-session -d -s "hw-watchdog__${BATCH}" \
"<skill_directory>/scripts/highway_watchdog.sh <BATCH_DIR> <WIDTH> <SESSION_ID> 300 12 2>&1 | tee -a <BATCH_DIR>/watchdog.log"
```
Then touch `<BATCH_DIR>/.manager-heartbeat` again at the start of every Phase 5
cycle (step 1) and after each merge, so the watchdog defers while your turn is
active and only takes over once you have genuinely gone idle.

**Width, the tmux socket, and escalation.** `<BATCH_DIR>/.width` is the single
source of truth for the target lane count (the scripts read it there); changing
width mid-run is an explicit act — **edit `<BATCH_DIR>/.width` AND log it in the
weave-in log**, nothing else moves width. Every highway tmux command runs on the
socket `HIGHWAY_TMUX_SOCKET` (default `hw`) — hence the `-L hw` above and on the
Phase 7 kill. A wake whose prompt begins `HIGHWAY ESCALATION` means go straight
to Phase 6 and lead with `NEEDS YOU:`; the watchdog stays alive throughout.

Verify launch: run `highway_status.sh` once — every lane LIVE past its first
LLM call (log growing), watchdog LIVE. Then build the **todo lane board** (see
below).
Expand All @@ -185,9 +219,11 @@ invariant exists to prevent.)
2. Get READY (count of ready, unblocked items) from the work queue.
3. **Run `highway_status.sh BATCH_DIR WIDTH READY` and paste its output.**
4. **If `DEFICIT>0`: refill FIRST** — before merging, before reporting, before
anything. Pick the top-priority ready items (strategist's choice), goalify
each inline, `launch_lane.sh` each. Under-width with ready work is allowed
only with an explicit one-line justification in the transcript that cycle.
anything. Pick the top-priority ready items (strategist's choice) and
`launch_lane.sh` each from its pre-composed `BATCH_DIR/goals/` file — refill
is a bare launch, never a compose-then-launch. Under-width with ready work is
allowed only with an explicit one-line justification in the transcript that
cycle.
5. **Width first, then merge — never the reverse.** Step 4 (restore width)
always precedes this. For each ENDED lane: `verify_lane.sh`, then YOUR own
artifact check, then `merge --no-ff` from the main checkout, resolve the item
Expand All @@ -201,8 +237,10 @@ invariant exists to prevent.)
Repair small defects in place or file the honest negative — never let one
straggler block the others.
6. Strategize: process anything new (weave-in log: now / queued / declined,
with reasons), re-prioritize, handle STALLED and ENDED-NO-DONE lanes
(inspect the lane log tail; relaunch or reassign).
with reasons) — and the instant you queue an incoming item, goalify it inline
and write its `BATCH_DIR/goals/` file so a later refill stays a bare launch.
Re-prioritize, handle STALLED and ENDED-NO-DONE lanes (inspect the lane log
tail; relaunch or reassign).
7. Update the **todo lane board** and rewrite `HIGHWAY.md`. Regenerate its
Landed section from git ground truth — `scripts/landed_from_git.sh <repo>
[base]` — so the Operating Picture can never drift from what actually merged
Expand Down Expand Up @@ -271,8 +309,12 @@ deadline reached, the user's release given, or (for *achieve-and-close*) the
outcome verified with nothing pending.

When you close: final Phase 5 pass; merge
or honestly disposition every open lane; kill the watchdog by the exact
name `highway_status.sh` reports (`tmux kill-session -t <wd_name>`). **Archive
or honestly disposition every open lane; then **run `infra_ledger.sh BATCH_DIR
sweep` and do not treat the highway as closed until it exits clean** — it tears
down every DTU, gitea instance, container, service, and background process the
run ledgered, whether a lane or the manager stood it up (Rule 14). Kill the
watchdog by the exact name `highway_status.sh` reports
(`tmux -L hw kill-session -t <wd_name>`). **Archive
the per-lane evidence BEFORE pruning** — pruning the lane dirs otherwise deletes
`lane.log` and the markers with them:
```bash
Expand All @@ -286,6 +328,7 @@ status, landed list from `landed_from_git.sh`, residuals with named reasons);
report with `DONE:` or `GAVE UP:` leading.

**Success criteria**: no `hw__` tmux sessions, no stray worktrees/branches,
`infra_ledger.sh BATCH_DIR sweep` exits clean (nothing ledgered still standing),
final report matches git facts.

## Rules — each bought with a documented failure
Expand Down Expand Up @@ -320,8 +363,16 @@ final report matches git facts.
live shared services are read-only to lanes.
13. **If `$ARGUMENTS` is empty, ask** — do not invent an outcome. (The fork
sibling of this failure killed a real goal-batch invocation silently.)
14. **Infrastructure is ledgered at creation and swept at close — nothing the
highway stands up outlives it.** Any DTU, gitea instance, container,
service, or background process a lane OR the manager stands up is recorded
with `infra_ledger.sh BATCH_DIR add ...` at creation, and Phase 7 does not
close until `infra_ledger.sh BATCH_DIR sweep` exits clean. (A run closed
leaving a DTU and a gitea container running.)

## Known limits (still not built)

## Known limits / v2 mechanisms (noted, not built)
(Width pin, escalation, and the infra ledger are now implemented above.)

- A hook that injects `highway_status.sh` output into every turn (the way the
todo reminder does) would make drift structurally impossible to ignore —
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# First run — a 15-minute throwaway highway

The point of a first run is to see the whole loop — **gate → lanes → watchdog →
merges → refill → close** — on work you do not care about, at width 2, before
you trust it with something real. Nothing here is special to width 2; it is just
small enough to watch every moving part.

## Before you start

- A **throwaway git repo** you can break (a scratch clone, or `git init` a
sandbox with a couple of trivial files). A remote is optional — lanes commit
locally and merge fine with no network.
- `git`, `tmux`, and the `amplifier` CLI on PATH.
- Two or three tiny, independent chores in that repo (e.g. "add a docstring to
each of files A, B, C") — enough to fill two lanes and leave one to refill.

## The sequence

1. **Invoke** in the interactive TUI:

```
/highway reach a green throwaway: do the three chores in <scratch-repo>,
width 2, achieve-and-close
```

In a headless one-shot, name the skill in prose instead of the bare slash
token: `amplifier run "Use the ten-lane-highway skill and drive: <outcome>"`.

2. **Intake + strategize (Phases 1–2).** The manager writes `BATCH_DIR`
(e.g. `~/dev/hw-firstrun`), a `HIGHWAY.md`, pins `BATCH_DIR/.width` to `2`,
and **pre-composes a goal file per queued item** into `BATCH_DIR/goals/`.

3. **Approve at the gate (Phase 3).** You will see one screen: outcome, width 2,
the first wave (lane → repo → item), the priority rationale, watch cadence.
Reply `go`. Nothing launched before this.

4. **Saturate (Phase 4).** Two lanes come up — each a worktree + branch + tmux
session running `/goal` — then the **watchdog** starts on the `hw` tmux
socket. Confirm with the status instrument: both lanes LIVE, watchdog LIVE,
`DEFICIT=0`.

5. **Watch it run (Phase 5).** As a lane finishes, the manager verifies it from
git facts, merges `--no-ff`, tears the lane down, and **refills the instant a
slot opens** from the pre-composed queue — a bare `launch_lane.sh` call, no
re-goalify. The todo lane board is your live dashboard.

6. **Close (Phase 7).** With `achieve-and-close` and nothing pending, the
manager does a final full-suite sweep, runs the infra-ledger sweep
(`infra_ledger.sh BATCH_DIR sweep` must exit clean), archives per-lane
evidence, prunes worktrees/branches, kills the watchdog, and reports
`DONE:`.

## What you should observe

- The **gate blocks** until you say go — enthusiasm and silence are not consent.
- Width holds at 2 while work remains: a drained lane refills immediately, not
after the whole wave lands.
- Every merge is proven by the merged lane's **own tests**, with the full suite
on a cadence and at close — never a lane's self-report.
- `HIGHWAY.md` and the todo board agree at the end of every cycle.

## Stop everything (panic button)

```bash
# BATCH is the sanitized batch name (basename of BATCH_DIR, non-alnum → _)
tmux -L hw kill-session -t "hw-watchdog__${BATCH}" # the watchdog
tmux -L hw list-sessions -F '#{session_name}' \
| grep "^hw__${BATCH}__" | xargs -r -n1 tmux -L hw kill-session -t # lanes
infra_ledger.sh "$BATCH_DIR" sweep # tear down anything lanes stood up
rm -rf "$BATCH_DIR" # worktrees, goals, HIGHWAY.md, logs
```

All highway tmux commands use `-L hw` (the `HIGHWAY_TMUX_SOCKET`, default `hw`),
so a stray `tmux kill-server` on the default socket never touches the highway,
and this never touches your other tmux work.
Loading
Loading