coat-of-many-colors
Stitches what your agents left behind into one thing you can read.
Agents leave scraps everywhere â logs, diffs, notes, results â and then you're
the one who has to work out what actually happened. coat collects the scraps,
records where each one came from at the moment it was made, and stitches
them into a single self-contained HTML page.
$ coat install
𪥠wired PreToolUse, PostToolUse, Stop in .claude/settings.json
agents work, coat collects, coat.html lands when the session stops
Then work. Nothing to prefix, nothing to remember:
$ coat patches
1 linter autocorrect
2 refactorer harden the parser
$ coat seams
𪥠1 seam, 1 open
â lib/parser.rb â linter, refactorer
$ coat mend lib/parser.rb --note "kept the refactorer's version"
𪥠mended lib/parser.rb â linter, refactorer
$ coat build --title "Overnight run, 26 August"
đ§Ľ coat.html â 4 patches, 0 of 1 seams open
Install
gem install coat-of-many-colors
The words
- A scrap is raw agent output. On its own it's noise.
- A patch is a scrap with its provenance still attached â what ran, where, how it exited, what it touched. That's the unit the coat is sewn from.
- A seam is where more than one source laid a patch over the same ground. coat finds seams; it does not resolve them.
- A seam is mended when a person says it's settled. Only a person can: coat can see that two agents disagreed, not which one was right.
Commands
| Command | What it does |
|---|---|
coat install |
Wire the hooks so you never type the rest of this table |
coat add --from CMD |
Run CMD, keep its output as a patch |
coat add --file PATH |
Take an existing file as a patch |
coat pin |
Mark where the working tree stands, for --since |
coat patches |
List the scraps collected so far |
coat seams |
Where two sources touched the same ground |
coat mend PATH |
Say that seam is settled |
coat build |
Stitch the coat into one HTML file |
coat verify |
Walk the hash chain and report the first break |
coat hook |
Read one Claude Code hook payload on stdin |
Options for add: --label TEXT, --agent NAME, --claims A,B, --cwd DIR,
--cmd CMD, --exit N, --since [KEY].
Options for mend: --by NAME, --note TEXT.
Options for install: --settings PATH, --tools LIST.
Options for build: -o PATH, --title TEXT.
Let the harness do the typing
coat install writes three hooks into .claude/settings.json, all of them the
same command:
| Hook | What it does |
|---|---|
PreToolUse |
Pins the working tree before the tool runs |
PostToolUse |
Adds what the tool produced, and asks the pin what moved |
Stop |
Stitches the coat |
By default it watches Task, so you get one patch per subagent â coarse enough
to read, fine enough for seams to mean something. --tools 'Task|Bash' gets you
a patch per shell command too, and a much longer coat.
Everything already in your settings file is left alone, and installing twice does nothing the second time.
A hook never fails the work it is watching. If coat can't make sense of a payload it says so on stderr and exits zero.
Provenance the harness hands over
coat add --from runs the command, so it knows everything first-hand. A hook
fires after the tool has run, so it can only be handed the result. Those are
different, and the ledger says which: a captured patch is recorded as
"kind":"captured", never as something coat watched happen.
Captured patches claim nothing by default â text can't know what it touched.
That's what coat pin is for: pin the working tree before, ask --since after.
coat pin
# ... something else does the work ...
coat add --file /tmp/agent.log --cmd "claude -p 'harden the parser'" --exit 0 --since
Provenance is captured, not reconstructed
coat add --from runs the command itself. That's the whole point â the
command, the working directory, the exit status, the duration, the output, and
its SHA-256 are all recorded at the moment the scrap is made. Nothing is
inferred afterward from a file lying around, because after the fact you can
only record what you can guess.
Everything lands in .coat/ledger.jsonl, append-only, one JSON object per
line, each entry carrying the hash of the entry before it:
{"ts":"2026-08-26T04:12:03Z","event":"patch","label":"autocorrect","agent":"linter","kind":"command","cmd":"bundle exec rubocop -A","exit":0,"duration_s":6,"body":"0001-autocorrect.txt","body_sha256":"9c2âŚ","claims":["lib/parser.rb"],"seq":1,"prev":"000âŚ","hash":"a1fâŚ"}
A coat is evidence of what your agents did. Its provenance should be at least
as hard to quietly rewrite as the work it describes. coat verify walks the
chain and tells you the first entry that doesn't hold.
Seams, and mending them
If two different agents touch the same file, that's a seam. coat shows
both patches, marks them, and lists the seam at the top of the document.
It does not pick a winner. Surfacing the disagreement is the value; deciding who was right is a judgment call a tool has no business making.
Which is why a seam stays open until you say otherwise:
coat mend lib/parser.rb --note "kept the refactorer's version"
That lands in the same chained ledger as everything else â {"event":"mend"},
with your name and the time on it. It's the one entry in a coat a person makes
rather than a tool, and the document draws the difference: an open seam is
double-stitched in red thread, a mended one is stitched shut and goes quiet.
The contested path stays marked either way. The disagreement still happened.
Mending the same path twice is a correction, not a second seam â the latest word wins.
Claims come from git â coat digests the contents of everything git reports as
changed, before and after the command. Content, not git status codes: a file
an earlier agent already dirtied stays M no matter how many more agents
rewrite it, so status codes can't see the second edit, which is the exact case
this feature exists for. Outside a git checkout, pass --claims.
The PATCHWORK style
The output has its own look, and the metaphor does real work in it:
- Every patch is bordered with a running stitch â a dashed seam in thread color.
- Every source keeps its own color, derived from a hash of its name, so the same agent is the same color in every build on every machine. Color is provenance; the header strip doubles as the legend.
- An open seam is double-stitched in red thread, with the contested path underlined wavy in the metadata. A mended one is stitched shut in plain thread and says who settled it.
- A command that exited non-zero is torn, not hidden. A failed step is still evidence.
- Warm linen background, woven texture drawn in CSS, serif body, mono for
anything a machine wrote. Light and dark, honoring both
prefers-color-schemeand an explicitdata-themeoverride. - Every coat opens with a line from Dolly â a saying or a single lyric, picked at random per build.
One file, no build step, no external requests. See example.html.
Development
bundle install
rake test
In memoriam: Dolly Parton
Named for Coat of Many Colors, which she wrote in 1971 on the back of a dry-cleaning receipt from Porter Wagoner's suit, on the tour bus. She has called it her favorite of everything she wrote.
It's about a coat her mother sewed out of rags people had given the family, telling her the story of Joseph while she stitched. Dolly wore it to school proudly and the other children laughed at her for being poor.
The scraps were never the point. The stitching and the story are what made them worth something. That's the whole thesis of this tool: a fragment of agent output on its own is noise, and a fragment with its origin still attached is evidence.
It's written in Ruby because Dolly was a gem.
She wrote thousands of songs, and that's the part everyone knows. The rest of it deserves saying too:
- The Imagination Library, founded in 1995 in honor of her father, who never learned to read. It mails a free book every month to any enrolled child from birth to age five. It has given away well over 200 million books and now runs across the US, Canada, the UK, Ireland, and Australia.
- A million dollars to Vanderbilt University Medical Center in April 2020, which helped fund the research behind Moderna's COVID-19 vaccine. Her name is in the acknowledgments of the paper.
- The My People Fund. After the 2016 wildfires tore through Sevier County, she paid $1,000 a month for six months to every family that lost a home â roughly 900 households â and closed it out with a larger final check.
- Dollywood and the Dollywood Foundation, which turned her hometown corner of the Smokies into one of its largest employers, and whose Buddy Program cut the local high school dropout rate by paying students to keep each other in school.
- She turned down the Presidential Medal of Freedom. Twice. She said she didn't feel she'd earned it.
She also acted â 9 to 5, Steel Magnolias, The Best Little Whorehouse in Texas â and kept the publishing rights to her own catalog at a time when almost nobody in Nashville let a woman do that.
Keep the scraps. Keep the story with them.
License
MIT. See LICENSE.txt.