# machine commands ## `/good [note]` Save the latest user/assistant turn as a good example. ```text /good /good --as "Go to Settings → Security → Reset password." /good --trace ``` Default destination: the project's `train.jsonl` in the Machine store. Run `/machine data` to see the path. ## `/good --trace` Reconstruct the last user turn as a trajectory: - user - assistant prose - assistant tool calls - tool results Default destination: the project's `traces.jsonl` in the Machine store. These rows are explicitly judged good. Reasoning is omitted unless `--reasoning` is set. The JSONL row contains: - `messages` — Tinker chat JSONL, including OpenAI-style `tool_calls[].function` - `trajectory` — Letta-style records - `kind: "trace"` - `tag`, `source`, `entryIds` ## `/bad [note]` Same as `/good`, written to the project's `rejected.jsonl` in the Machine store. ## `/tagged` List recent rows from `train.jsonl`, `traces.jsonl`, `observed.jsonl`, and `rejected.jsonl` in the Machine store. ## `/machine auto` Save the span Pi is about to compact as an unlabeled full trajectory. ```text /machine auto # toggle /machine auto on /machine auto off /machine auto status ``` Off by default. `/machine auto on` persists the setting for the current project. Two automatic writes go to `observed.jsonl` in the Machine store: - Compaction: `session_before_compact` writes the span *before* `firstKeptEntryId` with `kind: "auto-compact"`. - Headless exit: when `pi -p` or `--mode json` finishes a real prompt (`session_shutdown` reason `quit`), the last user turn is written with `kind: "auto-headless"`. Slash-command-only runs (`/train`, `/good`, …) are skipped. Reasoning is omitted. `/machine auto off` disables both. Automatic rows use `tag: "observed"`. Completion and compaction are evidence that work happened, not judgments that the behavior was good. `/train` does not select `observed.jsonl` by default. ## `/machine fork [note]` Start a new headless `pi -p` run that reviews the latest observed turn. ```text /machine fork /machine fork use Julia, not Python machine fork please don't delete the file ``` Machine reads the latest `auto-headless` (else latest observed) row in this project's `observed.jsonl`, builds a follow-up prompt from that user turn, the previous assistant answer, and your leftover args as the correction, then spawns `pi -p` with `MACHINE_FORK=1` if `pi` is on `PATH`. If the host cannot run a program, it prints the prompt and the command so you can rerun headless yourself. This does not copy the observation into `train.jsonl`. Observed rows stay unlabeled; only `/good` creates positive training examples. The same flow is available outside the TUI as the `machine` CLI (`machine help`, `machine data`, `machine observed`, `machine fork`, `machine correction --id`). ## `/machine correction --id prompt` Replay a specific saved row instead of the latest observation. ```text /machine correction --id c0ffee123456 use Julia, not Python machine correction --id c0ffee123456 "use Julia, not Python" machine correct --id c0ffee123456 "use Julia, not Python" ``` Machine looks up that `id` in `observed.jsonl`, then `traces.jsonl`, then `train.jsonl`. It spawns `pi -p` with the original user turn plus the correction, setting `MACHINE_FORK=1` and `MACHINE_ROW_ID=`. If `pi` is not on `PATH`, it prints the composed prompt. New `train` / `traces` / `observed` / `rejected` rows get a short hex `id`. Older rows keep working; `machine observed` prints `(no id)` when a row has none. Observed rows stay unlabeled; this does not copy them into `train.jsonl`. ## `/machine data` Show the current project's Machine store, automatic-capture setting, dataset paths, and row counts. Machine stores data outside the working tree by default: - All platforms: `~/.machine/-` Set `MACHINE_DATA_DIR` to override the base directory. Full trajectories can contain tool output and private source material; inspect them before training or copying them. Versions before `0.2.0` used a project-local `data/` directory. Machine leaves existing files in place; pass one explicitly to `/train` or move reviewed rows yourself. ## `/machine work` and `/machine student` Flip between the daily driver and the student (Tinker) lane. ```text /machine student # Inkling-Small 256K, or latest /tinker use checkpoint /machine student Qwen/Qwen3.8-27B:peft:262144 /machine student thinkingmachines/Inkling-Small:peft:262144 /machine work # back to Grok / last non-Tinker model ``` `/machine student` remembers the current non-Tinker model. `/machine work` switches back to it. Checkpoints registered with `/tinker use` are preferred over the Inkling-Small 256K base when no id is passed. HuggingFace-style Tinker ids (`Qwen/…`, `thinkingmachines/…`, `tinker://…`) do not need a `tinker/` prefix. `/machine ft` is an alias for `/machine student`. Machine registers the Tinker chat catalog itself (Inkling, Qwen3.8-27B 64K/256K, and `/tinker use` checkpoints). `pi-tinker` is no longer required. Train on Qwen 3.8-27B with `/train sft --model Qwen/Qwen3.8-27B`. Chat the 256K peft id after `/reload`: ```text /machine student Qwen/Qwen3.8-27B:peft:262144 ``` See [tinker/commands.md](tinker/commands.md) for `/tinker`. ## `/train validate [jsonl]` Lightweight JSONL checks, plus Python renderer/token-mask validation when `tinker-cookbook` is installed. ```text /train validate /train validate /path/to/reviewed-traces.jsonl --model thinkingmachines/Inkling-Small --quick ``` The default file is the explicitly judged `train.jsonl` in the current project's Machine store. `/train` prefers `.venv/bin/python` in the current project, then the machine package venv, then `python3`. ## `/train sft [jsonl]` Write `train_sft.py` and `tinker.yaml` for Tinker Cookbook SFT. ```text /train sft /train sft /path/to/reviewed-traces.jsonl --model thinkingmachines/Inkling-Small --force /train sft --epochs 10 --steps 60 ``` Training runs at most one epoch by default; small datasets often need `--epochs N` for the format to stick before `--steps` can take effect. ## `/train smoke [--yes]` Run `python3 train_sft.py max_steps=2`. This can use the Tinker API. ## `/train eval` ```text /train eval init --force /train eval baseline --yes /train eval checkpoint tinker://.../sampler_weights/... --yes /train eval compare eval_results/baseline.json eval_results/step-20.json ``` ## Status line (Pi) Pi paints a compact Machine footer next to other extension statuses: - `last turn untagged` after a reply that has not been `/good` or `/bad` - `last: good`, `last: good trace`, or `last: rejected` just after a judgment - `student` when the Tinker lane is active - `auto` when automatic observation is on - quiet `N train` and `N obs` counts from this project's store The line hides when there is nothing to report. Letta Code has no footer.