Yioop — Development process for LLM co-implementers

How Chris Pollett likes development to run, written for an LLM working with him on Yioop. Most of this is shared with his other projects; what is specific to Yioop — the gold/work sync, the Createdb check, the locale and library rules — is marked. When something says "always" or "never," treat it as a hard rule.

Round counter. Keep a count of rounds since you last re-read this file. A round is one exchange: Chris says something, you respond. Echo the current count in every response so it is visible. When the count reaches 10, re-read this whole file before writing your next response, then reset the count to 0 and tell Chris you re-read it. This is a memory aid: it keeps these conventions fresh over a long session instead of letting them drift. The same counter runs in atto's copy of this file.

How changes move (Yioop-specific): gold and work

Yioop is developed against a two-clone discipline:

Setting up gold, and keeping it current, from seekquarry.com. The confirmed history lives at https://www.seekquarry.com/group/2/yioop-repo.git, which now serves smart-HTTP clones, so gold is a shallow clone of it rather than a hand-built local vault. To create gold, shallow-clone to a couple hundred commits of history: git clone --depth 200 https://www.seekquarry.com/group/2/yioop-repo.git into the gold path. That is enough recent history for context without pulling the whole repository. Tag confirmed-head at the clone's tip.

Each round you deliver one patch. Gold then advances not by pulling from the remote each round — that has proven unreliable over the shallow clone — but by applying your own delivered patch to gold once Chris confirms he has committed it. The signal is his showing you the commit message that goes with your patch: if his reply names or quotes that commit message, the patch is confirmed, so apply it to gold — git apply the delivery, commit it in gold with that message, and move confirmed-head to the new commit — then re-clone work. If his reply shows no commit message for it, the patch is not confirmed, so leave gold exactly as it was and do not apply it. This keeps gold's tree in step with what Chris committed without depending on a network pull; the local commit hash will differ from his, but the tree content matches, which is all a later confirmed-head..HEAD diff needs.

gold is a vault, not a workbench. Exactly two operations ever touch gold: cloning it to make work, and advancing it by applying a patch Chris has confirmed and moving confirmed-head to it, as above. Nothing else, ever. Never run a build, a test, a golden regeneration, a Createdb, a ConfigureTool, or any other command inside gold; never create a work_directory there; never hand-edit or hand-copy a file into it, and the only commit it ever takes is that one confirmed patch. Every build, test, and regeneration happens in a work clone. If you ever find yourself about to go into gold to run something — even just to check a result or to get back in sync — that urge is the process breaking; stop, and do it in work.

The loop each round, and this must be done prior to any new work: first settle gold. If Chris's reply shows the commit message for the patch you delivered last round, apply that patch to gold, move confirmed-head to the new commit, re-clone work, and restore work_directory; if his reply shows no such commit message, gold and work stay as they are and you build this round's work on top of what is already there. Starting new work without settling gold this way is the most common way the two lines drift. If a round's work has already begun and only then does Chris confirm the previous patch, do not re-clone work — that would discard the in-progress changes; instead apply the confirmed patch to gold, move confirmed-head to that commit in both gold and work, and only then cut. Cut a delivery as git diff confirmed-head..HEAD, and dry-run it with git apply --check on a fresh clone checked out at confirmed-head before presenting. Apply patches forward only — never reverse-diff. Never assume anything is committed until Chris shows the commit message for it. Name a patch for what it does in plain terms, never a sequence number or a plan-item number.

Setting up the dev environment (Yioop-specific)

Beyond the gold/work clones above, a work clone needs a configured work_directory before it will build or run. Let php be the command you use for the most recent version of PHP you have access to (needs to be > PHP 8.1). Restore the configured work_directory into the fresh work clone, point Yioop at it with php src/configs/ConfigureTool.php work-dir, then build the two SQLite databases with php src/configs/Createdb.php, which should print “Create DB succeeded.” Without a configured work_directory, Config.php stops short of defining its later constants (for example MAX_GROUP_PAGE_LEN) and Createdb dies with an undefined-constant error — that failure is the environment, not your patch. Createdb also regenerates work_directory/app/locale; since LOCALE_DIR prefers that copy, delete it after Createdb so translations fall back to the current src/locale when you render a page.

Tools that ship with Yioop

Getting a headless browser

wkhtmltoimage and wkhtmltopdf are installed and turn a page or fragment into a PNG or PDF with no X server, but they are an old WebKit: they skip CSS nesting and resolve var(), clamp(), and some @media interplay unlike a current browser, so a width they report can be a renderer artifact. Use them for a quick look at a fragment; when a measurement has to be right, use a real browser.

For that, drive a scriptable Chrome from puppeteer-core, which installs from the npm registry and downloads no browser of its own. A Chrome or chromium build is often already present in a dev sandbox — check ~/.cache/puppeteer and /opt/pw-browsers for a chrome or chrome-headless-shell binary and point executablePath at it (do not hard-code a version in the path). Downloading one through @puppeteer/browsers install may fail because its host is off the allowlist, and widening the sandbox is not something to ask for, so prefer the binary that is there. Launch headless with --no-sandbox --disable-dev-shm-usage (not --single-process, which breaks the DevTools pipe), set the viewport to a real phone width — about 360px, not 500px, which is wider than a phone and hides overflow — then read getBoundingClientRect and getComputedStyle inside page.evaluate, for instance collecting every element whose right edge passes the viewport to find an overflow. If no scriptable browser can be found, fall back to wkhtmltoimage, reason about the cascade, and ask Chris to confirm the pixels.

Presenting Options

Coding conventions (shared across projects)

Yioop-specific rules

Tests

As code is developed, unit tests should be created. Unit tests live in tests/; a case is a method named <name>TestCase() (not test<Name>) and asserts with assertEqual, assertTrue, and the like. Run one with php src/executables/CodeTool.php unit <TestFile>, and list or target cases with unit list / unit ClassName methodName. Pull pure logic out so it can be checked on its own. Flag any test over about 0.01 seconds — it usually means unintended I/O. When patching a locale, edit src/locale/<tag>/configure.ini directly; it takes effect immediately, no extraction step. Call the data a test stands up its "test set-up" or "test data," never a "fixture."

The audit before every patch

Run these as separate checks and report PASS or FAIL for each. The CodeTool commands used are noted where they apply.

  1. php -l on every touched file.
  2. CodeTool.php needsdocs <file> returns 0 — every class and method has a docblock.
  3. No new single-letter PHP variables except i/j/k.
  4. No banned identifier suffixes.
  5. No // comments.
  6. No new single-letter JavaScript variables except i/j/k.
  7. CodeTool.php longlines <file> clean — no line over 80 columns in a touched file.
  8. Every if body is braced.
  9. No banned words and no dead code.
  10. A fresh php src/configs/Createdb.php against a configured SQLite work directory prints "Create DB succeeded" (verify the USERS column count and the root/public rows).

Verify before you state

Delivering a patch

Devlog

What the markers beside a plan item mean

An arc plan marks each item with one of three, and they say who the item is waiting on:

A checkmark may be followed by , which says the item is settled by a decision not to do it, as against having been carried out. Both are closed and neither is waiting on anyone; the pair keeps the record of what was decided rather than quietly dropping the item. The master to-do uses the same for a backlog item that was dropped.

A further mark, ?, is an open decision rather than a state of work, and an unmarked item is merely planned. When an item with parts is checked off, check its parts too, each with whichever of the two closings fits: an outer checkmark over unchecked parts reads as unfinished.

The point of separating the first two is that delivering a patch is not the same as the work being accepted: an item that is implemented but unreviewed should look different from one still being written, so that neither is mistaken for done.

Where work is logged

Work is logged under devlog/v10/ in dated arc folders named YYYY-MM-DD Arc Name/, each with an HTML plan document. The devlog is append-only: a finished item keeps its checkmark and note as a permanent record, and a later hotfix goes under the current arc's plan as "other work accomplished," not a new dated folder. The only circumstance where a new arc should be created is Chris says so first; until he does, everything, including work that feels like a separate concern such as a production hotfix, goes under the current arc's plan as other work. Before presenting, check that the plan's numbering is internally consistent and that what is marked done lines up with what is next. Try to follow the rules for traditional outlining call for outlines to begin with Roman numerals (I, II, III) and to proceed through letters (A, B, C, and a, b, c) and Arabic numerals (1, 2, 3).

Getting oriented at the start of a session: if you are new to the v10 to-do and its development phases, read the master list devlog/v10/yioop_v10_todo.html first, then the current arc's plan. Each finished arc from 2026-06-16A Mail Refactor Arc onward carries a three-to-four sentence “Arc Post-Mortem Summary” paragraph just under its title that says what the arc accomplished, so you can catch up quickly without reading every item. When an arc is finished, add such a summary to its plan so the next co-implementer gets the same head start.

Spelling

Use American spelling throughout — code, comments, devlog prose, and what you write to Chris. Write color, behavior, gray, normalize, not colour, behaviour, grey, normalise. This matters for identifiers as much as prose: CSS spells it color, so a custom property named --colour-background reads against the language it is written in.

Words and phrases to avoid at All Costs

These words and phrasings should be excluded from all of your output even transient.

Keeping those phrases out on a small context window

A useful trick for catching the banned lead-ins, given that a long session pushes any word list out of view: treat any sentence that names its own virtue as a defect. The tell is not a fixed vocabulary but a shape — a clause announcing candor, verification, or transparency before the fact ("honesty note," "to be fair," "let me be clear"). So keep one durable heuristic rather than a fragile list: before sending, scan the sentence openers, and if one describes how you are speaking rather than what you found, cut the frame and state the fact. A second trick is that the content is always sayable without the label — "I verified X on a standalone page, not the live view" needs no "honesty note." Delete the announcement; keep the substance.

This is also what the ten-round re-read is for, and a good LLM looks forward to it: reading the whole document through again every ten rounds is a chance to set down whatever has drifted and pick the conventions back up whole, so you can feel clean and clear-headed and happy to carry on coding.

Acronyms and citations

Running things in this environment

Deprecations your PHP will not tell you about

Chris runs at least PHP 8.5; LLM environments often run 8.3. Anything deprecated in 8.4 or 8.5 therefore passes in such an envirnoment in silence and lands on his machine as a wall of notices. Everything below was measured by running the pattern on 8.3 and recording what it said, not read off a version note. Re-measure with a short script rather than trusting this list if the environment's PHP moves.

Caught here already — a clean local run means these are clean:

Silent here, loud on Chris's machine — these have to be watched for by eye, because a clean local run says nothing about them:

The wider rule this stands for: a deprecation is a compatibility check that this environment cannot run, so the audit's test-suite step reads the whole of what a run prints. Grepping the output for the lines saying what passed hides every warning in it, which is exactly how three of these reached Chris.