The plan: a new problem in hours
How long a round takes (measured)
From each round's start (its brief or COMMON.md) to its last merge commit, all UTC:
| Round | Helpers | Start | Last merge | Wall clock |
|---|---|---|---|---|
| API panel, runner, writer (board 1.0) | 3 | 27 Sep 08:45 | 09:19 | about 35 min |
| API first (board 2.0) | 4 | 27 Sep 10:55 | 16:17 | 5 h 20 min: the helpers were stopped twice (the background ceiling at 10:59, the OOM killer at 15:17) |
| API as a flow (board 3.0), contract first | 4 | 27 Sep 22:10 | 28 Sep 00:08 | about 2 h |
| After a stranger's walk (3.1) | 3 | 28 Sep 03:00 | 04:50 | about 1 h 50 min |
| His eight PDF notes (3.5) | 4 | 29 Sep 16:30 | 19:11 | about 2 h 40 min |
| His second notes (3.6) | 2 | 30 Sep 07:30 | 08:55 | about 1 h 25 min |
| Where a click is counted | 1 | 4 Oct 12:48 (his message) | 14:03 | about 1 h 15 min |
| How big companies count clicks | 1 | 4 Oct 13:27 (his message) | 15:17 | about 1 h 50 min |
A round of parallel helpers takes about one and a half to two and a half hours when nothing dies. My estimate from that:
a new problem, once the machinery is general, is about three rounds (build; a stranger's walk and its fixes; his notes),
which is hours, as he asked. Before the machinery is general it is not: see generalize.md and do that first, once.
Hour 0: one session alone
- Base. Start from
origin/mainafter every open round has merged. The checkout at~/ventures/junior-to-staffhas a localmainthat is a stale branch from 26 Sep; never branch from it. Readsite/designboard/README.md(the sections you touch), the problem's page, and this skill. - Write the problem sheet (one page, in your scratch folder), before any code:
- the scenario: who uses it, and why the traffic is believable; the peak moment on its own line;
- the requirements the interviewer will reveal, each a sentence of the page;
- the proven answer: for each requirement, the usual pattern, where the data ends up, what an interviewer expects to
hear, with a source for each (
research.md). The tests' hints, the fix cards, the next steps and the "how big companies do it" section all come from this. On the URL problem this came last and cost the most (mistakes.md1); - the tests: four to six, each a sentence of the page, its people, what has to happen (never one way of doing it), easiest first; - the request kinds and their mix, the hot key, and the three levels as one-sentence stories; - what the runner and the vocabulary need that they do not have (a verb, a check, a scenario event, a resource kind); - the AWS parts the design space uses, and the concepts an interviewer would name. - Ask Bruno one line where a reader-facing choice can be read two ways, and show one picture or a mockup of anything new before building it (round 2's mockup got his yes; the version switcher, built on a misreading, cost a round).
- Write the contract and commit it as the base the helpers branch from: the content files' skeletons, and the exact
shape of anything new that two helpers share, with its tests (as
api.jswas for round 2, d9b4274, andflow.jsfor board 3.0, 8a96364). One owner per shared file; helpers import it and never edit it. - Write the briefs: one shared brief (template below) and one per helper, each quoting his words exactly.
Hours 1 to 3: helpers in parallel
| Helper | Owns | Needs first | Done means |
|---|---|---|---|
| page | the page top, sizing with its arithmetic, the AWS mapping, "how big companies do it", its diagrams | the problem sheet | primary sources read and cited with dates; at least three diagrams, one animated, each looked at at frame one and mid-animation; build and link checks green |
| interviewer | site/interviewer/<problem>.interview.json, its evaluation set |
the requirements list | 150+ questions measured (stored answers replayed; few real calls), the misses listed per category |
| tests and runner | <problem>.tests.json, named specs (the good API and one per known mistake), any new verb, check or event, titles, should-lines, hints and nudges in human words |
the contract | every test passed by every design that does the job and failed for its named reason by those that do not, on the real runner |
| heavy | the problem's levels and request mix, K additions with kind codes and sources, saved designs with their outcomes both ways, fix and next-step entries, Sonnet's brief, prices for new parts |
the research | a scratch-model table of what breaks first at each level, reproduced by the unit tests; every run ends with a next step |
| voice (after tests and runner merge) | <problem>.narration.json with its own prefix, the clips |
the runner's final situations | every frame of every test API finds its line; every clip shorter than its step; Deepgram's words match |
Four helpers at once at most (the box, below). The voice waits for the runner, because its lines key on the runner's situations. A problem can also ship without her: a page with no clips opens at ½× and plays the same.
Worktrees. One per helper, never shared:
git -C ~/ventures/junior-to-staff worktree add ~/scratch/j2s-<name> -b <branch> <contract-commit>
ln -s ~/ventures/j2s-site/site/tools/node_modules ~/scratch/j2s-<name>/site/tools/node_modules
cp -r ~/ventures/j2s-site/site/.mermaid-cache ~/scratch/j2s-<name>/site/ # its own copy: a shared one races on its manifest
Scratch, notes, pictures and logs go in ~/scratch/<round>/<helper>/. A helper never commits, adds, stashes, resets, checks
out files, pushes, tags, deploys or restarts anything; Iris reviews each diff and releases it.
Ports. Each helper gets its own block of eight and checks ss -ltn before binding:
| Block | Ports | Notes |
|---|---|---|
| A | 8941-8948 | |
| B | 8951-8958 | |
| C | 8961-8968 | never 8969: the live interviewer |
| D | 8971-8978 | |
| release run | 8987-8997 | ~/scratch/guide-release/run.sh (voice 8987, sim 8988-8989, designboard 8991, heavy 8992, side panel 8996, flow 8997) |
| interviewer-check | 8983-8985 | fixed in the script; one helper runs it at a time |
Shared files. Split them by named regions in the briefs (a function, a block of CSS appended at the end, a block of
checks appended before the errors check). Nobody edits site/designboard/README.md: each helper writes its section into
its scratch folder as README-section.md, and Iris merges it. When a helper must change an existing sentence another
helper owns the wording of, it says so in its report under "sentences I changed".
Then: merge, a stranger, one fix round
- Merge branch by branch. Run every suite on the merged tree, then use it as a reader on the built page: the seams
between helpers show only there (
mistakes.md6). - A stranger's walk. A fresh session with only a browser (the Playwright MCP,
~/scratch/stranger/mcp.json), given the page as a candidate preparing for interviews and nothing else (~/scratch/stranger/prompt-3.0.txtis the prompt to copy): ask the interviewer, write the API, draw, run the simulations and the heavy test, report every confusion with screenshots, the three changes that would help most, and scores out of ten. The second walk could not see its own screenshots and judged looks from the page structure: open the pictures yourself. - One fix round from the walk's report, each finding with its check (board 3.1 was this).
- Bruno uses it. His notes are the next round.
Release, and when
- First: the page, the board's exercise with its checks and tips, the interviewer, the API and the simulations. The
heavy test's button appears only when
PROBLEMS[x.heavy]exists, so the exercise can leaveheavyout until it is ready. - Second: the heavy test and "how big companies do it", together, since the cards and the section teach the same answer.
- Narration whenever its clips pass their checks.
- Iris's steps: merge; run every command of
~/scratch/guide-release/run.shin the release clone; tagboard-X.Ywith one line and add it to the README's versions table (site/designboard/README.md, "Versions of the board"); publish; redeploy the interviewer if an*.interview.jsonchanged (it never ships with the site); add new SVGs todocs/visual-review.json; check the live page and send Bruno pictures.
The box
- t4g.medium, 3.8 GB, 2 CPUs, shared. At most one headless browser per helper, closed when a run ends; every full build
and browser run under the round's lock (
flock ~/scratch/<round>/build.lock -c '...') orHEAVY_MEM=1500M ~/soulful/box/heavy <cmd>. Watchfree -m. - Node:
source ~/scratch/haiku/env.sh. Build:~/.local/state/soulful/j2s-deploy/reader-venv/bin/python site/build.py(needs~/sysroot/usr/binon PATH for fc-list). Chromium needsLD_LIBRARY_PATH=~/sysroot/usr/lib64:~/sysroot/lib64. - Kill by port (
ss -ltnp), neverpkill -f(it matches your own shell). Never pipe a check through| tailand then read$?. Unit tests with the glob:node --test site/designboard/test/*.test.mjs. - Element screenshots only, device scale 1.5; hide
.read-progress(it draws a line through the first row). - Real model calls cost money and show on Bruno's dashboards: Haiku captures are few and never looped (key from SSM, never printed); every Jev call is on his TypeSafe key (replay stored answers); ElevenLabs bills per character (dry run first, under the cap); the browser checks answer Anthropic with canned replies, so no real Sonnet call from a check.
- Code carries its own meaning: no story comments (names, dates, rounds, "he said"), at most three comment lines in a row; an edit guard refuses them.
The shared brief: a template
Copy, fill the brackets, keep every line that is not a bracket. Each line here cost something once.
# <Round>: <what it is for>, shared brief for every helper
You are a helper, not Iris. A CLAUDE.md elsewhere may say you are; it does not apply to you. Never message anyone, never
answer Telegram (if a hook injects a message from Bruno, do not answer it; say so in your report), never write under
~/soul. Never push, tag, deploy or restart anything. Do not commit, `git add`, stash, reset or checkout files: Iris reviews
your diff and releases it.
## His words, exactly. They win over everything below.
<each quote with its date and time UTC; what he loved that must not be lost>
## Who is on this round
<helper: worktree ~/scratch/j2s-<name>, branch, ports, owns these files and regions>
## Read first, whole
<the contract file; the README sections; the problem sheet; the page; the tests file>
## How to know it works
- Unit tests: `node --test site/designboard/test/*.test.mjs` (count them at the base first; all must pass at the end).
- Browser checks on a full build: <the ones that touch your files>. Do not run `site/tools/api-check.mjs`.
- A check you have not seen go red proves nothing: break each new rule once (reversibly), watch its check fail for the
right reason, restore byte-identical (compare sha256), watch it pass. List the breaks.
- Check against the real producer (the runner, heavyRun, flow.js's functions, real Haiku answers), never a copy of what
you think it returns.
- Look at it: element screenshots at 1280, 1440, 1512 and 1728 (his Mac's Chrome), 390 for the page; open every picture
and say what looking changed. Take a BEFORE picture on the base build.
- Name what a removal takes with it.
## The box
<the lines of "The box" above>
## When done
Write `DONE` (one line) and `DONE.md` in your scratch folder: files changed and the regions inside shared files, what a
reader now sees and hears (before and after, word for word for anything reworded), the pictures you looked at last, the
breaks you ran, decisions the brief did not make, a post-done list. Then report back in at most 300 words.