Development reports

Dev Log: 2026-07-17

The question that started the week was small and awkward: whose work is this, actually?

Timbers records entries against a workset — a set of commits — and for a while that felt like enough. Git already knows who authored what. Why duplicate it? But worksets are fragile in a way commits aren't. Rebase, squash, shallow clone, prune — any of those can vaporize the SHAs an entry points at. And once the SHAs are gone, so is the person-level credit. A future report that wants to say "here's what Alice shipped this quarter" is left holding a bag of orphaned references.

So contributors became a first-class, capture-time snapshot on the entry itself. Mailmap-normalized Git authors, Co-authored-by trailers folded in, provenance tracked per identity. The interesting design call was around --who: when an operator supplies it explicitly, it replaces the entire automatic set rather than merging. Merge semantics for identity are a swamp — whose intent wins when the automatic and explicit sets disagree? Replacement is blunt, but it's unambiguous, and ambiguity in an audit trail is worse than bluntness.

The subtler piece was the agent guidance. A capable feature is worthless if the agents driving Timbers day-to-day don't know when to reach for it. The prime, the onboard flow, log --help, the MCP schema hints — all of them needed to say roughly the same thing: do nothing by default. Git attribution is automatic; the agent only needs to steer when something's unusual (pairing, bots, a correction after the fact). And when it does steer, it needs to know that --who is a full replacement, not a nudge. Progressive disclosure, applied to agent instructions rather than UI.

Somewhere in the middle of all that, the site got a personality. The neutral Timbermill theme had done its job — readable, unobjectionable, forgettable — and Working Mill replaced it with something that actually shows the capture-to-report transformation: an industrial hero, self-hosted Geologica, a small licensed icon set, dark mode, reduced-motion-safe effects. Then a polish pass caught the things that always survive a first draft: a hero install command that ballooned into a scrollable strip, dark-mode borders that hadn't been tokenized, link colors a shade too vivid, metadata rows that didn't quite baseline-align. The kind of defects that are invisible until you see them and then impossible to unsee.

The through-line, if there is one: treat identity and presentation as capture-time concerns, not query-time ones. Trying to reconstruct "who did this" from Git after the fact is a losing bet against history rewrites. Trying to derive a brand from a neutral baseline is a losing bet against never getting around to it. Snapshot the thing you care about when you have it. The tradeoff is duplication — the contributor list on an entry can drift from the Git reality if history is rewritten — but a stale snapshot with clear provenance beats a live query against data that might not exist.

What's unresolved: person-level views still need a known-human roster to filter bots out. Contributors are identities, not people. That reconciliation lives downstream, and it's fine that it does — the ledger's job is to capture faithfully, not to decide who counts.

The work feels like solid ground. The attribution contract is small, additive, and the agent guidance around it is quiet enough that most sessions won't notice it exists — which is exactly the shape it should have.

Written with AI assistance from session logs.