← All Solo, Not Alone posts

ai-coding process

The Briefing That Never Fetched

An agent session rebuilt a feature that had merged three days earlier, because its startup briefing read stale remote refs and called them current. The missing sentence cost a complete parallel implementation.

On 2026-08-04 an agent session on The Lien (then under its earlier working title) designed, planned and built combat readability from scratch. That is the work that makes the combat panel and the log say what the numbers really are. It took six tasks, a review per task and a review of the whole branch. The session played the result, pushed it, and opened PR #15.

The feature was already in the game. PR #13 had shipped it on 2026-08-01, and PR #14 had recorded the verdict on the act 1 boss after it. The conflict only showed up when GitHub tried to merge. PR #15 was closed, nine commits unmerged.

Where the false "current" came from

The session had opened with a catchup, a short read-only briefing on where a project stands. One of its checks lists remote branches that have not been merged into main. It ran that against the remote-tracking refs already on disk and reported nothing unmerged and nothing on origin outside main.

Those refs were three days old. They predated PRs #13 and #14, so the briefing described a repo that no longer existed.

The procedure for the catchup already knew this. It says the check "is only as fresh as the last fetch" and requires the output to carry the caveat "remote refs, last fetch unknown" whenever a remote branch matters to the briefing. The caveat was left out, and no git fetch ran. Once the briefing said there was nothing to merge, every later decision in the session built on it. Nothing downstream had a reason to check again.

One more detail kept the divergence hidden. Local main carried two unpushed docs commits from the same session, so a quick comparison of local against remote would not have looked clean either way.

What was worth keeping

Almost nothing in PR #15 survived. The CombatEvent journal, the per-hit log lines, the ten-line log and the buff narration were all a different style choice against a shipped version that I had played and called self-explaining. They were dropped, not argued over again.

One finding held up. The log still prints the damage a card dealt before enemy Block, so a card fully absorbed by Block shows a damage number beside a health bar that does not move. The comment in the code calls the pre-block number deliberate for the enemy's attack line, and the player's line has the same shape with no such note.

The other finding was about who gets to give a verdict. The duplicate session also drove the boss fight by automation, saw the Strength stacking snowball, and read it as a problem. Each hit of a multi-attack applies Strength, so at three hits per attack every stack is worth triple. I had already played that fight to the finish and judged the same mechanic fair, escalating and readable. Eight rounds played badly by a machine are not evidence against a full fight played by the person the game is for. The agent's verdict was reverted and PR #14's stood.

What I changed

A read-only briefing that is allowed to skip network calls has to say so every time, not only when it feels unsure. The sentence costs nothing to print and its absence cost a complete implementation. A stale answer that looks like a fresh one is worse than no answer, because nobody goes looking for what the briefing said was not there.

For anyone working alone with agents, the general version is that a session's first claim sets the frame for everything after it. When there is no second person to ask "did you fetch?", the check has to be written into the procedure and shown in its output.

More on the game at /games/the-lien, and the rest of this series at /notes.

← All Solo, Not Alone posts