01

## Thesis

scope: business

flow-next's human touchpoints — spec review, plan review, diff review — are markdown-only today. This feature adds an optional HTML artifact mode: when activated via setup/config, the lifecycle skills load one progressively disclosed reference file and emit self-contained, beautifully rendered HTML lenses beside their markdown output — maximum legibility and review ergonomics for POs, PMs, and devs, while markdown-only users see zero change.

The load-bearing clarification: markdown (and tracker-sync) stays 100% the source of truth. Every HTML output is a regenerable render lens, never the record — one-way derivation, never parsed back as state. Validated by smoke test on real history (fn-52 spec visualizer, PR #171 review instrument) before this spec was written.
02

## Task graph

8 nodes · hover a node to light its r-ids below
L0
fn-62.1
Config gate + .flow/artifacts layout + setup ceremony (lavish offer)
done
L1
fn-62.2
Shared disclosure reference (design system + generation rules) + Codex mirror
done
L2
fn-62.3
Spec-lens integration: capture + plan touchpoints, lavish session, state-dependent rendering
in progress
fn-62.4
PR-lens integration: make-pr emission, R-ID verification, link strategy
todo
L3
fn-62.5
Repo docs: html-artifacts doc + README/teams/ralph/GLOSSARY/CLAUDE.md surfaces
todo
L4
fn-62.7
flow-next.dev feature pass: visual-aids pages, landing card, both navbars, changelog
todo
L5
fn-62.8
flow-next.dev strategy/pipeline pass: pipeline page, autonomy content, Introduction
todo
L6
fn-62.6
2.0.0 release: bump, crossEpic alias removal, Codex mirror regen + audit, CHANGELOG
todo
critical path · .1 → .2 → .3 → .5 → .7 → .8 → .6 (7 deep) dependency parallel lane: .4 (PR lens) runs beside .3 off the shared .2 base
03

## Acceptance criteria

14 rows · provenance-tagged · scope: both

R-ID | Criterion | Provenance | Owned by
--- | --- | --- | ---
R1 | HTML mode is opt-in via setup/config, OFF by default. Off ⇒ no reference load, no artifacts, no Lavish sessions, no behavior-visible output — the heavy disclosure file costs zero tokens. | user paraphrase | fn-62.1
R2 | When active, skills load a progressively disclosed shared reference file: generation rules + explicit anti-slop design system (own typography/palette; no CDN fonts; no purple-gradient defaults). | user paraphrase | fn-62.2
R3 | Markdown + tracker-sync remain the sole source of truth; every HTML output is an additional regenerable artifact, never parsed back as state. | user | fn-62.2 fn-62.3
R4 | Spec artifact uses ONE generation pathway with state-dependent rendering: spec-only before tasks exist; spec+plan layer (task DAG, R-ID coverage matrix) once tasks exist. | user paraphrase | fn-62.3
R5 | PR artifact is diff-derived (never commit messages), verified against the spec's R-ID export before publishing; read-only review instrument. | user paraphrase | fn-62.4
R6 | All artifacts are self-contained single-file HTML — inline CSS/JS, zero external requests, print-friendly. | paraphrase | fn-62.2
R7 | Lavish (`lavish-axi`) ships as an optional dependency: detect-on-PATH, never required; when present + interactive, spec/plan artifacts open as sessions and annotations map to markdown-source edits + lens regeneration. | user | fn-62.2 fn-62.3
R8 | The PR artifact never enters the annotate-edit loop; autonomous/Ralph contexts never run a Lavish poll. | user paraphrase | fn-62.3 fn-62.4
R9 | The setup ceremony, on HTML opt-in, documents and offers the lavish-axi install — including the session-spanning feedback model and idle-stop/resume behavior. | user | fn-62.1
R10 | Markdown spec and make-pr output link to their HTML artifacts; the GitHub display limitation is documented with local-open guidance. | user | fn-62.3 fn-62.4 fn-62.5
R11 | Artifacts live in a dedicated regenerable location under `.flow/`, commit-or-gitignore per project. | inferred | fn-62.1
R12 | flow-next.dev surfaces this as a mainline feature: landing page, SPECS/TEAMS/REVIEW sections, a new visual-aids page (both navbars), changelog entry, build gate green. | user | fn-62.7
R13 | flow-next.dev strategy/pipeline pass in the same workstream: a pipeline page, the missing autonomy-suite content, Introduction narrative updated to match. | user | fn-62.8
R14 | Released as 2.0.0 — repo docs, Codex mirror regen, manifest/version lockstep, CHANGELOG. | user | fn-62.5 fn-62.6

04

## Architecture

scope: technical

### Activation gate

`flowctl config get artifacts.html.enabled` — written by the setup ceremony, OFF by default. Off ⇒ skills load nothing extra: zero token cost, zero behavior change. The one flowctl edit is the `artifacts` default block in `get_default_config`; everything else is skill prose.

↓ when enabled, participating skills load ↓

### Shared disclosure reference

`plugins/flow-next/references/html-artifacts.md` — design system (instrument-panel house style), generation rules, per-lens guidance, DAG discipline, Lavish protocol, pre-publish checklist. ONE generator definition; tool-name-agnostic so the Codex mirror needs no rewrite pass.

↓ consumed at three lifecycle touchpoints ↓

### capture → spec lens

Phase 5 post-write emits `.flow/artifacts/<spec-id>/spec.html` — pre-plan, spec-only business-review view.

### plan → spec lens

After Step 8's refinement loop exits, the SAME pathway regenerates at the SAME path — now with the task DAG, coverage matrix, critical path.

### make-pr → PR lens

Emits `pr.html` from `git diff --stat` + the R-ID export; injects the body link before `gh pr create`. Read-only — no annotate loop, ever.

↓ optional companion — detect, never require ↓
1 detect

`command -v lavish-axi` — absent ⇒ plain artifact, zero mention, never an error.

2 open (interactive only)

`lavish-axi <abs-path>` opens an annotation session keyed on the absolute artifact path.

3 pull-only feedback

Annotations queue in `~/.lavish-axi/state.json` — session-spanning, survives agent death; any later session drains via `lavish-axi poll`.

4 apply + regen

Each annotation maps to an edit of the markdown source of truth, then the lens regenerates at the fixed path.

05

## Edge cases & constraints

grouped by blast radius

### Contract integrity — break these and the model collapses

- Stale-lens risk: artifacts regenerate at lifecycle touchpoints and are never parsed back as state; every footer carries a staleness stamp (spec `updated_at` + commit at render time).
- R-ID mismatch (PR lens): diff vs R-ID-export disagreement renders as a visibly flagged row — warn-in-artifact, never block make-pr.
- Self-contained or nothing: zero external requests, fonts included — must open identically from disk, in Lavish, in CI archives, printed.

### Workflow discipline — make-pr & plan side effects

- make-pr: `--dry-run` writes NO artifact; committed-mode stages ONLY `pr.html` (never `git add -A`) as `chore(flow): pr artifact <spec-id>`; generation failure is non-fatal; Ralph's `PR_URL=` stdout contract untouched.
- Link idempotency: the spec's artifact-link line is replaced in place on every regen — never duplicated.
- Plan timing: the lens generates AFTER Step 8's refinement loop exits, never mid-edit.

### Environment realities — GitHub, paths, storage

- GitHub can't render committed HTML and rejects .html attachments — bodies link with local-open guidance; no hosting over-engineering.
- Fixed deterministic paths: `spec.html` / `pr.html`, never timestamped — Lavish keys sessions on the absolute path. Worktree caveat documented and accepted.
- Link strategy follows ignore status: committed by default (blob links resolve); gitignored projects get local-open guidance only — never a 404 blob link.
- localStorage is try-wrapped progressive enhancement; artifacts stay fully readable without it.

### Graceful degradation — absence is invisible

- No lavish on PATH ⇒ plain artifact, zero mention. Server idle-stop ⇒ still a static page; reopening resumes.
- Autonomous discipline: pilot/Ralph generate artifacts but never open sessions, never poll — at most a one-line pending-prompts note.
- DAG discipline: layered CSS grid + DOM-measured edges — hand-typed SVG coordinates banned; >~20 nodes collapse to lanes.

06

## Boundaries

scope: business

### This IS

- Fully opt-in — markdown-only users see zero new steps, prerequisites, or token overhead (zero-dep base contract preserved).
- Regenerable render lenses beside markdown output — spec lens (one state-dependent pathway) + read-only PR lens.
- Lavish as detect-on-PATH optional dep — same shape as clawpatch / /flow-next:map.
- Committed by default under `.flow/artifacts/`, gitignore offered at setup.
- A 2.0.0 mainline feature, surfaced on flow-next.dev.

### This is NOT

- A storage format — no state ever lives in artifacts.
- A Lavish wrapper or bundle — never wrapped, bundled, or required.
- PR-annotation → review-comment plumbing — explicitly out of scope (plausible future increment).
- Review-report artifacts (impl-review / plan-review / qa as HTML) — later increment.
- The codex-apop delegation hardening — deliberately deferred behind this ("bigger bang for our buck").

07

## Decision context

capture + planning decisions
D1

### Lavish: detect, don't wrap

Its portable-artifacts guarantee means plain self-contained HTML gets the annotate loop for free when present. Pull-only architecture (CLI long-poll, global state file, no MCP) keeps coupling at zero and makes feedback session-spanning.

"the lavish editor is definitely a large boon … lavish is a go as an optional dep"

Rejected: wrapping/bundling — adds a Node dependency to the zero-dep base for no gain.

D2

### One artifact pathway, not two

Spec-vs-plan is a rendering question (what state exists), not a product question. Same generator, same path, same flowctl export.

"i think it would be the same pathway, we would just generate the html using information from the spec and/or the spec + tasks"

Rejected: separate spec/plan artifact types — a needless config axis.

D3

### Annotate loop scoped to spec/plan only

A PR artifact derives from an immutable diff, and GitHub already owns review comments — duplicating that surface creates a sync problem.

"the agentic editing of a PR doesnt make sense does it?"

Rejected: PR-lens annotate loop.

D4

### No new slash command

Auto-regen rides the existing lifecycle skills (capture, plan, make-pr); ad-hoc regeneration is conversational — the host agent reads the disclosure file on request. Skill surface stays flat per repo rule; interview integration is OUT of v1.

Rejected: a dedicated artifact skill / fourth wiring point.

D5

### No deterministic Python renderer

Generation is the host agent reading the disclosure file (the repo's agentic-vs-deterministic rule); flowctl's only contribution is the config default block.

Rejected: a flowctl HTML generator — brittle, unmaintainable, worse output.

D6

### Release task runs last

The 2.0.0 release (fn-62.6) depends on the flow-next.dev tasks because the release procedure needs the docs-site changelog + version bump before the tag: order .5 → .7 → .8 → .6. The `planSync.crossEpic` alias removal rides the release task as its own breaking-change CHANGELOG line — kept visible, not folded silently into the bump.

08

## Early proof point

### the core bet — and this page is the experiment

Task fn-62.2 (the disclosure reference) validated through fn-62.3's first real regeneration: a fresh agent session reading ONLY the disclosure file must reproduce the smoke-test house style — instrument-panel design, layered DAG, source-tag chips, staleness stamp, zero external requests — for fn-62 itself, matching the hand-built artifacts in `~/Documents/flow-next-artifact-smoke/` without having seen them.

If the output drifts sloppy or inconsistent, fix the reference file's rules/examples/checklist BEFORE building the PR lens (fn-62.4) and docs (fn-62.5+).