Skip to content

Provenance: Spec 0012 — HQ File Download

Spec: .sdd/specification/spec-0012-hq-file-download.md Executed: 2026-03-18 Agent: Claude Code CLI (claude-sonnet-4-6)


  1. Read .sdd/specification/spec-0012-hq-file-download.md — full spec
  2. Read sites/hq-kevinryan-io/app/api/chat/route.ts — system prompt location and existing structure
  3. Read sites/hq-kevinryan-io/app/components/MessageBubble.tsx — existing bubble component (56 lines, plain string render)
  4. Read .sdd/provenance/template.md — provenance format
  5. Modified sites/hq-kevinryan-io/app/api/chat/route.ts — appended DOCUMENT GENERATION section to BASE_SYSTEM_PROMPT
  6. Modified sites/hq-kevinryan-io/app/components/MessageBubble.tsx — added DocumentBlock interface, parseDocumentBlocks(), downloadDocument(), and download button rendering
  7. Created .sdd/provenance/spec-0012-hq-file-download.provenance.md — this file

No autonomous decisions were required — all actions were explicitly specified in the spec.

#AssumptionSpec ReferenceRationale
A1message.content is a plain string in MessageBubble§2 “Assumption: The MessageBubble component receives the full message content as a string prop”Confirmed by reading the component — message.content is typed as string and rendered directly
A2User messages do not need document parsing§2 (rendering section applies to assistant messages)The spec instructs HQ (the assistant) to emit markers, not the user; parsing user messages would be wasteful and could produce false positives
A3Using doc.filename as the React key for download buttonsNot specifiedFilenames within a single message are expected to be unique; using the filename avoids index-as-key anti-pattern
#AmbiguitySpec ReferenceInterpretationAlternative Reading
B1Where exactly to place download buttons relative to the message bubble§2 “render a download button below the message text”Buttons render outside and below the inner bubble div, still inside the outer div wrapperCould be inside the bubble div, after the text

No deviations from spec.

FileStatus
.sdd/specification/spec-0012-hq-file-download.mdAlready existed (pre-committed by spec author)
sites/hq-kevinryan-io/app/api/chat/route.tsModified
sites/hq-kevinryan-io/app/components/MessageBubble.tsxModified
.sdd/provenance/spec-0012-hq-file-download.provenance.mdCreated

Status: Complete Summary: Added document download capability to HQ chat. BASE_SYSTEM_PROMPT now instructs HQ to wrap downloadable content in ---DOCUMENT:filename.md--- / ---END DOCUMENT--- markers. MessageBubble parses these markers, strips them from displayed text, and renders a lime-accented download button per document using client-side Blob download. Known limitations: During streaming, raw markers are briefly visible as text arrives. Once streaming completes, the component re-renders with markers stripped and the download button visible. This is an accepted limitation for this iteration (per spec §3).

#CheckResult
1Spec saved to .sdd/specification/spec-0012-hq-file-download.mdPass
2BASE_SYSTEM_PROMPT in route.ts contains the DOCUMENT GENERATION section with marker formatPass
3MessageBubble.tsx contains the parseDocumentBlocks functionPass
4MessageBubble.tsx contains the downloadDocument functionPass
5MessageBubble.tsx renders a download button for each detected document blockPass
6Download button uses lime accent #A8E10C and JetBrains Mono fontPass
7Marker text is stripped from displayed message contentPass
8No new npm dependencies addedPass
9No infrastructure files modified (no Terraform, K8s, or GitHub Actions changes)Pass
10pnpm build passes inside sites/hq-kevinryan-io/Pass — verified after implementation
11pnpm lint passesPass — verified after implementation
12Provenance record exists at .sdd/provenance/spec-0012-hq-file-download.provenance.mdPass
13All files committed together in a single commitPass