Retrospectives - axolotl-logic/project-buddy GitHub Wiki
The orchestrator writes one entry after each stage's cleanup, before briefing the next stage (rule "Retrospective between stages" in How the build runs). Newest first.
Each entry has:
- What cost time: failures, reruns, supervisor questions, wrong predictions in briefs or reports.
-
Code that keeps changing: files changed again this stage after changing in earlier stages, from
git log --format= --name-onlyacross stage merges; candidates for a refactoring lane. -
Rule changes, applied to the plan and the next briefs:
- removed;
- modified;
- added.
- Refactors queued: lanes added to the next stage, or "none".
- Orchestrator's decisions this stage, each with the question posed, the options and the choice, marked "Axlog can reverse".
-
A known flake stayed open through all four lanes. The chat visual shots failed now and then on
maintoo (1 px of height, or a blank band under the composer). Three lanes spent runs on it and each asked the supervisor about it, untilvisual-upkeepfixed the settle step (fit-screen.ts: 5 of 60 shots failed before, 0 of 80 after). Fixing it first, alone, would have saved runs in every lane. -
Supervisor questions: 12. Most were real out-of-path edits named in no brief (the hide-rule layer,
biome.jsonc'sviewport,chat-thread.tsx,memory-history.tsx, Streamdown's buttons, WebKit sign-in). The brief predicted the shared files but not the edits the lanes needed in them. -
Two merge interactions that no lane could see alone:
-
min-h-11on Rename chat: a spacing utility beat the role's--target-sizeand followed the theme. -
mobile.spec.tsmeasured Streamdown's off-screen buttons at 0×0 under load: one failed full run.
-
-
Reviewers found a bug the integration's probe missed: switching off the pinned header sets it
static, so its fade strip floats one screen down. The probe checked computed properties only; no test switches that flag. -
Parallel lanes duplicated a helper being centralised.
mobile-fixeswrote the theme cookie by hand whilevisual-upkeepexportedthemeChoiceCookiefor exactly that. - Smoke worker's shell slip sent a stray "x" message (within the cap). The sweep report missed its exact final verdict line.
- Bash-open alerts: 9, all long test runs. Each cost a process check.
-
What went well:
- The merge-tree predictions matched every conflict exactly.
- The Git deployment fired again (4 s).
- 248/248 e2e twice on the merge.
- Every screenshot reviewer said OK.
- The device projects worked on their first review.
Commits since 2026-10-09 (non-merge):
-
src/app/page-roles.css9, 290 lines: roles for every page in one file. Every UI lane edits it.-
Watch: accounts adds the account page's roles. If two round-3 or personas lanes need it at once, split it by page area (
page-roles.cssfor the shared roles, chat-page roles besidechat.css).
-
Watch: accounts adds the account page's roles. If two round-3 or personas lanes need it at once, split it by page area (
-
src/components/chat/chat.css7: chat and Markdown roles. It churns with chat features. -
e2e/visual/visual-page.ts5: settled now thatfit-screen.tsholds the screen fit. -
src/components/site-header.tsx5: 25 lines. Every stage adds a link. Accounts adds Account (and may hide links signed out). Small, so no split. -
src/tutor/reply.ts16: untouched this stage. Re-measure after accounts, as planned.
Removed
- "Record the chat visual flake as an open risk" (option A): the flake is fixed, so a failing visual shot is a failure again.
Modified
-
Touch targets: sized through
--target-size, never spacing utilities. Recorded under "Patterns the rules force". -
Interaction probes check what the user sees. A known-interactions step in the integration brief also takes a screenshot or a
click({trial:true})check, not only computed styles. -
Section C's report must end with the exact line
Sweep verdict: OKorSweep verdict: BROKEN. The after-merge workflow passes the sweep's verdict into its return value.
Added
-
Each extra's off state has a browser test, written by the lane that builds or tags the extra. The rule is in
common.mdfor accounts and personas; it came from design M1. -
Helpers centralised in a stage replace parallel copies at merge. The integration brief lists the helpers each lane exports for others (
themeChoiceCookie,manualSection,PHONE_VIEWPORT). The integration worker converts any parallel lane's hand-written copy, as a merge fix. - A known flake is fixed first, alone, before the lanes that would trip on it start, or in round 1 of the stage.
Balance: 1 removed, 3 modified, 3 added.
-
chat-ui-followups(accounts round 1, besideaccounts-coreanduse-cases-accounts):- pinned-header off state (design M1, rules M1);
- typed
extraTagand the tag test (design M2); -
mobile.spec.tson the shared helpers (design M3, rules L2); - the untested use-case promises (rules M2);
- Lows: design L2, L4, L5; rules L3; README's page lists (design L1);
use_case_use_on_phonenaming Settings.
-
Into
account-page-and-flags:- design L3: decide on a shared "choice" helper (cookie, pre-paint lookup,
<html>observer) once flags store per user; - design L6: seed the cookie at sign-in with
hiddenFlagsCookie; - the signed-out Settings link.
- design L3: decide on a shared "choice" helper (cookie, pre-paint lookup,
-
Smoke reply cache:
cacheRead39.6k,cacheWrite7.5k of 47.2k input. The reply searched 5 times, so the input was bigger thanlane-splitting's 26k. - Opening: 3.55 s, down from 4.9 s.
All are recorded in the plan under chat-ui-and-mobile ("Supervisor approvals" and the after-merge notes), each with the question posed and the rejected options:
- the hide rules in a last cascade layer
extras; - the failed-tool tag in
chat-parts.tsx; -
manualSectionshared ine2e/chat-page.ts; -
chat-composer-dock; - the
viewportexport allowed inbiome.jsonc; -
PHONE_VIEWPORTine2e/viewports.ts; - Rename chat unpinned;
- the memory mask class;
- Streamdown's buttons at 1.5rem;
- WebKit sign-in by minted cookie;
- hidden chat names as a split link;
- at merge, Rename chat on
--target-size; - at merge,
mobile.spec.tsmeasuring each control on screen; - the chat name clamped to one line on phones;
- the follow-up fixes as a third round-1 lane in accounts, rather than waiting for
deploy-v1(the off-state bug is live in production, and round 3 adds an extra that needs the typed tag).
-
A lane ended its run on a failed check.
visual-baselines' first run stopped whenbiome checkfailed (useValidTestTitleon a template-literal title), with nothing committed; it needed a resume. The fix was ordinary; the cost was the stopped run. -
A wrong "merges cleanly" prediction.
copy-per-area's report predicted no conflict insite-header.tsx; theme-polish's edit on the adjacent line conflicted. It cost one supervisor round trip. Reports guessed by reading diffs rather than testing the merge. -
A brief bug. The after-merge brief's pathspec
':!e2e/visual/*-snapshots'didn't exclude the PNGs; the worker caught it and asked. -
Deployment. The push produced no Git deployment at all; the CLI fallback ran. The smoke worker noticed that
vercel deployfrom the repo would upload.envand.env.test(the CLI ignores only.env.localby default) and deployed from a clean worktree. Good judgement, but nothing in the brief protected against it. -
/reloadstopped the workflow controller. The child kept running; relaunching the same script re-attached. No work lost. - Bash-open alerts (three) were all long test runs. Each cost a check.
-
One secret leak into a tool output: the integration worker printed
.env.test's test-only passphrase while reading the file. Not copied anywhere. - What went well: the visual baselines replaced throwaway screenshot scripts and pixel comparisons in one stage; reviewers used them directly; e2e 147/147 twice; the five-branch merge with an old-base branch (theme-polish) needed no spec fixes.
Commits touching each file since 2026-10-09 (non-merge, src and e2e):
-
src/ui/copy.ts18: resolved bycopy-per-area. -
src/tutor/reply.ts16,reply-test-kit.ts10,reply.test.ts10: every reply-touching lane edits them. 287 lines; not oversized, but it is the hottest file andmulti-persona-chatswill reshape it. Watch: re-measure afteraccounts-and-quotas; if accounts lanes also edit it, queue a split (request parsing / streaming and saving / step logging) beforemulti-persona-chats. -
src/components/chat-view.test.tsx16: 263 lines, 3 describes. Churn follows chat features; no split yet. -
src/components/new-chat-form.tsx15,new-project-form.tsx13: persona-picker churn;persona-editorandmulti-persona-chatsreplace most of it. -
src/tutor/system-prompt.ts12, its test 13,src/personas/personas.test.ts13: queued aspersona-parts-move(round 1 ofpersonas-and-prompts). -
src/chats/store.ts11:persona-storerewires it.
Removed
- "Lanes save screenshots; fresh agents view them", throwaway screenshot scripts and script pixel comparisons (with the RGB note): replaced by the visual baselines.
- The 175k "commit, hand off and end" rule and the
context-handoffadd-on: replaced by compaction at 175k (Axlog). - "A fresh session per stage": one long session with compaction (Axlog).
- The
visual-baselineslane's "don't importCOPY" limit: it ended with the merge.
Modified
-
Conflict predictions are tested, not guessed. The integration worker's first step runs
git merge-tree --write-treefor each branch against the merge so far, in order, and lists the predicted conflicts before merging; lane reports stop predicting merges. -
Deploy fallback only from a clean worktree of the pushed commit;
chat-ui-and-mobileadds a.vercelignorewith.env*. -
Diffs that exclude a folder use
':!<dir>/**'. -
Secrets: briefs add "never print
.env*files; read single variables withnode --env-fileorgrep -c".
Added
-
A failing check isn't the end of a run. Common brief line: "A failing command is information. Fix it within your rules, or ask with
contact_supervisor; never end your run on a failed check." -
Visual pages wait for a settled page and real masks.
describeVisualPagewaits until no loading skeleton (aria-busy) remains, and asserts every mask locator matches at least one element (rules R-L2; the skeleton baselines). - Mobile is reviewed every stage (Axlog): device projects in the visual tests and a mobile reviewer.
Balance: 4 removed, 4 modified, 3 added.
-
theme-choice.tsexports the cookie form (themeChoiceCookie) andvisual-page.tsuses it (design M2, rules R-L1). - Visual specs import copy modules; masks built from copy; non-empty mask assertion; settled-page wait; shared
manualSection(rules R-L2, R-L3, design L2, L3). -
themes.ts"ADDING A THEME" step 5 (design M1). - CSS roughs: memory milestones' double marker and hanging indent; the checkbox gap on the spacing unit (R-L4); the composer's backdrop at 390; dark skeleton colour.
-
.vercelignore. - Left for
accounts-and-quotas(it ownsuse-cases/): design L4 (README wording), L5 (tighter slug check).
- Smoke reply cache:
cacheRead19.7k,cacheWrite6.3k of 26.0k input. The baseline forpersonas-and-prompts' cache-cost check.
-
site-header.tsxconflict: take theme-polish's side, then convertCOPY(rejected: hand-merging the two lines). Standing rule for the same pattern. -
Diff pathspec:
':!e2e/visual/*-snapshots/**'. -
Compaction numbers:
reserveTokens825000 for Opus 5.5 (trigger at 175k, matching the old limit),keepRecentTokens30000 (rejected: the default 20000, a little short for lane state). -
Stage order:
chat-ui-and-mobilebefore accounts (rejected: beside accounts, because the pages overlap). -
Request details for personas, prompt parts, multi-persona chats, the interview, flags, the pinned header and mobile: all recorded in
personas-and-prompts-rulingsandchat-ui-flags-and-mobile, each with the question posed and rejected options. - Mobile checks added to the running sweep before it started.