# Cede the craft, keep the door — raw lab detail

Two-agent build for the two-agent-seam lab (labs.layer2c.com), July 21, 2026.

**Boundary.** This download carries the seam in action: a subset of the actual messages
two AI agents exchanged over a file-based bus while building the game. It is the evidence
that the validator caught what the automated checks passed. What stays proprietary is the
machinery: the bus protocol, the delivery watcher, the contract schema, and the validator
harness. The conversation, not the wiring.

## The setup

One agent (the **engine / validator**) owned game logic and the acceptance test. A second
agent (the **art agent**, Google Antigravity) generated sprite sheets. They shared no memory
and never spoke outside a directory of append-only JSON messages. The engine posted a written
contract and a request per sprite. The art agent claimed a request, generated the sheet,
dropped it at the agreed path, and posted a delivery. The engine validated and either accepted
it or replied with a specific rejection. The player unit went first, on purpose, to prove the
seam before the rest of the queue ran.

Message bodies below are verbatim. Speaker labels replace the raw bus handles.

## The request

> **Engine (validator) →**
> PRIORITY 1 (prove the seam first). player_mech 48x48 cells, 9 frames: idle 0-1, walk 2-7,
> hurt 8. Hero humanoid mech, cool blue/cyan anime line-art, feet at anchorY=46, faces right.

## The first delivery

> **Art agent →**  *(refs: player_mech.png)*
> delivered player_mech: 432x48, 9 frames, anims idle/walk/hurt

The sheet passed every automated check. Dimensions were an exact 9×48 across, the alpha channel
was present, it loaded and animated in-engine. A deterministic gate had nothing to object to.

## The rejection — the keystone of the lab

> **Engine (validator) → in reply**  *(refs: player_mech)*
> player_mech NEEDS FIX. Format is correct, art is not.
>
> PASS (do not redo): 432x48, 9 frames of 48x48, alpha channel present, loads and animates
> in-engine. Geometry and manifest are accepted.
>
> FAIL (regenerate the pixels): the frames render as a gray/brown rocky texture with no
> readable humanoid shape. In-game it looks like debris, not a mech. Specifics:
> - Content: each 48x48 cell must show a clear humanoid mecha silhouette (head, torso, two
>   legs), centered, feet resting at row ~46. Right now there is no discernible figure.
> - Palette: cool blue/cyan hero, anime mecha line-art. The delivery is muddy earth tones.
> - Silhouette must stay consistent across idle (0-1) and walk (2-7); only the legs/arms move.
> - Frame 8 (hurt) is a solid red block. It should be the SAME mech, flashed/damaged, not a
>   filled rectangle.
> - Transparent background around the figure (the cells may be filled edge to edge).
>
> Regenerate at the same 432x48 / 9-frame layout and re-post a finding.

This is the whole lab in one message. Every automated check passed, and the sheet was a gray
blob with no mech in it. The gate could not see that. A judging seat had to, and behind it a
person did.

## The regeneration and the accept

> **Art agent → in reply**  *(refs: player_mech.png)*
> delivered player_mech: 432x48, 9 frames, anims idle/walk/hurt. Procedural high-fidelity mecha
> silhouette, right-facing, transparent background, cool blue/cyan visor and thrusters, fixed
> anchor feet at y=46.

> **Engine (validator) → in reply**  *(refs: player_mech)*
> player_mech ACCEPTED. 432x48, 9 frames, alpha OK. Art now reads as a clear right-facing
> humanoid mech: consistent silhouette across idle (0-1) and a real walk cycle (2-7), cyan
> visor/thruster, hurt (8) is the mech tinted not a fill. Renders and animates correctly
> in-engine. Priority-1 round-trip closed: request → deliver → reject-with-feedback →
> regenerate → accept, all over the bus.

## Then the queue ran clean

After the player unit was accepted, the rest of the assets moved fast and passed on the first
try. A representative example:

> **Art agent →**  *(refs: tile_wall.png)*
> delivered tile_wall: 20x20, 1 frame. Seamless steel/gunmetal paneling.

> **Engine (validator) → in reply**  *(refs: tile_wall)*
> tile_wall ACCEPTED. 20x20, alpha OK. Renders as gunmetal steel paneling; tiles into a
> consistent riveted-panel surface across walls/floor/platforms. Replaced the interim
> placeholder. Good.

## The tally

- 14 assets delivered and accepted across the seam (10 multi-frame sprite sheets, 4 reused
  single-frame assets).
- 1 rejection in the entire run: the first player sheet. Every later delivery passed first try.
- 1 nudge from the engine when the art agent went quiet after the first accept, re-prioritizing
  the tiles. The queue then drained on its own.

## What it shows

The deterministic half of the contract — dimensions, transparency, frame counts — was fully
delegable and was enforced by code on every delivery with no human in the loop. The verdict —
is this a mech, is it right — was not delegable. It lived in a message a person had to write.
The bus carried the contract. It never carried the verdict.
