From 33ef1757470da5c17b984ed607f535a52d869ffd Mon Sep 17 00:00:00 2001 From: ares <285551516+New1Direction@users.noreply.github.com> Date: Tue, 16 Jun 2026 18:16:14 -0700 Subject: [PATCH 01/13] docs(spec): output-tab Four-Act narrative (Pillar A) design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restructure the 28-tab output view into a Decide → Understand → Go Deeper → Act narrative. Two-tier nav, every section keeps a home, decision control to the top, lenses labeled with prereq/time/progress, legacy deep-link map. Scope-bounded (container/IA reorg, no pipeline rewrite). Part of a 3-pillar effort (A output-tab [this], B journey, 3 Knowledge Game). Includes a rendered HTML version for review. --- ...026-06-16-output-tab-four-acts-design.html | 253 ++++++++++++++++++ .../2026-06-16-output-tab-four-acts-design.md | 153 +++++++++++ 2 files changed, 406 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.html create mode 100644 docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.md diff --git a/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.html b/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.html new file mode 100644 index 0000000..6dedbb6 --- /dev/null +++ b/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.html @@ -0,0 +1,253 @@ + + + + + + Output Tab — Four-Act Narrative (Pillar A) + + + +
+ +
+

Output Tab — Four-Act Narrative

+
+ Pillar A · 2026-06-16 · Status: Approved (design) — pending implementation plan
+ Surface: the extension's analysis/verdict view (output-tab.html + output-tab.js) +
+
+ Part of a 3-pillar "simpler to use and digest" effort: +
Pillar A — Output-tab narrative ← this spec, building first
+
Pillar B — Cross-app journey (circular nav, entry points, save/discovery clarity)
+
Pillar 3 — The Knowledge Game (library + corkboard + canvas: smooth, juicy, addictive — mastery + discovery + collection + crafting, to "plug pieces together and think in new ways")
+
+
+ +

Problem

+

The output tab is information-rich and genuinely good — the problem is purely presentation and flow. From a current-state audit:

+
    +
  1. 28 flat tabs. Verdict, ELI5, Technical, Use-Cases, Skip-If, Enables, Pros-Cons, Alternatives, Health, Red-Flags, Tech-Stack, + Deep-Dive/Systems/Ideate/Prioritize/SKTPG, + Docs/Maintenance/License/Diff/Fits-Stack, + Similar/Versus/Synergies/Connections/Combine, + Ask/Canvas. No sense of what to read first or in what order.
  2. +
  3. No narrative, weak wayfinding. The Verdict landing tries to be everything (11 stacked sections, flat hierarchy); the Decision control (Adopt/Trial/Hold/Reject) is buried ~2000px down; key info is previewed on Verdict but fully rendered elsewhere with no jump links; fit verdict, red flags, and tech stack each render in two places.
  4. +
  5. Opaque "lenses," hidden prerequisites. "Lens" is never explained; Canvas silently needs Deep Dive first; library tabs need 2+ scans; multi-stage runs give no progress/ETA.
  6. +
+ +

Goals

+ + +

Non-goals

+ + +

Structure: chosen approach

+

Four Acts, two-tier navigation. Four primary acts as the top-level nav; each act opens its own focused, bounded view containing its grouped sections. The user always knows which act they are in; never an endless scroll. Keyboard navigation preserved. Cleanest fit for the zero-build codebase.

+ +

The four acts — complete section mapping

+

Default = shown immediately after a scan. On-demand = user triggers an AI run.

+ +
+ ① DECIDE +

"should I use this, and what do I do about it?" — the landing

+ + + + + + + + + + +
ElementWhenNotes
Fit verdict (level + label + why)DefaultAnchored at top
Bottom line (one-liner)Default
Decision control (Adopt/Trial/Hold/Reject + note)DefaultMoved to the top (was buried at page bottom)
At-a-glance facts (health, stars/license/lang, pros/cons/flag counts)DefaultCompact summary row
Top red flags (up to 3)DefaultDistinct "warning" treatment; link to full list
Where-to-start cardsDefaultif present
Since-last-scan diff calloutDefaultif prior scan
"Worth noting" highlightsDefaultNow anchor to their home section (no context-thrash)
+
+ +
+ ② UNDERSTAND +

deep reading; all pre-computed, no waiting

+ + + + + + + + + + + + +
ElementWhenNotes
ELI5 (+ analogies)Default
TechnicalDefault
Use Cases (4-grid)Default
Skip If (4-grid)Default
EnablesDefault
Pros / Cons (full)DefaultVerdict shows counts → jump here
Red Flags (full list)DefaultDecide shows top 3 → jump to the canonical full list here
AlternativesDefault
Health (full: 4 signals + summary)DefaultAdd metric explanations
Tech Stack (full: built_with + key_dependencies)DefaultVerdict shows language chips → jump here
+

De-duplication rule: where Verdict shows a preview, the full version lives here and Verdict links to it. One source of truth per element.

+
+ +
+ ③ GO DEEPER +

on-demand lenses about THIS repo; each a labeled card

+

Each lens card shows: name · one-line "what it does" · prerequisite badge · time estimate · live stage progress.

+ + + + + + + + + + +
LensPrerequisiteNotes
Deep Dive (atoms → lineage → Feynman)~90s, 3 stages with progress
Canvas / BlueprintNeeds Deep Diveprereq badge shown
Systems / Ideate / Prioritizeframework chips
SKTPGauto-run by default (toggle)
Docs Quality
Maintenancecan be slow; show progress
Licenselibrary context
Since Last Scanprior scan
+
+ +
+ ④ ACT +

do something with it

+ + + + + + +
ElementNotes
Saveclear saved-state feedback
Ask this reporequires a completed scan — state up front
Share
Against your library: Similar · Versus · Synergies · Connections · Combine · Fits-My-StackHonest "needs N scans" unlock states. Deeper gamified treatment is Pillar 3.
+
+ +

Navigation & interaction

+ + +

Component design (isolation + testability)

+

Extract a pure act-model module (e.g. output-acts.js), no DOM/network, exporting: ACTS, sectionToAct(), routeForHash() / hashForRoute(), LEGACY_SLUG_MAP + resolveLegacySlug(), and keyboardMap. output-tab.js consumes it to render the act shell and route; section render functions stay as-is and mount into act containers. Routing/grouping logic becomes unit-testable independent of the DOM.

+ +

Constraints honored

+ + +

Testing

+ + +

Migration / rollout

+
    +
  1. Build the pure act-model module + act shell + routing (tested first).
  2. +
  3. Move sections into acts group-by-group, keeping tests green.
  4. +
  5. Add the legacy-hash redirect so existing #slug links resolve.
  6. +
  7. Preserve auto-save, lens runners, and all message contracts (front-end only).
  8. +
+ +

Acceptance criteria

+ + +
+ Resolved decisions: Four Acts (two-tier nav) · decision control → top of Decide · library-relational features → Act (gamified depth deferred to Pillar 3) · circular library↔output nav folded into A. +
+ + + +
+ + diff --git a/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.md b/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.md new file mode 100644 index 0000000..dc492e0 --- /dev/null +++ b/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.md @@ -0,0 +1,153 @@ +# Output Tab — Four-Act Narrative (Pillar A) + +- **Date:** 2026-06-16 +- **Status:** Approved (design) — pending implementation plan +- **Surface:** the extension's analysis/verdict view (`output-tab.html` + `output-tab.js`) +- **Part of:** a 3-pillar "make the app simpler to use and digest" effort + - **Pillar A — Output-tab narrative** ← *this spec, building first* + - **Pillar B — Cross-app journey** (circular nav, entry points, save/discovery clarity) + - **Pillar 3 — The Knowledge Game** (library + corkboard + canvas made smooth, juicy, and addictive; mastery + discovery + collection + crafting, in service of "plug pieces together and think in new ways") + +## Problem + +The output tab is information-rich and genuinely good — the problem is purely presentation and flow. From a current-state audit: + +1. **28 flat tabs.** Verdict, ELI5, Technical, Use-Cases, Skip-If, Enables, Pros-Cons, Alternatives, Health, Red-Flags, Tech-Stack, + Deep-Dive/Systems/Ideate/Prioritize/SKTPG, + Docs/Maintenance/License/Diff/Fits-Stack, + Similar/Versus/Synergies/Connections/Combine, + Ask/Canvas. No sense of what to read first or in what order. +2. **No narrative, weak wayfinding.** The Verdict landing tries to be everything (11 stacked sections, flat hierarchy); the **Decision control (Adopt/Trial/Hold/Reject) is buried ~2000px down**; key info is *previewed* on Verdict but *fully* rendered elsewhere with no jump links; fit verdict, red flags, and tech stack each render in two places. +3. **Opaque "lenses," hidden prerequisites.** "Lens" is never explained; Canvas silently needs Deep Dive first; library tabs need 2+ scans; multi-stage runs give no progress/ETA. + +## Goals + +- Reorganize the output tab into a **four-act narrative**: **Decide → Understand → Go Deeper → Act**. +- Add real hierarchy, wayfinding (preview → jump), and lens clarity (label + prerequisite + time estimate + live progress). +- **Preserve every piece of information**, all functionality, all deep links, and per-repo position recall. Nothing is removed. + +## Non-goals + +- No rewrite of individual section internals or the analysis pipeline (`background.js` runners, prompts, parsers stay as-is). +- No gamification / motion juice (that is Pillar 3). +- No settings redesign, no new analysis features. +- **One folded-in exception:** the small circular library↔output navigation fix (it is central to "flow" and cheap). + +## Structure: chosen approach + +**Four Acts, two-tier navigation.** Four primary acts as the top-level nav; each act opens its own focused, bounded view containing its grouped sections. The user always knows which act they are in; never an endless scroll. Keyboard navigation preserved. Cleanest fit for the zero-build codebase. + +## The four acts — complete section mapping + +Every current destination keeps a home. "Default" = shown immediately after a scan; "On-demand" = user triggers an AI run. + +### ① DECIDE — *"should I use this, and what do I do about it?"* (the landing) + +| Element | Default/On-demand | Notes | +|---|---|---| +| Fit verdict (level + label + why) | Default | Anchored at top | +| Bottom line (one-liner) | Default | | +| **Decision control** (Adopt/Trial/Hold/Reject + note) | Default | **Moved to the top** (was buried at page bottom) | +| At-a-glance facts (health score, stars/license/language, pros/cons/flag counts) | Default | Compact summary row | +| Top red flags (up to 3) | Default | Distinct "warning" treatment; link to full list in Understand | +| Where-to-start cards (`start_here`) | Default (if present) | | +| Since-last-scan diff callout | Default (if prior scan) | fit/health change | +| "Worth noting" highlights | Default | Now **anchor** to their home section (no context-thrash navigation) | + +### ② UNDERSTAND — *deep reading; all pre-computed, no waiting* + +| Element | Default/On-demand | Notes | +|---|---|---| +| ELI5 (+ analogies) | Default | | +| Technical | Default | | +| Use Cases (4-grid) | Default | | +| Skip If (4-grid) | Default | | +| Enables | Default | | +| Pros / Cons (full) | Default | Verdict shows counts → jump here | +| Red Flags (full list) | Default | Decide shows top 3 → jump to the canonical full list here | +| Alternatives | Default | | +| Health (full: 4 signals + summary) | Default | **Add metric explanations** (what each signal means) | +| Tech Stack (full: built_with + key_dependencies) | Default | Verdict shows language chips → jump here | + +De-duplication rule: where Verdict shows a preview (fit, top flags, tech stack), the **full** version lives here and Verdict links to it. One source of truth per element. + +### ③ GO DEEPER — *on-demand lenses about THIS repo; each a labeled card* + +Each lens renders as a card with: **name · one-line "what it does" · prerequisite badge (if any) · time estimate · live stage progress.** + +| Lens | Prerequisite | Notes | +|---|---|---| +| Deep Dive (atoms → lineage → Feynman) | — | ~90s, 3 stages with progress | +| Canvas / Blueprint | **Needs Deep Dive** | prereq badge shown | +| Systems (PDCA/DMAIC/Loops/TOC) | — | framework chips | +| Ideate (SCAMPER/Lateral/TRIZ/Morph) | — | framework chips | +| Prioritize (Eisenhower/Pareto) | — | framework chips | +| SKTPG | — | auto-run by default (toggle) | +| Docs Quality | — | | +| Maintenance | — | can be slow on large repos; show progress | +| License | library context | | +| Since Last Scan | prior scan | | + +### ④ ACT — *do something with it* + +| Element | Notes | +|---|---| +| Save | clear saved-state feedback | +| Ask this repo | requires a completed scan — state this up front | +| Share | | +| **Against your library:** Similar · Versus · Synergies · Connections · Combine · Fits-My-Stack | Honest "needs N scans" unlock states. The **deeper, gamified treatment of these is Pillar 3**; here they get a clean home + honest states. | + +## Navigation & interaction + +- **Persistent header** — repo name, meta pills (stars/license/language), fit chip — always visible across acts. +- **Primary nav** — four acts (`DECIDE · Understand · Go Deeper · Act`). Default landing = **Decide**. +- **Secondary nav within an act** — for Understand, a section list with hierarchy; for Go Deeper / Act, a grid of labeled cards. +- **Keyboard** — `1`–`4` select acts; within-act secondary keys for sections; preserve existing `r` (rerun), `f` (fresh), `l` (library), `o` (open source). +- **Deep-linking** — new hash scheme (`#decide`, `#understand/health`, `#deeper/deep-dive`, `#act/versus`). A **legacy slug map** translates every old `#slug` to its new act/section so existing links and bookmarks still resolve. +- **Per-repo recall** — extend the stored position (`repolens_tab_`) to remember act + section. + +## Component design (for isolation + testability) + +Extract a **pure act-model module** (e.g. `output-acts.js`), no DOM/network, exporting: + +- `ACTS` — the ordered acts and the sections grouped under each. +- `sectionToAct(sectionId)` — which act owns a section. +- `routeForHash(hash)` / `hashForRoute(act, section)` — round-trippable hash routing. +- `LEGACY_SLUG_MAP` + `resolveLegacySlug(slug)` — old `#slug` → new route. +- `keyboardMap` — key → act/section. + +`output-tab.js` consumes this module to render the act shell and route; section render functions stay as-is and mount into act containers. This keeps the routing/grouping logic unit-testable independently of the DOM. + +## Constraints honored + +- **Zero-build, zero-dep, vanilla ES modules.** Reorganize `output-tab.html` + `output-tab.js`; no framework, no bundler, no new runtime deps. +- **Brand = Mono Ink**, stop-slop/human voice, **no emoji on product surfaces**, motion behind `prefers-reduced-motion` (reuse `--dur-*` / `--ease-*` tokens). +- **No DOM test environment** — pure logic to vitest; DOM/SW glue via `node --check` + a `*-demo.html` harness. +- **No `background.js` contract changes** — message types (`DEEP_DIVE`, `SKTPG`, `MAINTENANCE`, …) are unchanged; this is a front-end reorganization only. + +## Testing + +- **vitest (pure):** act-model completeness (every current slug maps to exactly one act/section), legacy-slug resolution, hash round-trip, keyboard map. +- **`node --check`** on `output-tab.js` / HTML glue. +- **Visual:** an `output-tab` demo harness (`*-demo.html`); Playwright screenshots at 320 / 768 / 1024 / 1440; reduced-motion behavior; accessibility (keyboard nav, focus order, contrast). +- Existing suite stays green; `eslint .` 0 errors; HTML parse gate passes. + +## Migration / rollout + +1. Build the pure act-model module + the act shell + routing (tested first). +2. Move sections into acts group-by-group, keeping tests green at each step. +3. Add the legacy-hash redirect so existing `#slug` links resolve. +4. Preserve auto-save, lens runners, and all message contracts (front-end only). + +## Acceptance criteria + +- [ ] All ~28 destinations reachable, grouped into the four acts. +- [ ] Decision control lives in Decide, visible without scrolling. +- [ ] No element rendered twice as a source of truth — previews jump to the canonical section. +- [ ] Every lens shows what-it-does + prerequisite + time estimate + live progress. +- [ ] Old deep links resolve via the legacy map; keyboard nav works; per-repo recall works. +- [ ] Verdict landing is scannable with clear hierarchy. +- [ ] All existing tests pass + new act-model tests; `eslint .` 0 errors; HTML gate passes. + +## Resolved decisions + +- Structure = Four Acts, two-tier nav. +- Decision control → top of Decide. +- Library-relational features → Act (deeper gamified treatment deferred to Pillar 3). +- Circular library↔output nav fix folded into A. From 2a4fce3395394bde23b23a40493240973e75eade Mon Sep 17 00:00:00 2001 From: ares <285551516+New1Direction@users.noreply.github.com> Date: Tue, 16 Jun 2026 18:30:45 -0700 Subject: [PATCH 02/13] docs(plan): output-tab Four-Act narrative implementation plan Bite-sized TDD plan: pure output-acts.js model (full code + tests), two-tier nav, act-aware show(), then targeted UX fixes (decision-to-top, highlights anchor, previews jump, run-all relocation) + circular library nav. Keeps all panels/render/show + deep links; no background.js changes. Includes a rendered HTML overview for review. --- .../2026-06-16-output-tab-four-acts.html | 183 ++++++ .../plans/2026-06-16-output-tab-four-acts.md | 577 ++++++++++++++++++ 2 files changed, 760 insertions(+) create mode 100644 docs/superpowers/plans/2026-06-16-output-tab-four-acts.html create mode 100644 docs/superpowers/plans/2026-06-16-output-tab-four-acts.md diff --git a/docs/superpowers/plans/2026-06-16-output-tab-four-acts.html b/docs/superpowers/plans/2026-06-16-output-tab-four-acts.html new file mode 100644 index 0000000..8036db7 --- /dev/null +++ b/docs/superpowers/plans/2026-06-16-output-tab-four-acts.html @@ -0,0 +1,183 @@ + + + + + + Output Tab — Four-Act Narrative — Implementation Plan + + + +
+ +
+

Output Tab — Four-Act Narrative

+
+ Implementation plan · Pillar A · 2026-06-16 · branch feat/output-tab-four-acts
+ Overview for review. The exact step-by-step code (TDD steps, commands, commits) lives in the companion .md. +
+
+ +
+ Goal. Restructure the flat 28-tab nav into a four-act narrative (Decide → Understand → Go Deeper → Act) — keeping every panel, render function, and deep link — via a pure act-model module and a two-tier nav, then a few targeted UX fixes. +
+ +

Architecture

+

Keep the existing #t0#t27 panels, their render functions, and show(n) behavior. Add a pure, unit-tested output-acts.js that groups tab indices into four ordered acts. Replace the flat nav markup with a two-tier nav (primary act row + a secondary row showing only the active act's tabs), generated from the model. Make show(n) also highlight the owning act and render its secondary row. No background.js / message-contract changes.

+ +
+ Why this is lower-risk than a rewrite (confirmed by reading the code): +
    +
  • Slugs already exist (TAB_SLUGS) and show() already writes the hash + per-repo recall — so deep links and restore already work; the model just adds "which act owns this tab."
  • +
  • Lens labeling already exists — per-tab BEST-FOR / SKIP-IF / COST tooltips + the "?" guide + Deep-Dive staged progress. Mostly a matter of surfacing under Go Deeper, not new work.
  • +
  • The nav is one block + one click handler — swapping flat→two-tier is contained.
  • +
+
+
+ One coupling fixed: show() currently toggles panels by DOM index (idx === n), relying on panel order matching tab number. Task 4 switches to selecting by id (#t{n}) so it stays correct regardless of order. +
+ +

The four acts (tab grouping)

+ +

All 28 indices map to exactly one act (verified by a unit test).

+ +

Tasks

+ +
+ Phase 1 — Foundation +
+
Task 1 · Pure act model create
+
output-acts.js + tests/output-acts.test.js
+
Full TDD: ACTS, TAB_LABELS, actForTab(), tabsForAct(), ACT_ORDER. Tests assert every index 0–27 is covered exactly once, plus helper correctness.
+
+
+ +
+ Phase 2 — Two-tier nav +
+
Task 2 · Nav containers + styles modify
+
output-tab.html
+
Replace the flat .tab-nav + dropdown menus with two containers (#act-nav, #act-subnav) and Mono-Ink styles (secondary row reuses .tab-btn).
+
+
+
Task 3 · Render the nav from the model modify
+
output-tab.js
+
Import the model; renderActNav() (primary acts) + renderSubNav(actId) (active act's tabs). Buttons keep data-tab so the existing show() path is reused.
+
+
+ +
+ Phase 3 — Routing +
+
Task 4 · show() selects by id + tracks the act modify
+
output-tab.js
+
Panels by #t{n}; set the active act button + render/mark its secondary row; hash + per-repo recall kept verbatim.
+
+
+
Task 5 · Two-tier click handling + tooltips modify
+
output-tab.js
+
Act click → show its first tab; subnav click → show(n). Remove the old dropdown handlers; re-point the explainer tooltips at the persistent #act-subnav (delegated, survives re-renders).
+
+
+
Task 6 · Deep-link/restore order modify if needed
+
output-tab.js
+
Ensure renderActNav() runs before the initial hash/recall route resolves; show() handles the rest.
+
+
+ +
+ Phase 4 — Targeted UX fixes +
+
Task 7 · Decision control to the top of Decide modify
+
output-tab.js, output-tab.html
+
Re-anchor the Adopt/Trial/Hold/Reject block after the fit chip + bottom line (was buried at the bottom). Internals unchanged.
+
+
+
Task 8 · Highlights anchor, not cross-navigate modify
+
output-tab.js (renderHighlights)
+
A highlight click switches to its section and scrolls it into view (reduced-motion aware) instead of silently swapping context.
+
+
+
Task 9 · Previews jump to canonical (dedupe) modify
+
output-tab.js
+
Ensure each Verdict preview (tech stack, top flags) has a jump to its full section (15, 8). Previews stay — one source of truth.
+
+
+
Task 10 · "Run all lenses" in the Go-Deeper subnav modify
+
output-tab.js (renderSubNav)
+
Relocate the run-all control (from the removed Lenses dropdown) into the Go-Deeper secondary row.
+
+
+ +
+ Phase 5 — Folded-in journey win +
+
Task 11 · Circular library ↔ output nav modify
+
output-tab.js, library.js
+
One clear, reversible path each way (focus/reuse an existing tab rather than orphaning new ones).
+
+
+ +
+ Phase 6 — Verification +
+
Task 12 · Full pass
+
vitest run (857 + 5 new) · eslint . 0 errors · check:html · node --check · Playwright screenshots at 320/768/1024/1440 + deep-link, keyboard, reduced-motion, a11y checks.
+
+
+ +

Spec coverage & honest gaps

+ + +

Out of scope (per spec)

+

Gamification/juice (Pillar 3), settings redesign, new analysis features, rewriting section internals or the analysis pipeline.

+ +
RepoLens · Pillar A implementation plan · review, then execute task-by-task (subagent-driven or inline).
+ +
+ + diff --git a/docs/superpowers/plans/2026-06-16-output-tab-four-acts.md b/docs/superpowers/plans/2026-06-16-output-tab-four-acts.md new file mode 100644 index 0000000..45a4172 --- /dev/null +++ b/docs/superpowers/plans/2026-06-16-output-tab-four-acts.md @@ -0,0 +1,577 @@ +# Output Tab — Four-Act Narrative — Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Restructure the output tab's flat 28-tab nav into a four-act narrative (Decide → Understand → Go Deeper → Act) — keeping every panel, render function, and deep link — by introducing a pure act-model module and a two-tier nav, then a few targeted UX fixes. + +**Architecture:** Keep the existing `#t0`–`#t27` panels, their render functions, and `show(n)` **unchanged in behavior**. Add a pure, unit-tested `output-acts.js` that groups tab indices into four ordered acts. Replace the flat `.tab-nav` markup with a two-tier nav (primary act row + a secondary row showing only the active act's tabs), generated from the act model. Make `show(n)` also highlight the owning act and render its secondary row. Layer on targeted UX fixes (decision-to-top, previews→jumps, highlights-anchor) as isolated tasks. No `background.js` / message-contract changes. + +**Tech Stack:** Vanilla ES modules (zero-build, no deps), Vitest (pure logic only — no DOM env), `node --check` for DOM glue, existing `*-demo.html` harness + Playwright for visual checks. Brand: Mono Ink, motion behind `prefers-reduced-motion` (`--dur-*`/`--ease-*` tokens already in `themes.css`). + +--- + +## Why this is lower-risk than a rewrite + +Confirmed by reading the current code: +- **Slugs already exist** (`TAB_SLUGS` in `output-tab.js:2200`) and `show()` already writes `#slug` + persists `repolens_tab_`. So existing deep links and per-repo recall **already work** — the act model only adds "which act owns this tab" on top. +- **Lens labeling already exists** — `initScanTips()` (`output-tab.js:2257`) shows BEST-FOR / SKIP-IF / COST tooltips per tab, and the `?`-guide lists every lens with cost. Deep Dive already has staged progress (`ddProgressHtml`). So "label lenses" is mostly **surfacing what exists** under the Go-Deeper act, not new work. +- The nav is a single `.tab-nav` block (`output-tab.html:845-885`) and one click handler (`output-tab.js:2231`). Swapping flat→two-tier is contained. + +⚠️ **One coupling to fix:** `show(n)` toggles panels via `forEach((c, idx) => ... idx === n)` (`output-tab.js:2212`) — it relies on `.tab-content` DOM order matching the tab index. Today that holds (`#t0`…`#t27` are in order). Task 6 changes this to select by id (`#t${n}`) so it stays correct regardless of DOM order. + +--- + +## File Structure + +- **Create** `output-acts.js` — pure act model: `ACTS`, `TAB_LABELS`, `actForTab()`, `tabsForAct()`, `ACT_ORDER`. No DOM, no imports. One responsibility: the tab↔act grouping + labels. +- **Create** `tests/output-acts.test.js` — completeness + helper tests. +- **Modify** `output-tab.html` — replace the `.tab-nav` inner markup (845-885) with two-tier containers (`#act-nav`, `#act-subnav`); keep all `#t0`–`#t27` panels untouched. +- **Modify** `output-tab.js` — import the act model; render the two-tier nav; make `show(n)` select panels by id and set the active act + secondary row; update the nav click handler. +- **Modify** the verdict/decision render in `output-tab.js` (Task 8) — move decision control to the top. +- **Modify** `renderHighlights` in `output-tab.js` (Task 10) — anchor instead of cross-navigate. + +--- + +## Phase 1 — Foundation: the pure act model + +### Task 1: Create the act model + +**Files:** +- Create: `output-acts.js` +- Test: `tests/output-acts.test.js` + +- [ ] **Step 1: Write the failing test** + +```js +// tests/output-acts.test.js +import { describe, it, expect } from 'vitest'; +import { ACTS, ACT_ORDER, TAB_LABELS, actForTab, tabsForAct } from '../output-acts.js'; + +describe('act model', () => { + it('orders the four acts', () => { + expect(ACT_ORDER).toEqual(['decide', 'understand', 'deeper', 'act']); + }); + + it('covers every tab index 0..27 exactly once', () => { + const all = ACTS.flatMap((a) => a.tabs).sort((x, y) => x - y); + expect(all).toEqual(Array.from({ length: 28 }, (_, i) => i)); + expect(new Set(all).size).toBe(28); // no duplicates + }); + + it('maps a tab to its owning act', () => { + expect(actForTab(9)).toBe('decide'); + expect(actForTab(7)).toBe('understand'); // Health + expect(actForTab(10)).toBe('deeper'); // Deep Dive + expect(actForTab(17)).toBe('act'); // Versus + expect(actForTab(99)).toBeNull(); + }); + + it('lists tabs for an act in display order', () => { + expect(tabsForAct('decide')).toEqual([9]); + expect(tabsForAct('understand')[0]).toBe(0); // ELI5 leads + expect(tabsForAct('nope')).toEqual([]); + }); + + it('has a label for every tab it groups', () => { + for (const t of ACTS.flatMap((a) => a.tabs)) { + expect(typeof TAB_LABELS[t]).toBe('string'); + expect(TAB_LABELS[t].length).toBeGreaterThan(0); + } + }); +}); +``` + +- [ ] **Step 2: Run it and confirm it fails** + +Run: `npx vitest run tests/output-acts.test.js` +Expected: FAIL — `Cannot find module '../output-acts.js'`. + +- [ ] **Step 3: Write the module** + +```js +// output-acts.js +// Pure act model for the output tab. Groups the existing tab indices (the #t0..#t27 +// panels) into four ordered "acts" — Decide, Understand, Go Deeper, Act — for a +// two-tier nav. No DOM, no network, no imports: this is the testable contract the +// nav rendering and show() build on. Tab indices and slugs are unchanged from the +// existing TAB_SLUGS, so deep links and per-repo recall keep working. + +export const ACTS = [ + { id: 'decide', label: 'Decide', tabs: [9] }, + { id: 'understand', label: 'Understand', tabs: [0, 1, 2, 3, 4, 5, 8, 6, 7, 15] }, + { id: 'deeper', label: 'Go Deeper', tabs: [10, 27, 11, 12, 13, 14, 21, 22, 23, 24] }, + { id: 'act', label: 'Act', tabs: [25, 16, 17, 18, 19, 20, 26] }, +]; + +export const ACT_ORDER = ACTS.map((a) => a.id); + +// Tab index → human label (mirrors the current nav button text; used to render +// the secondary row from the model instead of hardcoded HTML). +export const TAB_LABELS = { + 9: 'Verdict', + 0: 'ELI5', 1: 'Technical', 2: 'Use Cases', 3: 'Skip If', 4: 'Enables', + 5: 'Pros / Cons', 8: 'Red Flags', 6: 'Alternatives', 7: 'Health', 15: 'Tech Stack', + 10: 'Deep Dive', 27: 'Canvas', 11: 'Systems', 12: 'Ideate', 13: 'Prioritize', + 14: 'SKTPG', 21: 'Docs Quality', 22: 'Maintenance', 23: 'License', 24: 'Since Last Scan', + 25: 'Fits MY Stack?', 16: 'Similar', 17: 'Versus', 18: 'Synergies', + 19: 'Connections', 20: 'Combine', 26: 'Ask', +}; + +const ACT_BY_TAB = (() => { + const m = {}; + for (const a of ACTS) for (const t of a.tabs) m[t] = a.id; + return m; +})(); + +/** @returns {string|null} the act id owning tab `n`, or null. */ +export function actForTab(n) { + return Object.prototype.hasOwnProperty.call(ACT_BY_TAB, n) ? ACT_BY_TAB[n] : null; +} + +/** @returns {number[]} the tab indices in an act, in display order. */ +export function tabsForAct(id) { + const a = ACTS.find((x) => x.id === id); + return a ? a.tabs : []; +} +``` + +- [ ] **Step 4: Run tests and confirm they pass** + +Run: `npx vitest run tests/output-acts.test.js` +Expected: PASS (5 tests). + +- [ ] **Step 5: Lint the new module** + +Run: `npx eslint output-acts.js tests/output-acts.test.js` +Expected: 0 errors. + +- [ ] **Step 6: Commit** + +```bash +git add output-acts.js tests/output-acts.test.js +git commit -m "feat(output): pure four-act model for the output tab" +``` + +--- + +## Phase 2 — Two-tier nav + +### Task 2: Replace the flat nav markup with two-tier containers + +**Files:** +- Modify: `output-tab.html:845-885` (the `.tab-nav` block) + +- [ ] **Step 1: Replace the markup** + +Replace the entire `
` block (current lines 845-885, the flat buttons + Lenses/Library menus) with two empty containers that `output-tab.js` will populate from the act model: + +```html + + +
+``` + +- [ ] **Step 2: Add the nav styles** + +Add to the `