SWE-Lego-Live

Block Design

The abstraction the whole pipeline is built on

A block is the unit of work in SWE-Lego-Live. Every stage of the pipeline — data curation, trajectory generation, training, and evaluator measurement — is a block, with the same shape and the same three skills (:setup, :check, :run). This page is the long-form design: the vocabulary, the schema, the dependency rules, and the archive format.

Anatomy of a SWE-Lego-Live block

The diagram shows the block boundary. A block is not just a script directory: it is a package around one unit of work. config.yaml is the declaration layer; it names the block, pins code repositories, declares child blocks and dependencies, and separates runtime inputs from runtime outputs. The rest of the block is defined by that declaration.

Inside the block, repos/ holds pinned code dependencies, plugin skills expose the block's setup/check/run operations, and memory/ keeps the context and traces an agent needs while operating the block. scripts/ contains the concrete dry run, smoke test, and run entrypoints; dashboard/ turns logs, metrics, and state into an inspectable surface; subblocks/ lets the same shape nest, so a block can be a leaf task or a parent pipeline.

The side panels are part of the contract too. Code repos are pinned outside the block logic but referenced by config; the config schema declares what the block is allowed to depend on and publish. A run then produces artifacts/: logs, archives, cache, output, and environment snapshots. That gives the root block something stable to inspect before execution and something durable to review after the run finishes.

Block

A self-contained directory that owns one stage of the pipeline. Every block has the same shape: a config.yaml for inputs and outputs, a scripts/ set for execution, an artifacts/ tree for results, an optional repos/ for vendored dependencies, and a CLAUDE.md that documents the agent contract.

Root block / subblock

The repo is a tree of blocks. The repo root is the root block; every directory under subblock/ is a child block. A parent block lists its children under meta_info.subblocks (with a role one-liner each); each child declares its own upstream hand-offs in its meta_info.dependencies. Children can have children — the abstraction nests.

config.yaml

Every block's config.yaml is one-shot per run: every key is configuration. Live state — running, completed, failed — does not live here. It lives in artifacts/index.yaml. See Reference / config.yaml for the full schema.

runtime_info.input

The values a block needs that originate outside the block tree: API keys, GitHub tokens, model names, human decisions. These are the only values you fill by hand.

runtime_info.output

The values a block publishes once it has run, for downstream blocks to consume — e.g. curator.output.swe_tasks_dir. Downstream blocks reference these through dependencies, never by hand.

Dependency

Inter-block values are wired in the consumer block's own meta_info.dependencies: the key is the dot-path in that block's runtime_info.input that receives the value, and the value is <source_block>.output.<key> (with optional when:/required: modifiers for conditional or optional hand-offs). scripts/validate_config.py — run by every dryrun and by /root:check — resolves every dependency at preflight time; an unresolvable dependency fails the check before anything heavy runs.

Repo

A vendored, pinned dependency under a block's repos/ directory (e.g. tracer/repos/harbor/). Pinned by commit SHA in config.yaml under meta_info.repositories.<name>. Editing files under repos/ is forbidden — auth/env fixes belong in scripts/ or config.yaml.

Resources

meta_info.resources.ip declares where a block runs. local (or null) means the current host. A real remote IP means the agent SSHes into that node and runs inside a tmux session, with meta_info.resources.directory as the working directory.

Archive

Every run is archived to artifacts/archives/run_NNN/: a snapshot of the config, the scripts as they were, the repo SHAs, and a metadata.yaml with timestamps and exit code. The EXIT trap installed by scripts/start.sh fires archive_run.sh regardless of how the run ended, so the timeline is always complete. See Reference / Artifacts.

Live state

The newest entry of artifacts/index.yaml. Status is one of completed | failed | interrupted, derived from scripts/start.sh's exit code. Always read live state from here — never from config.yaml.

root plugin

The Claude Code plugin at .claude/plugins/root-plugin/ that operates any block in the tree. Three skills:

  • /root:create — scaffold a new block with the full directory tree wired to the contract.
  • /root:check — recursively sanity-check schema, inputs, dependencies, remote-resource reachability, and LLM endpoints. Read-only.
  • /root:run — preflight, then execute scripts/start.sh (locally, or in tmux over SSH) and archive the result.

Both /root:check and /root:run take a free-form argument. The agent resolves the target block by name or unambiguous paraphrase; ambiguity triggers a clarification question rather than a guess.

On this page