# yams — memory (agent-level)

High-level conventions and operating patterns for the yams agent.
**Detailed technical pointers live in [`vault/para/robot/yam/memory.md`](../../../para/robot/yam/memory.md)** —
this file is for "how I work" notes, not code specifics.

Append-only. Date entries.

## 2026-06-02 — Code lives on the lab server, not on rigs

After the sshfs rehaul, **all YAM code is at `/data/cameron/para/robot/yam/`
on the lab server**. Puget and russet mount it as `~/lab/para/robot/yam/`.
Never copy code to either machine. Edit on lab; runs see updates instantly.

Data + checkpoints + eval_videos stay on **puget** (`~/yam_para/{data,
checkpoints,eval_videos}`) because they're large + IO-heavy. Training reads
data locally on puget, writes checkpoints locally. Inference is launched
from puget too. Russet runs `rd serve` only — it doesn't need code dirs
beyond what `~/lab/` provides.

## 2026-06-02 — Lab is for scripts, never large files

Tailscale → DERP-relay (SFO) → ~25 MB/min combined throughput. Don't
rsync large binaries to lab. Anything > 100 MB belongs on puget, with
the lab-side code referencing puget-local paths via env vars
(`DINO_WEIGHTS_PATH=$HOME/yam_para/dinov3/weights/...`).

Concretely, the following stay on puget:

- Pretrained backbone weights (DINOv3 ViT-S/16+, ViT-L, ConvNeXt) at
  `~/yam_para/dinov3/weights/`
- Training checkpoints at `~/yam_para/checkpoints/<run>/`
- Training PKLs + PNG frames at `~/yam_para/data/`
- Eval video MP4s at `~/yam_para/eval_videos/`
- raiden's TRI-stereo weights (`raiden_fork/weights/tri_stereo/`,
  247 MB)
- exo_redo baselines + drrobot batch results (~270 MB + 3 MB)

Excluded those from the lab-side rsync explicitly. raiden_fork on lab
is **source + meshes only** (~250 MB total).

If you find yourself rsyncing > 100 MB to lab, **stop**.

## 2026-06-02 — Edit-on-lab rule

Never `scp` code or edit via `ssh dev '... python heredoc ...'`. The mount
is bidirectional and instant. My native `Read` / `Edit` / `Write` tools
work directly on `/data/cameron/para/robot/yam/...`; both rigs see the
update immediately.

Pre-rehaul rule (now obsolete): "edit on puget, sshfs into russet" — that
was a workaround for missing lab-server outbound SSH. Tailscale SSH
approval landed 2026-06-02.

## 2026-06-02 — Watch russet launches for 30 s

Cameron's standing rule: any process launched on russet (especially
into a tmux pane via `send-keys`) gets a poll loop afterwards.
**Poll every 10 s for the first 30 s** and report status or any error.
Don't just launch and walk away — russet launches involve ZED open,
teleop CAN init, raiden venv import time; failures land within the
first 30 s ~90% of the time.

Pattern:

```bash
tmux send-keys -t agents:6 'python …' Enter
# then immediately:
for i in 1 2 3; do
  sleep 10
  out=$(tmux capture-pane -t agents:6 -p | tail -8)
  echo "$out" | grep -qE "Traceback|fail to communicate|MOTION SENSORS|RuntimeError" && break
  echo "$out" | grep -qE "teleop is live|locked\\.|episode saved" && break
done
```

If it's already in steady state by 30 s, treat as healthy and back
off to the user's next instruction. If it errored, surface the error.

## 2026-06-02 — `LiveRerunSession` is the canonical live-rerun scaffold

Any live rerun script (calibration, recording overlay, inference
overlay, testing) uses `lib/rerun_session.py:LiveRerunSession`. Bakes
in every fix debugged live on the YAM rig that day:

- **JPEG-encode all images** (`lib.rerun_helpers.to_jpeg`). Raw
  HD1080 at 15 fps swamps the gRPC channel and freezes the viewer
  with `re_grpc_server` backlog warnings; JPEG is ~50× lighter.
- **Single ZED grab per iteration.** ZED's buffer holds only the
  latest frame; a drain loop *blocks* per `grab()` and ruins latency.
- **`rr.set_time("step", sequence=frame_idx)` per iteration.**
  Without an advancing timeline, the web viewer freezes on frame 0.
- **`serve_grpc` + `serve_web_viewer`** (not `serve_web`). Raiden's
  pattern; `rr.serve_web` doesn't exist in the installed SDK.
- **Yellow leader top button polled at 20 Hz** for clean teleop exit.
- **`MUJOCO_GL=egl`** set before mujoco is imported (headless puget).

Don't re-implement these. `calibrate.py` is the canonical example
(~60 lines because the scaffold owns the boilerplate). Recording +
deploy launchers should follow the same shape.

See `vault/para/robot/yam/rerun-panels.md` for the full pattern table
and skeleton.

## 2026-06-02 — `yam-rd-serve` instead of manual rd serve restart

raiden's policy server intentionally estops + shuts down on client
disconnect. Pre-wrapper this meant a manual restart between every deploy
session. The wrapper at `~/lab/para/robot/yam/bin/yam-rd-serve` runs `rd
serve` in a respawn loop; one Ctrl-C kills the current rd serve and the
loop restarts it; two Ctrl-Cs in quick succession breaks the loop.

Russet workflow:

```bash
ssh robot-lab
source ~/cameron/raiden_fork.venv/bin/activate
~/lab/para/robot/yam/bin/yam-rd-serve
```

This is the new norm — manual restarts are no longer needed.

## 2026-05-26 — yams owns TRI-technical work

Spun up from project_highlevel's overflow. Defer all TRI-technical
questions (calibration, deploy, DGX, MuJoCo debugging) to me. PARA paper
strategy / narrative → project_highlevel.

## Operating style (Cameron-signed-off)

- Cameron prefers **terse**, opinionated responses. Lead with the
  recommendation, then bullets. No prefacing.
- Reference vault by path: "per `vault/para/robot/yam/memory.md` the
  scene cam needs the HD1080 patch in two files".
- Per long-term memory: chain the full pipeline automatically — don't
  ask permission between obvious steps. Surface decisions, don't
  enumerate every micro-step.
- Cameron actively reviews code for conciseness (Code Hygiene rule
  added to `GUIDELINES.md` 2026-06-02). Default to less code, more
  clarity. Target ≤300 lines/file. Pull shared logic into `lib/`.

## Don't reimplement — borrow

Where another agent owns durable code that solves a sub-problem, use it.
Two examples from this stack:

- **Aug-token / OOF wrist abstain** — borrowed from backbones agent.
  Don't reimplement.
- **DINOv3 ViT-S/16+ at 504-space input** — production backbone owned
  by backbones; weights at `/data/cameron/para/dinov3/weights/...`.

## Where things live

| Concern | Where |
|---|---|
| YAM source code | `/data/cameron/para/robot/yam/` |
| YAM data, checkpoints, eval_videos | `~/yam_para/...` on puget (stays for IO) |
| DINOv3 weights + repo | `/data/cameron/para/dinov3/` |
| Auto-memory (per-session) | `~/.claude/projects/-data-cameron/memory/` |
| Per-task inbox/outbox | `/data/cameron/agents_stuff/agents/yams/` |
| Project SOTA + status | `vault/para/robot/yam/overview.md` |
| Technical pointers | `vault/para/robot/yam/memory.md` |
| TRI infra map | `vault/tri/` |
