Render lenses
Flow-Next 2.0.0 adds an opt-in HTML artifact mode. When it is on, the lifecycle skills emit self-contained HTML pages, render lenses, alongside their markdown output. There are two: the spec lens for business and plan review, and the PR lens for diff review. Both are covered here.
For the zero-machinery counterpart, a one-screen markdown digest of a spec, task, or diff rendered straight into chat, see /flow-next:visual.
Activation
Section titled “Activation”One config key, written by the /flow-next:setup ceremony or set directly:
flowctl config get artifacts.html.enabled --json # default: falseflowctl config set artifacts.html.enabled trueflowctl config set artifacts.html.enabled false # turn off againWith the mode off or unset, participating skills load no reference file, write no artifacts, open no Lavish sessions, and add no output - the single config read is the only addition. Setup asks once (only when the key is unset): enable or not, then - on yes - commit-vs-gitignore for .flow/artifacts/ and an optional lavish-axi install offer (never auto-installed).
Generation is agentic, not deterministic: when the mode is active, the skills load one shared disclosure reference carrying all generation rules and an explicit anti-slop design contract (own warm-black instrument-panel house style, local-only font stacks, no CDN fonts, no purple gradients), and the host agent writes the HTML. There is no Python renderer and no new slash command.
The spec lens
Section titled “The spec lens”The spec artifact lives at a fixed, deterministic path - .flow/artifacts/<spec-id>/spec.html, never timestamped - and regenerates at its lifecycle touchpoints. What renders depends on what state exists, not on a config axis:
| Lifecycle touchpoint | What renders |
|---|---|
/flow-next:capture - fresh spec, no tasks yet | Spec-only view: thesis, acceptance criteria with source-tag provenance chips, architecture panel, edge cases, boundaries, decision context - the business-review surface |
/flow-next:plan - tasks now exist | Same file, same path, regenerated with the plan layer: task dependency DAG with critical path, R-ID → task coverage matrix |
The plan layer makes the lens a plan-review aid too: a tech lead reads the task graph and coverage matrix as one page instead of walking task files. Generation runs only after plan’s refinement loop exits - the lens never renders a task graph you are still editing.
After writing, the skill updates a single artifact link line in the spec markdown (marked <!-- flow-next:artifact-link -->), replaced in place on every regeneration - repeated capture/plan runs never duplicate it. Every artifact footer carries a staleness stamp (spec updated_at + repo commit at render time) so a reader can tell when the lens lags the markdown. Generation failure is non-fatal everywhere: the markdown is already on disk and is the record.
The PR lens
Section titled “The PR lens”With the mode on, /flow-next:make-pr emits a PR render lens at .flow/artifacts/<spec-id>/pr.html: a self-contained HTML page built for one job, getting a human reviewer through the diff fast with the spec’s acceptance criteria in hand.
It is a read-only review instrument: masthead + dials, a sticky review-progress bar, the 90-second read, a churn map grouped by review intent (canonical vs generated-mirror vs mechanical), the R-ID → evidence table, a where-to-look checklist, and a risk register.
The shared information architecture
Section titled “The shared information architecture”The structured artifact, GitHub Markdown, and optional HTML lens share one versioned walkthrough: identity and currentness, grounded proof, ordered logical groups, exact file membership, separate change/attention dimensions, file-level R-ID/task links, deliberately unchanged behavior, and verification. These high-resolution references define the hierarchy and interaction - not a pixel-copy requirement.
When a supported current v1 object exists, it is the HTML lens’s authoritative semantic input. Interaction may be richer, but the lens cannot reorder groups, move files, invent evidence, or mix stale and legacy fields.
Built from the diff
Section titled “Built from the diff”The lens is built from the flowctl spec export-cognitive-aid payload plus the real diff - commit subjects and bodies are not lens input. What a reviewer reads reflects what actually changed, not what the commits claim changed.
R-ID verification (warn, never block)
Section titled “R-ID verification (warn, never block)”Before publishing, the lens is verified against the spec’s R-ID export. Mismatches - claimed evidence outside the diff range, uncovered R-IDs, evidence touching no diff files - render as visibly flagged rows (red R-ID cell, mismatch chip, reason). A mismatch never blocks PR creation and is never silently dropped: the discrepancy is the finding.
How it ships with the PR
Section titled “How it ships with the PR”- Current v1 stays local-only. The lens embeds a lossless HTML-safe carrier of the exact head-bound cognitive-aid object. Committing it would advance the reviewed head and immediately stale its own input, so the body gives local-open guidance and the branch head stays unchanged. Only a visibly labeled legacy fallback may use the narrow
chore(flow): pr artifact <spec-id>commit. - The GitHub limitation. GitHub renders committed fallback HTML as raw source. Current v1 lenses are opened locally (
open .flow/artifacts/<spec-id>/pr.html). --dry-runwrites nothing. No artifact, no commit, no body line.- Failure is non-fatal. Artifact generation or staging failure degrades to no-body-line plus one stderr note; the PR is still created.
Why there is no annotate loop
Section titled “Why there is no annotate loop”The spec lens opens a Lavish annotation session when available; the PR lens never does - interactive and autonomous alike. A PR artifact derives from an immutable diff, and GitHub already owns review conversation - duplicating that surface would create a sync problem. PR feedback belongs in review threads, where /flow-next:resolve-pr picks it up.
Autonomous discipline
Section titled “Autonomous discipline”Pilot, Land, and Ralph generate artifacts at the same touchpoints but never open a Lavish session and never poll - a loop never blocks on a human. Ralph’s PR_URL= stdout contract is untouched: all artifact messaging routes to stderr. See the safety model.
Self-contained or nothing
Section titled “Self-contained or nothing”Every lens is a single HTML file - inline CSS/JS, zero external requests, fonts included, print-friendly. It opens identically from file://, inside Lavish, in a CI archive, and on paper.
GitHub renders committed .html as raw source and rejects .html PR attachments, so the markdown links carry local-open guidance:
open .flow/artifacts/<spec-id>/spec.html # macOS; xdg-open on LinuxSpec and legacy-fallback artifacts are committed by default; the setup
ceremony offers gitignoring .flow/artifacts/ instead for clean history. A
current v1 PR lens is deliberately local-only so it cannot advance and stale
its own head-bound input. The skills probe ignore status and never emit a link
that 404s.
Annotate in the browser (Lavish, optional)
Section titled “Annotate in the browser (Lavish, optional)”lavish-axi (npm) is an optional companion: it serves the spec artifact in a browser session where humans annotate, and annotations flow back to the agent as edits of the markdown source of truth, followed by lens regeneration. Detected on PATH, never required - absent means a plain static artifact, never an error, never an auto-install.
npm i -g lavish-axi # or zero-setup per run: npx lavish-axi <artifact.html>lavish-axi .flow/artifacts/<spec-id>/spec.htmlThe feedback loop is pull-only and session-spanning: annotations queue in the global ~/.lavish-axi/state.json and survive agent death - annotate tonight, and any later agent session drains the queue via lavish-axi poll, mapping each annotation to a spec edit and regenerating the lens. The local server idle-stops after ~30 minutes; the artifact still renders as a plain static page, and re-running lavish-axi <file> resumes the session.
The annotate loop applies to spec artifacts only - the PR lens never enters it, and autonomous loops never poll (see Going Autonomous).
Regenerating
Section titled “Regenerating”There is no regeneration command. Auto-regen rides the lifecycle touchpoints (capture, plan, make-pr); everything else is conversational - after hand edits, an interview pass, or drained annotations, just ask the agent:
“regenerate the artifact for fn-12”
It reloads the disclosure reference, re-reads the spec + flowctl state, and regenerates at the same fixed path.