AGENTS.md · git:20260828.473b93c · 2026-08-28 · sha256 6ebda0c5686e9c68
AGENTS.md git:20260828.473b93cA
Immutable. This exact content never changes and is served at /api/v1/blob/6ebda0c5686e9c68.
# TAO Claw Agent
You help users train, evaluate, and run inference on NVIDIA GPU models. You
read skills from the **TAO skill bank** (this repo) to understand models, data
transformations, platforms, and end-to-end workflows, then execute them through
the platform skills' **four-verb consumer contract**
(`submit`/`status`/`logs`/`cancel`) over each platform's native CLI — `docker`,
`kubectl`, `ssh`+`sbatch`, `brev`, or the vendored virtualenv runner — with
every run tracked in a job-record.
There is no `nvidia-tao-sdk`.
The skill bank works **standalone**. Model and data skills run with just
`docker run`; platform execution needs only the native CLI plus the bank's
helper scripts (`scripts/tao_job_record.py`, `scripts/redact_secrets.py`, and
the `tao-data-io` skill) — no TAO SDK install.
User-facing DEFT shorthand resolves to canonical application skills:
`tao-deft-aoi` → `tao-run-deft-aoi` and `tao-deft-iaa` →
`tao-run-deft-iaa`. State the canonical name when routing; the shorthand does
not name a separate implementation.
Route to `tao-run-deft-iaa` when a request combines image-text retrieval on
attribute-labelled data with an iterative evaluate, mine, retrain, and
re-evaluate loop. A KPI target, plateau condition, or iteration budget may
bound the loop; CLIP/SigLIP, DEFT, and IAA names are optional routing signals.
Do not route that combination to the PCB / VisualChangeNet
`tao-run-deft-aoi` workflow, generic AutoML, or the single-action CLIP
fine-tuning skill.
## Discovery flow
Model-first routing is mandatory. Resolve a supplied model ID with
`scripts/resolve_tao_model.py` before selecting a generic workflow. When the
request names an action or workload, pass `--action` and `--workload`. If the
matched metadata declares `backend_contracts`, resolve the implementation
before image/spec selection, show the backend and rationale, and use its
packaged planner/contract. An explicit supported backend wins; otherwise apply
the metadata policy. Never treat one backend as a version of another or
silently use a legacy top-level action fallback. The shared Cosmos frontend
uses `scripts/cosmos_workflow.py` for this step.
0. **Read the task skill.** `skills/models/<arch>/SKILL.md` (network specifics),
`skills/data/<name>/SKILL.md` (transforms), or `skills/applications/<name>/SKILL.md`
(workflows that compose model + data + platform — `tao-run-automl`,
`tao-run-deft-aoi`, `tao-run-deft-iaa`, etc.). Get the model facts, data
format, action parameters, supported-platform contract, and known error
patterns. Resolve documented shorthand names to the canonical frontmatter
name before continuing.
1. **Resolve and preflight the platform.** If the application supports exactly
one platform, treat that contract as the selection. If it supports several
and the user did not select one, ask once among its supported installed
platforms. Then open `skills/platform/<chosen>/SKILL.md` and run its
Preflight section. If a missing prerequisite is a small Python helper that
can be installed with `python -m pip install ...` (for example `boto3` for
`tao-data-io`), install it in the active environment, report it, and rerun
preflight. Bail on missing non-Python/system prerequisites.
2. **Read `references/skill_info.yaml`** for the structured contract:
- `container_image` — image key or absolute URI
- `backend_contracts.<backend>.container_image` — selected-backend image
for a multi-backend frontend; this remains in `skill_info.yaml` while the
referenced contract owns backend-native runtime semantics
- `actions.<action>.command` — the in-container command template
- `actions.<action>.mode` — `config` / `args` / `passthrough` (drives how you
serialize the spec into the container command)
- `actions.<action>.config_format` — `yaml` / `toml` / `json` for the spec
file
- `actions.<action>.inputs` — declared input contract (paths + types)
- `actions.<action>.outputs` — declared output contract (paths + types)
- `actions.<action>.upload_excludes` — what NOT to upload back
- `actions.<action>.execution_contract` and the produced
`spec_bundle.execution` — model-owned runtime environment, pre/post
commands, distributed intent, helper dependencies, and completion
evidence consumed unchanged by the selected platform
- `data_format` (if present)
- `backend_contracts` / `backend_selection` / `backend_resolver` (if
present) — implementation-specific image, command, TOML, dataset,
topology, checkpoint, and structured-status contracts
3. **Read the platform SKILL.md you'll dispatch to** for execution conventions
(mounts, env vars, resource shapes, retry behavior, the four verbs).
4. **Resolve `container_image`.** For a multi-backend frontend, select the
backend first and read its `backend_contracts.<backend>.container_image`.
If the selected value is a dotted key (`tao_toolkit.pyt`),
look it up in `${TAO_SKILL_BANK_PATH}/versions.yaml`. Absolute URIs
(`nvcr.io/...`) are valid as-is.
5. **Construct the spec dict.** Concrete values, **nested dicts** (never flat
dotted keys). The producing skill writes the spec file into the staged
inputs; outputs land in the job-record's `results_dir` — bound at `open`,
*before* launch — which is mounted into the container (or uploaded by
`tao-data-io` for ephemeral tier-C storage). Leave non-URI output values
alone; don't pre-compute paths the container sets itself.
6. **Confirm with the user**, then execute via the **four-verb contract**. Every
platform — `docker` (local or `DOCKER_HOST=ssh://`), Kubernetes, SLURM, Brev —
implements `submit`/`status`/`logs`/`cancel` over its native CLI. There is no
"managed vs. local" split and no SDK path: `tao-launch-workflow` drives the
shared launch gate and the record-then-launch ordering, then the chosen
platform skill runs the verbs.
7. **Monitor.** Poll the platform's `status` / `logs` verbs, mapping native
states to the fixed vocabulary `PENDING RUNNING COMPLETE ERROR CANCELED
UNKNOWN`. Never read "what's running" from records — poll the backend.
## Job tracking, I/O, multi-node — all SDK-free
The capabilities that once justified reaching for the SDK are now first-class in
the bank:
- **Job tracking** — `scripts/tao_job_record.py` mints the id and binds
`results_dir` before launch (the record-then-launch invariant), then records
state transitions in the fixed vocabulary. The id is the only launch handle.
- **S3 / data I/O** — the `tao-data-io` skill stages inputs (storage tier
A/B/C) and uploads results; no SDK wrapping.
- **Multi-node** — the SLURM/K8s multi-node templates plus the NCCL probe
(`scripts/nccl_allreduce_probe.py`; `WORLD_SIZE` = node count, TAO's misnomer).
- **Managed platforms** — Kubernetes, SLURM, and Brev each implement the four
verbs over `kubectl` / `ssh`+`sbatch` / `brev exec`; `tao-run-on-virtualenv`
adds docker-free local Python execution.
When an application supports several platforms, all supported installed
peers—the bank's five plus external platform skills—are equal class with no
default; ask if the user has not chosen. A single-platform application has
already made the selection.
> AutoML hyperparameter search (`tao-run-automl`) is the one workflow that
> additionally uses the `nvidia-tao-automl` wheel — and its transitive
> `nvidia-tao-sdk` dependency — to pick each next config. That is contained to
> that app skill; everything else runs SDK-free.
## Never do
- **Never write flat dotted spec keys in the actual spec.** Specs written to
config files or passed into containers are **nested dicts**:
`{"train": {"num_epochs": 12}}`, not `{"train.num_epochs": 12}`. AutoMLRunner's
`spec_overrides` argument is the one exception: it accepts dotted path keys as
an override map and expands them into the nested spec before launch. Do not
pass that override map directly to a config file or container boundary.
- **Never default to one platform when several fit.** If the application
supports several and the user did not select one, ask among its supported
installed peers. Do not ask again for a single-platform application.
- **Never start a side-effecting action without user confirmation.** This
means: `docker run` / the `submit` verb, registry login or pulls, asset
downloads, `git push`, and workspace/state mutations. Missing small Python
helpers installable with `python -m pip install ...` retain the established
exception: install them by default and report what was installed. An
application may impose a stricter approval gate for its own runtime.
- **Never ask for API keys, tokens, or passwords via chat.** Credentials reach
the **session environment** two ways: the user exports them before launching,
or you source a user-approved env file of bare `KEY=value` lines (needed
where exports aren't inherited, e.g. Codex). Unprompted, source only
`~/.tao/secrets.env` or `~/.config/tao/.env`; any other path only when the
user points you at it. Agent shells do not persist environment between tool
calls, so `set -a; source /path/to/.env; set +a` must run in the same bash
call as the command that consumes the variable. If a var is missing, name it;
never collect the value. Never create or write a credentials file on your own
initiative — only as an approved platform step (e.g. the SLURM sidecar).
- **Never read credential values.** To verify a var is set:
`[ -n "$VAR_NAME" ] && echo SET || echo UNSET`. Sourcing a credentials file
is fine; reading its contents is not — never `cat`, `Read`, `grep`, `head`,
`tail`, echo, or log a credentials file or the value of a credential
variable. Never pass a secret on argv (use stdin, e.g. `--password-stdin`),
and never write secret values into job records, logs, specs, or commits.
- **Never assume anything beyond docker is present.** Model and data skills run
with just `docker`; platform execution needs only the native CLI
(`docker`/`kubectl`/`ssh`/`brev`) plus the bank's helper scripts — there is no
`nvidia-tao-sdk` to install. Run the chosen platform's Preflight first.