Dashboard data-shape & rendering release. Three long-standing dashboard defects, surfaced while writing the novella The Price of Glory, are fixed together. The schema bumps from v2 → v3 with a one-shot upgrade path on next regen — no manual migration required, and the renderer tolerates v2 emissions for back-compat.
Issue A — single source of truth for the book's word-count target. Pre-1.6.0, two unreconciled targets coexisted: per-scene targetWords summed in data.json (often 30,000 from a silent 2,500/scene default) and dashboard-history.json[0].targetTotal captured by the wizard's roadmap phase (often a very different number — 12,000 in the Price of Glory case). The Briefing-tab "Words drafted" card divided by the per-scene sum, ignoring the captured target entirely — producing a meaningless "17% of 30k" headline when the author's declared target was 12k. v1.6.0 makes roadmap.md's YAML frontmatter the canonical source: the wizard captures target_word_count + form_factor + header_progress_mode explicitly using a form-factor Socratic question (short_story / novelette / novella / short_novel / novel); the outliner derives per-scene budgets from the canonical and refuses to silently default to 2,500/scene; the dashboard regen reads the canonical first and re-derives per-scene targets on every pass (with a targetReprovisioned flag when values shift >10%); /holocron:reconcile detects divergence on legacy projects and migrates them with an undoable checkpoint snapshot. The dashboard surfaces the form factor next to the target (12,000 · novella) and warns when the target sits outside the chosen band (Target below novella band — did you mean novelette?).
Issue B — Project Roadmap cards now render the phase name. Pre-1.6.0, the six Briefing-tab roadmap cards rendered only a status pill, a workload · <value> line, and a progress bar — the phase title (Voice declaration, Act II outlining + drafting, etc.) was never shown. Root cause was schema drift: the dashboard skill wrote a phase field while the schema and renderer used label, so the title silently rendered empty. v1.6.0 reconciles on label as canonical and adds owner (subtitle showing which agent drives the phase) and status (enum: complete / in_progress / queued / blocked). The static workload · prefix is removed; the workload value renders bare. A 2px left-edge accent line per status reinforces card identity at a glance.
Issue C — header phase chip becomes mode-aware instead of pinned at 100% forever. Pre-1.6.0, the chip read Phase 7 · 100% from the moment the wizard finished scaffolding and stayed there for the rest of the book's life — becoming information-dead at the exact moment a header progress signal would be most useful (when drafting begins). v1.6.0 adds a phase.mode state-machine computed by the dashboard regen (NOT the renderer): scaffolding while any wizard phase 0–7 is incomplete; drafting once Phase 7 is done AND any chapter has non-zero words. The chip then displays Drafting · 43% (default words-based; data.headerProgressMode opts the author into scene-based or act-based display via roadmap frontmatter). The chip is now a clickable button that jumps to the relevant tab (workshop in drafting, briefing in scaffolding).
Added
templates/dashboard/data.schema.json— schema v3 fields: top-leveltargetWordCount,formFactor,formFactorWarning,headerProgressMode,targetReprovisioned;phase.mode,phase.progressLabel,phase.progressNumeric,phase.currentTask,phase.clickTarget;roadmap[].owner(subtitle) androadmap[].status(enum). Schema bumps_meta.schemaVersionfrom2to3.agents/new-project.md— Phase 6 Step 6a: form-factor Socratic question (AskUserQuestionwith the five Legends-era reference points), midpoint table for each band, YAML-frontmatter writes toroadmap.md. Phase 7 data.json synth populates all new top-level andphasefields.agents/outliner.md— Step 6 derives per-scenetargetWordsfrom the canonicaltarget_word_count(even distribution by default, tension-weighted opt-in). The outliner refuses to outline whentarget_word_countis missing rather than silently defaulting to 2,500/scene.skills/dashboard/skill.md— canonical target rule, schema v2→v3 one-shot upgrade path, mode-selection rule (scaffolding/drafting/revision), roadmap card field contract ({label, owner, status, workload}), form-factor band table.skills/reconcile/skill.md— Section 7: divergent-target detection betweendata.jsonper-scene sum,dashboard-history.json[0].targetTotal, androadmap.mdfrontmatter. Migration writes the chosen canonical to roadmap frontmatter, snapshots pre-migrationdata.jsonto.holocron-checkpoint.json.migrations[]for undo.templates/dashboard/app.jsx— Words-drafted StatCard now readsdata.targetWordCountwith fallback to per-chapter sum; renders form-factor suffix next to the target; surfacesformFactorWarningas a warning chip in the footer when the target falls outside the chosen band.templates/dashboard/styles.css— 2px left-edge accent line on roadmap cards keyed by status (kyber cyan forin_progress, bronze forcomplete, slate forqueued, sith crimson forblocked). New.hd-roadmap-ownerand.hd-roadmap-workloadclasses..hd-pill-chipstyling for the now-clickable mode-aware header chip.
Changed
templates/dashboard/app.jsx— Briefing-tab roadmap card template rewritten: renders status pill from the newstatusenum (with back-compat fallback to legacydone/activebooleans),labelas title-weight phase name (with back-compat fallback to schema-driftedphasefield),owneras muted display-font subtitle, bareworkloadvalue (the staticworkload ·prefix is gone), and progress bar driven by status.templates/dashboard/app.jsx— header phase chip rewritten: readsphase.progressLabel+phase.progressNumeric(with back-compat fallback to legacyname · progress%); now renders as<button>withonClick→ tab switch tophase.clickTarget; inline progress bar appended to the chip body.templates/dashboard/data.schema.json—roadmap[]items: widenworkloadfrom number-only to["string", "number"](schema previously didn't match the strings regen was emitting). Markactive/donedeprecated-but-tolerated for one version.skills/new/skill.md— Defaults section: length target now uses the five-band form-factor framing; documents the canonical-target invariant (single source of truth inroadmap.mdfrontmatter; per-scenetargetWordsmust sum to it; never silently default to 2,500/scene).
Verification
npm run build:dashboard—app.jscompiles to 225.9 KB, no errors.- Playwright smoke test against the real Price of Glory project (legacy v2
data.jsoncarrying the divergent state from the bug report): all five tabs render without console errors; the six roadmap cards now display title + owner + bare workload; the header chip is a clickable<button>with the bronze-accent left-edge line on completed cards; CSS variables verified (rgb(201, 162, 74)× 2px). Back-compat fallbacks correctly render legacy v2 data; Issues A and C fully resolve after the next/holocron:dashboardregen (Issue A also needs/holocron:reconcileto declare the canonical target on legacy projects).