Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions docs/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@

### Build lane
- **Where:** its own worktree per piece, on a branch from an up-to-date `main`. If the session isn't in a worktree yet (`git worktree list` shows its folder as the main checkout, not under `.claude/worktrees/`), it creates one before touching anything, and never checks out a branch in the main folder, where the measurement lane works. Claude Code's worktree option puts it under `.claude/worktrees/`; run `npm ci` there first. A worktree made with `git worktree add` gets no `.env.local`: run `npm run env:local` there, or the end-to-end tests find no interviews. Its browser check uses `app-build` in `.claude/launch.json` (port 3200), never `app` or `app-real`, which are the measurement lane's on port 3000. It never runs `measure`, `measure:fake` or `dev:real`, never edits the measurement lane's files above, and changes code in `src/server` only where its piece needs it, never what the model receives (listed above); its pull request says which `src/server` files it changed and why.
- **Doing:** the GIF's click, on `docs/readme-video-link` (`.claude/worktrees/readme-video`), from `main` at 8c410ca, waiting for the owner's push and pull request. The README's GIF is merged (d8e39c8, with 42f2002 recording slice 24's merge and 8c410ca planning slices 25 and 26), but its click opened GitHub's file page for the MP4, which doesn't play videos ("we can't show files that are this big right now", at 2.5 MB), and the raw file downloads as `application/octet-stream` (checked 2026-10-22). So the click now opens the same MP4 through GitHub's own video hosting: the owner uploaded it on 2026-10-22 (https://github.com/user-attachments/assets/e7412df8-9fca-4f2a-b3f0-89b2c3291125; GitHub, *Attaching files*: MP4 up to 10 MB on a free plan, H.264 recommended, public for a public repository, read 2026-10-22 through Context7). Until it's posted, the upload is the uploader's alone: signed out, the link answered 404 (2026-10-22), so the pull request's description carries the link, which publishes it; check that it plays signed out before the merge. The GIF is `docs/media/prd-assistant-demo.gif` (960×540, 15 fps, 4.8 MB, looping), and the MP4 stays in the repository as the source copy, `docs/media/prd-assistant-demo.mp4` (1920×1080, 30 fps, 318 frames, silent). Both are a 10.6-second motion piece about the interface, made in Remotion 4.0.538 (free for an individual under its licence, checked 2026-10-22) in its own project next to this one, `D:\IT_Projects\Web Dev\prd-assistant-video`, outside the repository: the owner chose, on 2026-10-22, the interface's look and behaviour on black over a recording of the app, with invented sample content, so the README calls it an illustration. Its copy, colours and timings are in that project's `src/config.ts`; `npx remotion render PrdAssistantDemo out/prd-assistant-demo.mp4 --codec=h264 --crf=16 --image-format=png`, and for the GIF `--codec=gif --every-nth-frame=2 --scale=0.5`. Checked: the frame counts and sizes, and every frame around each transition from the MP4. Nobody has seen it play on GitHub yet.
- **Doing:** slice 25, the shared motion values and what arrives, is done on `feat/motion-arrivals` (`.claude/worktrees/slice-25-motion`), from `main` at a4d5574 (the GIF's click merged), waiting for the owner's look, push and merge. Local checks on 2026-10-22: `verify` (574 unit tests, 20 new) and `test:e2e` (77, 8 new, which then passed five more runs each) passed; two recordings of the whole scenario tour on a production build, read frame by frame around each arrival (`src/features/AGENTS.md`, *Checking motion by recording it*): the chat and then the PRD rising in as the intro gives way, the visitor's message springing from its corner, each line, the saved line's tick drawing itself with its ring, the statements one after another, the tables, the notices and Jump to latest, all settling without a jump, the conversation above them still; nothing arriving after a reload; no long animation frames during the tour, two at page load. Fixed on the way: a folded run's hidden labels stretched the chat below its last line (on `main` too: blank space under a run that was the answer's last line), the chat sank back as an arriving last line settled, and a pane's rise and delay passed to everything in it. It changes no file in `src/server` or `src/lib`, so nothing the model receives.
- **The README's demo** (merged, a4d5574): `docs/media/prd-assistant-demo.gif` and its source copy `prd-assistant-demo.mp4`, a motion piece about the interface made in Remotion 4.0.538 in its own project, `D:\IT_Projects\Web Dev\prd-assistant-video`, outside the repository; its copy, colours and timings are in that project's `src/config.ts`. `npx remotion render PrdAssistantDemo out/prd-assistant-demo.mp4 --codec=h264 --crf=16 --image-format=png`, and for the GIF `--codec=gif --every-nth-frame=2 --scale=0.5`. The GIF's click opens the MP4 through GitHub's own video hosting.
- **Next:**
1. Slice 25, then slice 26: the app's motion after the demo video (Design, 2026-10-22), each on its own branch from `main` once this branch is merged; one session each.
1. Slice 26, the words, the fold and the pop-over, on its own branch from `main` once `feat/motion-arrivals` is merged; one session. Its curves are in `src/app/globals.css` already (the pop-over's spring and fade).
2. Slice 8, the rate limit, once 9d is done and the owner has decided its legal basis and size (*Deferred*).
- **Unverified:** on staging, a reload keeping the PRD and the downloaded file (local Chromium only); a stop ending the answer on Cloudflare too, where the call in flight may still be finished and counted; the quota message against Cloudflare's real refusal (the tests replay its reply of 2026-10-20) and whether its per-minute 429 carries a retry header; a source name's pop-over, "Your decision, not from the interviews." under a claim of the visitor's, the table fix and the intro screen; Safari and Firefox (only Chromium ran; without anchor positioning the pop-over is a centred box, by design, and without `field-sizing`, before Safari 26.2 and Firefox 152, the message box keeps its three lines; the moving band, whose fallback is the still grey line; the PRD's highlight and rolling count; Jump to latest; the folded line's slide, which falls back to showing at once; the words' fade; the copy button, its label and the clipboard; Inter and its resized fallback, which needs Arial installed, so Linux and Android show the system's font until Inter arrives; a table's cells keeping their 144px and its box's sideways scroll; the Thinking line's band). On staging, a real reply's table, and the Thinking line through the real model's waits with the times it shows (the fake model's are about 0s). On staging, a reply that arrives whole fading in as one, and a section's copy over HTTPS pasted into another app. Expect the Security Advisor's lint 0028 on `search_passages` on staging; it's intended (`supabase/AGENTS.md`). Production waits for launch and its Cloudflare token.
- **Waiting on the owner:** pushing `docs/readme-video-link` and opening its pull request with the video's link in the description, then the merge once the link plays signed out; whether `next dev` may keep adding its block to `AGENTS.md` (KI-8); the GitHub description and topics whenever they like.
- **Unverified:** on staging, a reload keeping the PRD and the downloaded file (local Chromium only); a stop ending the answer on Cloudflare too, where the call in flight may still be finished and counted; the quota message against Cloudflare's real refusal (the tests replay its reply of 2026-10-20) and whether its per-minute 429 carries a retry header; a source name's pop-over, "Your decision, not from the interviews." under a claim of the visitor's, the table fix and the intro screen; Safari and Firefox (only Chromium ran; without anchor positioning the pop-over is a centred box, by design, and without `field-sizing`, before Safari 26.2 and Firefox 152, the message box keeps its three lines; the moving band, whose fallback is the still grey line; the PRD's highlight and rolling count; Jump to latest; the folded line's slide, which falls back to showing at once; the words' fade; the copy button, its label and the clipboard; Inter and its resized fallback, which needs Arial installed, so Linux and Android show the system's font until Inter arrives; a table's cells keeping their 144px and its box's sideways scroll; the Thinking line's band; what arrives, on `linear()` and `@property`, whose plain fallbacks are an ease-out and, without `@property`, a pane's rise and delay passing to what's in it). Motion on a phone and a slow machine (only headless Chromium on this one). On staging, how arrivals look at the real model's pace, a real reply's table, and the Thinking line through the real model's waits with the times it shows (the fake model's are about 0s). On staging, a reply that arrives whole fading in as one, and a section's copy over HTTPS pasted into another app. Expect the Security Advisor's lint 0028 on `search_passages` on staging; it's intended (`supabase/AGENTS.md`). Production waits for launch and its Cloudflare token.
- **Waiting on the owner:** a look at the motion (`npm run dev:replay` and its tour, from the worktree on port 3200), then pushing `feat/motion-arrivals`, its pull request and the merge; whether `next dev` may keep adding its block to `AGENTS.md` (KI-8); the GitHub description and topics whenever they like. Merged and identical to `main`, `docs/readme-video-link` and its worktree `.claude/worktrees/readme-video` can go; this session, fenced into its own worktree, couldn't remove another.

### Shared rules
- One branch per piece, from an up-to-date `main`; the owner pushes it, opens the pull request and merges it (`AGENTS.md`, Branches). After the other lane's merge, rebase an unpushed branch onto `main`, and merge `main` into a pushed one; never rewrite a pushed branch.
Expand Down Expand Up @@ -121,9 +122,9 @@

### 24 · A tour of every state the chat and the PRD can show · risk: normal · status: done (8a03a22)

<!-- Slices 25 and 26, the app's motion after the README's demo video (docs/decisions.md, Design, 2026-10-22). The video's motion, to match: `D:\IT_Projects\Web Dev\prd-assistant-video`, `src/Showcase.tsx` and `src/ui/motion.ts`. It was drawn at about twice the app's size, so halve its distances and blurs. Its springs (Remotion's `spring`): damping 16, mass 0.7, stiffness 120 for small pieces; 15, 0.6, 140 for the pop-over; 18, 0.9, 90 for larger panes. Its eases: cubic-bezier(0.16, 1, 0.3, 1) out and (0.65, 0, 0.35, 1) in and out. CSS and the React the app has, no animation library; check MDN's compatibility data for `linear()`, `@starting-style` and `transition-behavior` before relying on them, with a plain fallback. The scenario tour (`npm run dev:replay`) plays every state; check the motion by recording it in Chromium and reading the frames around each change (the video project's `Strip` composition lays frames out as contact sheets). -->
<!-- Slices 25 and 26, the app's motion after the README's demo video (docs/decisions.md, Design, 2026-10-22). The video's motion, to match: `D:\IT_Projects\Web Dev\prd-assistant-video`, `src/Showcase.tsx` and `src/ui/motion.ts`. It was drawn at about twice the app's size, so halve its distances and blurs. Its springs (Remotion's `spring`): damping 16, mass 0.7, stiffness 120 for small pieces; 15, 0.6, 140 for the pop-over; 18, 0.9, 90 for larger panes. Its eases: cubic-bezier(0.16, 1, 0.3, 1) out and (0.65, 0, 0.35, 1) in and out. CSS and the React the app has, no animation library; check MDN's compatibility data for `linear()`, `@starting-style` and `transition-behavior` before relying on them, with a plain fallback. The scenario tour (`npm run dev:replay`) plays every state; check the motion by recording it in Chromium and reading the frames around each change (how slice 25 did it: `src/features/AGENTS.md`, *Checking motion by recording it*). -->

### 25 · Motion from the demo video: the shared curves and arrivals · risk: normal · status: todo
### 25 · Motion from the demo video: the shared curves and arrivals · risk: normal · status: done (on `feat/motion-arrivals`; its id on `main` goes here after the merge)
- **Goal:** what appears in the chat and the PRD arrives the way it does in the README's video, not in a jump.
- **Acceptance:**
- One set of motion values in `src/app/globals.css`: the video's springs replayed with `linear()`, its two eases, and the durations; the fold's slide, the rolling count, the copy label and the just-changed highlight use them too.
Expand Down
Loading
Loading