A footer means it finished
- Why LLMKIT: sharing what works across five stacks
- Context is the hard part
- The fourth and fifth stack
- The boring 20% that made it stick
- One view across Claude Code, Codex and Copilot
- Copy, never move
- Normalize once, at the end
- Windows 11, and an honest scorecard
- Shippable, with findings
- Mirror, don't ask
- A name isn't enough
- A footer means it finished
A scheduled team publish at 08:45 got killed mid-run — 65 seconds after an installer run re-registered the schedule and stopped the job underneath it. The log held a header line and nothing else.
The ambiguity
A header with nothing after it looks exactly like a hang. It also looks exactly like a run still in progress. Working out which one it was took ten minutes and four commands.
The fix
Every exit path in the publish now writes a footer. A header with no footer means the run was interrupted. Even a refusal writes one — a refusal is a completed run, and it shouldn’t look like a kill.
The footer is deliberately not written by an exit handler or a signal handler. A process that gets terminated doesn’t run its exit handlers, so the footer’s absence is the evidence — and catching the signal to write one would destroy the very thing this exists to create.
The side effect
Re-registering the schedule now warns, with the process ID, if the job is already running. It warns and proceeds rather than refusing, because a refusal would mean a stuck job could never be replaced.
The habit
When you add logging, it’s worth designing for what the log looks like when the process dies — not just when it finishes cleanly.