Decisions
Who proposed and who decided? Each row is one decision of the record: a row of a decision table or a ruling of a build.
Who decided, by topic
A click on a number shows only the decisions of that topic and decider in the table below.
| Topic | Fadel | Alan | Claude | Measured | Unknown | Decisions |
|---|---|---|---|---|---|---|
| Translation and LLMs | 0 | 0 | 0 | 73 | ||
| Exports and report | 0 | 0 | 0 | 69 | ||
| Interface and help | 0 | 0 | 61 | |||
| Deployment and operations | 0 | 0 | 0 | 53 | ||
| Browser engine | 0 | 0 | 46 | |||
| Specification and scope | 0 | 46 | ||||
| Project records | 0 | 0 | 0 | 34 | ||
| R and design rules | 0 | 0 | 31 | |||
| Analysis | 0 | 0 | 0 | 0 | 1 |
When they were decided
The bars always show all decisions. The filters change only the table: a click on a day or on a number of the grid shows the matching rows of the table.
Table of the bars
| Day | A person | Claude | Measured | Unknown |
|---|---|---|---|---|
| 14 Oct | 29 | 0 | 0 | 0 |
| 15 Oct | 32 | 50 | 0 | 0 |
| 16 Oct | 35 | 78 | 0 | 0 |
| 17 Oct | 52 | 53 | 0 | 0 |
| 18 Oct | 0 | 0 | 0 | 0 |
| 19 Oct | 38 | 44 | 0 | 3 |
Showing 414 of 414.
All decisions
| Date | Decision | Proposed by | Decided by | How | Basis | Record |
|---|---|---|---|---|---|---|
| Ruling 1`slowRuns` and the null `maxLoadingGap` live in `replication_materials/tests/deployed/helpers.ts` (it imports only Playwright types, so vitest can import it), not in the spec file — a unit test that imports a spec file registers Playwright tests | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 2T5-d control: if a blob worker is blocked by the page policy, the control for the console path is a `console.error` with the CSP violation text from the page (the path `consoleHits` reads), and the report says that worker-origin messages stay unproven — the plan asked for a worker, but the policy forbids blob workers by design | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 3T6-f: the bounded page loop throws; the GET answers whatever status the existing GitHub-error path gives (the test asserts that status and its fixed message), not necessarily 503 — the plan named 503 from memory; the existing mapping is the authority | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 4subagents run the secret scan only with `--env` and a made-up file; the controller runs it with the real `.env` — the plan's Task 1 Step 4 and Task 8 Step 6 say "run node scripts/secret-scan.mjs", but a task that changes the scanner could print a value by a bug, and subagents never read `.env` | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 5Task 3 ends with the probe and its CSV as evidence, the non-working worker throttle removed, and the limitation stated in the helper comment, the README and spec 17.1; the stall limit and its test stay; the author gets the risk and the options (measure on a real low-end phone, or accept: a false stall shows a Retry button while loading continues) — the plan said stop on this result, but the finding is complete and the limit is the author's rule, not mine to change | Claude | Claude | Ruling during a build Changed later |
Classified by Claude | Claude kept the 5 s limit and gave Fadel the options. He chose "20 trials, then rule (Recommended)" (2026-10-19 04:50 UTC), and the limit became 16 s. | |
| Ruling 6T4-g: the header comment in lib/security-headers.ts cites decision A11 (alpha design: 'A Content Security Policy is set now'), not AP12 as the plan says (AP12 is the Vercel link) — the plan named the id from memory | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 7T6-d formula stays: a crafted body with a long whitespace run in the name can pass checkAnswer (whitespace collapses) and still exceed 25,600 bytes, but the page's name field has maxLength 100 and the comment field its own limit, so every answer the page can send fits; the cap protects the server | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 1Task 1's fast check may fail only on the TS/R report-version agreement and on tests that read the R report shape through TS fixtures; Task 1 lists each such failure in its report, and Task 2 must leave `npm run check` fully green — the plan splits one version bump across two tasks for review size | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 2keep the help.spec.ts change inside Task 4 — it is a test pinning a text that Task 3 changed by plan, and the full check after Task 4 is the plan's first browser gate since Task 2 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 3the replication-materials skill (installed 2026-10-19 23:51 local) defines another record structure (.replication/, project/*.md, replication-site.yml); this repository already has its own approved one (project/roadmap.json, decisions.json, process/process.json, the project site), so Task 5 keeps the repository's structure, adopts the skill's compatible rule (no internal agent IDs in the ledger copy), and the question of a migration goes to Fadel | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 4the no-claim paragraph says "wrong from A13" in plain text instead of the plan's \(A_{13}\) — components/review/QuestionCard.tsx:33 renders text paragraphs as plain <p> text, so the LaTeX form would show literally | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 5Task 5 creates the ledger copy replication_materials/plans/2026-10-19-alpha-review-fixes-execution-ledger.md now (repository naming, as for project pages), without internal agent IDs (Ruling 3), because roadmap.json must name an existing ledger; the controller refreshes it after the final review | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| F1The MA claim applies in the 12 regions that Alan agreed to or kept (4, 8, 16, 32, 64; 128 with 1 to 24 and with 65 to 127 factors; 256, 512, 1024, 2048, 4096) and in the 128-run region with 25 to 64 factors (40 to 64 by his answer #61, 25 to 39 by F2). Statement: "Minimum aberration design from the FrF2 catalogue, entry {name}." (his answer #11). | Alan | Alan | Stated in the decision table | From the table of the plan | Decided by in the table: Alan | |
| F2128 runs with 25 to 39 factors get the MA claim now (`xu2009-128-runs.R`), with a check at generation time: for 25 to 40 factors, the claim needs the computed WLP of the design to equal the WLP of Xu's MA design of that size, built in R from his printed columns. If the check fails, the claim is `none` (fail closed). The check proves that the design has the aberration of Xu's design; the MA status of Xu's design rests on his complete enumeration. Alan is asked to confirm (F6). | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel (2026-10-19: switch on if the designs can be verified when they are made) | |
| F3The 19 entries that share rank 1 (128 runs; 41 to 44 and 50 factors) get the MA claim: they are the only entries of their sizes, Alan's answer #61 calls the 128-run catalogue designs with 40 to 64 factors MA, and their WLPs are equal (measured). | Unknown | Unknown | Not known | Not known | Decided by in the table: Fadel; Alan is asked to confirm (F6) | |
| F4The unranked entries (223, names such as 29-19) and the 12 first-ranked entries outside the documented region (69-61.1 to 80-72.1, 256 runs) get the statement "Design from the FrF2 catalogue, entry {name}. FrF2 lists it as good, not necessarily minimum aberration." (his answer #11; comments #58 to #60 and #63). | Unknown | Unknown | Not known | Not known | Decided by in the table: Fadel; Alan is asked to confirm (F6) | |
| F521-16.1 and 22-17.1 get the MA claim (32-run region confirmed; measured as best by the computed WLP among all entries of their size). The other 87 entries with a stored WLP error, the 7 broken entries and the ranked entries after the first keep the statement that names only the entry. | Unknown | Unknown | Not known | Not known | Decided by in the table: Fadel; Alan is asked to confirm (F6) | |
| F6Four questions are asked again: the 128-run region (context: F1, F2 and the evidence), the entries without an MA claim (new title "Claims for the other catalogue entries", context: F3 to F5 as four numbered claims), and the glossary entries `all_2fis_clear` and `guarantee` (new texts, F9). An answer filed before a question changed shows under it as an earlier answer and does not count. The rule uses the issue number: the question counts only answers in issues after #65. | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| F7The refusal of 26-17.1 and 27-18.1 stays. Alan is revising the FrF2 findings (#64); the question stays as it is and is not asked again. | Alan | Alan | Stated in the decision table | From the table of the plan | Decided by in the table: Alan | |
| F8Glossary: the texts of `generators`, `clear_2fis` and `effect_heredity` use Alan's words (#33, #34, #36). Spec Section 1.8 takes the new effect heredity text, as it took his earlier text (R20). The 33 entries that he agreed to or wrote get `reviewed_by: "Alan R. Vazquez"` and `reviewed_on: "2026-10-19"`. | Alan | Alan | Stated in the decision table | From the table of the plan | Decided by in the table: Alan | |
| F9Glossary: `all_2fis_clear` gets a text from the measurement (9-4.1 is an example, not the only design), and `guarantee` describes the three statements of F1 and F4. Both stay "Draft, not yet reviewed" until Alan answers again (F6). | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| F10References: add the three works of #62 to the glossary references (Crossref-checked on 2026-10-19), cite them in the `guarantee` entry, and add Mee (2009) to spec Section 19. | Alan | Alan | Stated in the decision table | From the table of the plan | Decided by in the table: Alan | |
| F11`report_version` becomes 1.3.0, because the statement and the new `claim` field change. Stored and imported projects of 1.2.0 rebuild with the existing rule (spec 8.1). | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| F12The known issues on the review page say that two glossary entries are drafts and that four questions are asked again. | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| F13A new open item in spec 17.1: the field of application (Alan's comment #65), owners both authors, needed before the Milestone 4 test set and before the paper draft. The answers stay out of the public repository (spec 14.4). | Alan | Fadel, Alan | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel and Alan | |
| F14The scope of the paper (spec 17.1 row "The scope of the paper"): the paper covers the tool up to and including the design families of DoE.wrapper (Phase 4) and their benchmarks. The aim: a practitioner writes a short text with the factors and the constraints, and EXPERTA leads from the choice of a design, or of a sequence of designs in sequential experimentation, to the analysis. The row is answered; the order of the work after this plan is planned again in a separate design. | Fadel | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel (2026-10-19) | |
| PS1Three pages (records, decisions, progress) and a landing page, updated from commits, pull requests and issues | Fadel | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| PS2The readers of each page as in Section 1 | Fadel | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| PS3All pages are public | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| PS4The decisions page has both the grid with the timeline and the table | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| PS5People by name, also later co-authors; never "Author" or "Reviewer" | Fadel | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| PS6Two fields: proposed by and decided by | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel (not objected) | |
| PS7Claude classifies the past decisions with evidence; no check of each row by a person; a corrections file | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel ("The one-hour check is not worth doing") | |
| PS8The progress page leads with the completed work by plan and the blockers to the next milestone | Fadel | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel | |
| PS9GitHub Actions builds the pages and deploys them to GitHub Pages | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel ("Now go implement this") | |
| PS10The address `project.expertadoe.app` | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel ("Now go implement this") | |
| PS11No LLM call in the build | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel ("Now go implement this") | |
| PS12The switch-on waits for the end of the review by Alan R. Vazquez | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel ("Now go implement this") | |
| PS13Claude may push work branches (never `main`) without asking, so the progress page shows the current work | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel ("Yes, I give you the permission") | |
| PS14The timeline colors dots by kind; the grid has one named column for each person | Claude | Claude | Stated in the decision table | From the table of the plan | Decided by in the table: Claude (within PS5) | |
| PS15GitHub data through `gh api`: the code never reads or handles a token | Claude | Claude | Stated in the decision table | From the table of the plan | Decided by in the table: Claude | |
| PS16New decision tables get the columns "Proposed by" and "Decided by" | Claude | Fadel | Stated in the decision table | From the table of the plan | Decided by in the table: Fadel (not objected) | |
| Ruling 1`node scripts/project-site/decisions.mjs --list` prints exactly the output of collectDecisions (copies removed), so its keys equal the keys the T4 test checks — the T4 classifier and the test then see the same set | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 2the T4 data test requires a record only for table decisions in files dated on or before `classified_on` (2026-10-19) whose table has no "Proposed by"/"Decided by" columns; later decisions fall back to the table columns or keywords, as design Section 4 says | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 3summarize returns taskIds (plan headings) and completedIds (ledger lines); a milestone's tasks = its plan task ids, completed = ledger ids that are plan ids, and extraTasks = ledger ids not in the plan (print ["S"], alpha ["9b-1","9b-2"], m1 ["0"]); the page says "8 of 8 tasks, plus 1 added during the build" — keeps the T5 test values | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 4matches(dataset, filters) treats each dataset value as a space-separated list and holds when, for every filter key, some listed value is in the filter's list; timeline bars filter by bin: rows carry data-bin (the label of the bin of their date) and bars carry data-filter-bin (replaces data-date/data-filter-date in the T7 test) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 5the byte comparison of the spec page before and after the process-figure move is a one-time check in Task 6 (both files built to temp, compared with `cmp`, result in the report); the permanent test checks that build-spec-page.mjs imports processFigure from scripts/lib/process-figure.mjs and that processFigure(process.json) has id="process-figure" and one event item per event | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 6namesToIds ignores text in parentheses and quotes, splits on "," and " and ", and maps "Fadel", "Alan", full names, "FMM", "ARV", "Claude", "Measured", "Measurement" | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 7I2 keeps the plan's positional keys (merged ledgers are finished records and only grow at the end); instead each ruling record in decisions.json (Task 4) carries `anchor` = the first 40 characters of the ruling text, and the Task 4 data test fails when a record's anchor differs from its ruling's text — a shift then fails the suite instead of mislabeling a ruling | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 8data-bin carries the bin KEY (ISO date of the bin's first day), not its display label, because labels contain spaces and matches() splits dataset values on spaces (Ruling 4) — refines Ruling 4's wording, same intent | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 9the Decisions timeline stays as stacked bars per day by kind (people, Claude, measurement) instead of one dot per decision with the name on hover — about 380 decisions in 6 days overlap as dots; the bars carry the same counts with a data table, and the names are in the table | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 10a grid click filters the table, not the bars; the bars always show the whole record and the page says so — keeps the client script small; the design asked for both | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 11the plan's ledger is copied into replication_materials/plans/2026-10-19-project-pages-execution-ledger.md now (so the pages milestone counts its tasks) and refreshed at the merge, as for the earlier milestones | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 12parked as latent; fix when the roadmap reaches such a pair (dedupe by item across the two lists) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 13parked; no status starts with a name | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 1only Task 4 consumes `config/print-layout.json`; the plan's "Tasks 4 and 7" is a slip (Task 7 is the citation) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 2`lib/exports/archive.ts` stays unchanged: the zip gets the report text that step 6 rendered with the chosen options, so the zip report equals the download by construction (the e2e asserts it) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 3`LOCAL_TIME_PATTERN` and `isoWithOffset` move to a small module `lib/projects/time.ts` that both `lib/projects/schema.ts` (re-export, so other importers do not change) and `lib/card/card.ts` import — card.ts importing schema.ts would be a load-time cycle (schema.ts builds ProjectSchema from CardSchema at module top level) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 4as in plan 1, subagents run the secret scan only with `--env` and a made-up file; the controller runs it with the real `.env` | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 5the Task 1 probe goes to `replication_materials/tests/e2e/print-layout.spec.ts` (skipped unless FFD_PERF=1, as perf.spec.ts), not `tests/perf/` — playwright.config.ts has testDir tests/e2e, so a spec in tests/perf is never found; the CSV still goes to tests/perf/ | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 6Task 1 and Task 4 use a measured width model (per-character widths of header and body text, cell overhead, fixed Run/Std/Response 22 mm/Notes 35 mm, 5% margin) and a shared packFactorBlocks() instead of one K — K = 4 from 12-character names would split the common 7-factor design into two blocks; real names vary | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 7content-visibility is not used (R4 fallback): CSS containment does not apply to table row groups, and the view times show no stable gain; the tbody groups of 256 stay | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 8the spec goes to version 7 with the planned Phase 4 (Section 1.9, the author's request of 2026-10-19, applied by the controller between Task 1 and Task 2 as its own docs commit); Task 8 adds the print changes to version 7, not version 8 — one release, one version | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling on the spec version. The Phase 4 text answers Fadel's request of 2026-10-19 04:16 UTC: "Can you also add the following to the planned extensions". | |
| Ruling 9a measured width table per character (ASCII 32-126, header bold and body, largest of 3 runs; non-ASCII counts as the widest character) replaces the single per-character width, with the largest positive residual added to the overhead — one W-width for every character is an upper bound too loose for real names, and an average is not an upper bound | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 10Task 3 removes the notation line from the Design properties section, because the title block (always present) shows it — two copies on page 1 add nothing | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 11estimatedPages(rows, blocks) = blocks x ceil(rows / rows_per_page_landscape) and printRowsOption(rows, nrows, blocks); step 6 takes the block count from the same shared column builder and packFactorBlocks — the plan's (rows) and (rows, nrows) signatures did not know of column blocks | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 12a translated project stored before Task 5 (voters present, meta null) opens its section with PROVENANCE_UNDATED = "EXPERTA interpreted the request. The date and the mode were not recorded for this project. The user checked the specification in step 2 and confirmed it." — the plan's provenanceIntro needs a date and a mode that such projects lack | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 13the acknowledgment closes every report outside the numbered sections, whatever the contents choice; the citation stays in the Versions part — R11 says "in every report" and also "in the Versions and citation part", which conflict when Versions is unchecked; the author's acknowledgment is not optional content | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling on the place of the acknowledgment. The acknowledgment and its text are Fadel's decisions (R11). | |
| Ruling 14the app link gets target="_blank" rel="noopener noreferrer" and the step 6 sandbox adds allow-popups allow-popups-to-escape-sandbox, so the link opens a new tab and the preview stays; print() gets a try/catch — a link that does nothing in the preview would confuse; the report has no script, so popups come only from a click | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 15the WLP splits into tables of at most 10 word lengths; the Factors table is `small` only up to 20 factors — a one-row table cannot wrap, and a long factor table should split rather than leave page 1 blank | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 16meta.factors (ids and names at interpretation) gives removed, added and moved lines; NO_CHANGES only with meta in ensemble mode, NO_CHANGES_SINGLE in single mode, nothing when meta is null; a card `source` (translation, hand, imported; null for old cards) decides the hand/imported reading — the section must never state something false; meta is new and not deployed, so its shape can change now | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 17data/supported-limits.json measured_on goes back to 2026-10-15 (its values have not changed since f2a6ef5); derive-budgets writes a file's date only when its values change — a measured date must name a measurement | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| R1No forced page break. Sections flow; a heading stays with the text after it; a small table, a code block and an alias group do not split across pages. | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-19 01:13 UTC, on the old print: "(a) it seems that you are forcing each section into a new page". He approved the plan at 01:53 UTC. | |
| R2The Request section shows the request text once. The turns after the first (the clarification rounds) follow under "Clarification", as "Question from EXPERTA" and "Answer". | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-19 01:13 UTC: "(b) the request and then the you in the request is confusing". Claude proposed the labels; Fadel approved the plan at 01:53 UTC. | |
| R3Aliasing has two parts, "Main effects" and "Two-factor interactions". Each starts with its summary sentence as a paragraph, without "Example: ...", because the report lists every group. The groups are a numbered list in columns of at least 20rem. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-19 01:13 UTC: "(c) the print out of the aliasing (all same level bullets should be improved ...)". Claude proposed the two parts; plan approved at 01:53 UTC. | |
| R4No JavaScript table package. The report has no script (C11), and the frame does not run scripts. A paged or virtual table shows only some rows, so the print would lose rows unless the package had its own print mode, and the package would have to be inlined into each report file. The screen view uses CSS only: a scroll box (at most 75vh), a sticky header row, a sticky Run column, alternate row shading, and the rows in groups of 256, each group with `content-visibility: auto` so the browser skips the layout of groups out of view. Task 1 measures that the print still shows every group and that the view of 32,768 rows is not slower. If either fails, the groups stay and `content-visibility` goes. | Claude | Fadel | Approved with the plan | Classified by Claude | Fadel asked if "a nice HTML table js or similar package" would help (2026-10-19 01:36 UTC). Claude advised against it; Fadel approved the plan at 01:53 UTC. | |
| R5Print row limit, set in step 6: "Rows of the run sheet in print", with "All rows" and "First 64", "First 256", "First 1,024" (only the values below the number of rows), each with its estimated pages. Default: all rows when the sheet has at most 256 rows, else the first 256. A limited print shows a note under the table. The HTML view always has every row. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-19 01:36 UTC: "Even the 25 page limit seems a lot (is there a reasonable way to configure this)". The default is Claude's; plan approved at 01:53 UTC. | |
| R6The run sheet prints on landscape pages (a named page). When a design has more factors than fit on one landscape page (K, measured in Task 1), the print uses column blocks: each block repeats Run and Std order. The header row repeats on each page. Blank Response and Notes columns are in print only, in the last block. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked how 32 factors would print (2026-10-19 01:13 UTC) and chose "Yes, Response and Notes (Recommended)" at 01:36 UTC. The page layout is Claude's. | |
| R7Running header and footer from `@page` margin boxes, with app texts only (no user text inside CSS): top left "EXPERTA · Design report", top right the date, bottom left "expertadoe.app · version {APP_VERSION}", bottom right "Page {n} of {N}". Chromium and Edge print them; other browsers print without them. The screen view does not change. The icon is in the title block of page 1 (inline SVG, no `url()`). | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-19 01:13 UTC: "(e) add some styling in heading and footer to capture EXPERTA; its favicon; date; version". He approved the plan at 01:53 UTC. | |
| R8The PDF file name: during `print()`, the app sets the page title to "{project name}: EXPERTA design report" and puts the old title back after. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the report print plan without a change to this row, 2026-10-19 01:53 UTC: "I approve both plans and the order." | |
| R9Citation in APA 7 and BibTeX, both with `https://expertadoe.app`. In the report, a CSS-only toggle; the print shows both forms and no controls. The home page gets the same two forms with a toggle. The report may contain one link, to `https://expertadoe.app`; no other `href`. | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-19 01:13 UTC: "(f) in the citation, put a link to the app and provide it as a toggleable .bib vs APA citation". He approved the plan at 01:53 UTC. | |
| R10New section "How the specification was made", after "Specification", with its own check box in step 6. The card keeps the model id of each voter and the mode, the prompt, schema and Jev-question versions and the time of the interpretation, with defaults, so stored and imported projects still read (`PROJECT_SCHEMA_VERSION` stays 1). A project without these values says "Not recorded". | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked if the report should show the agreement and versions of the models (2026-10-19 01:13 UTC); he chose "Short section (Recommended)" at 01:36 UTC. | |
| R11One acknowledgment line, no amount: "The API and hosting costs of EXPERTA are funded by the Raymond E. Glos Professorship in Business at Miami University, held by Fadel M. Megahed." It covers hosting too, so it is in every report (heading "Acknowledgment" in the Versions and citation part) and on the home page under "Maintained by". | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked about his professorship (2026-10-19 01:13 UTC), chose "Acknowledgment, no amount (Recommended)" at 01:36 UTC and gave the text at 01:53 UTC; Claude polished it. | |
| R12Other improvements: the title block replaces the empty first page; the design notation prints in the accent colour (today it is white on a background that browsers do not print); the word length pattern is one row; "Std" becomes "Std order"; numbers use tabular digits; the Versions part is a table plus the run sheet SHA-256, and it no longer repeats the run order. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the report print plan without a change to this row, 2026-10-19 01:53 UTC: "I approve both plans and the order." | |
| R13No change of `report_version` (the R report data do not change) and no app version change; the authors choose the version at release. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the report print plan without a change to this row, 2026-10-19 01:53 UTC: "I approve both plans and the order." | |
| Ruling P1Task 2 checks, when FFD_EXPECT_CSP=1, that `content-security-policy` is present and not empty, `referrer-policy` is `no-referrer` and `x-robots-tag` is `noindex`; Task 5 changes that check to compare with `contentSecurityPolicy()` — the function does not exist before Task 5 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P2Task 3 creates `lib/ops/scripts.ts` with RATE_SCRIPT only; Task 4 adds RESERVE_SCRIPT and SETTLE_SCRIPT, as its text describes them — the spend semantics belong to Task 4 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P3Task 9 drops the `ste-check.mjs` step; the task reviewer checks the ASD-STE style of the changed documents by reading, and the missing script is recorded as a spec 14.1 gap for the authors — the script does not exist | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling (alpha ledger). It left the missing style-check script as a gap for the authors; no person decided on it by 2026-10-19. | |
| Ruling P4accept the 3 moderate npm audit findings (sprintf-js GHSA-hp3w-g68c-fv3c via fengari via ioredis-mock) — dev-only test dependency, never in the app bundle | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P5secret-scan.mjs takes `--env <path>` (default `.env`); the worktree has no `.env` (git-ignored), so the Task 1 implementer runs the scan with patterns only, and the controller runs it with `--env` pointing at the main checkout's `.env` at Checkpoint A — subagents should not read the real secrets | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P6tighten the plan's patterns instead of an allowlist: openai and anthropic get the lookbehind `(?<![A-Za-z0-9_-])` before `sk-`; private_key matches only a header that ends its line (`\s*$`) or is followed by a literal `\n` escape and at least 16 base64 characters; test inputs are built at run time (concatenation / repeat) so the committed test file holds no match; the patterns-only scan of all commits must then be clean — plan defect (patterns matched ordinary text and the plan itself) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P7the runtime-file check always skips dot files (expected count 198, not the plan's 199) and the FFD_SKIP_DOTFILES flag goes — `.ffd-webr.json` is a marker that only scripts/setup-runtimes.mjs reads; no browser code loads it | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P8option 1 — a module `lib/zod.ts` that calls `z.config({ jitless: true })` and re-exports `z`; every app module (lib/, components/, app/) imports `z` from `@/lib/zod` instead of "zod"; a unit test fails if any source file outside lib/zod.ts imports from "zod" directly; no 'unsafe-eval', no guard exception — under the CSP the JIT is blocked anyway, so jitless costs no speed compared with the deployed behaviour, and it removes the false violation | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P9accept `lib/release-stage.ts` (re-exported by lib/site.ts) — next.config.ts cannot load lib/site.ts because of its @/package.json import | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P11rephrase the two plan texts without "Should": guarantee.no-claim question "After the review, do these entries also get no MA claim?"; guarantee.refused-defaults question "Does the tool keep the refusal? Agree keeps it. Change means: accept the two entries after the tool computes their aliases and clear 2FIs again; give the check in the comment." The advice-word test then covers titles, context texts and question texts of all 55 questions — plan defect (it mandated both the rule and texts that break it) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P12add REVIEW_MESSAGES.unavailable = "The review service is not available now." for a store failure of the review limiter (503), so "not configured" means only a missing configuration | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P13accept the rate limit before the key check (it also slows key guessing) and one limit for GET and POST together (30/min, 300/day still exceeds a page load per answer) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P14Task 9 runs now without its Step 1 (budgets) and without the measured values in the 17.1 stall row (that row says the measurement runs at Checkpoint A); a small Task 9b after Checkpoint A derives the budgets from alpha-slow-start.csv and closes the stall row — Checkpoint A waits for the author's approval, and the documents do not depend on the number | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling. Fadel then approved Checkpoint A, 2026-10-18 03:26 UTC: "go ahead with Checkpoint A once done with rereview". | |
| Ruling P16the VERCEL=1 dependence stays in code; Checkpoint A item 3 records that "Automatically expose System Environment Variables" is on, and Checkpoint B step 4 confirms in the Upstash data browser that rl:m:* and rl:d:* keys exist and hold hashes (proof of the shared store); Checkpoint B step 6 confirms the smoke issue's Commit line shows a SHA — a code fallback (for example NODE_ENV) would break the local production test build | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P17defer the Upstash call time limit (Minor 6) until Checkpoint B measures the latency (measure, do not guess); record it as an open 17.1 row now | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P18the one-character fix (`\b`) rides with Task 9b (the planned small task after Checkpoint A, with its own review) instead of a second fix wave — the texts contain no advice word today | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingstands; no path passes such a value. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P19Task 9b-1 (now, cheap model): site.spec checks /review only under FFD_EXPECT_CSP=1 (alpha code), keeps /runtimes/webr/R.js in the base list (COOP/COEP); plus the P18 one-character `\b` fix in review-messages.test.ts; verify against production; then the controller reruns site.spec and the slow trials; Task 9b-2 (budgets) follows the CSV — the fix-wave scope put a not-yet-existing route in a check that must run against the old main | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P20store call limit = 10 x the largest measured call, rounded up to a whole second = 1000 ms (largest 59.2 ms, n = 100), derived by `scripts/derive-store-budget.mjs` into `config/store-budgets.json`, as for the translation deadline | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P21the limit is a signal function (`signal: () => AbortSignal.timeout(ms)`) on the Upstash client, not one AbortSignal. Read in node_modules/@upstash/redis (nodejs.js, request()): with a plain signal, an aborted fetch returns a 200 Response whose result is the text "Aborted", which the counters would read as a script result; with a function, the abort throws. The signal is made once per request, so the limit covers the retries and their backoff (default 5 retries, 50 e^n ms, about 4.3 s) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P22the count line of "Other comments" moved to `commentCount()` in lib/review/answer.ts ("1 comment filed", "2 comments filed"), so a unit test covers it | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P23the export is a plain Node script (`scripts/export-review.mjs`) that reads the issues with `gh issue list` (the author's CLI login, not the review token). Its rule of "counted" is a copy of latestAnswers, and its unit test builds the issues with the page's own issueFor and requires the same counted set as latestAnswers. One documented difference: the script cannot see the question list, so it counts an answer to a question that the page no longer has. Default output `alan_feedback/alpha-review-answers.csv` (git-ignored, as Alan's other feedback); the authors decide if answers become public. CSV as the run sheet (RFC 4180, CRLF, UTF-8, cells unchanged) | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling (alpha ledger). Whether the answers become public is left to the authors; no person decided it by 2026-10-19. | |
| Ruling P24the apex `expertadoe.app` is the main address, and `www` redirects to it with 308 (Vercel docs: add www separately and redirect one to the other, to avoid duplicate content) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling P25`experta-doe.vercel.app` keeps serving the app and does not redirect, as the author asked ("in addition to") | Fadel | Fadel | Answer in chat Stood |
Classified by Claude | Fadel, 2026-10-19 00:41 UTC: "public facing domain in addition to https://experta-doe.vercel.app/app"; 00:49 UTC: "For the paper, we will just expertadoe.app". | |
| A1The link is public. Users do not sign in, and the app has no access gate. The scope rule refuses requests that are not about two-level designs. A refusal still costs one LLM round, so three limits hold the cost: the per-address rate limit, the daily spend caps of the app, and the limits on the provider keys. | Fadel | Fadel | Answer in chat | Classified by Claude | Claude proposed a link for Alan and Fadel only. Fadel, 2026-10-17 21:15 UTC: "Would not our app reject non related requests? ... I have limits on all the keys as a backup". | |
| A2The alpha is done when all review questions have an answer. Both authors can answer, so both get the review key. | Claude, Fadel | Fadel | Answer in chat | Classified by Claude | Claude proposed the end of the alpha. Fadel, 2026-10-17 21:15 UTC: "Yes,when we answer all questions". The review key for both authors is Claude's, not objected. | |
| A3Vercel hosts the app (the Pro plan of the author). Upstash Redis from the Vercel Marketplace holds the counters. | Fadel, Claude | Fadel | Answer in chat | Checked by Fadel | Fadel M. Megahed, 2026-10-19: he decided on Vercel hosting, with his Vercel Pro plan as the deciding input. | |
| A4Vercel is the only host for now. No Dockerfile and no ChatISA start script. | Claude | Fadel | Answer in chat | Classified by Claude | Claude proposed to leave Docker for the public release. Fadel, 2026-10-17 21:15 UTC: "Ignore for now. We should use vercel for everything for now". | |
| A5The project name is `experta-doe`, so the address is `experta-doe.vercel.app`. `experta.vercel.app` is in use by another site (checked on 2026-10-17). | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-17 21:15 UTC: "experta.vercel.app would be great if it is available". It was in use; Claude proposed experta-doe; Fadel, 21:19 UTC: "experta-doe is fine". | |
| A6Vercel's Git integration on `fmegahed/experta`: `main` deploys to production; other branches get preview deployments that only the Vercel team can open. | Claude | Fadel | Answer in chat | Classified by Claude | Claude proposed the Git integration. Fadel, 2026-10-17 21:15 UTC: "Yes, that would be perfect so it auto deploys with each update". | |
| A7The first deploy is measured before other work starts (Section 4.1). | Claude | Fadel | Answer in chat | Classified by Claude | Claude proposed to measure the first deploy. Fadel, 2026-10-17 21:15 UTC: "Sure". | |
| A8Ensemble mode: all four voters. | Claude | Fadel | Answer in chat | Classified by Claude | Claude proposed the ensemble with all four voters. Fadel, 2026-10-17 21:15 UTC: "Yes that is the plan". | |
| A9The limits stay at the defaults: 10 translations per minute and 100 per day for each address, USD 5 for each provider for each day. | Claude | Fadel | Answer in chat | Classified by Claude | Claude proposed to keep the default limits of Milestone 3A. Fadel, 2026-10-17 21:15 UTC: "Sounds good". | |
| A10Each LLM call reserves its worst-case cost before the call. The real cost replaces the reservation after the call. This closes the spec 17.1 item on cap overshoot. | Claude | Fadel | Answer in chat | Classified by Claude | Item 10 of Claude's list with recommendations. Fadel, 2026-10-17 21:15 UTC: "10--17 I will follow your recommendations". | |
| A11A Content Security Policy is set now. The browser tests run with it. | Claude | Fadel | Answer in chat | Classified by Claude | Item 11 of Claude's list with recommendations. Fadel, 2026-10-17 21:15 UTC: "10--17 I will follow your recommendations". | |
| A12The review page files an answer only when the link has the review key. | Claude | Fadel | Answer in chat | Classified by Claude | Item 12 of Claude's list with recommendations. Fadel, 2026-10-17 21:15 UTC: "10--17 I will follow your recommendations". | |
| A13The questions: the guarantee table (spec 7.7), the 35 glossary entries, R23, the spec 1.8 references, the refused FrF2 defaults `26-17.1` and `27-18.1`, and "Other comments". The Dark2 purple is settled, so the page does not ask about it. | Claude | Fadel | Answer in chat | Classified by Claude | Item 13 of Claude's list. Fadel, 2026-10-17 21:15 UTC: "I will follow your recommendations (but we setlled the purple color ...)", so the purple question was removed. | |
| A14Each answer becomes one GitHub issue with the label `alpha-review`. A fine-grained token that can only read and write issues on the repository files it. Each question has the choices Agree, Change and Not sure, and an optional comment. The page reads the issues back and shows which questions have an answer. | Claude | Fadel | Answer in chat | Classified by Claude | Fadel chose "In-app page → GitHub issues (Recommended)" (2026-10-17 11:21 UTC) and accepted item 14 at 21:15 UTC: "10--17 I will follow your recommendations". | |
| A15The private repository gets the full history of `main`, after a secret scan of each commit. `refs/` and `alan_feedback/` go into `.gitignore`. `public/brand/tecnologico-de-monterrey-blue.png` (the fallback that spec 9.8 names) is committed. | Claude | Fadel | Answer in chat | Classified by Claude | Fadel chose "Private now (Recommended)" (2026-10-17 11:21 UTC) and accepted item 15 at 21:15 UTC: "10--17 I will follow your recommendations". | |
| A16Rulings 29 and 30 of Milestone 3C are fixed: "Delete all" resets step 1 and stops a translation in flight. | Claude | Fadel | Answer in chat | Classified by Claude | Claude surfaced Rulings 29 and 30 of Milestone 3C and proposed the fix (item 16). Fadel, 2026-10-17 21:15 UTC: "10--17 I will follow your recommendations". | |
| A17Ruling 25 of Milestone 3C stays as built: option (a), the note under "Request text". | Claude | Fadel | Answer in chat | Classified by Claude | Claude proposed to keep Ruling 25 of Milestone 3C as built (item 17). Fadel, 2026-10-17 21:15 UTC: "10--17 I will follow your recommendations". | |
| A18The stall limit of the engine start is measured on a slow device profile (spec 17.1 assigns it to the alpha). | Claude | Fadel | Approved with the plan | Classified by Claude | Item 18 of Claude's list got no answer (Fadel answered items 1 to 17). The design says "Claude, not objected"; Fadel approved it, 2026-10-17 21:26 UTC: "yes, write the plan". | |
| AP1The counters are Lua scripts run with `EVAL` (one atomic step each). The unit tests run the same scripts on `ioredis-mock`. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP2The reserve of an LLM voter covers two calls (the first call and the repair retry, `llm-voter.ts`): input `2 × b + 8192` tokens and output `2 × 8192` tokens, where `b` is `callBound(threadMessages(turns)).inputTokens` and 8192 is `MAX_OUTPUT_TOKENS`. The reserve of Jev is the UTF-8 bytes of its request as input tokens. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP3An LLM voter settles at the spec 13.1 charge: `usage + unread`. A Jev call that the deadline cut off keeps its reserve; any other Jev call settles at its usage. This refines design 4.2 ("a voter that the deadline cut off keeps the full reserve"). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP4A store that is missing or fails gives `503 { kind: "unavailable", message: MESSAGES.store_unavailable }` = "Interpretation is not available now. You can fill in the form yourself." | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP5The rate-limit keys hold `HMAC-SHA256(RATE_LIMIT_SALT, address)` in hex. Without a salt of at least 32 characters, the Redis store is not used (store kind `none`). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP6The review route has its own limits (30 per minute, 300 per day per address, key prefix `rv`), a body cap of 16 KB, and answers that only a request with the key can read. Each instance keeps the issue list for 60 seconds and drops it after its own POST. An issue with the label `withdrawn` does not count. "Other comments" has no choices and needs a comment. The progress count leaves out "Other comments" (54 questions). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP7The deployed-site checks have their own Playwright configuration (`playwright.deployed.config.ts`, `FFD_BASE_URL` required) and never run in `npm run check`. The rate-limit check stops before its second request if the first answer is not "unavailable" (that is, if keys are set). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP8The slow-device profile is the Lighthouse mobile default: CPU 4× slower, latency 150 ms, download 1,638.4 kbit/s, upload 675 kbit/s, set with the Chrome DevTools Protocol. The measured gap is the longest time between two changes of the footer text during the download ("R engine: loading (p%), x of y MB"); the text changes at each 0.1 MB, so this gap is an upper bound of the gap between progress messages. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP9The stall rule stays as it is ("3 × the longest progress gap, rounded up to whole seconds"); `scripts/derive-budgets.mjs` adds the slow-profile CSV to its sources. | Claude | Measured, Fadel | Measurement | Classified by Claude | The rule (3 x the longest progress gap, rounded up) was fixed before the slow-profile runs and approved with the plan (2026-10-17 21:43 UTC); the runs set the value. | |
| AP10`package.json` `engines.node` becomes `">=22.14.0 <23"`, and the Vercel project uses Node.js 22.x. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP11The secret scan reads the added lines of every commit (`git log -p --all`) and reports: (a) each `.env` value whose name matches `KEY|TOKEN|SECRET|SALT|PASSWORD` and that has at least 12 characters, and (b) the fixed key patterns of Facts. It prints the variable or pattern name, the commit and the path, never the value, and exits with status 1 when it finds one. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP12The controller links Vercel from the worktree (`vercel link`), whose `.gitignore` has `.vercel/` (Task 1). Vercel is connected to the empty repository before the first push, so the push of `main` makes the first production deploy from Git. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP13The Upstash SDK runs with `enableTelemetry: false`. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| AP14The controller installs the three packages once, before Task 1, while Dropbox is paused, and commits the two package files. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the alpha release plan without a change to this row, 2026-10-17 21:43 UTC: "I like your recommendations for execution" | |
| Ruling 1Task 3's report shows generators in the format of generatorLines() ("Feed = Temp·Pressure·Speed"), not "Feed = Temp:Pressure:Speed" — the report must match step 3, and generatorLines() is the shared source | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 2Task 4's downloads test reads the stored project from IndexedDB with its own small helper (the code of records.spec.ts); Task 5 moves those helpers to helpers/records.ts and switches downloads.spec.ts to them | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 3exclude replication_materials/plans from tsconfig — the probe specs in m3c-probes/ are records whose relative imports resolve only from tests/e2e, and plan records are not app code (vitest and Playwright do not collect them) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 4the synthetic 32,768-row, 15-factor report goes in one shared fixture, replication_materials/tests/fixtures/large-report.ts, used by Task 2 (xlsx and archive tests) and Task 3 (report test) — the plan asks for it three times in two tasks, and three copies would drift | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 5Task 3's "Specification" section holds a factor table (Factor, Low, High, Unit, Type: quantitative or qualitative; <th scope="col">) and a list of the design settings that CoreSpec holds (runs, resolution, replications, center points, randomization, seed — only fields that exist) — spec 8.3 and mockup 05b name the section but show only placeholder lines; the table mirrors the step 2 card | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 6the report's subtitle and Versions section read project.versions (the versions the browser ran: R 4.6.0, webR 0.6.0 in the fixture), not report.versions (made by native R 4.6.1 for the fixture) — as rScript does in Task 1 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 7DesignStep gives DownloadMenu the DesignProject `{ ...project, r_code: project.r_code ?? generateCode(project.spec).designCode }` whenever the design shows (spec and report present) — the page already shows that fallback code, so the menu appears with every shown design and the .R file equals the page's code (spec 8.3 "same file from each place") | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 8"Print" is in RunSheet.tsx:61, not DesignView; DesignView passes the menu to RunSheet as an `actions?: ReactNode` prop rendered right after Print, so RunSheet stays free of project logic — the brief's "beside Print" and mockup 05b put Print and Download side by side | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 9"Report and all files (step 6)" is an `<a href="/app?project={id}&step=6">` whose click (without modifier keys) calls go(project.id, 6) and prevents the default — the brief tests a link (role link), and no step link exists yet; go() builds the same address with URLSearchParams | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 10Task 5 dispatch rulings — Duplicate uses crypto.randomUUID, new Date() and the device time zone as newDesign does and opens the copy at the current step; Rename goes through saveProject (which stamps updated_at); Delete of a project that is not open keeps the address, focus to "New design" in both cases; Export all takes one file per listed readable project from store.raw (unreadable records excluded, C8); failStore shows CLOSED_ERROR when the error's message is CLOSED_ERROR, else STORE_ERROR — the brief leaves these open; each follows an existing pattern or a C-decision | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 11Review Focus 5 says the result of a download is announced once, but no brief asks for it (Tasks 4, 5, 7 make downloads). Task 9 (accessibility) adds one polite announcement in lib/projects/download.ts's shared downloadBlob, a fixed text such as "Download started: {file name}." in that module, with a unit test of the text and a Chromium assertion — one place covers every download, and "started" does not claim what the browser does next | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 12after a failed "Delete project", focus returns to that project's "Project actions: {name}" button; after a failed "Delete all", to "Clear"; the store error is shown and announced as now — the action did not happen, so focus goes back where the user started it (the "Keep" rules of C14) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 13Task 6 import rules the brief leaves open — (a) existingIds = ids of listed projects + keys of unreadable records + ids already taken earlier in the same selection, so no stored record and no file of the same batch is overwritten (C2: nothing on the device is overwritten); (b) importChecks holds only imported projects with a stored report or pending_rebuild (a project with a spec and no report makes its first design in step 3 as now, with no import text; one without a spec has nothing to check); (c) the import check never writes: on IMPORT_MATCH and IMPORT_DIFFERS the stored record stays unchanged, and only a held project follows P1 (replace the report on a match), with "Project imported. " before REBUILT or DIFFERS; (d) announcements: one per import action — polite importedCount(n) when nothing failed; one assertive text with the count (if n > 0) and the error messages when something failed; (e) the file input (multiple, accept ".json,.zip", visible label "Import project") clears its value after reading, so the same file can be chosen again; (f) newId = crypto.randomUUID | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 14the project file inside "All files (.zip)" is made from the stored record, as "Export project" is: ArchiveOptions gets `record: Record<string, unknown>` (the store.raw record) and allFilesZip writes projectFileText(options.record, …); StepProps gets `readRecord(id): Promise<Record<string, unknown> | undefined>` (Workspace passes store.raw) for ReportStep — projectFileText serialises the object as given, and the in-memory project has zod's key order and schema defaults, so the two places could give different bytes (spec 8.3, C7 "equal projects give equal files") | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 15the preview frame is `sandbox="allow-same-origin allow-modals"`, not C11's `allow-same-origin` alone — Chromium ignores print() in a sandboxed document without allow-modals, so "Print / PDF" would do nothing while the stubbed test passes; without allow-scripts no script runs, so C11's reason holds; Task 7 checks with the real print() that Chromium logs no "Ignored call to 'print()'" message | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 16when the import check differs and versionChanges is empty, the import_differs state shows and announces NO_VERSION_CHANGE = "None. The stored R, webR, FrF2 and DoE.base versions equal the current versions." as its only list item — the plan-mandated IMPORT_DIFFERS ends "Versions that differ:" and the e2e case (only the SHA-256 changed) gives an empty list; 3B's DIFFERS has no list lead-in and stays as it is | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 17one helper `designProjectOf(project: Project | null): DesignProject | null` in lib/exports/types.ts (null without spec or report, or with pending_rebuild; r_code falls back to generateCode(spec).designCode) is used by DesignStep (replacing its inline build from Task 4) and ReportStep — steps 3 and 6 must hand the same value to the builders (spec 8.3), and two copies would drift | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 18a readStored that rejects or returns undefined gives RECORD_MISSING; an allFilesZip error gives ZIP_FAILED = "The archive of all files could not be made." (assertive, no file) — the read and the build fail for different reasons, and one text for both would name the wrong cause; the test forces the build failure by replacing crypto.subtle.digest | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 19Task 9 dispatch rulings — downloadNotice(fileName) = "Download started: {file name}." announced (polite) once in downloadBlob (Ruling 11's form); "Fields marked * are required." once above step 2's factor table; titles from the step rail's titles; focus targets that mount later use an effect on the state change; every sessionStorage access in try/catch; deferred a11y minors of Tasks 4, 5, 7 stay for the final review unless axe or a custom check fails on them | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 20focus drops outside C14's list are fixed in Task 9 before review — C14's rationale is "No focus may drop to the page body (WCAG 2.4.3)"; targets: a question after the first interpretation → the Answer field; a refusal → the request field; footer Retry and the footer Cancel of an R run → the step heading when the button unmounts; measure refusal and Retry first, fix only measured drops, one Chromium test each | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 21Task 10 "before the landing page is drawn" is asserted as no first-contentful-paint on the "/" document. An init script (PerformanceObserver, type "paint") writes sessionStorage "flow:landing-painted" when location.pathname is "/". The test also asserts that the landing h1 is not visible after the redirect. Stability is measured with --repeat-each=10. A paint in any run is reported as a spec 9.2 defect (DONE_WITH_CONCERNS), not hidden — why: the head script (app/layout.tsx:20-21) is synchronous, so "drawn" means painted, not parsed; a DOM check would fail on the parsed but unpainted h1 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 22spec version 5 records the rulings that changed what was built: 11 (download announcement), 12 and 20 (focus rules), 13 (import rules), 14 (archive project file from the stored record), 15 (allow-modals), 16 (NO_VERSION_CHANGE), 18 (RECORD_MISSING, ZIP_FAILED), and C10, C11, C16, which are not in the brief's list of edits; each is written as spec text, with no ruling number; the list is in W/task-11-rulings.md — why: the spec is the authority, and an unrecorded change would make version 5 describe a different app | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 23the stall-limit caveat stays in 17.1 as its own open row ("The stall limit (4 s) of the engine start was measured on one fast desktop computer." | Fadel M. Megahed | Alpha release: measure on a slower device) — why: 3C did not measure it again, so marking it done would drop an open risk | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling (Milestone 3C ledger): the open row keeps Fadel as owner. The alpha release then measured the limit (A18); no person changed the ruling. | |
| Ruling 24e27's source transcript is "e39a0a82", the session in which Tasks 2 to 11 ran and the event time falls; e27's detail and time are written again after the final review, as 3B did for e25 — why: source.time must come from the transcript that names it | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 25Important 3 takes option (a). When "Request text" is unchecked, step 6 shows "The project name stays in the file names and in the report. To change it, rename the project." The spec says that the name is not part of the request text — why: C1 covers the request and the clarification turns, and the name is the user's own label, which Rename changes. Option (b) would give two exports of one project different names and would touch five builders | Claude | Claude, Fadel | Ruling during a build Stood |
Classified by Claude | Claude's ruling (option a). Fadel kept it as decision A17 of the alpha design, 2026-10-17 21:15 UTC: "10--17 I will follow your recommendations". | |
| Ruling 26the fix wave covers F1-F10 of W/final-findings.md: the three Important findings; the three must-fix deferred minors; and the cheap extras with a user-visible effect (spec 7.9 Status, XML control characters in the .xlsx, the .R file from r_code, the "The project was deleted." announcement, an empty-file import test, the CSV choice in the spec). These stay deferred: putRecord put versus add (multi-tab, spec silent), the xlsx DOS time zone, the Blob URL revoke timing (Milestone 4 cross-browser), a crafted pending_rebuild, no busy state on Export all, Ruling 10's duplicate step, and the 45 "can stay" minors — why: one wave, limited to defects a user meets and lines of the spec that are wrong | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 27the .csv file writes values unchanged, with no formula prefix, and spec 8.3 says so — why: the .csv is the file for R and Python, a prefix would change the data, and the .xlsx (inline strings) is the file for spreadsheet programs | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 28the step 1 draft is removed after a successful "Fill in the form yourself" (keys "new" and the project's), after "Delete all" (every ffd-draft: key), and after a project delete (its key) — why: "Delete all" is the privacy action, and typed text must not come back after it on a shared computer | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling 29Parked: the typed text stays in the field after "Delete all" when step 1 is open with no project. The text never comes back after a navigation, so the letter of Ruling 28 holds. It is surfaced to the authors at the merge decision. The fix is a generation counter in Workspace, combined into StepPanel's key, plus one Chromium assertion — why: the skill allows no second fix wave, and the residual is Minor | Claude | Claude | Ruling during a build Changed later: see A16 |
Classified by Claude | Parked by Claude and surfaced at the merge. Fadel decided to fix it in the alpha (A16), 2026-10-17 21:15 UTC: "10--17 I will follow your recommendations". | |
| Ruling 30Parked and surfaced as a merge option: a translation that runs on step 1 with no project open survives "Clear → Delete all", and its answer then stores a new project with the request text. This existed before 3C's fix wave. The fix is the same generation key, which remounts step 1 and stops the request, plus one Chromium test — why: it is a privacy defect that a user can meet only by deleting during a running request; no later task builds on it, and the skill gives no second fix wave | Claude | Claude | Ruling during a build Changed later: see A16 |
Classified by Claude | Parked by Claude and surfaced at the merge. Fadel decided to fix it in the alpha (A16), 2026-10-17 21:15 UTC: "10--17 I will follow your recommendations". | |
| Ruling 31the closing docs commit changes the defaults of build-spec-page.mjs from "version 4" to "version 5" (ribbon and description) and rebuilds the spec page — why: Task 11 made version 5, and the page label is part of the document record, not app code | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| C1Step 6 has a "Request text" check box, checked by default. It decides whether the report and the project file inside "All files (.zip)" contain the request and the clarification turns. Without the request, the project file also drops the quotes of the card ("From your text" values become interpretation values). "Export project" in the project menu always gives the whole project. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-17 11:41 UTC: "Step 6 check box, on (Recommended)". | |
| C2An imported project whose id is already on the device gets a new id and the name "{name} (imported)". Nothing on the device is overwritten. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-17 11:41 UTC: "Keep both (Recommended)". | |
| C3No byte progress for `R.wasm`. Until the first package progress message, the footer says "R engine: starting R" (no percentage). After the last package byte, it says "R engine: preparing the R packages", and the stall timer stops, because the save to IndexedDB and the FrF2 load send no progress. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C4The report stays parsed on the main thread. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C5After a save, the workspace replaces the saved project in its list (`withSaved`) and does not read all projects again (3B M5). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C6The `.xlsx` file is hand-built OOXML (inline strings, one hidden sheet, a minimal style sheet) zipped with `fflate`. The same library writes and reads the `.zip` files. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C7The project file is `{ "format": "experta-project", "format_version": 1, "app_version": "...", "project": <stored record> }` as UTF-8 JSON with two-space indentation and a final newline. It has no export time, so equal projects give equal files. A project whose report waits for a rebuild is exported from its stored record. Import reads the record with the store's `readRecord` (current or older report version). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C8"Export all (.zip)" gives `experta-projects-{yyyy-mm-dd}.zip` with one `{stem}.project.json` per readable project (names made unique with `-2`, `-3`). "Import project" accepts `.json` files and `.zip` files; it imports every `*.project.json` in a `.zip`. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C9The import check of spec 8.5 runs in step 3 of the imported project, in this session: R makes the design again from the spec and the seed and compares the run-sheet SHA-256. Equal: "Project imported. The rebuilt design matches the stored run sheet (SHA-256)." Different: the stored run sheet stays, and the step names the versions that differ. A project with an older report version uses the P1 rebuild path. A project with a spec and no card gets a card from its spec, with a new origin `imported` that shows the label "From the project file". | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C10The project menu is a disclosure button per project ("Project actions: {name}", `aria-expanded`), with four buttons: Rename, Duplicate, Export project (.json), Delete. It is not an ARIA menu. Rename and Duplicate are not available for a project whose report waits for a rebuild (3B M3). Delete asks for confirmation in the page. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C11The report file is one HTML document: inline CSS, no script, no link, no external resource, system fonts (Georgia for headings, Arial for text), the accent `#625d96`, a print style sheet (each section starts on a new page, table headers repeat). Step 6 shows it in an `<iframe sandbox="allow-same-origin">` with `srcdoc` (no script can run); "Print / PDF" prints that frame. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C12The `.csv` file: RFC 4180 quoting, CRLF line ends, UTF-8 without a byte order mark, "NA" for a missing value, a final line end. Columns: Run, Std, the real levels (headers with units), then the coded levels (headers "{name} (coded)"). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C13Each step of the workspace sets the page title "Step {n}: {title} | EXPERTA". Required fields (factor name, low and high level) have `aria-required="true"`, and their "*" is `aria-hidden`. The accessibility sweep is a guard in `npm run check` on every page; it defines the five custom checks of spec 11 as Playwright assertions. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C14Focus rules (3B M4 and P17): "Delete all" moves focus to "New design"; "Keep projects" returns it to "Clear"; "Delete record" moves it to the "Your projects" heading; "Keep record" returns it to that record's "Delete"; Cancel of a translation returns it to the request field (or the Answer field); Cancel of an R run moves it to the step heading; "Previous rows" and "Next rows" use `aria-disabled` at the ends; "Interpret request" and "Send answer" use `aria-disabled` while busy. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C15The unsent text of step 1 is kept in `sessionStorage` (key `ffd-draft:{project id or "new"}`) and comes back after a plain link and the browser's Back button; it is removed when the interpretation is stored (3B M8). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C16A select of step 2 whose value is not in its list (a disagreement chose a run size or resolution that the list does not have) shows that value as "{value} (not available)"; the field's error stays and "Generate design" stays unavailable (3B M7). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| C17The 2026-10-14 mockups show the red accent of that date. They fix the layout and the labels only; colours come from the tokens of spec 9.8 (purple). The mockups stay unchanged, because they record what was selected then. | Claude | Fadel | Approved with the plan | Classified by Claude | Fadel, 2026-10-17 11:27 UTC: "The mockups do not use the purple color". Claude's answer (the tokens set the colours; the mockups stay) was approved with the plan at 12:33 UTC. | |
| C18The controller installs `fflate` and `@axe-core/playwright` once, before Task 1, while Dropbox is paused, and commits the two package files. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3C plan without a change to this row, 2026-10-17 12:33 UTC: "sub-agent driven" | |
| RulingB1, B2, I3, I4, I6, I7 and Minors 8-10, 12-14, 16, 18-22 accepted as the scan proposes — each is a measured defect with a verified fix | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingI5 extended — content-length check plus a streamed byte cap (chunked bodies too); the per-IP limit stays after parsing, because a refused request makes no provider call | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingMinor 11 partly — NFKC, U+2212 and thousands separators fixed; Spanish "once" kept (slice S2 has Spanish number words), English "once" recorded as a known false match for 11 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingMinor 15 — outcomeOrdersAgree stays evaluation-only (Milestone 4), documented at the type | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingMinor 17 — import type allowed from any lib/translate module; messages.ts uses the JSON import attribute; Task 10 gains an `npm run build` step | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe number reader uses NFC plus a full-width digit map, not NFKC — NFKC turns "2⁴" into 24, a number the user did not write | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingbyte cap 7 x 12 x MAX_REQUEST_CHARS + 4096 — a client may escape one character as two backslash-u sequences | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingon a NoObjectGeneratedError the voter parses error.text and lets validateModelResult report the errors with field paths; non-JSON text gets the fixed "The answer is not valid JSON." — the brief's firstLine(error.cause) kept only "Type validation failed: Value: {...}", so the repair retry never named the failed field (spec 5.7 item 6), and a schema vote's message carried 300 characters of the model's answer | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingadd a committed test for a deadline during the retry keeping a schema-valid first answer (P4); the implementer had verified it only with a deleted test | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulinga call without text counts its usage and follows the schema-failure path (one retry) — spec 5.7 gives one retry to an answer that fails the schema, and no answer fails it | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingkeep a schema-valid first answer on a provider error during the retry (extends P4); carry to Task 12: record it in spec 5.7 item 6 with P4 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe empty previous answer is sent as "(no answer)" — Anthropic rejects empty text blocks | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe Jev voter keeps the served model id when interpretJev refuses the answer — the record of a paid call names its model | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingsignal.throwIfAborted() right after the Jev call — an answer after the deadline gives "deadline" even from a client that ignores the signal (the real SDK takes { signal }) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulinga deadline between the answer and the interpretation stays "deadline" (same as the LLM voter) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingan unknown number label throws the fixed "Jev gave an unknown number label." (no label in the message: labels hold user words); outcomeOrdersAgree is false when a choice is missing — fail closed like the outcome and category paths | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingties break in request order (strict >, first label sent wins) — reproducible across server key orders | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe 254-candidate cut keeps the first 254 in text order; recorded in a comment and a 300-number test — rare (pasted tables), gives a disagreement flag, not a silent value | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix now — canonical uses a new exported exactNumber(text) in numbers.ts (whole text must be one NUMBER match), and computeAgreement sorts the LLM opinions by VOTERS order — one number reader for the whole module set, and P6/P7 must not depend on the caller | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingdiscard the earlier session's untracked Task 8 files and run Task 8 again from its brief with a fresh implementer — the files have no report, no TDD evidence and no self-review, and a transcription task costs little to redo | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingcommits made in this session end with the Co-Authored-By line only; the Claude-Session line is dropped — that link names the earlier session, and a wrong session link in the replication record is worse than none | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingamend the message of 1791f48 to the Opus 5.5 line — the global rule is word for word and every earlier commit carries it | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe hard stop goes into the voters at the provider call (exported untilAborted in llm-voter.ts, used by both voters), not into translate.ts — a race in translate.ts would cut off an LLM voter before its catch keeps a schema-valid first answer (P4); a race at the call lets each voter's own deadline path run at once | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingLlmVote.attempts counts the answers received before the deadline; the Task 5 test of a provider that aborts inside doGenerate then answers expects attempts 0 — the late answer is refused by the race | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix Minor 1 now — translate orders the LLM votes by VOTERS before the reports and the base spec — same principle as the Task 7 ruling (P6/P7 must not depend on the caller) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix Minor 2 (a) and (c) now (stated requirements of the brief without a test); (d) is covered by the new hanging-Jev test. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulinga Jev answer that arrives after the deadline is not read: the failed vote has zero usage and model id null; change that test's expectations and name, and keep the Task 6 rule (served model and usage kept) for answers received before the deadline — the response must not wait for a client that ignores the signal, and the race cannot read a late answer | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix the Important now although config already refuses a NaN cap — the tracker is a money control and must fail closed on its own: capReached is true unless total < cap, and record treats a non-finite or negative cost as reaching the cap for the rest of the UTC day — same direction as P10's highest-price rule for an unknown model | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix two Minors now that give the carried and new paths real evidence: a test with a hand-built table whose periods are out of order, and a log test for kind "result" | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingcount an upper bound for each LLM call whose answer is not read because the deadline passed — new LlmVote/VoterReport field unread (input: UTF-8 bytes of the JSON of instructions, messages and the model-facing JSON Schema, since a token has at least one byte; output: MAX_OUTPUT_TOKENS); the handler charges usage + unread, and the log records unread tokens — the caps are the money control that P11 relies on and must fail closed; this also closes the gap that the Task 8 race ruling left | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulinga Jev call cut off by the deadline is not bounded — measured cost about USD 0.0002 per call and its output price is 0 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix Minors 2, 3, 4 and 5 now (tests at the edges of stated limits, one comment) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingkeep unread in the 200 body — the body is TranslateOutput by contract (brief: "200 | TranslateOutput (Task 8)"), VoterReport now types the field, and it holds token counts only (no user text, no secret); carry to Task 12 (spec contract note) and to 3B (the card ignores unread; it is accounting data) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingevery live command runs through the redaction filter, and the implementer never reads or prints .env — the authors' condition | Fadel | Fadel, Claude | Answer in chat Stood |
Classified by Claude | Fadel, 2026-10-16 11:55 UTC: "copy the four keys (as long as this won't leak, i.e, their values are never committed or printed in the conversation)". The filter is Claude's method. | |
| Rulingthe controller runs the paid live commands of Step 4 itself, in this session where the authors' approval is visible, through the redaction filter; the implementer then does Steps 5-6 (unit test, check, commit) — the approval names this exact action, and the controller doing a command is not a code fix that skips review | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling on who runs the paid commands. It rests on Fadel's approval, 2026-10-16 11:55 UTC: "approved, copy the four keys ... and run all four voters". | |
| Rulingcarry out the authors' decision in agreement.ts too — Jev's numbers count whenever an LLM voter gave a design (whatever Jev's outcome), and Jev's category is compared only when an LLM voter also gave a scope category — the authors chose "Jev still votes on the numbers", and a lone Jev category on a design request would show a category flag with nothing to cross-check | Claude | Fadel, Claude | Answer in chat Stood |
Classified by Claude | Fadel chose "Flag only (Recommended)" (2026-10-16 12:07 UTC), whose text says that Jev still votes on the numbers. The rule for the category is Claude's. | |
| Rulingthe 100 Google calls run through the Task 11 latency test with two new environment parameters (FFD_LIVE_REPEATS, default 2; FFD_LIVE_CSV, default m3a-translate-latency.csv), written by the Task 11 implementer and reviewed with Task 11; output CSV replication_materials/tests/perf/m3a-google-latency-100.csv — one measurement path for all latency data, no throwaway script | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthis session now has its own session link; commits from here on end with Co-Authored-By and Claude-Session: https://claude.ai/code/session_01Wc7WXMFHs2SXBhwsTi2xnf — the earlier ruling dropped the line only because the old link named another session | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingencode the authors' 40 s as a rule that the derive script recomputes — deadline = the largest LLM-voter p95, rounded up to a whole 10 s, each voter's p95 from its largest sample (the 100-call CSVs for the LLMs, the 4-voter CSV for Jev) — today exactly 40000 ms; the unit test also checks that every LLM p95 and the OpenAI and Anthropic p99 are below the deadline — a measured, reproducible threshold (the authors' "measure, don't guess" rule); pooling Google's 20-call and 100-call samples would give a p95 above 40 s, and the authors based the decision on the 100-call sample | Fadel | Fadel, Claude | Answer in chat Stood |
Classified by Claude | Fadel, 2026-10-16 12:56 UTC: "I am leaning towards using 40 seconds as the cutoff driven from the ~p95". Claude wrote the rule that gives 40 s from the data. | |
| Rulingdrop the outcome from the Jev smoke expectation and keep status, model id and numbers — Jev's outcome is a flag only (authors' decision) and a smoke test that is red from the start hides real model changes; no re-run, because the received object of the controller's run matches the new expectation | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling on a test expectation. It follows Fadel's answer "Flag only (Recommended)" (2026-10-16 12:07 UTC). | |
| Rulingfix Minors 2-8 now (they guard paid runs, the deadline file and the authors' 40 s; one revert; two text fixes) | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling on review findings (Milestone 3A ledger). The 40 s deadline of the authors is only named as a reason. | |
| Rulingfix the placement, the Jev cost (measured value) and the backticks in one round | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingone fix wave (final-fix-wave.md) with I2 (left_out in the response meta, voter ids moved to schema.ts, total unchanged), M1, M2 (+ jev_questions_version in meta and log), M3 (answered), M6 (comments), M8, M9, M10, M11, M12, M14, two missing tests, and I1 recorded in spec 17.1/17.2 — cheap items that 3B or the gate depend on, plus two security guards | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingtotal keeps counting the voters that have a key; a voter without a key appears in left_out with reason no_key — the card can name all four voters without changing "n of total" semantics or the reviewed tests | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe fixtures get left_out [], jev_questions_version "jev-q1" and agreement answered counts by script, without a paid re-recording — every recorded case had all four voters with keys and no cap, the Jev questions were the v1 texts, and answered is the sum of the recorded counts | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingI1 is recorded in the spec now and implemented before deployment (Milestone 4) — the review grades it as not blocking the merge once recorded; a reservation needs a per-request bound design | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingacknowledge and record as a Milestone 4 deployment item in spec 17.1 (added to F6 of the fix wave), not a code change now — it is decision P11 (authors' accepted cost), the right source depends on the host (a host that overwrites the header vs a proxy that appends), and no deployment happens before Milestone 4; I1 weakens P11's "spend caps bound the cost", so both are listed together | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling (Milestone 3A ledger). It cites P11, which Fadel approved with the plan (2026-10-16 00:45 UTC); no person changed it. | |
| Rulingkeep; the mock resolves in a few ms and the module cache is warm, so 200 ms is ample margin (the review called widening optional) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe spec is incomplete, not contradictory; carry to the first docs task of 3B | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingcarry to Milestone 4 (the evaluation adds prompt versions) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingcarry to 3B (a Playwright spec that imports them would break the JSON constraint) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingkeep; the plan is the historical record and the ledger records the rename | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingkeep eval(parse(text = case$r$call)) in test-precheck-behaviour.R (flagged by a security hook) — it evaluates only call strings from the committed case file replication_materials/tests/fixtures/precheck-cases.json, never user input, and the calls hold nested factor.names lists that a structured do.call form would make harder to read | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingpin katex@0.19.0, not 0.18.11 — npm marks 0.18.11 deprecated ("Accidentally published with breaking changes. Use 0.19.0 instead."); the plan read 0.19.0 as a new minor line, but it is the corrected release of the same code, published 2026-10-01 (more than two weeks old); data/glossary.json is rebuilt and the drift test must pass | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix the WithHelp key now (key={helpKey} on the heading WithHelp in StepPanel) with a regression e2e test; carry to Task 6: its full StepPanel replacement keeps key={helpKey}, and DescribeStep's scope-notice WithHelp gets key={notice.scope} — the state leak shows the wrong panel to a user, and Task 6 overwrites StepPanel | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfinding 1 — no Generate test in Task 7; Task 8's design.spec clicks Generate design and checks step 3, the R code of the stored spec and the sidebar name | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfinding 3 — check-by-edit, Remove and Keep are covered by the Task 4 unit tests (editText resolves flags; removeFactor/keepFactors resolve the count flag), and the held-project rule is enforced by the store itself (Task 1 test: put of a pending project rejects); the unmount flush gets an e2e test in fix round 1; the held-project note stays untested UI text | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfinding 1 — skip the save when step 3 has closed (alive ref cleared on unmount); the next visit runs the design again (deterministic, a few seconds) — saving after close would need the current stored project, which a closed step does not have | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfinding 2 — add a failed-save state with text and Run again; the "project arrives after ready" path is not reachable: StepPanel keys DesignStep by project id, and Workspace sets the store and the project list in the same update, so the step remounts with both | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingcarry both fixes into Task 9, whose brief replaces DesignStep.tsx as a whole — otherwise Task 9 would undo them | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingone fix wave with I1 (fixed note in step 3 when the card differs from the stored spec), M1 + the Task 6 minor (keep an unsent answer, store the thread without it on a refusal), M2 + the Task 4 minor (seed "not given" means today's date; boolean choice test), the two Task 10 privacy sentences, the Task 9 Clear text, projectsSize in useMemo (part of M5), M9 glossary text (note backslashes, nruns "at least", clear_2fis wording; Alan R. Vazquez's own effect_hierarchy text stays), M10 (FrF2 message keys, Roman numeral in resolutionSentences), and two spec 17.1 rows for M5 and M6 — I1 is user-facing and cheap; the others are the reviewer's before-merge triage or one-line fixes | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling (Milestone 3B ledger). It keeps the effect_hierarchy text that Alan wrote; no person changed the ruling. | |
| RulingM3 (held project and closed-database texts; edits while held) deferred to 3C — no stored older-version report exists until the next report version step | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingM4 (focus lost when a focused button disables itself or unmounts: Interpret request, Send answer, Previous/Next rows, step 1 remount) deferred to the 3C accessibility sweep with the P17 focus items | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingM5 remainder (each save re-reads and re-parses all projects) carried to 3C with the P17 parse measurement; recorded as a spec 17.1 row in the fix wave | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingM6 (privacy notice fixed at build time on static pages) recorded as a Milestone 4 deployment item in spec 17.1 (rebuild after a mode change, or dynamic rendering) — no deployment before Milestone 4 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingM7 (a disagreement can set a run size or resolution that the select does not list) deferred to 3C — the error list names the value and Generate stays blocked | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingM8 (the step 1 draft is lost when the user follows a plain link) deferred to 3C | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingre-review note "DescribeStep keeps an unsent answer across projects" is not a defect — StepPanel.tsx:42-50 keys DescribeStep by project id, so a change of project remounts it and clears the field | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| P1A stored report with another `report_version` is not hidden. The store reads the project with `report: null` and `pending_rebuild: { report_version }`. Step 3 runs R again from the stored spec and seed and compares the run-sheet SHA-256. If it is equal, the new report replaces the old one; if it differs, the stored record stays unchanged and the step names the versions that differ. A record that matches no schema is listed in the sidebar as "cannot be opened", with Export and Delete. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-17 01:51 UTC: "Recompute from spec + seed (Recommended)". | |
| P2Milestone 3B uses R23 and the accent `#625d96` as they are. The main session publishes a one-page note that asks Alan R. Vazquez to confirm both, and the references of P4. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-17 01:51 UTC: "Proceed; I draft a note (Recommended)". The confirmation by Alan is still open. | |
| P3Claude drafts the glossary (35 entries). An entry with `reviewed_by: null` shows "Draft, not yet reviewed" in its panel and on the glossary page. The test "every `?` key has an entry" runs now; the test "every entry is reviewed" runs only with `FFD_RELEASE=1` and is a release gate (Milestone 4). | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-17 01:51 UTC: "I draft; label as draft (Recommended)". He made the same choice on 2026-10-15 23:57 UTC. | |
| P4The references are Wu and Hamada (2021, 3rd ed., Section 4.6), Box and Meyer (1986), Hamada and Wu (1992), Li, Sudarsanam and Frey (2006) and Ockuly et al. (2017), checked against Crossref on 2026-10-16. The glossary cites no number from Ockuly et al. (2017), because its abstract was not read. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-17 01:51 UTC: "My candidates, Alan confirms (Recommended)". | |
| P5The document pages (`scripts/spec-page.css`, `figures/architecture.svg`) use the accent `#625d96` (text accent `#4c4977`), and `#9e9ad0` and `#b0addb` in the dark theme, with the ribbon `#625d96` (light) and `#57538a` (dark). The old mockups and the earlier plan pages keep their colours, because they record what was decided then. | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-17 01:57 UTC: "Are not we replacing the Miami red with purple in those accents?" Claude then measured the purples for the document pages. | |
| P6Logic lives in `lib/` with vitest unit tests in Node. Components are thin and are tested in Chromium against the production build. No React Testing Library and no jsdom. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P7The project schema stays version 1. The new fields have defaults: `card` (null), `frf2_messages` ([]), `pending_rebuild` (null) and `request.notice` (null). A Milestone 2 record still reads. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P8Pre-checks add two rules to spec 6.2: a factor limit for each run size (the catalogue has no entry for, for example, 40 factors in 1024 runs, and FrF2 then stops with "subscript out of bounds"), and the refusal of the 7 default sizes whose catalogue entry has the status `broken` (FrF2 uses `26-17.1` for 26 factors in 512 runs without a message). The rows limit uses $(N + c) \times r$, as the report does. One JSON file holds the cases for the TypeScript test and the native R test. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P9The card is stored in the project. Each factor has an id, so its labels and flags move with it when the order changes. A disagreement or a "Check this value" flag blocks "Generate design" until the user selects a value, confirms it or edits it. A disagreement on the number of factors is resolved by "Keep these factors" or by an edit of the list. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P10A field where all voters that gave it agree shows "{n} of {n} agree" only when $n \ge 2$ (`answered`, not `checked`, because Jev gives only some fields). A field with one answer shows no agreement text; the voter summary says "Not cross-checked" when fewer than two voters are valid. The card ignores `voters[].unread` (accounting data). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P11A quote ("From your text") is shown only for a value that passed the evidence check. A value in `check_fields` shows "Check this value" instead. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P12`run_sheet_sha256` is the SHA-256 (hex) of the UTF-8 text `JSON.stringify({ labels, run, std, levels, coded })` from the report. 3C writes the same value into the hidden sheet of the `.xlsx` file and checks it on import. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P13A help panel has three parts: "What it means" (the glossary text, the review state and the source), "In your design" (sentences that `lib/report/explain.ts` computes) and a link to the glossary entry. "Watch this part" comes with the video (Milestone 4). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P14A new project gets its name from the first six words of the request, or "{k} factors in {n} runs" for a card filled by hand. A rename control comes with the project menu (3C). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P15Step 3 starts the run when the project has a spec and no report, and stores the report after the checks pass. "Print" prints the page that is shown; "Download" comes with the exports (3C). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P16The glossary source is `content/glossary.json` (text with `\( ... \)` math). `scripts/build-glossary.mjs` converts it with KaTeX (`output: "mathml"`, `throwOnError: false`, `trust: false`) to `data/glossary.json`, which is committed; a unit test fails if the two differ. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P17Moved to 3C: the download progress of `R.wasm` (spec 17.1), the measurement of the main-thread parse of the largest reports (Milestone 2 ledger), the focus after Clear and Cancel and the size of the Home link (axe sweep). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P18The FrF2 messages of the design call (`conditions`) are shown and stored in `frf2_messages`. The warnings of the report call (`reportConditions`) stay hidden. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P19A record that cannot be opened has Export (its stored JSON) and Delete in the sidebar. A project whose rebuild gives a different run sheet stays in storage unchanged; export of whole projects comes with the project menu (3C). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| P20The translate client validates every answer with a client zod schema (`lib/translate/response.ts`) and fails closed. A unit test checks that every recorded fixture matches it, and a type test checks that the schema and `TranslateApiResponse` describe the same object. Cancel aborts the request. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3B plan without a change to this row, 2026-10-17 03:39 UTC: "sub-agent driven" | |
| RulingFrF2 stores all.2fis.clear as the string "all" for 159 catalogue entries (resolution V and higher; checked over the whole catalogue, no other string occurs). The plan's as.integer() turned it into NA with a warning, so every resolution-V report would carry null and fail the page schema. Added "all" -> all factor positions, with the test 'a catalogue entry that stores "all" gives every factor' (RED: NA + coercion warning; GREEN) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingdata/catalogue-summary.json and data/guarantee-table.json embed report_version; regenerated with scripts/build-catalogue.R (diff: the version line only), because test-catalogue-files requires committed = fresh build — the plan missed these two files | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingadded one e2e assertion (shell.spec "Start a design opens the workspace": the link background is rgb(98, 93, 150)) beyond the plan, because the unit test reads tokens and class names but cannot see that Tailwind generates bg-accent (Review Focus 4); proved by a mutant (bg-accentx → rgba(0, 0, 0, 0), 1 failed) and restored (9 passed) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe accent on light tan measures 5.02:1; the plan's expected value 5.00 was the search threshold, not a measurement. The spec (9.8) quotes 5.02. The plan's "stop and report" was meant for real mismatches, and this is the plan's own rounding | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe spec (7.5) and the decision log also state that FrF2 stores all.2fis.clear as "all" for 159 entries (the Task 1 finding), so the documents match the code | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingevents e21 and e22 written in process.json's compact hand style (same fields and values as the plan's pretty-printed block) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Ruling4096 runs x 30 factors reports ok = FALSE — its default entry is a refused broken entry (Milestone 1 behaviour, not in this range) — stands | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingstored projects with an older report_version would fail the strict ReportSchema and be hidden by validOnly() — no code stores a report yet (newProject() stores report: null), so nothing is stranded now; carried to Milestone 3B as a design item (migrate, default, or recompute) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe R19 chart palette has no code yet (Phase 2) — spec text and measurement checked only — stands. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe plan page reads "Milestone pre-3B" (the plan's own title choice) — stands — cost: cosmetic. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingcommit trailers name Claude Opus 5.5 as the session's attribution reminder and the plan require — stands. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe 9.4 example note ("move that factor to position 9") is interface guidance, not a fixed scope message, so the advice-word rule does not apply — stands. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe Verification steps (e23, publishing, memory, merge question) are main-session work after the review — done next. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| R18The tool is EXPERTA, with the subtitle "Fractional Factorial Design Translator". The full name "EXPERTA: Fractional Factorial Design Translator" is in the browser title and the citation. Constants `APP_NAME`, `APP_SUBTITLE` and `APP_FULL_NAME` in `lib/site.ts`. Replaces R7. | Alan, Claude | Alan, Fadel | Review comment | Classified by Claude | Alan's review PDF (2026-10-16): "Name of the application: EXPERTA". Claude offered the subtitle form; Fadel chose "EXPERTA + subtitle (Recommended)" (2026-10-16 21:08 UTC). | |
| R19Charts: the Dark2 colours purple `#7570B3`, orange `#D95F02`, teal `#1B9E77` and gray `#666666`, in this order, at most four. Interface accent: `#625d96` (the Dark2 purple, darkened to pass WCAG AA for text), hover `#4c4977`. The favicon and the video title-card rule use the accent. Replaces the Miami Red accent and the ChatISA chart palette. | Alan, Fadel, Claude | Alan, Fadel | Review comment | Classified by Claude | Alan's PDF asked for purple. Fadel proposed Dark2 with a purple accent (2026-10-16 21:21 UTC); Claude darkened it for contrast; Fadel chose "Dark2, adjusted (Recommended)" at 21:24 UTC. | |
| R20New Section 1.8: effect hierarchy, effect sparsity and effect heredity (strong and weak). The Phase 1 report follows the hierarchy principle. Phase 2 uses sparsity and heredity in the analysis. | Alan | Alan, Fadel | Review comment | Classified by Claude | Alan's review PDF (2026-10-16), section "General". Fadel chose to apply his changes in one plan: "Small pre-3B change set (Recommended)" (2026-10-16 21:08 UTC). | |
| R21The report shows the number of clear 2FIs and the factors with all 2FIs clear, as FrF2 does (`nclear.2fis`, `clear.2fis`, `all.2fis.clear`). This is a measure only: minimum aberration stays the selection rule, and requests for MaxC2 stay "not supported". Estimable 2FIs move from Phase 3 to "Later (not planned)". | Alan, Claude | Alan, Fadel | Review comment | Classified by Claude | Alan's PDF put the clear 2FIs in the Phase 1 report. Fadel chose "Measure only (Recommended)" and "Later (not planned) (Recommended)" (2026-10-16 21:14 UTC). | |
| R22The not-supported message adds: "Step 3 lists the clear two-factor interactions (2FIs). To change which factors have them, change the factor order in step 2." The scope rule against alternatives (D1, Section 1.6) applies to out-of-scope requests; this request is in scope. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question after Alan's review, Fadel, 2026-10-16 21:14 UTC: "Point to factor order (Recommended)". | |
| R23All $\binom{k}{2}$ 2FIs of a full factorial are clear, and all its factors have all 2FIs clear. Before this decision the report gave none, because a full factorial has no catalogue entry. The independent check of the tests (`clear_2fis_from_cube`) already counted them as clear. | Claude | Fadel | Approved with the plan | Classified by Claude | Claude found the gap and proposed the rule. Fadel approved the pre-3B plan, 2026-10-16 21:39 UTC: "I will follow your recommendation". Alan's confirmation is an alpha review question. | |
| R18The tool is EXPERTA, with the subtitle "Fractional Factorial Design Translator". The full name "EXPERTA: Fractional Factorial Design Translator" is in the browser title and the citation. Constants `APP_NAME`, `APP_SUBTITLE` and `APP_FULL_NAME` in `lib/site.ts`. Replaces R7. | Alan, Claude | Alan, Fadel | Review comment | Classified by Claude | Alan's review PDF (2026-10-16): "Name of the application: EXPERTA". Claude offered the subtitle form; Fadel chose "EXPERTA + subtitle (Recommended)" (2026-10-16 21:08 UTC). | |
| R19Charts: the Dark2 colours purple `#7570B3`, orange `#D95F02`, teal `#1B9E77` and gray `#666666`, in this order, at most four. Interface accent: `#625d96` (the Dark2 purple, darkened to pass WCAG AA for text), hover `#4c4977`. The favicon and the video title-card rule use the accent. Replaces the Miami Red accent and the ChatISA chart palette. | Alan, Fadel, Claude | Alan, Fadel | Review comment | Classified by Claude | Alan's PDF asked for purple. Fadel proposed Dark2 with a purple accent (2026-10-16 21:21 UTC); Claude darkened it for contrast; Fadel chose "Dark2, adjusted (Recommended)" at 21:24 UTC. | |
| R20New Section 1.8: effect hierarchy, effect sparsity and effect heredity (strong and weak). The Phase 1 report follows the hierarchy principle. Phase 2 uses sparsity and heredity in the analysis. | Alan | Alan, Fadel | Review comment | Classified by Claude | Alan's review PDF (2026-10-16), section "General". Fadel chose to apply his changes in one plan: "Small pre-3B change set (Recommended)" (2026-10-16 21:08 UTC). | |
| R21The report shows the number of clear 2FIs and the factors with all 2FIs clear, as FrF2 does (`nclear.2fis`, `clear.2fis`, `all.2fis.clear`). This is a measure only: minimum aberration stays the selection rule, and requests for MaxC2 stay "not supported". Estimable 2FIs move from Phase 3 to "Later (not planned)". | Alan, Claude | Alan, Fadel | Review comment | Classified by Claude | Alan's PDF put the clear 2FIs in the Phase 1 report. Fadel chose "Measure only (Recommended)" and "Later (not planned) (Recommended)" (2026-10-16 21:14 UTC). | |
| R22The not-supported message adds: "Step 3 lists the clear two-factor interactions (2FIs). To change which factors have them, change the factor order in step 2." The scope rule against alternatives (D1, Section 1.6) applies to out-of-scope requests; this request is in scope. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question after Alan's review, Fadel, 2026-10-16 21:14 UTC: "Point to factor order (Recommended)". | |
| R23All $\binom{k}{2}$ 2FIs of a full factorial are clear, and all its factors have all 2FIs clear. Before this decision the report gave none, because a full factorial has no catalogue entry. The independent check of the tests (`clear_2fis_from_cube`) already counted them as clear. | Claude | Fadel | Approved with the plan | Classified by Claude | Claude found the gap and proposed the rule. Fadel approved the pre-3B plan, 2026-10-16 21:39 UTC: "I will follow your recommendation". Alan's confirmation is an alpha review question. | |
| Rulingrun R through the PowerShell tool (`& "C:\Program Files\R\R-4.6.1\bin\Rscript.exe" ...`) — the worktree guard refuses Bash commands whose program path is quoted with spaces — costs nothing if wrong; Bash git commands still work. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingTasks 8 and 9 are characterization/namespace tests that pass on first run by design; the task review should not treat the missing red phase as a defect — the plan's text and spec 6.2 require them — if wrong, a reviewer asks for a red phase that would be artificial. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingTask 10's full sweep and Task 5's errata build may exceed a 10-minute foreground command; implementers run them with output to a log file and a long timeout — if wrong, only wall-clock time is lost. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingjsonlite writes CRLF on Windows; no script change — .gitattributes (eol=lf) normalizes on commit and the Task 7 freshness test compares readLines(), which ignores line endings — if wrong, a rebuild shows a whitespace-only diff. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingcommit trailers name the model that wrote the commit (each implementer uses the Co-Authored-By line its own session gives it, plus the Claude-Session line); Task 1's commit keeps the plan's "Opus 5.5" line rather than rewriting history — the plan fixed Opus 5.5 because the controller expected to commit, and the replication record should be accurate about authorship — if wrong, trailers are inconsistent but no code changes. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingTask 11's republish of the spec page is done by the controller after Task 11, as the approved plan states — the user approved this publish in the plan — if wrong, the page shows facts the user has not reviewed yet. | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling (Milestone 1 ledger). It rests on the plan that Fadel approved on 2026-10-15 05:01 UTC; no person changed it. | |
| Rulingffd_coded_matrix snaps coded values within 1e-9 of an integer to that integer (coding branch only); post-checks stay exact; a new test in test-design-reading.R ("decimal levels give exact codes", RED first) covers it; the fix ships in the Task 6 commit (one commit per task) with a body line — plan defect: Task 3's test used only binary-exact levels — if wrong, a value off the grid by less than 1e-9 counts as on the grid (negligible). | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingTask 10's full sweep (FFD_FULL_CATALOGUE=1, whole suite) is run by the controller as a background command with output to task-10-full.log; the implementer writes the test, runs the fast suite, does not commit, and is resumed after the sweep to report timings and commit — a foreground run can exceed the 10-minute tool cap and a subagent's background handling is unproven here — if wrong, one extra resume round-trip. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingTask 11 Step 4 runs the fast suite, not the full sweep — Task 11 changes no R code, and the full sweep passed at 5bd4968 (Task 10) — if wrong, nothing is lost, because no R file changes in Task 11. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingTask 11 event times come from `git log -1 --format=%ct -- <path>` converted to UTC in PowerShell, instead of TZ=UTC with --date=iso-strict-local — same value, and it does not depend on how Git for Windows reads TZ — if wrong, an event time is off by the UTC offset and is visible in process.json. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingrefuse (fail closed) 26-17.1 and 27-18.1 — add generic post-checks "generators" (count = nfactors - k; each added cube column = product of its base columns) and "aliases" (every tag in aliased$main/fi2 maps to a factor); errata gain category extra_generators; build-catalogue gives them class broken_entry and summary status "broken" — spec fail-closed rule and the user's 2026-10-15 decision to refuse broken entries; accepting them needs recomputed aliases and clear 2FIs that Alan should review first — if wrong, 2 of 554 FrF2 default sizes (512 runs x 26 or 27 factors) are refused until a later milestone accepts them. | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling. It applies Fadel's choice "Verified errata list (Recommended)" (2026-10-15 04:52 UTC) to two more entries; Alan's view is an alpha review question (A13). | |
| Ruling26-17.1 moves from stored_wlp_error to extra_generators; the findings report, script, CSV and draft note are corrected (facts verified in R before they are written); the controller rebuilds and republishes the findings page to the same private link — correction of a publish the user approved in the plan; leaving a known error on a page meant for sharing is worse — if wrong, the page shows corrected counts the user has not reviewed yet (reported to the user). | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling (Milestone 1 ledger). It corrected a page that Fadel had approved in the plan and reported the correction to him; no person changed it. | |
| Rulingthe JavaScript return shape (NULL seed, NA_integer_, length-1 vectors, data.frames, the coded matrix) is deferred to Milestone 2 and recorded as an open item in spec 17.1 — the conversion path (WebR toJs or jsonlite inside WebR) is an M2 decision that must be tested in WebR, and nothing consumes the shape yet — if wrong, M2 changes the shape once and bumps FFD_REPORT_VERSION. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingffd_check_spec validates nfactors, replications, center_points (and nruns, min_resolution when given) as single finite whole numbers, and every post-check is coerced with isTRUE so a zero-length value fails closed — escalated minor; fail-closed is a global constraint | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingFFD_REPORT_VERSION stays "1.0.0" — M1 is not released and nothing consumes it — if wrong, a consumer cannot tell the pre-fix shape (none exists). | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingleft as minors (not fixed now): all.equal in ffd_stored_wlp_agrees (safe at current magnitudes); repeat_only/randomize/seed checks against the design (M2, where codegen exists). | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingparked — a refused entry's report keeps its name-based catalogue$class (27-18.1 says "MA", broken ones "catalogue_not_MA") while guarantee-table.json says broken_entry — ok is FALSE so nothing is shown and no statement claims MA; Milestone 2/3 read class only when ok is TRUE — if wrong, a consumer that ignores ok sees "MA" for a refused entry (told to the user as an M2 item). | Claude | Claude | Ruling during a build Changed later: see P5 |
Classified by Claude | Parked by Claude and told to Fadel as a Milestone 2 item. Decision P5 of the Milestone 2 plan, approved by Fadel on 2026-10-15, resolved it. | |
| Rulingparked — findings report lines 158 and 164 state two facts verified in R but not printed by the script; the fast suite gains about 23 s (GWLP of 20-8.1) — both true / a trade-off, not defects. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| P1The worker installs packages by writing each verified `.tgz` file into WebR and calling `utils::untar(tar = "internal")`. It does not use `webR.installPackages()` (the ChatISA method). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P2Cancel and the hard limit terminate the worker and start a new one. `webR.interrupt()` is not used. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P3`ffd_report()` sorts alias chains by factor position: inside a chain, shorter terms come first, then factor order; chains follow their first term. The report version becomes 1.1.0. | Claude | Fadel | Answer in chat | Classified by Claude | Claude asked Fadel to review P3. Fadel, 2026-10-15 18:06 UTC: "P3, P8 and P10 are reasonable." | |
| P4The report JSON comes from `ffd_report_json()` in R (jsonlite 2.0.0 in both runtimes). Arrays stay arrays, scalars are unboxed one by one, and the run sheet is in rows. `versions` is the last key. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P5A catalogue entry whose `generators` check fails is reported as `broken_entry` (rule `generators_check`), whatever its name says. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P6New post-check `run_order`: `repeat_only`, `randomize` and `seed` in the spec equal the values that the design stores. Codegen uses `repeat_only && replications > 1`, because FrF2 accepts `repeat.only = TRUE` with one replication and stores `TRUE` without a message (measured). | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P7The strict core-spec schema (`lib/spec/validate.ts`) and the factor-name rule (`lib/spec/names.ts`) are made here, not in Milestone 3. A quantitative factor must have numeric levels. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P8Supported limits: every usable catalogue default size, plus the full factorials of up to 4096 runs. A size is left out if its estimated warm time in Chromium is above a 120-second ceiling. The maximum total rows comes from a ladder of replications. | Claude | Measured, Fadel | Measurement | Classified by Claude | The measured times set the supported sizes under a ceiling fixed before. Claude proposed 60 s; Fadel, 2026-10-15 18:06 UTC: "Make the 60 seconds 120". | |
| P9The footer has "Home", the version and the R engine status. The Glossary, Architecture and Paper links come when those pages exist (Milestones 3 and 4). The landing page has no video block until Milestone 4. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P10If `TRANSLATE_MODE` is not set, or names an unknown provider, the privacy notice is the ensemble notice. | Claude | Fadel | Answer in chat | Classified by Claude | Claude asked Fadel to review P10. Fadel, 2026-10-15 18:06 UTC: "P3, P8 and P10 are reasonable." | |
| P11The Node tests use a copy of WebR in `public/runtimes/webr/` with one patched line in `webr-worker.js`. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P12No ESLint in Milestone 2. The checks are TypeScript (`tsc --noEmit`) and the tests. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P13The engine starts on every page (landing and workspace). "Start a design" is a client-side link, so the worker continues. | Claude | Fadel | Answer in chat | Classified by Claude | Plan decision by Claude, approved with the plan (2026-10-15 18:06 UTC). Claude asked again after the merge; Fadel, 23:22 UTC: "Download on landing page is ok". | |
| P14Steps 1, 2, 3 and 6 show "This step is not available in this version." until Milestone 3. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 2 plan without a change to this row, 2026-10-15 18:06 UTC: "Subagent driven for sure." | |
| P15While a design runs, the footer shows "R engine: computing the design (m:ss)" and an activity bar (an indeterminate progress bar) from the start of the run. At the soft limit, the text changes to "R engine: still running (m:ss)" and a Cancel button appears (spec 7.9). Milestone 3 shows the same indicator in step 3, and moves the engine announcements into the global announcer (spec 9.10). With reduced motion, the bar is hidden and the text stays. | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-15 18:06 UTC: "Make the 60 seconds 120 and add some progress or computing indicator". Claude designed the footer text and the activity bar. | |
| RulingF1 onProgress default takes one argument `(_progress) => {}` — tsc infers `() => void` from the old default and fails | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF2 shell.spec.ts gets a local APP_NAME constant; cases.ts imports the summary JSON `with { type: "json" }`; new Global Constraint on JSON in browser tests — Playwright loads specs as native ESM and Node 22 refuses JSON without the attribute | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF3 the Tec SVG is copied from the tracked mockup asset (byte-identical to the authors' untracked public/brand copy, checked with cmp); the unused PNG is dropped from the task | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling (Milestone 2 ledger). At the merge Claude moved Fadel's identical untracked copy to a backup; no person changed the ruling. | |
| RulingF4 openProjectStore reads the database once before it returns it (new unit test with a database that opens but cannot be read); Workspace catches store failures and shows "The project could not be stored on this device." — spec 8.2 and Fail closed forbid silent failure | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF5 (.next holds the test build after the browser tests) parked — the plan states the cost ("run npm run build again before a deployment") and a separate distDir adds an untested config path | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF6 conditionText reports "The text of this R condition could not be read." instead of dropping the warning (spec 7.5); mkdir keeps its catch with a comment, because the next writeFile reports any real failure and the errno may not survive the WebR channel | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF7 the pointer test now proves that writeLastPage refuses a bad value | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF8 the two long e2e tests set test.setTimeout(600_000) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF9 Task 11 Step 5 wording corrected (soft limit stays 3 s in the test build). | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF10 "New design" is disabled until the store is open — removes a click race in the e2e tests | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF11 the isolation test also checks the COEP header of /workers/webr-worker.mjs. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF12 kept both rule names (report: generators_check, table: catalogue_errata) and documented the difference in r/README.md — they name different things | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF13 perf-cases.ts reuses cases.ts `make` (now exported); csv.ts readCsv reuses derive-budgets readCsvFile. The two-line `median` and the `DesignCode` type repeats stay (minor) | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF14 CSP header deferred to deployment (Milestone 4), the Privacy details link and the global announcer deferred to Milestone 3, all added as spec 17.1 open items in Task 12; the activity bar is hidden under prefers-reduced-motion; Review Focus 3 text corrected | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF15 Global Constraints now say that every commit adds the two trailer lines; the task commands stay subject-only. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingF16 the stall limit also uses the progress gaps of a start from the cache (new CSV column cache_max_progress_gap_ms) — measure, don't guess | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingappend run_order to the expected check names in test-report.R "a post-check without a value fails" — P6 adds the check, and that test enumerates the interface; the alias-text rule is untouched | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingadd legacy-peer-deps=true to .npmrc with a comment, and verify a clean npm ci + npm run check — replication must work with plain npm ci, and later tasks add packages | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingplan-mandated Important — all-non-Latin names collapse to "X" and collide; change the fixed rule to encode non-ASCII letters/digits as _HEX ("温度" -> X6E29_5EA6) — spec line 273 asks for unique names after a fixed rule, and Review Focus 1 says non-Latin names work | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingupgrade Minor 2 (mixed number/text levels written one by one: 100000 reaches R as "1e+05", and 100000 vs "1e+05" passes validation then FrF2 fails) to Important — incorrect behaviour — fix: both levels as text when not both numbers | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe open item is a Minor folded in by me, not part of the Important defect (behaviour is correct, reviewer agrees); parked as a deferred minor for the final fix wave, with the hint that the edit tools seem to decode \u escapes, so make the change with a byte-level shell edit (or new RegExp("[\u0300-\u036f]", "g")) and check with od | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix now — compare every file of the copy with node_modules/webr/dist (worker = patched source), exit 1 naming the file, normal mode re-copies; move the patch into a pure applyWebrPatch() with unit tests for once/zero/two — the script's own contract and the supply-chain risk require it | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingaccept the Task 4 file change — setup writes public/runtimes/webr/package.json {"type":"commonjs"} and --verify checks it, because the project's "type": "module" makes Node load webr-worker.js as ESM ("Dynamic require of worker_threads"); the planning probe folder was commonjs — browsers ignore the file | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingfix the open-failure path now — the worker probes self.indexedDB.open("ffd-probe") and mounts IDBFS only on success, else memory — it is the likely failure (browsers that refuse IndexedDB) and needs no timeout | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingpark the save-path case (quota failure during syncfs(false) after a fresh install) — it needs a 25 MB save to fail after a successful open; the user then sees "loading has stopped" and Retry, not a silent hang; a timeout would need a measured value the plan does not have | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude parked the case and raised it with Fadel (2026-10-15 23:19 UTC). His answer at 23:22 UTC was about the two other questions, so the ruling stood. | |
| Rulingreviewer Minor 1 (false stall on a cold start over a slow link: webR.init downloads R.wasm, 18 MB, before any progress message, and the stall limit is measured on localhost) — keep the plan's stall rule for Task 11, and have Task 12 add a spec 17.1 open item "stall limit of the WebR start on slow networks" for the authors — the right value depends on a network-speed assumption that is a product decision | Claude | Claude | Ruling during a build Stood |
Classified by Claude | Claude's ruling: an open item for the authors. The alpha release took the item over (A18, AP9); no person changed the ruling. | |
| Rulingthe worker constructs WebR with ChannelType.PostMessage — IDBFS needs it (spec 7.9 cache); the PostMessage channel cannot interrupt R, which P2 already avoids | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| RulingHEAD-check webr-worker.js, R.js and R.wasm before webR.init(), throwing "Could not load <url> (HTTP <status>)." — Review Focus 3 requires a stated reason — with a committed Chromium test for R.wasm 404 | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingthe stall timer starts at the first progress message (client.ts: no armStall in spawn), with a unit test — WebR's own start downloads R.wasm (18 MB) with no progress, so a 4 s stall from spawn would fire on almost every first visit over a real network and Retry would restart the download; spec 7.9 says Retry appears only if progress stops | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingkeep the measured stall value (it includes the start phase, so it is conservative for the new start point); no re-measurement. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingone fix wave (final-fixes.md): I-1; m-2 codegen parses its input; m-3 comment on RunOutcome ok; m-5 and m-1 spec wording; Task 3 names.ts visible escape — all small, and m-5/m-1 correct the record | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| Rulingm-4 (project dates accept any text) and m-6 (no factor limit in supported-limits.json) stay deferred to Milestone 3, as the reviewer triaged; the Milestone 3 conditions (strict model-facing schema, transaction-complete writes, onversionchange, date validation) are recorded here. | Claude | Claude | Ruling during a build Stood |
Rule for rulings | ||
| P1LLM voters call `generateText` with `output: Output.object({ schema })`, `instructions`, `maxOutputTokens: 8192` and `maxRetries: 0`, with no temperature. Each provider uses its lowest reasoning setting: OpenAI `reasoningEffort: "low"` and `reasoningSummary: null`, Anthropic `effort: "low"`, Google `thinkingConfig.thinkingLevel: "low"`. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P2The model-facing schema is the spec's schema as written: nullable fields, a string-or-number union for levels, and `nruns` as one number enum. Counts are plain numbers there; the strict server schema checks integers and ranges. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P3Evidence is required for `nruns`, `min_resolution`, a non-default `replications`, `repeat_only`, `center_points`, `randomize` and `seed`, for each factor name (or, with default names, for the number of factors) and for each level that is not the default -1/+1. Units and `quantitative` need no evidence. Paths have the form `factors[0].name`; the form `factors.0.name` is accepted too. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P4One repair retry when the first answer fails the schema or the evidence check. If the retry fails the schema but the first answer passed it, the voter keeps the first answer with its marked fields. A deadline during the retry also keeps a first answer that passed the schema. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P5Jev gets one request with 14 Choice questions: the outcome in two option orders (averaged), the 8 out-of-scope and the 11 not-supported categories, and five number fields (runs, factors, replications, center points, seed) in two orders, each with "none" last. The category is read only when the averaged outcome needs one. "none" means the default (runs: not given, replications 1, center points 0, seed: not given; for the number of factors, Jev then gives no vote). The response must report the pinned model. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P6The returned spec is the spec of the first valid LLM voter in the fixed order OpenAI, Anthropic, Google. The agreement flags list every value with its count; the card (3B) makes the user resolve each disagreement. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P7Agreement compares normalized values: text by NFKC, case, quotes, dashes and white space; numbers as numbers. Factor fields are compared by position, only among voters with the same number of factors as the base voter; the count itself is its own field. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P8If `TRANSLATE_MODE` is not `single` with a known `TRANSLATE_SINGLE_PROVIDER`, the mode is `ensemble`. A voter whose key is missing is left out. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P9One deadline for all voters. Until Task 11 measures it, `config/translate-budgets.json` holds a provisional 30,000 ms (the slowest planning call took 11.1 s, and a repair retry can double it). Task 11 sets it to 1.5 × the largest p99 voter time, rounded up to a whole second; `TRANSLATE_DEADLINE_MS` overrides it. | Claude | Fadel | Approved with the plan Changed later: see the ruling of 2026-10-16 |
Classified by Claude | Plan decision by Claude (1.5 x the largest p99), approved with the plan, 2026-10-16 00:45 UTC. Fadel replaced it on 2026-10-16: 40 s, from about the p95 of Google. | |
| P10Spend caps: a voter whose daily cap is reached is left out like a failed voter. When no LLM voter is left, the route returns "Interpretation is paused until tomorrow. You can fill in the form yourself." The default cap is USD 5 per provider per UTC day; `DAILY_SPEND_CAP_USD_*` overrides it. The tally is in memory (one Node process, spec 13.1). A model with no price uses the highest price in the table. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P11The rate limit uses fixed windows per IP address (one minute, one UTC day; defaults 10 and 100, spec 13.1). The address is the first entry of `x-forwarded-for`, then `x-real-ip`, then "unknown". It is never logged. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P12OpenAI calls set `store: false`, so the Responses API does not keep the request. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P13At most 3 clarification rounds: a thread with more than 3 tool turns gets HTTP 400, and a third answer that still needs clarification gives "The request still needs clarification after 3 rounds. Fill in the form yourself." | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P14No mock mode in the app. Unit tests inject mock models; the 3B end-to-end tests replace `/api/translate` in the browser with the responses that Task 11 records from the real route. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P15Default factor names follow FrF2: A to Z without I, then a to z without i (50 names); above 50 factors, F1, F2, ... | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P16The prompt is a versioned TypeScript module (`prompts/translate-v1.ts`) with seven named parts and a default order. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| P17Live tests are opt-in (`FFD_LIVE=1`). `FFD_LIVE_VOTERS` chooses the voters (default: all with a key); Task 11 runs all four. | Claude | Fadel | Approved with the plan | Classified by Claude | Plan decision by Claude. Fadel approved the Milestone 3A plan without a change to this row, 2026-10-16 00:45 UTC: "Subagent and now retest Gemini" | |
| D1Purpose: Public tool and paper companion. Out-of-scope requests get an "outside scope" reply with no alternative. | Claude, Fadel | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-14 18:46 UTC: "Public tool + paper companion + (... this is outside of its scope | do not recommend a different approach)". The scope rule is his addition. | |
| D2Verification of the translation step: Superseded by R1: deterministic checks, user confirmation, and a parallel translation step that is an evaluation arm. | Claude | Fadel | Answer in chat Changed later: see R1 |
Classified by Claude | Answer to Claude's question, Fadel, 2026-10-14 18:50 UTC: "Checks + user confirms (Recommended)". R1 replaced it on 2026-10-15. | |
| D3Hosting: Portable Node app. No sign-in. Rate limit and spend caps. Host decided later. | Claude | Fadel | Answer in chat Changed later: see A4 |
Classified by Claude | Answer to Claude's question, Fadel, 2026-10-14 18:52 UTC: "Undecided: portable Node app". The alpha release later made Vercel the only host (A3, A4). | |
| D4Staging of design families: Core first (Phase 1). Then analysis (Phase 2). Then blocking, split-plot and foldover (Phase 3). Plackett-Burman later. R21 moves estimable 2FIs to Later. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-14 18:58 UTC: "Core first, then extend (Recommended)". R12 and R21 later moved foldover and estimable 2FIs. | |
| D5Analysis: Phase 2, for core designs. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Analysis was a "nice to have" in Fadel's first request. Answer to Claude's question, 2026-10-14 19:00 UTC: "Phase 2, with core designs (Recommended)". | |
| D6Stack: ChatISA stack, trimmed: Next.js 16, React 19, Tailwind v4, Vercel AI SDK, zod. | Claude | Fadel | Answer in chat | Classified by Claude | Answer to Claude's question, Fadel, 2026-10-14 19:00 UTC: "A: ChatISA stack, trimmed (Recommended)". His first request named ChatISA as the reference. | |
| D7Help (`?` buttons): Static reviewed glossary plus sentences computed from R output. No LLM at help time. Placement: R4. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked for "? buttons to make clarifications if the user needs it" (2026-10-14 19:05 UTC), then chose "Static + computed only (Recommended)" at 19:06 UTC. | |
| D8Timeouts: Set from measurements. Soft limit with a Cancel option. Hard limit only as a safety net. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-14 19:13 UTC, on the 60 s limit: "this needs to be unit tested". Claude proposed measured soft and hard limits; Fadel replied "Yes." at 19:16 UTC. | |
| D9R code display: The view shows the exact code that runs in the browser. Read-only in Phase 1. | Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked why the R code does not run (2026-10-14 19:13 UTC). Claude said that it runs in the browser and is read-only in Phase 1; Fadel replied "Yes." at 19:16 UTC. | |
| D10Isomorphic designs: Phase 1: the user can change the factor order. Choice of fraction comes in Phase 3. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked about isomorphic designs (2026-10-14 19:16 UTC), then chose "Reorder factors only (Recommended)" at 19:17 UTC. | |
| D11Working title: Replaced by R7. | Claude | Fadel | Answer in chat Changed later: see R7 |
Classified by Claude | Claude proposed the working title. Fadel, 2026-10-14 19:19 UTC: "Yes, use the working title; continue to section 5". R7 replaced it on 2026-10-15. | |
| D12Anthropic API key: Superseded by R1 and R2: Anthropic is one of the three LLM providers. | Claude | Fadel | Approved with the plan Changed later: see R1 |
Classified by Claude | Fadel offered the Anthropic key "if you think it would be helpful" (2026-10-14 19:22 UTC). Claude proposed evaluation use only; Fadel: "yes, git init and write the spec". R1 and R2 replaced it. | |
| R1Build the parallel translation step (3 LLMs + TypeSafe Jev) into the one translator module. Single model and ensemble are evaluation arms. A rule written before the test-set run sets the production default. Agreement is a flag on the spec card, not a vote. Replaces D2. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel proposed three LLMs and JEV "with an ensemble vote" (2026-10-15 02:34 UTC). Claude proposed flags, not votes; Fadel chose "Build both; evidence decides (Recommended)" at 02:49 UTC. | |
| R2`claude-opus-5-5`, `gpt-6.1-sol` (no dated snapshot; log the returned model id), `gemini-4-argon`, Jev pinned to `jev-1.13.0`. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel named the models "opus 5.5, gpt 6.1-sol, and gemini argon 4" (2026-10-15 02:34 UTC). Claude's research set the ids and the Jev pin; Fadel approved spec v2 at 04:11 UTC. | |
| R3Project workspace: sidebar with projects (this device only), step rail Describe → Confirm → Design → Responses → Analyze → Report. | Claude | Fadel | Answer in chat | Classified by Claude | Mockup 01: Claude recommended option B. Fadel, 2026-10-15 02:58 UTC: "B makes the most sense". | |
| R4No Help item in the header. Each `?` opens help in place, under the item. Layers: reviewed definition, "In your design" (computed from R output), video chapter link; Phase 2 adds the opt-in AI chart explanation. A "Show explanations" switch is remembered on the device. Glossary, Architecture, Paper and Home are in the footer. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked for help "at hand near the buttons" (2026-10-15 02:58 UTC). On mockup 03 Claude recommended B; Fadel, 03:23 UTC: "For Q2, I like B too." | |
| R5Separate landing page at `/` for the first visit. Later visits open the remembered last page (a pointer in localStorage; projects in IndexedDB). `/?home` always shows the landing page. The landing page carries the About content. | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-15 03:08 UTC: "why would not we leverage local storage to open the last opened page". Claude drew it in mockup 03. | |
| R6Plain academic labels: "Maintained by", "Privacy", "Citation", "R code", "All files (.zip)". No marketing language. | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-15 03:23 UTC, on the labels of the mockups: "this is very artificial"; he proposed Authors or Maintained By. At 03:31 UTC he also rejected the R code label. | |
| R7Spell out "Fractional Factorial Design Translator" for now (no "FF" abbreviation). One `APP_NAME` constant. Final name is still open. | Fadel, Claude | Fadel | Answer in chat Changed later: see R18 |
Classified by Claude | Fadel, 2026-10-15 03:08 UTC: "I do not like the FF Design Translator abbreviation -- so either spell it out". To Claude's name options, 03:17 UTC: "spell out for now". | |
| R8Run sheet and design properties side by side; stacks below about 1100 px. | Claude | Fadel | Answer in chat | Classified by Claude | Mockup 04: Claude recommended option C. Fadel, 2026-10-15 03:29 UTC: "C works for me, go ahead with the exports". | |
| R9`yyyymmdd` of the user's local date (for example 20261014). The user can edit it. The project file records the full creation time and time zone. Designs with the same number of runs made on the same day get the same run order. | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-15 03:31 UTC: "Can we set the random seed default to yyyymmddhhmm?" Claude measured that it is too large for R; Fadel, 03:33 UTC: "So just make the default seed yyyymmdd". | |
| R10`pkg::fun()` everywhere, no `library()`. Report helper reads generators from `design.info(d)$catlg.entry`, because `DoE.base::generators()` needs `catlg` on the search path. A test runs all R code in a fresh session with nothing attached, in native R and in WebR. | Fadel | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-15 02:34 UTC: "For the R code, use my preferred pkg_name::function_name() styling". The generator detail comes from Claude's probe gen_probe.R. | |
| R11Tested in desktop Google Chrome; other browsers get a notice, not a block. Phase 1 code view is a highlighted `<pre>` (no CodeMirror). | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-15 02:34 UTC: "I think we should say that this is a Chrome-based tool for now." The code view without CodeMirror was Claude's proposal. | |
| R12Moves to Phase 3 as an action on a saved project ("Augment this design"). Plackett-Burman stays in "Later". Fix the `sequential_or_adaptive` versus `foldover` contradiction. | Claude | Fadel | Approved with the plan | Classified by Claude | Fadel asked why foldover was not planned (2026-10-15 02:34 UTC). Claude moved it to Phase 3 "unless you object"; Fadel approved spec v2 at 04:11 UTC: "I have reviewed it and I approve it." | |
| R13Three places, each with one job: "Download" in context (run sheet in step 3; each chart in Phase 2), step 6 Report (report .html, print to PDF, "All files (.zip)"), and the project menu (export, import, duplicate). Run sheet .xlsx carries a response column and a hidden checksum; upload checks the factor columns run by run. On import, the stored run sheet wins over a rebuild that differs. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked to rethink the exports for later phases (2026-10-15 02:34 UTC). On mockup 05b Claude recommended C; Fadel, 03:35 UTC: "C works, move on to the video". | |
| R14One video of about 2:15 per minor or major release, chapters by step, built with the `narrated-demo-video` skill. Narration: ElevenLabs v4 (`ELEVENLABS_API_KEY`). Quiet CC-BY music, ducked under the narration and credited. Spanish version (narration and captions) ships with v1.0; a Spanish speaker reviews it. Self-hosted MP4 with WebVTT captions and a transcript; no third-party player. Filming uses the end-to-end test fixtures (no live LLM call). A stale check flags the video when filmed screens change. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel proposed a tutorial video (2026-10-15 02:34 UTC). At 03:42 UTC he chose "ElevenLabs v4", "Quiet CC-BY music" and "Yes, with v1.0", not Claude's recommended options. | |
| R15`.env` holds `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `JEV_API_KEY`, `ELEVENLABS_API_KEY`. Code maps `GEMINI_API_KEY` and `JEV_API_KEY` explicitly (the SDK defaults are `GOOGLE_GENERATIVE_AI_API_KEY` and `TYPESAFE_API_KEY`). | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel, 2026-10-15 02:34 UTC: "Update the configuration to include the additional keys (if we were to use them) within the app". Claude wrote the names and the mapping. | |
| R16Warm-white field with a Miami Red rule; both logos in their own colours with equal weight; black titles. Contrast at least 4.8:1 for every simulated colour-vision type (`card_contrast.py`). | Claude | Fadel | Answer in chat | Classified by Claude | Claude recommended card style B. Fadel asked to see cornhusker yellow, then answered "B" (2026-10-15 03:45 UTC). R19 later changed the colour of the rule. | |
| R17Two linked views of one event log (`process.json`): "By date" (timeline; each event tagged with stage and actors) and "By stage" (swimlanes = the events grouped by stage and actor). A toggle switches views; links go both ways. The paper uses the "By stage" view as a static SVG. Counts and times come from the transcripts via the sync script; a short glossary of agentic-tool terms links to the official docs. | Fadel, Claude | Fadel | Answer in chat | Classified by Claude | Fadel asked for a figure of the process (2026-10-15 02:34 UTC). Of Claude's options he wrote at 03:49 UTC: "I actually would like us to have a toggle between a and b". |
The process
Status on 2026-10-20. Times are UTC and come from the session transcripts. Links go from each event to its cell and back.
By stage
By date
-
Initial request. F. M. Megahed gives the request in plain language, the refs/ folder (two papers and the FrF2 2.3-5 manual) and the ChatISA repository as a model.0 Inputs · People
conversations/ -
Brainstorming skill loaded. Claude Code loads the superpowers brainstorming skill and checks the local R, Node and Python set-up.
-
Three research subagents. Separate agents read the two papers, the FrF2 documentation (with probes in native R) and the ChatISA code and issues. They report at 18:34, 18:38 and 18:40.
-
Design questions. Nine multiple-choice questions and discussion in chat, 18:41 to 19:23. Result: twelve decisions (D1 to D12).
-
Specification, version 1. Seventeen sections. The agent checks it for gaps and contradictions and commits it to git.1 Brainstorm · Claude Code1 Brainstorm · Records in replication_materials/
plans/2026-10-14-ff-design-translator-design.md -
Private web page. The specification is published as a private web page for review.
-
Sixteen-point review. F. M. Megahed reviews the page with the public replication package in mind.
-
Two more research subagents. The TypeSafe Jev documentation and the equation-rendering repository hf_arxiv_control_charts.
-
Ensemble decision. Build the parallel translation step; the single model and the ensemble become evaluation arms (R1).
-
Mockup screens. Ten screens in the visual companion, 02:58 to 03:50, built on real FrF2 output. The authors choose among the options on each screen.
-
Checks in R and Python. The alias structure of the example design, the search-path dependency of DoE.base::generators(), date-based seeds, and title-card contrast under simulated colour-vision deficiency.2 Spec review · Claude Code
mockups/2026-10-14-ui/source/ -
Decision log. Seventeen review decisions (R1 to R17), each with its evidence.2 Spec review · People2 Spec review · Records in replication_materials/
plans/2026-10-14-spec-review-decisions.md -
Specification, version 2. The specification is revised from the decision log. This page is built from it.2 Spec review · Claude Code2 Spec review · Records in replication_materials/
plans/2026-10-14-ff-design-translator-design.md -
Implementation plan, Milestone 1. The writing-plans skill turns Section 18 into test-first tasks for the R core. A reviewer subagent runs the plan's code and finds FrF2 catalogue errors. F. M. Megahed chooses a verified errata list and approves the plan.
-
FrF2 findings report. A reproducible check and a shareable report of the FrF2 2.3-5 catalogue problems.
-
Milestone 1: R core. Report helper, catalogue files and native R tests. Every catalogue entry that the tool accepts agrees with its stored WLP or the verified errata, and with DoE.base::GWLP() up to 1,024 runs. Seven entries are refused.
-
Implementation plan, Milestone 2. The writing-plans skill turns Section 18 into test-first tasks for the browser engine and the projects. Probes measure WebR 0.6.0 in Node and native R; they find the collation dependence of FrF2's alias order and an interrupt that leaves WebR unable to answer. F. M. Megahed approves the plan with a 120-second ceiling and a computing indicator during a run.3 Plan · People3 Plan · Claude Code3 Plan · Subagents and tools
plans/2026-10-15-m2-browser-engine-plan.md -
Milestone 2: browser engine and projects. Next.js shell, WebR worker with a SHA-256-pinned package mirror, codegen, project storage, and differential and performance tests. WebR and native R give byte-identical reports. A Chromium test found that IDBFS needs the PostMessage channel of WebR.
-
Implementation plan, Milestone 3A. F. M. Megahed splits Milestone 3 into three plans. Research subagents measure the four providers with live calls; they find that no model accepts a temperature and that gemini-4-argon needs billing, which F. M. Megahed enables the same day.3 Plan · People3 Plan · Claude Code3 Plan · Subagents and tools
plans/2026-10-15-m3a-translation-service-plan.md -
Milestone 3A: translation service. Schema, evidence check, prompt, four voters, agreement flags, translate route, rate limit, spend caps and log. Live tests measured each LLM voter with 100 calls; F. M. Megahed set the deadline rule (40 s, the largest LLM p95) and made Jev's outcome a flag only. The tests record the fixtures for Milestone 3B.
-
Review by Alan R. Vazquez. A. R. Vazquez marks his changes on the specification page: the name EXPERTA, the principles of effect hierarchy, sparsity and heredity, the number of clear 2FIs in place of estimable 2FIs, and purple in the palette. F. M. Megahed and Claude sort the changes by their risk to the merged work and measure the colours. Specification version 3 applies the decisions R18 to R23.
-
Implementation plan, pre-3B review changes. F. M. Megahed and Claude turn the review decisions into a plan of five tasks before Milestone 3B. Colour measurements replace the first purple with the Dark2 purple. F. M. Megahed decides that every plan is published as a page.
-
Pre-3B review changes. Claude carries out the five tasks in this session, test first. The tests show that FrF2 stores the string "all" for 159 catalogue entries, which the plan's code did not read. A fresh reviewer checks the whole branch and finds no critical or important issue. The full check and the full catalogue sweep pass.
-
Implementation plan, Milestone 3B. F. M. Megahed decides four questions: a report of an older version is computed again from the spec and the seed; the build does not wait for A. R. Vazquez to confirm R23 and the purple, and a note asks him; Claude drafts the glossary, marked as a draft until he reviews it; the references are a checked list that he confirms. He also asks that the document pages use the purple accent. Subagents check five references and draft 35 glossary entries. Claude measures the FrF2 behaviour behind each pre-check and runs the code of the plan in a copy of main before the plan is published.3 Plan · People3 Plan · Claude Code3 Plan · Subagents and tools
plans/2026-10-16-m3b-interface-plan.mdplans/m3b-probes/ -
Milestone 3B: interface. Claude gives each of the eleven tasks of the plan to a subagent, which works test first, and a fresh reviewer checks each task: storage ready for reports, the translation client, the pre-checks, the card model, the global announcer with help panels and the glossary, steps 1 to 3, the rebuild of older reports and the privacy page. The browser tests answer the translation route from the recorded fixtures, so the build makes no LLM call. A fresh reviewer checks the whole branch and finds one important issue: after an edit in step 2, step 3 shows the old design with no notice. One fix wave adds a notice for this case and eight smaller fixes. The full check passes.
-
Implementation plan, Milestone 3C. F. M. Megahed decides that the open questions for A. R. Vazquez do not block the work, and that an alpha version goes online for him after Milestone 3C. He decides two questions of the plan: step 6 has a "Request text" check box, checked by default, for the files that people share; an imported project whose id is already on the device is kept as a copy. Claude measures in a copy of main: no axe violation on any page, 40 ms to parse the largest report, a second full download of R.wasm when the worker reads it first, and an .xlsx file that Excel opens with its hidden sheet.
-
Milestone 3C: exports, import and report. Claude gives each of the eleven tasks of the plan to a subagent, which works test first, and a fresh reviewer checks each task: the file writers (.xlsx, .csv, .R, project file and the archive), the downloads of step 3, the project menu, import with its check in step 3, step 6 with the report file and "All files (.zip)", the engine start text and the accessibility sweep. A full-flow test runs Phase 1 from the landing page to the report, with a returning visit. The task reviews find defects that the task tests did not: a focus that dropped to the page body, an import that could reuse a taken id, and report step errors that were not announced. The specification goes to version 5 with the decisions C1 to C18. A fresh reviewer checks the whole branch and finds three important issues: a later import in the same tab, after "Delete all", gave each project a new id, the typed request came back after "Delete all", and the project name kept the first words of the request when "Request text" was unchecked. One fix wave corrects the first two, adds a note in step 6 for the third, and makes seven smaller fixes. The full check passes.
-
Alpha release design and plan. F. M. Megahed answers the questions of the alpha release with Claude's recommendations in front of the author. The link is public with no sign-in, because the scope rule, the rate limit, the daily spend caps and the limits on the provider keys hold the cost. Vercel hosts the app at experta-doe.vercel.app (experta.vercel.app belongs to another site), with Upstash Redis for the counters and ensemble translation. A review page files each answer of the authors as a GitHub issue, and the alpha is done when every question has an answer. The Dark2 purple is settled. Claude writes the design; a fresh reader finds eight questions, which the code and Claude's calls answer. Claude then writes the plan and measures that the Lua scripts of the counters run on an in-memory Redis for the tests.3 Plan · People3 Plan · Claude Code
plans/2026-10-17-alpha-release-design.mdplans/2026-10-17-alpha-release-plan.mdplans/alpha-probes/ -
Alpha release: counters, headers, review page and the first deployment. Claude gives each of the nine tasks of the plan to a subagent, and a fresh reviewer checks each task. Most tasks were written test first. In Tasks 4 and 6 the code came first, and the failing run was shown by setting the code aside. The tasks add the secret scan and the checks of the deployed site. They add the Upstash Redis counters with a keyed hash of the address, and the reservation of the spend caps before the calls. They also add the Content Security Policy and the review questions page with its GitHub issues. A fix makes "Delete all" mount step 1 again. A measurement shows that WebR needs eval in the worker, so the worker policy allows it and the page policy does not. Zod 4.6.5 probes new Function when it builds a schema, so the app runs Zod without the JIT. The task reviews find defects that the task tests did not, for example review page errors that pointed at the wrong field. A fresh reviewer checks the whole branch and finds one important issue. The Lua scripts gave Redis numbers that a host can write in exponent form. One fix wave corrects it and six smaller items. F. M. Megahed approves the first deployment. Claude creates the private repository fmegahed/experta and the Vercel project experta-doe, and the author connects them and adds Upstash. The first deployment of main has no keys. All 198 runtime files match their SHA-256. Twenty starts on the Lighthouse mobile profile take about 138 s each. The longest gap between progress messages is 1.4 s, so the stall limit becomes 5 s. The specification goes to version 6.4 Build · People4 Build · Claude Code4 Build · Subagents and tools4 Build · Records in replication_materials/
plans/2026-10-17-alpha-release-design.mdplans/2026-10-17-alpha-release-plan.mdplans/2026-10-17-alpha-execution-ledger.mdtests/ -
Alpha release goes live (Checkpoint B), and the follow-ups. F. M. Megahed approves Checkpoint B. Claude adds a random salt for the rate-limit keys without printing it, the review repository and the seven labels, and deploys again. The deployed checks pass: the exact security policy, and the eleventh request in one minute gets 429 from the shared store. Pairs of requests with and without one Redis call measure the store: a median of 17 ms and a largest call of 59 ms. At the request of the author, Claude sends the GitHub token, a new review key and the four provider keys from the local .env file to Vercel through a pipe, so no value is printed. One translation through the page costs USD 0.045. The three LLMs agree, and Jev reads the request as out of scope, as measured before. The author files one smoke answer, and Claude marks it withdrawn and closes it. Auto mode blocks a read-only check of the token access, and Claude does not try again. Then, at the request of the author, Claude sets a time limit of 1 s on each Redis call (10 times the largest measured call). The Upstash client returns the text "Aborted" as a result when a plain abort signal fires, so the limit uses a signal function. Claude also corrects the count line of "Other comments" and adds a CSV export of the review answers.4 Build · People4 Build · Claude Code4 Build · Records in replication_materials/
plans/2026-10-17-alpha-execution-ledger.mdplans/2026-10-14-ff-design-translator-design.mdtests/perf/alpha-upstash-latency.csvtests/ -
The public address expertadoe.app. F. M. Megahed registers expertadoe.app at Vercel and asks that it become the public address, in addition to experta-doe.vercel.app. Claude finds no host name in the app code, adds the domain to the project, and adds www.expertadoe.app as a permanent redirect to it. The domain works at once, because Vercel holds its DNS, and the deployed site check passes on the new address. The vercel.app address keeps working for the two authors, and the paper names only expertadoe.app. The domain sends no mail, so Claude adds SPF and DMARC records that reject mail in its name.4 Build · People4 Build · Claude Code4 Build · Records in replication_materials/
plans/2026-10-17-alpha-execution-ledger.mdplans/2026-10-14-ff-design-translator-design.md -
The deferred minor findings of the alpha release. F. M. Megahed asks that all deferred minor findings be done. An audit finds 63 findings in the 51 ledger lines: 47 open, 11 already fixed and 5 not actionable. Eight tasks fix 46 of them. A probe shows that Chrome cannot slow the CPU of the engine worker. So the 5 s stall limit rests on trials with the worker at full speed. The author decides on that limit.4 Build · People4 Build · Claude Code4 Build · Records in replication_materials/
plans/2026-10-19-alpha-minors-plan.mdplans/2026-10-19-alpha-minors-audit.mdplans/2026-10-17-alpha-execution-ledger.mdtests/ -
The printed report is redesigned. F. M. Megahed asks for a better PDF. The sections flow, with no forced page break. The run sheet scrolls in a box on screen. In print it uses landscape pages in column blocks of a measured width, with blank Response and Notes columns. Step 6 sets a row limit. A running header and footer, the project name in the PDF name, and a section on how the specification was made are new. The citation in APA and BibTeX and the acknowledgment are also new. The final review changed the app link to open a new tab and wrapped wide word length patterns. Four reference prints (7 factors in 16 runs, 32 factors in 64 runs, a resolution III design and 4,096 runs) have 5, 12, 6 and 14 pages. The print item leaves the known issues of the review page.4 Build · People4 Build · Claude Code4 Build · Records in replication_materials/
plans/2026-10-19-report-print-plan.mdplans/2026-10-14-ff-design-translator-design.mdfindings/tests/e2e/report-prints.spec.ts -
The alpha review by Alan R. Vazquez and its fixes. Alan R. Vazquez answers the alpha review questions in GitHub issues #7 to #65: the export reads 60 answers, and 55 count. He agrees to most regions, gives new texts for three glossary entries and asks for three references. Claude measures the open points with probes: the rank-1 ties have equal word length patterns, two defaults have a stored pattern with one split number, and the 128-run designs with 25 to 40 factors have the same pattern as the MA designs of Xu (2009). The app now makes the MA claim, or the claim for good designs, only where this evidence supports it. For 128 runs with 25 to 40 factors, it checks each design against Xu's design when it makes the design, and the claim is none if the check fails. The glossary has 33 reviewed entries and two new drafts. Four questions are asked again on the review page, and an earlier answer does not count. F. M. Megahed decides the scope of the paper: the tool up to and including the design families of DoE.wrapper.4 Build · People4 Build · Claude Code4 Build · Records in replication_materials/
plans/2026-10-19-alpha-review-fixes-plan.mdplans/review-fixes-probes/plans/2026-10-14-ff-design-translator-design.mdplans/2026-10-19-alpha-review-fixes-execution-ledger.md -
The review fixes go live. F. M. Megahed merges the project pages (pull request #66) and the review fixes into main, and Vercel deploys the app. The deploy job of the project site stays off until the switch-on. The checks on https://expertadoe.app pass: the site test with the security headers, the refusal of the review API without a key, and the MA statement in step 3 for 7 factors in 16 runs and for 30 factors in 128 runs. The design with 30 factors passes the check against the design of Xu (2009) in the browser. Claude closes the 52 review issues that the app now applies. Seven issues stay open: the earlier answers to three questions asked again, the refused FrF2 defaults and the comment on one field of application.4 Build · People4 Build · Claude Code
plans/2026-10-19-alpha-review-fixes-execution-ledger.mdplans/2026-10-19-project-pages-plan.mdtests/deployed/site.spec.ts
replication_materials/process/process.json. The "By stage" view groups the events of the "By date" view by stage and actor.The source of this figure is process.json.
How the table was made
Claude (the model Claude Opus 5.5) made this classification once, on 2026-10-19. A person did not check each row. For each decision, Claude read its row and the text around it in its record, and searched the three main session transcripts for the messages of Fadel M. Megahed, his answers to the multiple-choice questions of Claude and his approvals of plans. "chat" means that a person chose the decision in the conversation; "review" means a change from the review by Alan R. Vazquez; "measurement" means that measured values set the decision under a rule that was fixed before the measurement; "plan-approval" means that Claude wrote the decision in a plan and Fadel approved the plan without a change to it; "ruling" means a decision of Claude during a build. A ruling has a record only when it names a person or when a person changed it later; the other rulings are decisions of Claude that stood. Each evidence line quotes at most 25 words of a message, with its date and time in UTC, or names the record line. The decisions of the project pages design have the columns "Proposed by" and "Decided by", so they need no record. A correction by a person (decision-corrections.json) replaces a record on the page.
Basis of the 414 decisions:
- Checked by a person: 1
- Classified by Claude: 181
- From the table of the plan: 27
- Rule for rulings: 202
- Not known: 3
"Approved with the plan" means that the decision was part of a plan that Fadel approved as a whole. It was not a separate answer.
For a decision made by a review, a person in "Decided by" applied or required the change.