Working with AI agents
120 lessons. Most-repeated first.
- Council scores drift about 0.6 between sessions for the same artifact (v2 scored 9.6 then 9.0). Before judging a late round, re-score the current best in the same session; trust swapped-order pairwise votes over small score deltas.
- The landing shoot.py full-page capture renders black below the first viewport. Real scrolled captures are fine, so judge from those.
- Write skill files with LF line endings; CRLF hides the description from the skill list.
- Topology-opt + /design run: never block a tool call for long jobs on a loaded machine; run FE/optimisation/CAD/Playwright as detached processes that write logs, and poll with short calls. Launching OCC (STEP export) from a parent still holding a ~1 M DOF FE model crashed silently; run CAD in its own process. Headless Chromium can lose the first WebGL context, so the viewer must handle webglcontextlost/restored.
- Playwright
context.close() hangs once a page has started WebAudio (headless Chromium). Leave contexts open and end with os._exit(). Prefer file:// over a local HTTP server for static games; it also matches how the user opens the file. Kill orphan headless_shell processes between runs or the machine bogs down and every tool call times out.
- Never stop processes by matching ‘playwright’ in the command line; it also hit Chrome children of other sessions. Match the exact script path (e.g. ‘design\tools\bracket.py’ plus the run folder).
- Screenshot tools must scroll the page and force
.reveal visible before capturing. Otherwise scroll-reveal sections render blank and the judges score an empty page (bracket.py now does both).
- Judges penalise a toast left over from the previous page. In SPAs hide toasts on hashchange and gate it in e2e before re-judging.
- Skill folder renamed refine->hone mid-run and out/p rebuilt by a parallel session: re-run gates right before publish (correction from the human)
- Judges cannot give a stable 10/10 (noise 0.6); real gains came from turning judge-found errors into code gates (correction from the human)
- Jeda v1.7.3 queue: 5-judge absolute scores drifted 0.5-0.9 run to run (v4 7.08 with 3 judges -> 6.85 with 5), while pairwise stayed 3-0-2 for both candidates; always re-run a score that lost judges to timeouts, and treat pairwise as the steadier signal. Before pushing an app fix,
git fetch first: another session shipped the same queue item (NPC labels) minutes earlier. On a 100%-CPU box use a fresh browser per route + 300 s ready wait (smoke_robust.py); the shared-browser smoke crashes.
- Nadaku v8: git is not on PATH on this PC; call the full git.exe path. The single-threaded local http.server stalls when Playwright jobs run in parallel; run shot/walk jobs one at a time, detached, and wait_for_function on app globals before page.evaluate (demo=1 reloads). Judge sheets must show the states being claimed (all-done, hand-off), not just the default screens. In Indonesian ‘nada’ means tone: avoid copy like ‘Latih nada Nada 3’ when the mascot is called Nada.
- Council run spread is about 0.2, so a +0.3 keep bar rejected two rounds that each won blind pairwise 3-0 (+0.18, +0.20). When both signals agree in direction, ship and log it as ‘below margin’ rather than throwing the work away; the plateau stop still applies. Judges also re-flag things the screenshots already show (one judge called backlit, peg-folded shirts ‘flat’), so read the fixes across judges, not one at a time.
cairn vibe end closes the NEWEST live session, not yours, when several agents run in parallel - it closed another session’s Mint page. Close your own session by editing its file (status/ended/end line) or check which file end will hit first. Vault push needs git -c http.https://github.com/.proxy=http://localhost:3128 push (plain push gets 407).
- Bracket.py died silently (exit -1, no output) after the semi-finals when launched DETACHED from a Python tool cell that later timed out; the pair JSONs survive, so run the final with
council.py pair by hand. Also run a contrast script on every fg/bg pair (code-panel muted text failed AA at 4.38:1 while the judges did not notice).
- Before taking an open queue item, check other sessions’ scratch folders for files on that project modified in the last ~2 h (e.g.
~/.vector/scratch/*/ rglob by name + mtime). Two sessions both did the Jeda NPC-label fix in parallel; the second one had to park its patch. Mint image refresh was likewise already in flight elsewhere.
- Shared clones (vault, site, projects) are used by other sessions at the same time: re-read the remote head right before moving any ref, never
update-ref a branch without checking it still points where you think, and add catalog entries at the top of apps.json so parallel appends at the end do not conflict.
- Council noise is about 0.6 between two passes on identical screenshots (8.05 vs 7.45). Re-score the old best under today’s judges before comparing (r11 re-scored 7.84, not its logged 8.08). A +0.3 keep bar on a 2-pass mean is inside the noise, so treat ties as ties.
- Council score subprocesses can hang with no output; run them through exec_command with output to a file and poll instead of a blocking shell call. Local time on this PC is UTC+7; name Update Log notes by local time, not the UTC observedAt.
- Council means moved 7.98-8.33 across visually similar rounds; with +-0.5 judge noise, stop at the round cap instead of chasing 8.5 with micro-tweaks. The next gain needs a structural change (progressive setup, phone arena layout).
- Council plateaued at 7.0 for 3 rounds while pairwise kept preferring the newer build: label legibility moves pairwise, not the absolute score. The next absolute gain needs a structural change (phone layout, denser scenes).
- Shell tool calls die at 60 s and Python calls at 120 s (the interpreter restarts and loses state): keep helpers in files (helpers.py, gates.py, judge.py), run long work with Popen/exec_command and poll logs.
- Before pushing,
git fetch and look for parallel sessions on the same repo/queue (another session pushed cat.svg mid-run). Resolve by a cat-only council pair + read the reasons, not by overwriting.
- Plateau signal: once judge asks turn into opposite-direction taste calls (desktop tabs vs list, numbering), stop iterating and record them as declined-by-design instead of queueing them forever.
- Summing durations of parallel agents is a truth bug, not a style issue: use the union of active spans so a total can never exceed the clock, and show the sum separately (“N x in parallel”).
- Judge noise is about +-0.5 on unchanged views: v11 left the phone untouched yet phone criteria dropped a point. Trust the pairwise vote and the gates, not single-score deltas.
- Two sessions honing the same app share app/out// and helper scripts (round5.ps1 was overwritten). Use a unique round prefix and a private runner script per session.
- Re-score the current best in the SAME session as every candidate: r3 scored 8.0 then 7.65 an hour later; r0 7.5 then 7.1. Compare deltas, never cross-session absolutes.
- Shot runs can catch different demo states (camera preview vs camera unavailable). Judges count that as a design difference, so check modal shots before pairing.
- Full-page captures of fixed modals end the scrim mid-page and judges flag it every round: capture modal states at viewport size (shoot_ui.py now does this).
- (founder-studio v2) Judges only see stills: make interaction evident in a still (hint line, one inspector opened after a run) rather than relying on hover.
- Python tool calls cap at 120 s: never chain build + snap + wait in one call; put run helpers in a module file (ui3/h.py) so a session reset costs nothing.
- Bots panel and council can disagree (r3: council 8.2 but lost pairwise to r1 and bots said “not better”). Keep only when both agree; report both numbers.
- Full-page screenshots put fixed buttons mid-page; judges still penalise it. Shrink the FAB on phones and keep content clear of it rather than arguing.
- Self-judged scores run high: my own ‘council’ of personas gave 8.2 where the real 3-model council gave 7.25. Only report council.py numbers.
- Headless Chromium on the work PC does not render device audio; test AudioWorklet capture with
OfflineAudioContext (deterministic, 0.2 s).
- Pairwise payload: use pairsmall with PAIR_MAX=1800. At 1400 px the judges call the sheets identical; full-size sheets reset the gateway.
- Add_card.py can be undone by another session rewriting apps.json from an older read: check the entry is really there before pushing.
- A ship rate over auto-detected sessions is always 100% (they only end shipped or done); show count + share of all ended sessions.
- Two sessions shared out/founder-studio; give each session its own round prefix (s5-, j) and leave a rebase note in the Queue.
- Milestone/toast screenshots must wait for the toast transition to finish (700 ms), or judges see “no toast” and score it down.
- Absolute council scores swing ~0.6 between rounds; the pairwise both-orders vote is the ship signal (v7 8.0 beat v6 8.6 3-0).
- Scheduled MorningPaper task runs from Desktop/opencode_project/morning-news with no auto-pull, so merges need a ff-pull there (correction from the human)
- Judges liked the seal red as a shared “selected” and “destructive” colour. Switching selected chips to ink lost the round.
- A duplicate phone summary bar (same “Meet at” info twice) was penalised by every judge. One answer block per screen.
- A +0.4 council score gain still produced a 0/0/3 pairwise tie; report the pair result, not only the mean.
- Playwright WebKit on Windows lacks OfflineAudioContext; audio stubs must bail out instead of throwing.
- Pairwise judges show position bias; treat 0-0-3 ties as “no change” and keep the incumbent.
- Council pair mode with 6+6 images times out (URLError 10060); send 3 key views per side.
- Claim queue items before starting to avoid duplicate work with parallel sessions (correction from the human)
- (1) Rounds that only fix the judges’ named nits (chip clipping, ragged grid) move C2 but not the total; the keep came when Home got ONE dominant card and secondary info collapsed into one quiet rail (C1 7->8). (2) A desktop “next 7 days” strip with cramped day cells read as clutter (C2 7); the same data as a calendar row + agenda list read as deliberate. (3) Judge noise is ~0.5 per judge (one judge claimed a bottom nav on desktop): compare candidates in the same session and rely on the swapped pair. (4) The no-camera fallback button must use the app’s one primary colour; a second filled style (black) was flagged by two judges.
- 1) Full-page captures pin floating buttons over content, and judges score that as a real defect (C4 6), so move FABs into the layout before judging. 2) The council plateaus at about 8.7 while pairwise goes 3–0 every round. Absolute scores within ±0.3 are noise, so average 2 runs per version and report both signals. 3) Write the artifact as a current-state description, not a stacked changelog, because judges penalise stale lines from older versions. 4) Council runs hang when a judge stops answering (GLM): use –timeout 100 and launch with Start-Process so a python-tool timeout doesn’t kill it.
- Teduh landing: a fixed bottom HUD always covers content in judge screenshots; dock persistent game HUDs into the sticky header (swap out the nav while playing). Custom pages need class=”dna” on <html> for publish. slop W3 counts repeated article.shot as icon cards (false positive). council –image takes separate args, not a comma list. If L_direct publish fails with 128, the site remote moved: git pull –rebase, then publish again. In the Vector python tool, never name a variable
text (it is the output helper).
- Vow run 7: a desktop app shell (fixed left sidebar) lifted C5 7 -> 9 and the council 7.90 -> 8.30, but the pairwise only flipped to B once the judges’ leftover asks (card chrome, even chip grid, faded-red disabled primary) were also fixed. Full-page shots render fixed sidebars only 100vh tall: paint the rail tone on the body background (not fixed) so it spans the page. Never run gates and judge calls in parallel on this PC; both time out.
- Riak pond: a canvas scene plateaus near 8.1-8.2 with this council once UI polish is done; two rounds both won the blind pair (2/0/1, 3/0/0) yet gained only +0.27 and +0.17, so the +0.3 bar is the right brake. The judges’ biggest lever stays C1 art (stylised koi); procedural vector shading alone does not move it past 7.5. Next time try a painted sprite or texture approach for the hero subject before polishing UI.
- Pocketdex: council judges effectively read ONE image per call (multi-image runs got critiques of only the last screen). Score each screen separately (first-viewport crop, not full-page: fixed bars land mid-page in full-page captures) and average; run at most 2 in parallel or the gateway returns nothing. Single-screen noise is about +/-0.5, so trust the mean plus blind pairs, not one view.
- Lahap r4/r5: re-score the baseline in the SAME session before judging a candidate (v10 8.57 -> 8.65 on re-run). A judge timing out (GLM) drops the median by ~0.4, so compare per-judge totals for the judges both runs share before calling a regression. Renaming a label (Health -> Plate score) can overflow a tight phone grid: run the 320 px overflow test before shooting for the council.
- Vow runs 8-9: once a council sits at ~8.0-8.3 with +/-0.3 noise, a +0.3 keep bar is unreachable by polish; 9 candidates in a row failed and judges asked for things already on screen. Stop after one more run, hand the best candidate to the user or a different judge. Also: screenshot harnesses must wait for async UI states (camera getUserMedia) or shots flip between runs.
- Council absolute scores on near-identical builds swing +-0.2 and sit in a 7-8 band for game UI; use pairwise vs the live build as the keep/revert signal and tell the user plainly that a literal 10 is not reachable from LLM judges. Watch late CSS layers re-showing hidden elements (a
display:flex on #explore h2 brought the title back on phones).
- Precedent switchover: an agent that auto-pulls its queue never goes idle, so waiting for idle is wrong. Stop it via its API right after a round boundary, kill orphaned engine children (taskkill /T), copy final job state (not just history) into the new worker, re-import the queue, and close tasks the old agent finished after the first import.
- /hone on itself: Python
write_text on Windows writes CRLF, and a SKILL.md with CRLF loses its description in the skill list (shows ---), so the skill silently stops triggering. Write skill files with newline="\n" (or write_bytes); check_skill.py now fails on CRLF. Same bug was hiding precedent and ambitious-founder.
- Nongkrong cafe roles: when a request asks to ‘see all combinations’, make the variants URL params (host/cam/role) on one build and capture a versions gallery page, instead of separate builds; judges then compare like-for-like. Low-poly 3D tools cap ‘ASMR realism’ near 6.8/10 - real assets or video are the next lever.
- Toast placement is a trap for screenshot judges: top lane over the header pills and a bottom snackbar over content both got flagged. The real fix is fewer toasts (a ‘ready’ banner that repeats what is on screen); judge that change on its own instead of bundling it.
- Before shipping a queued UI item, re-read the Queue’s latest [x] lines for the same project: a parallel session had already council-rejected the one-row top (2-0-3) and I re-shipped it. Fetch origin AND re-read the Queue right before the commit, not only at start.
- (cairn vibe r6) With judge noise about ±0.3 and one judge often missing, a single council score is not a decision: average two runs, and once the absolute score sits near 9.3 treat a unanimous blind pair (both orderings) as the real signal.
- MCP config differs per client: Claude/Cursor
mcpServers, VS Code servers + type stdio, OpenCode mcp + type local + command array + environment, Claude Code claude mcp add NAME --env K=V -- cmd args.
- Founder-studio r13: interaction-only fixes (a sheet you must tap) are invisible to screenshot judges; either add a scripted shot of the opened state to round_j or don’t expect the score to move.
- /hone on itself: council judges (3/3) flagged duplicated autonomy/safety rules across SKILL.md and mandate.md as the main coherence loss; keep each rule in one file and point to it.
- The frozen rubric said “flat SVG”; when the user overrides the style (3D), report council C1 dips against the old rubric honestly instead of reverting the user’s request.
- (mint 3.5.4) Score intent (blueprint/keyword matching) on the prompt minus user-listed field names - a column called 项目/Project must not pick the Project template.
- (hoki v3.1.1) When the user later gives explicit direction (3D, face front, kawaii…), re-freeze the rubric as v2 with those asks; don’t judge against the old one.
bots.py compare calls a model and can take more than 120 s; run it with exec_command, never inside the python tool (it timed out and lost the session state).
-
| NEVER kill processes by a broad command-line name filter (round.py |
council.py); other sessions run the same scripts. Kill only PIDs you started. |
cairn vibe end without --session <slug> ends the NEWEST live session, which can be a parallel session’s. Always pass --session.
- Honest: not 10/10, council plateau ~7.0-7.3; a broad Stop-Process filter killed other sessions’ council runs - kill only own PIDs (correction from the human)
- Measure judge claims that are objective (contrast, sizes) before acting; a JPEG-viewed “fails AA” was 5.4:1 measured.
- Long runs: launch round_j.py as a detached Popen logging to a file; exec_command sessions die when the PC sleeps.
- Vector python calls die at 120 s and kill child processes: poll background jobs with sleep <= 55 s per call.
- Python tool calls time out at 120s and lose state: launch council runs detached and poll in short calls.
- A +0.03 council gain is noise; report it as such and keep going only within the 2-round stop rule.
- Brief must match app facts (witness required); added-explanation fixes read as clutter to council (correction from the human)
- First council sheet was unstyled (server race) - rebuild sheets only from warm-server shots (correction from the human)
- WebView2 permission prompts are drawn inside the app window (no own HWND). Make the window HWND_TOPMOST with SWP_NOACTIVATE, slide it so the prompt is not under another topmost panel, and click in PHYSICAL pixels (SetThreadDpiAwarenessContext(-4)); logical coordinates missed twice at 200 % scaling.
- Vault: the mandate names
Precedent/Queue.md, but that file’s header says the queue moved to Cairn (cairn autopilot add) and “is no longer read”, while other runs still append there. The skill owner should decide which is authoritative.
- Speech: a voice detector judges speech against what came before; clips of different speakers joined into one recording can be taken for background. Level them by speech level, not by peak, and report what the detector found per clip.
- A DOE sweep (springs 1.8–3.5 N) must not be judged as a production spec. Judge DOE samples only on what can break or block the test (stress, coil bind, fit). Then give a way to feed the measured results back (calibration + pick).
- Run: a split criterion where one judge quotes only the headline number (0 wrong replacements) and two quote the exception the bundle admits (“Zaira’s”) is a real defect, not judge noise; queue the fix, do not reword the bundle.
- Shot state confounds pairs: judges called fight-vs-cast and different tray states “different captured states, not quality”. Pin the phase of every stateful shot (fishing phase, tray states, care readings) before judging.
- With perplexity near 66, a low-confidence threshold of 0.5 marks almost every word; 0.02 marked 18%. Measure the fraction before choosing. Judges read dotted underlines as spellcheck, so explain such marks on the page.
- Tooling: each tool round carries a fixed context cost; batch file writes and chain commands. The Python tool session can restart between calls; keep helpers in a file and
exec it at the top of every call.
- Run: a score run with fewer judges than its baseline is not comparable; re-measure both versions in the same session with repeated runs, and write the keep rule down before looking at the numbers.
- Council drift is real: the same w1 screenshots scored 9.25 one run and 8.90 the next (one judge also dropped out). Re-score the baseline in the same session before comparing, or use –runs 2.
- The council needs the proxy variables cleared, and one judge can take over 80 s: poll for the output file. A repeat run with a missing judge must not be read as a new round.
- Run: one judge gave an unchanged dossier 9.05 and 7.4, so a single council run is noise at the size of MIN_GAIN; measure the baseline with
--runs 4 before round 1.
- QEMU: TCG does not enforce code-segment limits, so segment-limit W^X on 32-bit x86 cannot be tested there; NX needs PAE and a CPU model with the
nx flag.
- Run: a judge can fail on a dossier of about 109k characters by reasoning for 400 s without emitting JSON; expect 2-judge runs or keep the dossier smaller.
- Speech: before designing around a library’s behaviour, measure it with the real model, and check an object’s public names before copying its internals.
- Run:
council.py --log appends its row at the end of the log file; when the log ends with a stop: line, leave the flag out and add the row yourself.
- Tests: when a new mechanism is added, add the matching attempts to the hostile program too, so the denial shows in the log the judges read.
- Run: the baseline bundle can be scored while a build runs, because a council call is three web requests; keep timing measurements alone.
- Council: an honest limitation written into the documents is read by the judges as the next fix to ask for; that is the intended effect.
- Council: one judge quoted “mangled identifiers” that are not in the dossier; check a judge’s quoted evidence against the artifact.
- Speech: verify a hypothesis before building its fix: the “quiet clip” explanation was false for the recording that prompted it.
- Council: the
--log row has fewer cells than the Rounds table and writes the judge model names; write round rows by hand.
- Docs: do not write “answers in your language” in a README when the behaviour depends on a model that was not tried.
- Council: a gain just under MIN_GAIN with a clean pairwise win is still “not kept”; say so and report both numbers.
- Short equal-time CPU runs favour small models; continuing the best small model beat wider ones.
- Run: queue follow-ups with
cairn precedent queue "<text>" (plain by default; --auto means safe to run unattended, --needs-me means waiting on the user); cairn autopilot add GOAL is a different command that hands the goal to an autopilot agent. The CLI prints brain/tasks/... and brain/sessions/..., but the files are in the vault’s tasks/ and sessions/ folders, and the CLI does not commit them (still modified or untracked 5 minutes later). In the vault, git merge-base --is-ancestor <commit> origin/main re-checks a pushed note commit without a token; it reads the local tracking ref, so it is only as fresh as the last fetch.
- Council:
ping can report all judges ok while every scoring run hangs with empty output (3 approaches: wrapped, detached with images, direct with no images and --timeout 90). After one hung run, stop retrying, self-judge, mark it judged by self, and keep the round count low so the self-score doesn’t inflate.
- Council: a later run can succeed after earlier hangs (here it answered hours later with 3 judges). Re-try the council at the start of the next round before falling back to self-judging, and report self vs council scores separately - the self-judged 8.4 and the council 8.95 for the same v1 were not comparable.
- (inti r3) Four council runs gave the same 8.2 with the same criterion medians, so the spread between runs comes from the judges’ rounding, not from the dossier. A change shows only when it moves a median by a whole point.
- (mlbb-blame r6-7)
hone/judge.py spawns a detached council process that dies when launched from a short-lived shell tool call; launch it from a long-lived session and wait in the same command.
- (kilat r1)
council.py --help can hang in the foreground and a score run can go silent for 20 minutes; always run the council in the background with a done marker, and relaunch once.
- (kilat r1) After shipping a landing page by REST from the shared site clone, reset the clone back to its
origin/main so other sessions do not inherit a diverged commit.
- (inti r5) A run that reaches no judge (network down) is not a score. Write the repeat rule down and commit it before repeating, repeat once, and keep the failed file.
- Judge:
judge.py writes its snapshot to a fixed bundle path, so scoring v1 overwrote the v0 bundle. Snapshot each version into hone/versions/v<N>/ before scoring.
- (mlbb-blame r6-7) Council judges always return three fixes each, so “no suggestions left” is only reachable through a stop rule; close them by the rule and say so.
- (kilat r1) A browser check with a stubbed model found that a reply without a code fence was treated as code; always test the “model says no” path too.
- (kilat r1) git’s credential manager can take over 30 s under load; a timeout there is not a lost token, relaunch the same job.
- (kilat r1) Council score files name the private gateway’s models; keep them out of public repos.