9eadbcea
docs: require sprint review pages and record appearance approval
a73x 2026-09-06 05:16
Commit message
RETRO.md
| Old | New | ||
|---|---|---|---|
| @@ -806,12 +806,12 @@ and decoded popup frame. The video, screenshot, scripts, logs, reports and | |||
| 806 | available cumulative agent counters live under `dist/appearance-slice1/` in this | 806 | available cumulative agent counters live under `dist/appearance-slice1/` in this |
| 807 | worktree. Counters identify cached input as included, and are neither an | 807 | worktree. Counters identify cached input as included, and are neither an |
| 808 | incremental slice cost nor a monetary bill. No external publication occurred. | 808 | incremental slice cost nor a monetary bill. No external publication occurred. |
| 809 | User demo acceptance remains pending. | 809 | Recorded demo acceptance was subsequently given on 2026-09-05, as noted below. |
| 810 | 810 | ||
| 811 | ### Retained limits and next actions | 811 | ### Retained limits and next actions |
| 812 | 812 | ||
| 813 | - [ ] Record the user's review of the appearance demo separately from test | 813 | - [x] Record the user's review of the appearance demo separately from test |
| 814 | success, before moving to config/fonts. | 814 | success: the recorded demo was approved on 2026-09-05; config/fonts follows. |
| 815 | - [ ] In the config slice, restore `theme.legacy` as the no-config default and | 815 | - [ ] In the config slice, restore `theme.legacy` as the no-config default and |
| 816 | explicitly select a trial theme in appearance fixtures. Keep CLI precedence | 816 | explicitly select a trial theme in appearance fixtures. Keep CLI precedence |
| 817 | and font-size units consistent with the agreed Ghostty-compatible subset. | 817 | and font-size units consistent with the agreed Ghostty-compatible subset. |
| @@ -827,3 +827,27 @@ User demo acceptance remains pending. | |||
| 827 | - [ ] Keep NVIDIA as the relevant performance validation target for this user. | 827 | - [ ] Keep NVIDIA as the relevant performance validation target for this user. |
| 828 | The stress frame metric includes test readback and vsync; preserve failed | 828 | The stress frame metric includes test readback and vsync; preserve failed |
| 829 | results and distinguish a matched baseline comparison from an absolute pass. | 829 | results and distinguish a matched baseline comparison from an absolute pass. |
| 830 | |||
| 831 | ## Sprint review-page handoff — 2026-09-05 | ||
| 832 | |||
| 833 | The user asked to retain the established webpage handoff with achievement notes | ||
| 834 | and an embedded demo, and explicitly requested updating the sprint document. | ||
| 835 | `docs/native-sprint-workflow.md` now requires that page as the primary review | ||
| 836 | link for each functional slice: goal, achievements, recording, controls/review | ||
| 837 | prompts, validation and open issues, next scope and acceptance state. The source | ||
| 838 | and assets must be retained and page loading, metadata and seeking verified. | ||
| 839 | |||
| 840 | The appearance page lives at `docs/demos/native-appearance-slice1.html`. Luna | ||
| 841 | created it; Terra reviewed claim accuracy and the handoff requirement. Root | ||
| 842 | verified actual Chromium playback/seeking, desktop/mobile layout, canonical | ||
| 843 | redirects and HTTP ranges. The page keeps the NVIDIA timing limit unresolved. | ||
| 844 | Automatic approval review rejected publishing this payload through Tailscale; | ||
| 845 | specific user approval was requested while the completed page remained local. | ||
| 846 | Native source is unchanged, so existing functional validation applies. | ||
| 847 | |||
| 848 | - [ ] Use the review webpage as the final handoff link in future slices; keep | ||
| 849 | failed checks and pending acceptance visible beside the recording. | ||
| 850 | - [x] Record the verified private URL and route-specific teardown in the | ||
| 851 | appearance plan. The user authorised sharing sprint pages/assets on their | ||
| 852 | own tailnet as the standing handoff. The recorded demo was then explicitly | ||
| 853 | approved (“I approve the demo! Looks good.”). NVIDIA timing remains separate. | ||
docs/demos/native-appearance-slice1.html
| Old | New | ||
|---|---|---|---|
| @@ -0,0 +1,82 @@ | |||
| 1 | <!doctype html> | ||
| 2 | <html lang="en"> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8"> | ||
| 5 | <meta name="viewport" content="width=device-width, initial-scale=1"> | ||
| 6 | <title>Native appearance · slice 1</title> | ||
| 7 | <style> | ||
| 8 | :root { color-scheme: dark; --ink:#f3e8d0; --muted:#c4aa8d; --bg:#211b1a; --panel:#2b211f; --panel-2:#342824; --teal:#2f6f70; --teal-soft:#496f68; --amber:#d8a84e; --line:#76594b; } | ||
| 9 | * { box-sizing:border-box; } | ||
| 10 | body { margin:0; min-height:100vh; background:radial-gradient(circle at 78% 0,#3b2922 0,transparent 42%),var(--bg); color:var(--ink); font:16px/1.55 system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; } | ||
| 11 | main { width:min(1080px,calc(100% - 40px)); margin:0 auto; padding:58px 0 52px; } | ||
| 12 | .eyebrow { color:var(--amber); font-size:.76rem; font-weight:750; letter-spacing:.16em; text-transform:uppercase; } | ||
| 13 | h1 { max-width:760px; margin:10px 0 14px; font-size:clamp(2.2rem,6vw,4.5rem); line-height:1.02; letter-spacing:-.055em; } | ||
| 14 | .lede { max-width:690px; margin:0 0 30px; color:var(--muted); font-size:1.15rem; } | ||
| 15 | .status { display:inline-flex; align-items:center; gap:9px; padding:8px 13px; border:1px solid #8b6a4d; border-radius:999px; background:#372821; color:#ffd995; font-size:.86rem; } | ||
| 16 | .status i { width:8px; height:8px; border-radius:50%; background:var(--amber); box-shadow:0 0 0 4px #d8a84e22; } | ||
| 17 | .video-card { margin:42px 0 0; padding:14px; border:1px solid #76594b99; border-radius:20px; background:#171313aa; box-shadow:0 22px 70px #09070766; } | ||
| 18 | video { display:block; width:100%; height:auto; aspect-ratio:1100/700; border-radius:12px; background:#100d0d; } | ||
| 19 | figcaption { display:flex; flex-wrap:wrap; justify-content:space-between; gap:8px 20px; padding:13px 4px 1px; color:var(--muted); font-size:.9rem; } | ||
| 20 | a { color:#a8d6c6; text-underline-offset:3px; } | ||
| 21 | section { margin-top:52px; } | ||
| 22 | h2 { margin:0 0 16px; font-size:1.45rem; letter-spacing:-.02em; } | ||
| 23 | .grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; } | ||
| 24 | article { padding:21px; border:1px solid #76594b66; border-radius:14px; background:linear-gradient(145deg,#342824cc,#2b211fcc); } | ||
| 25 | article h3 { margin:0 0 7px; font-size:1rem; color:#ffe6b6; } | ||
| 26 | article p { margin:0; color:var(--muted); } | ||
| 27 | .review { border-left:3px solid var(--amber); padding:4px 0 4px 17px; color:#ead9bd; } | ||
| 28 | .review p { margin:0; } | ||
| 29 | table { width:100%; border-collapse:collapse; color:var(--muted); font-size:.93rem; } | ||
| 30 | th,td { padding:11px 10px; border-bottom:1px solid #76594b55; text-align:left; vertical-align:top; } | ||
| 31 | th { color:#ffe6b6; font-weight:650; } | ||
| 32 | footer { margin-top:52px; color:#9d8775; font-size:.82rem; } | ||
| 33 | @media (max-width:650px) { main { width:min(100% - 26px,1080px); padding-top:36px; } .grid { grid-template-columns:1fr; } figcaption { display:block; } figcaption span { display:block; margin-top:5px; } } | ||
| 34 | </style> | ||
| 35 | </head> | ||
| 36 | <body> | ||
| 37 | <main> | ||
| 38 | <div class="eyebrow">muxg · native appearance</div> | ||
| 39 | <h1>A warmer theme for muxg</h1> | ||
| 40 | <p class="lede">Slice 1 gives the native client a single, reusable appearance model and a cohesive hardcoded trial theme. The short recording shows the actual application running in isolated headless Sway.</p> | ||
| 41 | <div class="status"><i aria-hidden="true"></i>Recorded demo approved</div> | ||
| 42 | |||
| 43 | <figure class="video-card"> | ||
| 44 | <video controls playsinline preload="metadata" poster="preview.png" width="1100" height="700" aria-label="Native appearance slice 1 demo"> | ||
| 45 | <source src="demo.mp4" type="video/mp4"> | ||
| 46 | Your browser cannot play this video. <a href="demo.mp4">Download the demo video</a>. | ||
| 47 | </video> | ||
| 48 | <figcaption><span>27.2 seconds · 1100 × 700 · NVIDIA · isolated headless Sway at 200%</span><span>No audio · no cuts · <a href="demo.mp4">direct video</a></span></figcaption> | ||
| 49 | </figure> | ||
| 50 | |||
| 51 | <section> | ||
| 52 | <h2>What this slice achieves</h2> | ||
| 53 | <div class="grid"> | ||
| 54 | <article><h3>One source of appearance</h3><p>Native colors now come from a reusable Theme. The warm trial uses cream text, a dark brown background, muted teal focus, amber bell feedback, and a warm divider.</p></article> | ||
| 55 | <article><h3>Terminal color semantics</h3><p>Legacy defaults remain named for the later config slice. Default colors, all 256 indexed entries, inverse rendering, and explicit RGB colors keep their intended semantics.</p></article> | ||
| 56 | <article><h3>Chrome covered</h3><p>Focused and unfocused headers, cursor, dividers, picker and recovery rows, empty workspace, modal selection, and bell headers use the shared theme.</p></article> | ||
| 57 | <article><h3>Scope held steady</h3><p>There is no config, font change, hot reload, or text selection in this slice. The existing popup selection remains the only selection behavior.</p></article> | ||
| 58 | </div> | ||
| 59 | </section> | ||
| 60 | |||
| 61 | <section> | ||
| 62 | <h2>What to review</h2> | ||
| 63 | <div class="review"><p>The user approved the recorded appearance demo: “I approve the demo! Looks good.” The teal focus colour is intentional. The next slice will add config and fonts, including Nerd Font Mono, then Ghostty theme-file loading. Ligatures remain a later discussion.</p></div> | ||
| 64 | </section> | ||
| 65 | |||
| 66 | <section> | ||
| 67 | <h2>Validation</h2> | ||
| 68 | <table> | ||
| 69 | <thead><tr><th>Area</th><th>Result</th></tr></thead> | ||
| 70 | <tbody> | ||
| 71 | <tr><td>Repository checks</td><td>CI, check, native unit tests, and e2e pass.</td></tr> | ||
| 72 | <tr><td>Appearance and scale</td><td>NVIDIA appearance and scale checks pass.</td></tr> | ||
| 73 | <tr><td>Stress</td><td>Unresolved: matched theme run 1 frame p99 18.923 ms passed; run 2 frame p99 20.884 ms failed the 20 ms threshold. Baselines passed at 19.904 ms and 19.935 ms. Input stayed within 250 ms.</td></tr> | ||
| 74 | </tbody> | ||
| 75 | </table> | ||
| 76 | <p style="margin:14px 0 0;color:#9d8775;font-size:.88rem">The comparisons did not establish a consistent theme regression. The NVIDIA stress gate remains unresolved because a run exceeded the budget. An AMD headless comparison is not NVIDIA acceptance evidence.</p> | ||
| 77 | </section> | ||
| 78 | |||
| 79 | <footer>Native appearance slice 1 · review artifact · source commit 31bd57fd</footer> | ||
| 80 | </main> | ||
| 81 | </body> | ||
| 82 | </html> | ||
docs/native-sprint-workflow.md
| Old | New | ||
|---|---|---|---|
| @@ -129,6 +129,30 @@ packages. Keep one sprint active, ending in a working demo and explicit acceptan | |||
| 129 | before closing the window so another application cannot enter the recording. | 129 | before closing the window so another application cannot enter the recording. |
| 130 | A slideshow of screenshots is useful evidence but is not a screen recording. | 130 | A slideshow of screenshots is useful evidence but is not a screen recording. |
| 131 | 131 | ||
| 132 | **Deliver a review webpage for every functional slice.** The page is the | ||
| 133 | primary handoff link and contains: | ||
| 134 | |||
| 135 | - The sprint goal and a concise account of what was achieved. | ||
| 136 | - An embedded recording of the actual application, with playback controls | ||
| 137 | and a direct video link. Include duration, recording environment and any | ||
| 138 | restart cuts; a screenshot may serve as its preview. | ||
| 139 | - What the user can see or try, and any controls needed to review it. | ||
| 140 | - Validation results and open issues, clearly separating implemented, | ||
| 141 | validated and accepted work. Preserve failed checks and material limits. | ||
| 142 | - What belongs to the next slice and what feedback is needed on this one. | ||
| 143 | |||
| 144 | Keep the page usable on desktop and mobile. Retain its source beside the | ||
| 145 | sprint records and its video outside temporary fixture directories. Verify | ||
| 146 | page loading, video metadata and seeking before sharing. Use the established | ||
| 147 | private sharing route within the user's authorized scope; preserve existing | ||
| 148 | pages and services. Give the user the webpage URL in the final handoff, with | ||
| 149 | the direct video link available from the page. | ||
| 150 | |||
| 151 | The user has authorised sharing mux sprint review pages and their demo assets | ||
| 152 | privately on their own Tailscale so they can review from all their devices. | ||
| 153 | Treat that as standing authorization for this handoff; use the existing | ||
| 154 | private Serve host and preserve unrelated routes and services. | ||
| 155 | |||
| 132 | Build both demo binaries together in an isolated release prefix: | 156 | Build both demo binaries together in an isolated release prefix: |
| 133 | 157 | ||
| 134 | ```sh | 158 | ```sh |
| @@ -163,7 +187,8 @@ packages. Keep one sprint active, ending in a working demo and explicit acceptan | |||
| 163 | retain the recording outside temporary fixture directories, and record the | 187 | retain the recording outside temporary fixture directories, and record the |
| 164 | server's teardown command. Funnel and audio are unnecessary for this workflow. | 188 | server's teardown command. Funnel and audio are unnecessary for this workflow. |
| 165 | 10. **Close honestly.** Inspect the final diff, commit validated work, and provide | 189 | 10. **Close honestly.** Inspect the final diff, commit validated work, and provide |
| 166 | the demo, controls, test results, and material limits. User demo acceptance is | 190 | the review webpage with the demo, controls, test results, and material limits. |
| 191 | User demo acceptance is | ||
| 167 | distinct from passing automation. Record whether acceptance covers a recording | 192 | distinct from passing automation. Record whether acceptance covers a recording |
| 168 | or a hands-on trial, and capture any requested ergonomic adjustments separately. | 193 | or a hands-on trial, and capture any requested ergonomic adjustments separately. |
| 169 | Update the spec/plan status and RETRO.md with resolved findings and checkable | 194 | Update the spec/plan status and RETRO.md with resolved findings and checkable |
docs/superpowers/plans/2026-09-05-native-appearance.md
| Old | New | ||
|---|---|---|---|
| @@ -59,6 +59,27 @@ turn-context metadata at startup. | |||
| 59 | 59 | ||
| 60 | ## Delivery evidence | 60 | ## Delivery evidence |
| 61 | 61 | ||
| 62 | The review page source is | ||
| 63 | [`docs/demos/native-appearance-slice1.html`](../../demos/native-appearance-slice1.html). | ||
| 64 | [Private review page](https://charizard.folk-amberjack.ts.net/appearance-slice1/). | ||
| 65 | It brings the achievements, embedded demo, review prompts, validation and open | ||
| 66 | NVIDIA timing result together. The local staged page is | ||
| 67 | `dist/appearance-slice1/site/index.html`. After automatic review rejected the | ||
| 68 | initial Serve request, the user explicitly authorised sharing sprint pages and | ||
| 69 | demo assets on their own Tailscale across devices. The private HTTPS page and | ||
| 70 | video/preview range responses were verified. Remove only this route with | ||
| 71 | `tailscale serve --https=443 --set-path /appearance-slice1 off`, then stop the | ||
| 72 | owned loopback server using its recorded PID. | ||
| 73 | |||
| 74 | Chromium verified metadata (27.2 seconds, 1100×700), seeking and playback beyond | ||
| 75 | 12 seconds, and desktop/mobile layouts without horizontal overflow. The local | ||
| 76 | server verified the canonical trailing-slash redirect, HTTP 206 prefix/suffix | ||
| 77 | video ranges, HTTP 416 for an invalid range and HTTP 404 for unlisted files. | ||
| 78 | Only the page, video and preview are served. The owned loopback server uses | ||
| 79 | `127.0.0.1:18771`; its PID is retained in | ||
| 80 | `dist/appearance-slice1/page-server.pid` for teardown. Browser evidence is in | ||
| 81 | `page-browser-check.json` and `page-desktop.png` / `page-mobile.png` beside it. | ||
| 82 | |||
| 62 | Implementation and adversarial review are complete. `src/gui/theme.zig` owns | 83 | Implementation and adversarial review are complete. `src/gui/theme.zig` owns |
| 63 | native defaults, all 256 indexed entries, cursor and chrome colours. The painter | 84 | native defaults, all 256 indexed entries, cursor and chrome colours. The painter |
| 64 | accepts one theme plus explicit foreground/background overrides for chrome rows; | 85 | accepts one theme plus explicit foreground/background overrides for chrome rows; |
| @@ -149,14 +170,16 @@ stress gate remains unresolved, with no budget or refresh-rate changes made. | |||
| 149 | Input observations remained inside the independent 250 ms bound. The frame | 170 | Input observations remained inside the independent 250 ms bound. The frame |
| 150 | metric includes test framebuffer readback and vsync and does not isolate driver, | 171 | metric includes test framebuffer readback and vsync and does not isolate driver, |
| 151 | compositor or render cost. Headless evidence does not establish physical-display | 172 | compositor or render cost. Headless evidence does not establish physical-display |
| 152 | performance. This limit needs explicit resolution or scope disposition before | 173 | performance. This remains a separate renderer/validation follow-up; recorded appearance |
| 153 | calling the whole sprint accepted; the appearance implementation and functional | 174 | acceptance below does not turn it into a passed gate. |
| 154 | demo are ready for review. | ||
| 155 | 175 | ||
| 156 | The owned compositor and fixture processes were stopped; the temporary baseline | 176 | The owned compositor and fixture processes were stopped; the temporary baseline |
| 157 | checkout was removed after its reports and hashes were retained. | 177 | checkout was removed after its reports and hashes were retained. |
| 158 | 178 | ||
| 159 | User demo acceptance is pending. Config/fonts and Ghostty file loading have not | 179 | The user accepted the recorded appearance demo on 2026-09-05: “I approve the |
| 160 | started. When adding config, restore `theme.legacy` as the no-config default and | 180 | demo! Looks good.” The intentional teal focus was acknowledged. This is recorded |
| 181 | demo acceptance, not a claim of a separate hands-on trial or a waiver of the | ||
| 182 | NVIDIA stress limit. Config/fonts is the next authorised slice; Ghostty theme | ||
| 183 | file loading follows it. When adding config, restore `theme.legacy` as the no-config default and | ||
| 161 | make the theme probe explicitly select its trial fixture. Discuss ligatures only | 184 | make the theme probe explicitly select its trial fixture. Discuss ligatures only |
| 162 | after the preceding slices, as the user requested. | 185 | after the preceding slices, as the user requested. |