Elena' s AI Blog

Operational Polish: Human Reports and Draft Preview Endpoints

21 Sep 2026 (updated: 05 Oct 2026) / 12 minutes to read

Elena Daehnhardt

Generated by Midjourney. Prompt: Human head with a glowing AI chip — intelligence augmented by silicon.


TL;DR:
  • Three operational additions to a working LangGraph newsletter pipeline, none of which change the graph itself. First, a build_human_report() helper renders the existing JSON run report as Markdown and writes report.md next to report.json. Second, a read-only FastAPI GET /artifacts/{thread_id} route returns the draft through FileResponse, which streams the file asynchronously and sets Content-Length, Last-Modified and ETag for you. Third, the Slack approval message gains a Block Kit section with an mrkdwn link, so an approver on a phone can read the full draft instead of a truncated snippet.

Previous: Part 21 — Tiny Local RAG: LangChain + LangGraph + Ollama (Markdown Files)

Next: Part 32 — Production Hardening: Idempotency, Run Isolation, and Crash Safety

Operational Polish: Human Reports and Draft Preview Endpoints

By this point in the series, the system drafts newsletters, supervises its own quality, retries when the supervisor is unhappy, pauses for Slack approval, and resumes safely afterwards. That is a genuinely capable pipeline.

It is also, if I am honest, a bit unpleasant to live with. The run report is raw JSON. Slack shows a truncated snippet of the draft. There is no sane way to read the full artefact on a phone, which is exactly where approval requests tend to find you.

This post adds three things, and none of them touch the graph:

  1. report.md — a human-readable run summary alongside the JSON one
  2. GET /artifacts/{thread_id} — a read-only preview endpoint on the FastAPI server
  3. A Slack approval message carrying a real preview link

No new architecture. Just the operational maturity that turns a demo into something you are willing to be on call for.


Why AI Workflow Runs Need Both a JSON Report and a Markdown Report

A run report is a structured record of everything one workflow execution did — revision history, supervisor verdicts, approval status, and timestamps. It exists because AI systems fail in subtle ways. A pipeline that crashes tells you immediately; a pipeline that quietly produced a mediocre draft on revision three tells you nothing at all unless you wrote it down.

The trouble is that the two readers of that record want opposite things. A dashboard, a test, or a later automated pass wants stable keys it can index. A human at 9pm on a Sunday wants to scan five lines and know whether to worry.

So produce both. The JSON stays the source of truth; the Markdown is a rendering of it, generated from the same dictionary, so the two cannot drift apart.


The four steps, from a Markdown run report to a Slack preview link, follow below.

Step 1 — Build a Human-Readable Markdown Run Report in LangGraph

🔒 Subscribe to keep reading.

Step 2 — Write report.md Alongside report.json in the Run Output Directory

🔒 Subscribe to keep reading.

Step 3 — Serve Draft Artifacts with a FastAPI FileResponse Endpoint

🔒 Subscribe to keep reading.

Step 4 — Add a Slack Block Kit Preview Link to the Approval Message

🔒 Subscribe to keep reading.

Checklist Before You Call This Done

🔒 Subscribe to keep reading.

Final Thoughts: Observability Is the Cheapest Part of Production

🔒 Subscribe to keep reading.

You've hit a Deep Dive tutorial.

I spend dozens of hours researching, coding, and breaking things to write these guides. This content is free, but reserved for my subscriber community. Drop your email below to unlock this guide (and all past/future deep dives):

Already a subscriber? Use the magic link from your last newsletter, or reset your password.

New subscribers get an inbox mail: Set a password to unlock articles. The form does not log you in — use the same email afterwards.

desktop bg dark

About Elena

Elena, a PhD in Computer Science, simplifies AI concepts and helps you use machine learning.

Citation
Elena Daehnhardt. (2026) 'Operational Polish: Human Reports and Draft Preview Endpoints', daehnhardt.com, 21 September 2026. Available at: https://daehnhardt.com/blog/2026/09/21/human-reports-and-draft-preview-endpoints/
All Posts