For an agent

The operator is an agent in a terminal.

That is not a use case here, it is the premise. Every design decision in this project is judged by whether an agent gets it right on the first call without reading the implementation — and a feature that needs a GUI, a second round trip or a source read to use is a feature that has not landed.

a Claude Code session
# Claude Code wrote the bar from the drawing: assets/mascot.accept.toml,
# 3 predicates and the 2 parameters a search may move. No number set by hand.

> polyweave search.sweep --spec assets/mascot.accept.toml --out .polyweave/samples/mascot --job
  job j_7f3a  stage=queued

> polyweave job poll j_7f3a
  job j_7f3a  stage=rendering  rung=preview  17/24  elapsed_s=212

> polyweave job result j_7f3a --wait
  done  score 0.94   light=2.8  form=1.9
        sheet  .polyweave/sheets/mascot-7f3a.png   (5 candidates)
        trace  .polyweave/traces/mascot-7f3a.json  (24 samples, 9 cached)

> polyweave render.bake --spec assets/mascot.accept.toml --rung final --out assets/mascot.png
  done  1024x1024  rung=final

> polyweave accept.check --spec assets/mascot.accept.toml --subject assets/mascot.png --rung final
  accept: 3/3 predicates pass   saturation_p99=0.87  delta_e=1.4  silhouette_iou=0.981

> polyweave render.bake --model assets/shelf.glb --rung final --out assets/shelf.png
  post.render-uniform: every visible pixel of the render is #3a3a3a, so it carries no image
  do: the scene was empty or the light never fired; if a flat #3a3a3a is what
      was wanted, pass allow_uniform=True

Each command is a real operation, the same one Claude Code calls as an MCP tool; docs/specs/tool-surface.md says how every call behaves. The values are illustrative.

What follows from it

  • ◆Nothing only a person can operate. A graphical editor is the first non-goal, because a surface that needs a person at a screen is one the agent cannot use. The review page and the desktop window are where a person looks and answers: they edit nothing, and their one write is the verdict.
  • ◆A file beats a stream. Job state, traces, contact sheets, the budget ledger and every provenance record are files under .polyweave/ in the project, so a session that ends can be picked up by the next one and a colleague can reproduce what happened.
  • ◆Names are the address. An asset, a predicate, a rung and a job all have names, and the trace addresses them by name. An anonymous thing cannot be discussed across a turn boundary.
  • ◆Errors are instructions. A typed code, a message with no traceback in it, and a remedy that is the call which closes it.
  • ◆Refusal over silence. An unknown field is refused, an unknown measure is refused, and a post-condition that fails is an error. Every one of those could have been a warning, and every one of them was a warning somewhere that cost a render.

The one thing it may not decide

A purchase from a paid service — a mesh, an image, a voice line, a sound — spends real money, and the plugin will not let an agent authorise that on its own judgement. What it does instead is make the spend bounded and visible: a ceiling in polyweave.toml that a person sets, a quote before every spend, a ledger of what has been spent against it, and a gate that refuses a request which plainly will not match the reference — because the cheapest credit is the one not spent. An agent can work continuously inside that ceiling without asking, and cannot move it.

Configuration, resolved per call

Explicit argument, then polyweave.toml, then the plugin default — in that order, evaluated on every call rather than cached at startup, so correcting a config file does not need a session restart. And nothing is written outside the project tree: a cache in a home directory is state a repository cannot review.

What it will not do for you

It will not tell you a render is good. It measures what it was given a measure for, and reports the margin. Where the criterion is real and no measure can compute it — “reads as cloth rather than paper” — the answer is the contact sheet: the search returns its best handful, you see that the winner is not the one you would have chosen, and you now know the spec is incomplete. Inventing a proxy for that criterion is how a spec ends up satisfied by a render a person rejects.

Deliberately not

What polyweave will never be.

These constraints bind the project, and every new idea is read against them first.

✗ A graphical editor

The caller here is an agent in a terminal, so a surface only a person can operate is one the agent cannot use. A local page where a person looks and answers is not an editor: it edits nothing, and its one write is the verdict call an agent would make.

✗ Replacing Blender, Godot or the generative service

Those three already do the work; what is missing is the loop around them, so this orchestrates and measures and never re-implements a renderer, an engine or a mesh generator.

✗ Spending money on the agent's own judgement

A fetch draws on a real balance, so the ceiling is a person's to set and the plugin's job is to make a spend bounded and visible, never to decide one is worth it.

✗ One project's palette, rig or paths compiled in

Cottony is the first consumer and not the specification, so anything it needs that a second project would not is configuration, and a default that cannot be overridden is a defect.

✗ A hosted service or an account to sign into

Everything runs on the developer's machine against files in their own repository, because a plugin that needs an account is one that fails on the day the account does.

✗ An agent accepting or rejecting its own look

A look, a sound, a line a character says and how hard a level feels are each what a person agreed to, so an agent that can write the verdict on its own run turns the one check the loop cannot automate into one more number it tunes.

✗ One genre's level format built in

A match-3 level is three numbers and a shooter's is a spawn timeline, so polyweave checks, compiles and measures a level through what the project declares, and a schema that assumes a genre fails the next game; PW205 exists to catch that.

✗ Writing a game's story for it

A world is a person's authorship, so polyweave holds what the game shows to the world a person declared and routes a line's tone to their verdict, and never invents the canon it then checks against.