Designing a Changelog for Constant Change
A single, organization-wide view of every commit and pull request across all repositories and source control systems, with status and bulk actions in one place.
- ✓ Passing Approved
Add retry to deploy step
a.lee · 2h · main
ALJDplatform-api - ◐ Running Needs approval
Fix pagination on results table
r.kim · 5h · fix/paging
RKweb-app - ✕ Failed Changes requested
Bump parser to 4.2
t.santos · 1d · chore/parser
TSJDcore-engine - ✓ Passing Approved
Guard empty deploy payloads
a.lee · 1d · main
ALauth-service
What problem existed?
At organization scale, code changes were everywhere and visible nowhere. Commits and pull requests were spread across thousands of repositories and more than one source control system, so seeing what was happening meant opening each repository in turn.
There was no single place that answered a basic question: what changed recently across the organization, and what is the status of those changes? This was a brand-new feature, with nothing to start from.
Why did it matter?
At a few repositories you can keep the state of work in your head. At thousands you cannot.
Engineers and leads needed one view to see what was moving, whether checks passed, and what was waiting on review, without hopping between repositories and tools. As change volume grows, an aggregated, status-aware view is what keeps the work coordinated.
What constraints existed?
- Brand new, no precedent. No existing surface inside the product to extend or borrow from.
- Two audiences. Engineers acting on individual changes, and leads who need the state of work across the organization at a glance.
- Scattered across systems. The changes lived in thousands of repositories and more than one source control system, with no surface that pulled them together.
- Designed ahead of the data. I started from a mental model and a Figma design, before the team worked directly in the change data. The design had to anticipate real data it could not yet see.
- Scale. Thousands of repositories and many contributors per organization.
What role did I play?
This was teamwork. I worked closely with our founder and with engineering to understand the mental model and the use case before designing anything.
I owned the design. Working from the outcomes our founder wanted, I led the shaping of the patterns: the row layout, the type and status indicators, the check and review badges, and the filter controls.
What options were explored?
The real exploration was the table itself. The data is dense and the audience is developers, so the format carried the design.
- A traditional enterprise data grid. The default for this kind of data is a high-density admin grid that maximizes rows. It works, but it reads as generic internal tooling, and the audience here is developers.
- A modern, dev-tool-aligned table. A table closer to what developers already use, the pull-request lists in GitHub and similar tools. Clear type and status, scannable rows, room for check results and review state, and familiar interaction patterns.
- Grouping. Group changes by repository, by author, or a single chronological feed. I chose one chronological feed with filters, so the default answers “what changed” and the filters answer “what changed for me.”
I held out for the modern, dev-tool-aligned table. Engineering built it from my design, a table that looks like the tools developers already trust, which made a dense feed feel readable and familiar instead of administrative.
What tradeoffs were considered?
The sharpest tradeoff was completeness against trust. The team could have auto-summarized each change, but engineers distrust a model explaining their own work. So the changelog shows the real change with its type, checks, review state, and contributors, and no summarization.
The freshness tradeoff resolved the same way. Because the changelog reads from real change data, it stays current on its own, which is what makes it a dependable view of activity across the organization.
How did UX, engineering feasibility, and business strategy intersect?
The changelog read from data the product already had, so it added a surface without adding a backend.
That let it carry actions: from the list, selected changes can be approved, merged, or closed in bulk, without navigating to each repository. Filter and sort state lives in the URL, so any view is shareable and bookmarkable. The work was reshaping existing data into a surface people could act on, not building new capability underneath it.
How was AI used in the process?
I started this feature from a mental model and a Figma design. Once the structure held, I brought Claude in to harden it.
A mockup shows the happy path, and real data does not arrive happy. I used AI to enumerate and design every state the mockup hid: loading, empty, error, a partial response, a check still running, a title too long to fit, a change with a dozen contributors, a repository name that overflows. Designing those states is what let the interface hold when real data finally hit it.
The prompt that started that pass handed over the design and the shape of the data, then asked for what the mockup left out:
Here is the happy-path design and the data contract behind it.
Enumerate every state this mockup doesn't show: loading, empty,
error, a partial response, a check still running. Then the
content extremes: a title too long to fit, a change with a
dozen contributors, a name that overflows its column. For each
one, tell me what the interface should do. AI also co-authored component scaffolding for the table, the filters, and the badge variants. It was kept out of anything that carried trust. No AI-written change summaries, and the status-badge semantics stayed human-defined.
Default
real data
Add retry to deploy step
✓ Passing ApprovedLoading
skeleton, never a stuck blank
Empty
filters match nothing
Error
fetch failed, recoverable
Edge
long title, many people, check still running
Refactor deployment pipeline to support multi-region rollout with staged…
◐ Running +12What was learned?
A happy-path mockup is not a finished design. Most of the work lives in the states it hides, and AI is a fast way to generate that list before real data exposes it.
The other lesson was restraint. A changelog earns its place by being accurate, so the right call was to keep AI out of the change descriptions and let the real pull requests speak.
What was the outcome?
A real-time changelog that aggregates every commit and pull request across all repositories and source control systems into one view, showing type, check results, review state, contributors, and repository per row, filterable into shareable views and actionable in place.
From the list, selecting changes lets a team approve, merge, or close them in bulk without opening each repository. The dev-tool-style table, with its filter-chip and status-badge patterns, became the reference for dense data surfaces across the platform.