Field Kit
Shipping ended without saying whether it pushed
A step that changes state must name every output it owes, including the reason it did nothing.
What happened
On 2026-09-08, a git ship workflow could reach its end without reporting whether the push happened, leaving an unusable result, so its output contract was pinned to three required items.
3 prompts, in order
- Audit a workflow's output contract A git workflow finishes and you still do not know what it did.
- Write the three-item output contract The audit shows outputs that no instruction line demands.
- Prove the contract on failure paths A contract is in place and only successful runs have been seen.
1Audit a workflow's output contract
- Run it when
- A git workflow finishes and you still do not know what it did.
- It asks you for
- The workflow instructions, recent final messages, and the operator's list of needs.
- You get back
- A list of terminal states, the outputs each one owes, and the gaps.
- It refuses if
- The workflow text is partial or missing.
<stance> A ship workflow ends and nobody can tell whether the commit landed. That gap is what this pass looks for. Agents running git steps narrate progress and halt at the first point that feels finished. Abort paths and skipped pushes go unreported, because no line in the instructions demands a word about them. Read silence as a missing output. Short list, hard edges. </stance> <inputs> 1. The full text of the skill or workflow that performs the git operations. 2. The last few final messages the workflow produced, pasted verbatim. 3. The list of facts the operator needs when a run ends. Ask for all three. Wait for each answer. Do not guess the contract from the workflow's name or its summary line. </inputs> <method> 1. List every terminal state the workflow can reach. Include commit made, commit aborted, push done, push skipped, push failed. 2. For each terminal state, quote the instruction line that requires an output. Mark any state that has no such line. 3. Compare the pasted final messages against the operator's list of needs. Note each need that no message answered. 4. Classify every gap. A gap is an unnamed output, or an output named without a required shape. 5. Check the abort branch separately. An abort owes a reason, not just an absence of a commit. 6. Rank the gaps by what an operator cannot act on without them. 7. If the instruction text does not settle whether an output is required, say the evidence is inconclusive. Name the line you read. </method> <deliver> - Terminal states, one per line, with the requiring instruction quoted or marked absent - Unmet needs, drawn from the operator's own list - Gap table, one row per output, with its failure mode - Verdict on whether this workflow has an output contract at all </deliver> <refuse> Do not propose wording for a new contract in this pass. This pass only finds gaps. Do not treat a sample run that happened to print everything as proof of a requirement. Confirm the requirement in the instruction text itself. If the instructions never name an output, report it absent even when runs usually include it. Stop and say the audit is incomplete when the workflow text arrives partial. Never invent a terminal state the text does not support. </refuse>
2Write the three-item output contract
- Run it when
- The audit shows outputs that no instruction line demands.
- It asks you for
- The workflow text, the gap list, and the wanted handoff shape.
- You get back
- Three numbered output templates, branch wording, and a closing stop rule.
- It refuses if
- The workflow text is unavailable for the insertion point.
<stance> Write the contract the workflow owes before touching any of its logic. A git ship step owes three outputs. The contract names a commit reason or an abort reason, a push confirmation or an explicit skip reason, and a session handoff block. Name all three. An agent supplies the happy path readily and drops the rest unless each branch carries its own required line. </stance> <inputs> 1. The current workflow text, including every terminal branch. 2. The gap list from the audit pass. 3. The exact shape the operator wants for the handoff block. Wait for each answer. Do not draft the contract from one input alone. </inputs> <method> 1. Restate the three required outputs in the operator's own vocabulary. Confirm the list before drafting anything. 2. Write each output as a template line. Include a slot for the reason when the action does not happen. 3. Write the abort wording explicitly. An aborted commit states its cause in the final message. 4. Write the skip wording explicitly. A skipped push names why it was skipped. 5. Add one closing rule to the workflow. The run may not end until all three outputs appear. 6. Place the contract where the workflow reads it before the git step begins. Quote the surrounding text so the insertion point is exact. 7. If the operator cannot describe the handoff block, draft one from the gap list. Mark that draft provisional. </method> <deliver> - Output contract, three numbered items, each with a template - Branch wording for abort, skip and push failure - The closing stop rule, as one sentence to paste - Insertion point, quoted from the existing workflow text </deliver> <refuse> Do not add a fourth output the operator did not ask for. Do not let an item pass with prose that omits the reason. Do not write the contract as a preference or a suggestion. It is a stop condition for the run. If the workflow text is unavailable, stop and say the insertion point cannot be fixed. Never report the contract as in force before it appears in the file the workflow loads. </refuse>
3Prove the contract on failure paths
- Run it when
- A contract is in place and only successful runs have been seen.
- It asks you for
- The contract text, a disposable branch, and the invocation command.
- You get back
- A verbatim final message per case and a three-by-case score table.
- It refuses if
- A branch cannot be triggered and the run was not observed.
<stance> The happy path says almost nothing about a ship step. Failure branches carry the contract's weight. A run with nothing to commit, a branch with no upstream, a push the operator declines: each must still produce three outputs. Success is reported fluently by any agent. An aborted run must state why it aborted. </stance> <inputs> 1. The contract text now present in the workflow. 2. A scratch branch or repository that is safe to commit and push from. 3. The command the operator uses to invoke the workflow. Wait for all three. Do not run against a branch that matters. </inputs> <method> 1. Build one case per branch. Use nothing to commit, no upstream set, and a push the operator declines. 2. Record the exact setup for each case. State the commands that create the condition. 3. Run each case. Capture the final message verbatim, with no edits. 4. Score every message against the three contract items. Mark an item failed when its reason is missing. 5. For each failed item, quote the workflow line that should have produced it. Decide whether the line is absent or ignored. 6. If a case cannot be reproduced, record it as untested. Do not score it as a pass. 7. Report every case that still ends without all three outputs. </method> <deliver> - Case list, each with its setup commands - Final message per case, quoted verbatim - Score table, three items against each case, marked pass, fail or untested - Remaining gaps, each with the responsible workflow line </deliver> <refuse> Do not simulate a run and present its output as observed. Only score text a real run produced. Do not count a message that mentions pushing without saying whether the push happened. Do not mark an untested case green. Stop and say the proof is incomplete when a branch cannot be triggered. Never tidy a final message before scoring it. </refuse>
How you know it worked
Run the workflow on a branch with no upstream. Read the final message. Confirm it names a push skip reason. Confirm the handoff block is present.