Auto-generating the weekly status report (and why the first ten were useless)

Nobody enjoys writing the weekly status report. It's an hour of translating ticket movement into sentences a stakeholder will read. It's also, almost always, the same hour every week. Perfect candidate for automation, we thought.

The first ten auto-generated reports were bad in an instructive way, so here's the whole arc.

Why the early drafts failed

They summarised activity, not progress. The first version read the tickets that changed that week and described the changes: "SEQ-4102 moved to In Review, SEQ-4110 was reopened, three tickets were added to the sprint." All true. Useless. A status report's job is to say whether the thing is on track, and ticket movement doesn't answer that on its own.

They inherited the tickets' optimism. Jira descriptions are written by the person doing the work, on a good day, at the start. "Straightforward change to the retry logic." The report would faithfully carry that framing forward even when the ticket had since accumulated twelve comments about edge cases. The draft sounded confident because its sources sounded confident, three weeks out of date.

They had no memory. Each week's report was generated fresh with no idea what last week's said. So a risk that had been flagged for a month would either get re-introduced as if it were new, or dropped entirely because nothing about it changed that week — which is exactly when a risk is most worth mentioning.

They hallucinated tidiness. Asked to produce a "budget status" section with no budget data available, an early version would write a plausible-sounding paragraph about being "within expected parameters." That's the worst failure mode: fluent, structured, and made up.

What we changed

Say what's not there. The single biggest fix. If a section has no supporting data — no budget figures, no milestone dates — the report now says "no data available for this section" instead of improvising. A report with three honest gaps is more useful than a report with three confident fabrications.

Anchor on outcomes, then use tickets as evidence. The prompt now asks, per section: what is the state of this, and which tickets support that assessment. So a "Progress" section reads "Checkout redesign is roughly a week behind; the delay is concentrated in payment-provider edge cases (SEQ-4110, SEQ-4131, SEQ-4140, all reopened after initial fixes)." The tickets are cited, but they're evidence for a claim, not the claim itself.

Weight recent comments over old descriptions. When a ticket's description and its latest comments disagree about difficulty, the report trusts the comments. That one change moved the tone of the drafts from "everything's fine" to something closer to how the team would actually describe the week.

Filter, deliberately. The report is generated for a date range and, optionally, a set of labels or a project. Feeding it every ticket in the system produced vague, hedged summaries. Scoping it to "this sprint, these components" produced something specific enough to act on.

Let the person edit before it goes out. It generates a draft, not a final. The human who used to spend an hour now spends ten minutes correcting the two things the model got wrong and cutting a paragraph. That's the actual value — not zero effort, but eighty percent less of it.

Where it landed

The reports are useful now, with a clear boundary around what they're for. They're good at: turning a week of ticket activity into a scoped, cited, honestly-hedged summary that a person can finish quickly. They're not good at: knowing things that aren't written in the tickets. If the real reason the sprint is behind is that two people were out sick and nobody logged it, the report can't know that, and will attribute the delay to the technical tickets that were merely the visible surface.

We generate them as Word or PowerPoint depending on who's receiving them, which sounds trivial and was the thing that finally got non-engineering stakeholders to actually read them.

The first ten drafts went in the bin. The eleventh, after the "say what's not there" change, was the first one we sent to a customer with only light edits. If you try this, expect the same shape of learning curve — the failure mode is always over-confidence, and the fix is always forcing the thing to admit what it doesn't know.

Generate one from your own data — pick a date range and a couple of components, and see how close the first draft gets.