Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
47efc26
task package init
dorado269 Aug 31, 2026
06d9bf6
mission init
dorado269 Aug 31, 2026
587fa7b
mission init
dorado269 Aug 31, 2026
573a106
feat(llm_e2e): stage 1 -- e2e_deploy_standardized, model as a parameter
dorado269 Sep 1, 2026
9c6e78b
docs(llm_e2e): three environmental faults between `spur exec` and `ag…
dorado269 Sep 1, 2026
e0bea2f
fix(llm_e2e): a validation zone has no claude, and the body blamed th…
dorado269 Sep 1, 2026
8f85e2f
feat(llm_e2e): the two passing runs become few-shot exemplars and two…
dorado269 Sep 1, 2026
66c865d
docs(llm_e2e): README states all six added rules and the third control
dorado269 Sep 1, 2026
1bdf876
docs(llm_e2e): report the validation-zone/claude gap, and record the …
dorado269 Sep 1, 2026
1a01a0b
chore(llm_e2e): drop the placeholder readme.md, README.md replaced it
dorado269 Sep 1, 2026
4a6003f
add profile/analyze/integration demos
ChengYao-amd Sep 1, 2026
5be1ca8
Merge pull request #145 from AMD-AGI/dev.yaoc.aiopt.task_package
dorado269 Sep 2, 2026
2a71db3
feat(examples): kernel optimization task package (stage 4)
dorado269 Sep 2, 2026
be4d17d
feat(examples): single-task debug main for the workset contract
dorado269 Sep 2, 2026
c48ebbf
Merge pull request #147 from AMD-AGI/dev.yihou.aiopt.kernel_opt_module
dorado269 Sep 2, 2026
532da57
refactor(llm_e2e): stage 1 moves into `deploy-demo/`, and the root be…
dorado269 Sep 2, 2026
9bf72c8
debug the five e2e stage packages to one sealed handoff set each
dorado269 Sep 3, 2026
8a25003
feat(agent_sys): AgentsView as the o11y panel, and a browsable run tree
dorado269 Sep 4, 2026
5c5d3ea
Merge pull request #154 from AMD-AGI/dev.yihou.aiopt.more.demo
dorado269 Sep 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
171 changes: 116 additions & 55 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,129 @@
# Repository conventions

## DCO sign-off is required on every commit

This repository enforces the [Developer Certificate of Origin](https://developercertificate.org/).
CI blocks any PR containing a commit without a `Signed-off-by:` trailer, so an
unsigned commit is a broken PR, not a style nit.

Commit with `-s`, always:
# Task — `e2e_deploy_standardized`: the first stage of the LLM e2e optimisation task package

Build the **"e2e 运行"** module of
`agent_sys/examples/llm_e2e_performance_optimization/` and drive it to a stable
pass. One closure — `e2e_deploy_standardized` — with its **task / ai agent /
handoff / validator** fully specified, run by `agent_sys` on real hardware for
two models.

Acceptance for "integrated": after debug and fixes are done, **three
consecutive runs must pass with no intervention and no edits**. Environment
preparation and peripheral repair before that first clean run do not count
against it.

Scope agreed with the user for this round (mission steps 2–5):

1. **Step 2** — author the first-cut spec of `e2e_deploy_standardized`.
2. **Step 3** — drive it with **Qwen3.6-27B** on gfx950 until stable; sanitise
the resulting deliverable and add it as a **few-shot exemplar + validator
assertion**.
3. **Step 4** — reproduce **GLM-5.3-Flash** on the cluster from the given packup.
4. **Step 5** — drive `e2e_deploy_standardized` + **GLM-5.3-Flash** on gfx950;
same few-shot/assert treatment.

Steps 6 (mxfp4) and 7 (remote) are **out of scope this round** unless the user
re-opens them. MXFP4 GLM-5.3-Flash weights do not exist on this cluster.

## Background

`agent_sys` is a decoupled multi-agent task-flow system living inside the
`infera` repo. `examples/single_real_task` already proved the shape on gfx942:
an AI agent brought Qwen3.6-27B up in mix mode and handed back a packup-shaped
reproduction kit, checked by one program validator and one AI validator. This
round **generalises that one-off into a standardised, model-agnostic e2e deploy
step** and proves it on a second model and a second architecture.

Mission书: `agent_sys/examples/llm_e2e_performance_optimization/temp/mission.md`
(the series book) and the user's current `mission.md` at the repo root.

## Context — this environment, measured 2026-09-01

| | |
|---|---|
| where I am | login node `crs-m2m-cpu-spur-012`, **no GPU, no docker daemon access** |
| GPU nodes | slurm holds `94842`→`crsuse2-m2m-020`, `94843`→`crsuse2-m2m-188`, 8×MI355X **gfx950**, 288 GiB/GPU, idle |
| reaching them | `spur exec <jobid> bash -c '...'` — runs as **`yihou`**, docker talks to the **host** daemon |
| **walltime** | both jobs are 4 h, started 07:08 UTC → **hard stop ≈ 11:07 UTC**. Resubmit 8 h sleeper holds when they die |
| docker disk | on the 28 T NVMe, **~26 T free** — pulls and builds are fine (the 87 G on `/` is the exec namespace's own rootfs, a red herring) |
| local scratch | `/mnt/m2m_nobackup` (28 T, per-node, 10 GB/s) — **this is where a container workdir goes** |
| shared FS | `/shared_nfs` 360 T but **98 % full (7.6 T free)**, ~700 MB/s read, **no root_squash** (container root can write) |
| agent_sys roots | one knob: `--demo-root /shared_nfs/yihou/agent_sys_debug/runroot` relocates runs/handoffs/playground/workspace together |
| permissions | already default **off** (`AGENT_SYS_NO_PERMISSIONS` unset reads as `1`) |
| ports | 8080 taken; 8000–8079, 8081–8200, 30000 free. `--network host` works |
| GPU into containers | `--device /dev/kfd --device /dev/dri` + **numeric** `--group-add 44 --group-add 992` (named `render` fails) |

Weights: `GLM-5.3-Flash` (FP8, 62 shards) and `-BF16` complete under
`/shared_nfs/models/`; that directory is **not writable by me**, so Qwen3.6-27B
was staged to **`/shared_nfs/yihou/models/Qwen3.6-27B`** (copied from
`/shared_nfs/jiahazha/models/`, 15 shards / 51.75 GiB).

Images: no infera image exists on these nodes and `rocm/infera:sglang-dev` is
**not on docker.io**. `lmsysorg/sglang:v0.5.17-rocm720-mi35x` (gfx950) carries
`qwen3_5.py` but **not** `glm5_next`; infera is pure Python and installs into it
in seconds.

## Key references

- `agent_sys/examples/single_real_task/` — the template: `main.yaml`,
`steps/serve.yaml`, `assets/serve_qwen.task/readme.md` (the agent brief worth
copying wholesale), `assets/check_packup_shape.validator/`, `assets/lib/zone.py`.
- `/shared_nfs/yihou/packups/packups/`:
- `qwen36-27b.mix.gfx942-agent_sys.packup_20260901/` — the agent_sys-driven
reference run, its acceptance file `spec/B4-acceptance.md`, and
`notes-src/FINDINGS.md` (read this before re-deriving anything).
- `qwen36-27b.mix.gfx950-manual.packup_20260901/` — the gfx950 recipe.
- `glm53flash.mix.packup_20260830/` — the GLM-5.3-Flash recipe, incl. the
`Dockerfile.sglang.glm53` this repo does not carry.
- `/shared_nfs/yihou/agent_sys_debug/recon/RECON_20260901.md` — the measured
environment recon this table summarises.
- Packup skill: `agent_sys/examples/llm_e2e_performance_optimization/temp/claude_code_skill_used_by_human/experiment-result-packup/`.

## Core principles

1. **Read the artefact, not the exit code.** A previous stage reported 14/14
tasks and ten validators PASS over a run in which every result was zero.
Every acceptance claim names a file to open and a condition that fails.
2. **Write acceptance criteria before the run, not after.**
3. **Pin the run id at launch.** `ls -1td runs/ | head -1` is not "my run" —
this box is shared.
4. **Every identifier bound on a shared host is a parameter**: container names,
ports, workdir, served model name. `: "${VAR:=…}"`, never `export VAR=`, and
never `docker rm -f` a name you did not create.
5. **Research → gather → analyse → plan → work.** All temp activity stays in
`/shared_nfs/yihou/agent_sys_debug/ws/`; the repo only receives the
deliverable under `agent_sys/examples/llm_e2e_performance_optimization/`.
6. **Do not change host state** beyond docker images/containers we own and our
own directories. Ask before anything wider.
7. Bugs in `agent_sys` are recorded under
`agent_sys/examples/llm_e2e_performance_optimization/temp/bugs/` first, then
worked around; fixed only when the evidence is unambiguous.
8. Work in English; report to the user in Chinese.

## Other notable details

### DCO sign-off is required on every commit (unchanged repository convention)

CI blocks any PR containing a commit without a `Signed-off-by:` trailer.

```bash
git commit -s -m "..."
git commit -s -F - # when writing a longer message from a heredoc
```

That appends a trailer built from **your own** `user.name` / `user.email`:

```
Signed-off-by: Your Name <you@example.com>
```

**Sign off as yourself.** The DCO is an assertion that *you* have the right to
submit this code, so the trailer must name the person making the commit. Never
copy a colleague's line from an existing commit, and never use a bot or assistant
identity — contributors here sign off under several different addresses, and the
trailer has to match the commit's actual author.

Check what `-s` will produce before your first commit in a fresh clone or
container, where git may have inherited a default from the environment:

```bash
git config user.name && git config user.email
git config user.name && git config user.email # check before the first commit
```

If those are empty or wrong, set them (add `--global` outside a container):

```bash
git config user.name "Your Name"
git config user.email "you@example.com"
```

### Fixing commits that are already missing it

Sign off a range without disturbing commits that already carry the trailer —
rebasing from a point that includes signed commits appends duplicates:
Sign off **as yourself** — never a colleague's line, never a bot identity.
Cherry-picks do not inherit the trailer (`git cherry-pick -s`). To repair a
range without duplicating trailers:

```bash
git log --format='%h %s | %(trailers:key=Signed-off-by,valueonly)' origin/main..HEAD
git rebase --signoff <last-already-signed-commit>
git push --force-with-lease origin <branch>
```

Pick `<last-already-signed-commit>` as the newest commit that already has the
trailer. Check what you are about to touch first:

```bash
git log --format='%h %s | %(trailers:key=Signed-off-by,valueonly)' origin/main..HEAD
```

Cherry-picks do **not** inherit the trailer — `git cherry-pick -s`, or sign off
afterwards. This is the easiest way to reintroduce the problem on a second branch
after fixing it on the first.
`Co-Authored-By` is separate, is not a substitute, and must not be added when
contributing to third-party upstreams.

## Related trailers
### Branch / PR

`Signed-off-by` is the DCO assertion and is mandatory. `Co-Authored-By` is
separate, is not a substitute, and some upstreams reject assistant co-author
trailers outright — when contributing to a third-party repository (e.g. ROCm/aiter),
do not add them.
Branch `dev.yihou.aiopt.task_package`, PR 142. Activity is limited to
`agent_sys/examples/llm_e2e_performance_optimization/`.
51 changes: 50 additions & 1 deletion agent_sys/cli/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from env_mgr.fs.domain import DomainRegistry
from env_mgr.isolation.policy import Granted, Mode, interpreter_grants
from env_mgr.isolation.probe import Availability, probe, select
from env_mgr.prefix import CLAUDE_CONFIG_ENV_VAR, Prefix
from env_mgr.protocols import Context, DomainKind, NoConfinement, Tier

__all__ = [
Expand Down Expand Up @@ -282,6 +283,47 @@ def confinement(availability: Availability | None = None) -> str:
# Credentials


def _probe_environment() -> dict[str, str]:
"""The ambient environment **plus** the o11y prefix's `CLAUDE_CONFIG_DIR`.

Gate 1 covers *agent* children; this subprocess is not one, so it dropped a
JSONL into `~/.claude/projects` every run — measured. Copied, not replaced:
a bare `env={...}` strips `PATH`, and a probe that cannot run refuses the
whole run. Never into our own `os.environ`.
"""
env = dict(os.environ)
env[CLAUDE_CONFIG_ENV_VAR] = str(Prefix.resolve(os.environ).claude_home)
return env


#: Where the probe runs. Its own directory, because AgentsView names a project
#: after the session's cwd — resolving the git *main repository* when there is
#: one — so inheriting the caller's put ten identical probe transcripts into the
#: real `infera` project. A plain directory falls back to its basename, and
#: `probe` is what these sessions are.
PROBE_DIR = "probe"


def probe_cwd(prefix: Prefix) -> Path:
return prefix.state / PROBE_DIR


def _probe_cwd_or_none(prefix: Prefix) -> str | None:
"""The probe's own directory, or `None` if we could not make one.

**A cwd is not worth failing the run for.** `preflight_credentials` aborts
everything when it fails, and a child refuses a cwd that does not exist —
so an unwritable prefix must fall back to the old behaviour, not turn a
misfiled transcript into a dead deployment.
"""
try:
cwd = probe_cwd(prefix)
cwd.mkdir(parents=True, exist_ok=True)
except OSError:
return None
return str(cwd)


def preflight_credentials(*, cli: str = BACKEND, timeout: float = 90.0) -> str:
"""Ask the backend whether it can run at all, **before any zone is built**.

Expand All @@ -293,7 +335,12 @@ def preflight_credentials(*, cli: str = BACKEND, timeout: float = 90.0) -> str:
`CredentialsMissing` carrying **stdout and stderr both** on failure.

**It does not test what the run does, and saying so is the point.** This
runs `claude -p` *unconfined*, against the operator's own config directory.
runs `claude -p` *unconfined*, against the operator's own credentials — but
not their own config directory: `CLAUDE_CONFIG_DIR` points into
`~/.infera_agent_sys` like every other `claude` child we spawn, so the
transcript lands there. Measured to keep authentication working; see
`_probe_environment`. Not the relocation the table below is about.

A confined task gets a different arm: `material.deploy` points
`CLAUDE_CONFIG_DIR` into the zone — correctly, it is what removed the `$HOME`
grant — which also moves away the `env` block in `~/.claude/settings.json`
Expand Down Expand Up @@ -330,6 +377,8 @@ def preflight_credentials(*, cli: str = BACKEND, timeout: float = 90.0) -> str:
try:
done = subprocess.run( # noqa: S603 — `binary` came from `shutil.which`
[binary, "-p", "Reply with exactly one word: ready"],
env=_probe_environment(),
cwd=_probe_cwd_or_none(Prefix.resolve(os.environ)),
capture_output=True,
text=True,
timeout=timeout,
Expand Down
13 changes: 12 additions & 1 deletion agent_sys/cli/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

__all__ = ["SCHEMA_VERSION", "Event", "EventKind"]

SCHEMA_VERSION = "1.3"
SCHEMA_VERSION = "1.4"
"""The schema of the machine-readable stream.

Criterion 14 makes this an interface: **bump it on any change to `EventKind`,
Expand Down Expand Up @@ -68,6 +68,16 @@
one that was never declared, and the difference is the whole claim the run is
making.

**1.4** — `O11Y_PANEL`. The AgentsView panel's URL, and the notice that its
binary was fetched for the first time, were `log.info` calls. **Nothing in this
repository configures `logging`**, so the root logger sits at `WARNING` with no
handler and both lines were discarded — while the o11y failure paths, being
`log.warning`, reached stderr through `logging.lastResort`. Failures were
visible and successes were not, and the tests did not notice because
`caplog.at_level("INFO")` forces the level from pytest's side. A fact the user
is meant to read belongs in the stream, which is the thing in this package
whose job is being read; `logging` here is for the operator's diary.

`docs/interfaces.md` §5.7: once the whole-system CLI wants the same stream,
two artefacts share this constant with no bump policy. That is open.
"""
Expand Down Expand Up @@ -96,6 +106,7 @@ class EventKind(str, Enum):
PERMISSIONS_DISABLED = "permissions_disabled"
ZONE_PREPARED = "zone_prepared"
ACCESS_DENIED = "access_denied"
O11Y_PANEL = "o11y_panel"

# what this run did NOT check, and why. Absent is not the same as dropped.
VALIDATION_DROPPED = "validation_dropped"
Expand Down
Loading
Loading