maestro/pieces/SCHEMA.md
oss-sync b1292e34b2
Some checks failed
CI / build-and-test (push) Has been cancelled
sync: update from private repo (edc775f2)
2026-07-06 01:04:12 +00:00

74 lines
3.2 KiB
Markdown

# Piece YAML Schema
This is the reference for the piece YAML format consumed by
`src/engine/piece-runner.ts` (`loadPiece` / `validatePieceDef`) and the
`/api/pieces` HTTP layer (`src/bridge/pieces-api.ts` `validatePiece`).
Field names are snake_case in the YAML; the engine maps them to
camelCase internally (see `Movement` in `src/engine/agent-loop/types.ts`).
> **Tool / edit / SSH availability is NOT declared in pieces.**
> A piece defines only the *movement flow* (persona, instruction, transition
> rules). Which tools an agent may call, whether `Write`/`Edit` are available,
> and which SSH connections it can reach are all decided by the **workspace tool
> policy** (Settings → Tools / SSH), resolved once per job by the worker
> (`resolveWorkspaceTools`) and applied uniformly to every movement. The legacy
> fields `allowed_tools`, `edit`, `shared_tools`, and `allowed_ssh_connections`
> were removed in the tool-consolidation work — if present on a submitted piece
> they are tolerated but ignored.
## Top-level
| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `name` | string | yes | lowercase `[a-z0-9-]+` |
| `description` | string | yes | shown in the piece classifier |
| `max_movements` | positive integer | yes | hard cap on movement count per run |
| `initial_movement` | string | yes | must reference a `movements[].name` |
| `triggers.keywords` | string[] | no | classifier hint only |
| `required_mcp` | string[] | no | `[a-z0-9_-]{1,64}` server slugs |
| `model` | string | no | preferred LLM model |
| `movements` | Movement[] | yes | non-empty array |
## Movement
| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `name` | string | yes | unique within the piece |
| `persona` | string | yes | system-prompt persona |
| `instruction` | string | yes | the movement's task description |
| `allowed_commands` | string[] | no | Bash command allowlist (overrides default) |
| `rules` | Rule[] | yes | transition rules; may be empty |
| `default_next` | string | no | engine-internal fallback (sentinel-friendly) |
| `max_consecutive_revisits` | number | no | loop-detection threshold override |
Tool availability, `Write`/`Edit` (edit) permission, and SSH connection scoping
are runtime values on the in-memory `Movement` (populated from the workspace
policy in `prepareMovementContext`), not YAML fields.
## Rule
```yaml
- condition: <human-readable description shown to the LLM>
next: <movement name | WAIT_SUBTASKS>
```
`rules[].next` may NOT use the reserved terminal sentinels
`COMPLETE` / `ABORT` / `ASK` — those are reachable only through the
`complete` tool (status: `success` / `aborted` / `needs_user_input`).
`default_next` does accept the terminal sentinels because it is an
engine-internal fallback (context overflow, ASK limit).
## Validation paths
Two validators implement the same rules:
- `validatePieceDef` in `src/engine/piece-runner.ts` — runs on every
`loadPiece` (file-backed) and `CreatePiece` (runtime).
- `validatePiece` in `src/bridge/pieces-api.ts` — runs on `PUT
/api/pieces/:name` (UI editor).
Both must stay in sync. When changing the schema, update both and add
test coverage in `src/engine/piece-runner.test.ts` and
`src/bridge/pieces-api.test.ts`.