diff --git a/README.md b/README.md index 0011156..273d9d7 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ docs/TOKENMAXXING.md # local Claude = tokenmaxxing supervisor sume-desk/ GRAPHITE-HARD-LOCK.md # paste block for every author prompt skills/ # SoT (orchestration, gt-mq, mega-issue, Formats LC) + grok-hooks/ # ~/.grok/hooks/sume-desk.json template (registry rows) cursor-rules/user/ # ~/.cursor/rules cursor-rules/sume-com/ # /.cursor/rules ``` diff --git a/docs/FLOW.md b/docs/FLOW.md index 307178c..90ea79d 100644 --- a/docs/FLOW.md +++ b/docs/FLOW.md @@ -72,7 +72,9 @@ duplicate the full SKILL into the `.mdc`. a supervisor in front of Claude Code that pools subscription accounts and swaps near 5h / weekly limits. `claude-human-stream` / `agent-human-stream --backend claude` uses that `claude`. -Local Grok Build (`grok` CLI) uses `agent-human-stream --backend grok`. +Local Grok Build (`grok` CLI, tokenmaxxing-pinned) uses `agent-human-stream --backend grok`; +land jobs go through `sume-bg-launch … --until-landed ` (wrapper land-loop, +`LANDED:` line, steer via `agent-holders`). See `docs/TOKENMAXXING.md` § Grok Build pool. SoT: **`docs/TOKENMAXXING.md`**. Short version: diff --git a/docs/TOKENMAXXING.md b/docs/TOKENMAXXING.md index 7b575ea..6b0bf8b 100644 --- a/docs/TOKENMAXXING.md +++ b/docs/TOKENMAXXING.md @@ -3,8 +3,10 @@ This desk does **not** run bare `claude` against a single Anthropic login. On Chase’s machine, **`claude` on PATH is the tokenmaxxing supervisor**. `claude-human-stream` / `agent-human-stream --backend claude` (Fable/Opus -workers) go through that same binary. Grok Build is a different CLI (`grok`) -and uses `agent-human-stream --backend grok`. +workers) go through that same binary. **`grok` on PATH is also a tokenmaxxing +shim** (`__supervise-grok`, installed by `tokenmaxxing init --grok`); Grok +Build workers (`agent-human-stream --backend grok`) run through it — see +§ Grok Build pool below. Upstream: [anaclumos/tokenmaxxing](https://github.com/anaclumos/tokenmaxxing) (Bun global, `tokenmaxxing` on PATH). Subscription accounts only — not API keys. @@ -88,6 +90,41 @@ issues, or chat. - Codex can have its own tokenmaxxing pool (`init --codex`). This desk’s Fable/Opus path is the **Claude** pool. +## Grok Build pool (SuperGrok seats) + +`~/.config/tokenmaxxing/bin/grok` → `bun run ~/.local/src/tokenmaxxing/src/main.ts +__supervise-grok` → the binary named by `config.json` **`grokBin`** (a pinned +`~/.grok/downloads/grok--macos-aarch64`). That pin is the **only** Grok +that desk workers run. `~/.grok/bin/grok` (what `grok --version` from that +path reports) and `~/.grok/version.json` can be newer; they are not what +runs. `install.sh` prints both; `tokenmaxxing config get grokBin` is the +check. Bumping the pin = editing `grokBin` (then re-run the desk probes in +sumelabs/sume#5706, the wire shapes were captured on 1.0.11). + +Facts that shape `agent-human-stream --backend grok` (2026-09-02): + +- The supervisor ignores SIGINT/SIGHUP and has **no SIGTERM handler**: killing + it orphans the raw grok child with its stdout still on the pipe. The desk + steer (`sume-bg-launch --resume`) therefore kills the **process group and + the raw child** (`agent-holders kill `), never the supervisor alone. +- The child pid lives in `~/.config/tokenmaxxing/grok-live/` + (`{accountId, pid, startedAt}`); stale files self-heal by pid + start time. +- Three SuperGrok seats rotate on the **weekly** bar; a swap hot-reloads + `auth.json` on the next API call (no restart). The `StopFailure rate_limit` + respawn path relaunches `grok --resume ` **without** the headless + flags (`-p`, `--output-format`) — latent (never fired on this desk); the + wrapper aborts if a non-NDJSON line shows up. Upstream fix belongs in + tokenmaxxing, not cstack. +- Hooks: `~/.grok/hooks/tokenmaxxing-grok.json` (`Stop`, `StopFailure + rate_limit`) is the pool's; `~/.grok/hooks/sume-desk.json` (installed by + `install.sh`) is the desk registry hook. Both are silent, exit 0. + +```bash +tokenmaxxing status # grok seats: weekly bars +tokenmaxxing switch --grok # running sessions hot-reload on their next call +tokenmaxxing config get grokBin +``` + ## Install / repair (human) ```bash diff --git a/install.sh b/install.sh index 7edfebd..16b221f 100755 --- a/install.sh +++ b/install.sh @@ -176,6 +176,13 @@ ensure_wait_hint "$HOME/.codex/AGENTS.md" ensure_wait_hint "$HOME/.claude/CLAUDE.md" ensure_wait_hint "$HOME/.grok/AGENTS.md" +# Grok land rule (no monitor hand-off) for desks that already had the snippet. +if [ -f "$HOME/.grok/AGENTS.md" ] && ! grep -q "Land babysit (Grok Build worker)" "$HOME/.grok/AGENTS.md"; then + printf '\n' >> "$HOME/.grok/AGENTS.md" + sed -n '/^Land babysit (Grok Build worker)/,$p' "$ROOT/sume-desk/grok-agents-snippet.md" >> "$HOME/.grok/AGENTS.md" + echo "updated land hint: ~/.grok/AGENTS.md" +fi + if [ -x "$GTBIN/cstack-gt-wait-merge.test.sh" ]; then echo "== cstack-gt-wait-merge matcher ==" "$GTBIN/cstack-gt-wait-merge.test.sh" diff --git a/sume-desk/grok-agents-snippet.md b/sume-desk/grok-agents-snippet.md index 8c7f577..8ace1d3 100644 --- a/sume-desk/grok-agents-snippet.md +++ b/sume-desk/grok-agents-snippet.md @@ -9,3 +9,10 @@ Before any `gt submit` / `gt merge` on `sume-com`, read `cstack-gt-wait-merge` (labels the tip `merge-queue` now) — do not write a sleep/grep loop or wait for PR CI. Ignore sections marked **Cursor-only** unless you are Cursor. + +Land babysit (Grok Build worker): do **not** use `monitor` / `scheduler_*` +to wait — a background hand-off ends your headless turn with a snapshot. +Block in `run_terminal_command` (≤10 min slices, `sleep` between polls). Reply +`LANDED: yes` only when `git log origin/main --oneline --grep='(#N)'` hits; +otherwise end the turn with one status line — the desk wrapper re-prompts +this same session until the grep hits. diff --git a/sume-desk/skills/sume-main-agent-orchestration/SKILL.md b/sume-desk/skills/sume-main-agent-orchestration/SKILL.md index b768fc8..dcfcd4a 100644 --- a/sume-desk/skills/sume-main-agent-orchestration/SKILL.md +++ b/sume-desk/skills/sume-main-agent-orchestration/SKILL.md @@ -307,8 +307,13 @@ agent-human-stream --resume "Follow-up …" # backend from When the main agent needs a **Grok** worker (default **land babysit**, or author only if Chase named Grok): -1. Run **Grok Build** on the local machine (`grok` on PATH, currently - `~/.grok/bin/grok` via `~/.local/bin/grok`). Not Cursor `Task`. +1. Run **Grok Build** on the local machine. `grok` on PATH is the + **tokenmaxxing** `__supervise-grok` shim (`~/.config/tokenmaxxing/bin/grok`, + also `~/.local/bin/grok`); the binary that actually runs is the pin in + `~/.config/tokenmaxxing/config.json` `grokBin` (a `~/.grok/downloads/` + build — **1.0.11** as of 2026-09-02), **not** `~/.grok/bin/grok`. + `install.sh` prints both; `docs/TOKENMAXXING.md` § Grok Build pool is the + SoT. Not Cursor `Task`. 2. Launch with the same human-stream wrapper: `agent-human-stream --backend grok --name ""` Extra `grok` flags go **after** the prompt (`--model grok-4.6`, `--effort`, @@ -323,8 +328,35 @@ author only if Chase named Grok): exits 2 (`missing prompt`) before Grok starts. Pass `--prompt-file`. Same job slug stem as the Opus train when this is land babysit. 5. Do **not** route Grok land/author through Cursor `Task` / `cursor-grok-*`. -6. Steer / second `--resume`: use `sume-bg-launch` so the previous wrapper - on that uuid is stopped first (two `grok -p --resume` = empty live log). +6. Steer / second `--resume`: **only** via `sume-bg-launch --resume `. + It runs `agent-holders kill ` first: TERMs the whole holder group + (wrapper + tokenmaxxing supervisor + the raw grok child, which the + supervisor does not forward signals to), waits, KILL-escalates, and + refuses to launch (exit 3) if the uuid is still held. A bare second + `agent-human-stream --backend grok --resume ` is refused while a + holder exists — a second `grok -p --resume` on a live session blocks + forever in Grok `session_create` with no output (the empty live log). + Never `--continue` for Grok: every desk job shares one cwd, so it picks + whichever job started last (the wrapper refuses it when another Grok + job is open here). +7. **Land babysit contract** (#5697 / #5702 class): `grok -p` returns when + the **model turn** ends, not when the job ends — a `monitor` / + `scheduler_*` hand-off ends the run with a snapshot final. Launch land + jobs with **`--until-landed `** (+ `--wall-timeout 6h`): the wrapper + re-prompts the **same session** until `git log origin/main + --grep='(#N)'` hits, denies `monitor,scheduler_create,scheduler_delete`, + keeps the laptop awake (`caffeinate -i`), and always appends + `LANDED: yes|no` after the last `—— final ——`. Prompt wording like + "do not exit" cannot replace this; the prompt only says *how* to watch + (block in `run_terminal_command`, ≤10 min slices). +8. Session id is pre-assigned: fresh Grok launches mint `--session-id`, so + the stderr banner shows `📎 session_id= … (pre-assigned)` at t=0 + and the live log is `--.log` (also + `LATEST-.log`). `--resume ` works from any cwd but runs in + the session's **original** cwd. Registry rows carry model, child pid, + exit code, `landed`, context %, compaction count + (`agent-human-stream --sessions --backend grok`); transcript: + `agent-human-stream --export `. Copy-paste: @@ -340,7 +372,11 @@ Required skill: read ~/.agents/skills/sume-gt-mq/SKILL.md EOF # Shell description: Grok : (#N) cd /path/to/repo && sume-bg-launch --backend grok --name \ + --until-landed --wall-timeout 6h \ --prompt-file /tmp/sume-grok-prompts/.md -- --effort xhigh +# Steer the same session later (kills the live holder group first): +cd /path/to/repo && sume-bg-launch --backend grok --name --resume \ + --until-landed --prompt-file /tmp/sume-grok-prompts/-steer.md ``` ### Cursor-only — Opus / background-worker monitoring @@ -949,6 +985,12 @@ When the BP has a PR train, also say: land babysit unless the user said otherwise. - Do not invent extra slices beyond the BP train. +Launch every Grok land job through `sume-bg-launch … --until-landed ` +(§ "Grok transport" 7): the wrapper owns "stay until `origin/main`" and the +`LANDED:` line; the prompt owns the *method*. The prompt must forbid +`monitor` / `scheduler_*` (they end the `-p` turn) and tell Grok to block in +`run_terminal_command` with ≤10 min slices. + The **Grok** land prompt must say: MQ already enqueued → watch draft CI → **stay until** `origin/main` has `(#N)` (re-enqueue on eject; do **not** STOP at enqueue; do **not** write `HANDOFF: grok-land`) → issue