Skip to content

fix(pipeline): scratch files leaked into agent commits; install a logger - #276

Merged
ANonABento merged 1 commit into
mainfrom
dogfood-fixes
Aug 22, 2026
Merged

fix(pipeline): scratch files leaked into agent commits; install a logger#276
ANonABento merged 1 commit into
mainfrom
dogfood-fixes

Conversation

@ANonABento

Copy link
Copy Markdown
Owner

Both bugs found by actually running an agent from a column end to end — dogfooding #275. Neither was visible any other way.

The git exclude never applied in a worktree

execute_spawn_cli built the exclude path by joining .git/info/exclude onto the working dir, then guarded on .exists(). In a linked worktree .git is a file, not a directory, so that path never exists — the guard found nothing and silently skipped the whole exclusion.

So every worktree-based agent run has been committing .task.md. This is pre-existing, not new; .agent.md had just inherited it. First dogfood run:

 .agent.md       | 25 +++++++++++++++++++++++++
 .task.md        |  8 ++++++++
 agent-proof.txt |  1 +
 math.js         |  2 +-

Only the last two belong there.

git rev-parse --git-path info/exclude resolves the real common-dir file for both a plain repo and a linked worktree. exclude_from_git uses it, is idempotent per pattern, appends only what's missing, creates the parent dir, and no-ops outside a repo. Same pipeline re-run after the fix:

 agent-proof.txt | 1 +
 math.js         | 2 +-

Nothing was installing a logger

The log crate is a silent no-op until something registers one, and nothing did — no tauri-plugin-log, no env_logger, no set_logger anywhere in the tree. All 202 call sites were discarded, including 19 log::error!:

level sites
error 19
warn 117
info 62
debug 4

That is exactly what made the first dogfood failure undiagnosable: a trigger that failed and a trigger that never fired look identical from outside. I spent several rounds guessing at DB state before realising the diagnostics I was looking for had never been emitted.

env_logger now initializes in run(), defaulting to kaitencode=warn, controllable via RUST_LOG. Turning it on immediately printed the full trigger path — argv, working dir, tmux wait-for channel — and everything after that was straightforward.

What the dogfood run proved about #275

Real agent, real column, real repo, isolated data dir:

  • attached agent supplied the CLI and its model — argv showed --model sonnet from the agent config, not the workspace default
  • .agent.md written and followed: the agent wrote the proof token the instructions asked for
  • the attached skill was used — it ran the verification command and reported add(2, 3)5
  • exit 0 → agent_complete → auto-advance Todo → Fix → Done
  • worktree cleaned up on reaching the terminal column
  • the planted bug was actually fixed: return a - breturn a + b

Roadmap

Critical-now is now empty — the stale /usr/local/bin/claude is gone (verified: which -a claude returns one path, 2.1.239).

Recorded a new env-hygiene note: the same duplicate-binary shape now exists for codex. /usr/local/bin/codex is 0.130.0 while fnm's shim is 0.145.0 — the version every codex behaviour in this repo was verified against. The fnm path is per-shell and lives in tmpfs, so a reboot or a desktop-launcher start hands the app the stale one. Checked: not currently breaking anything — both carry --skip-git-repo-check and --dangerously-bypass-approvals-and-sandbox, and both have resume --last. Logged as latent, not urgent.

Checks

cargo clippy -D warnings · cargo test 559 (+2) · tsc · eslint · test:ipc · test:type-scale · vitest 444.

Both found by actually running an agent from a column end to end, which is
the only reason either was visible.

The git exclude never applied in a worktree.

`execute_spawn_cli` built the exclude path by joining `.git/info/exclude`
onto the working dir, then guarded on `.exists()`. In a linked worktree
`.git` is a *file*, not a directory, so that path never exists — the guard
found nothing and silently skipped the whole exclusion. Every worktree-based
agent run has therefore been committing `.task.md`, and `.agent.md` had just
inherited the same fate: the first dogfood run produced a commit containing
`.agent.md`, `.task.md`, `agent-proof.txt` and `math.js`, where only the last
two belong.

`git rev-parse --git-path info/exclude` resolves the real common-dir file for
both a plain repo and a linked worktree. `exclude_from_git` now uses it, is
idempotent per pattern, appends only what's missing, creates the parent
directory, and no-ops outside a repo. Re-running the same pipeline afterwards
produced a commit with only `agent-proof.txt` and `math.js`.

Nothing was installing a logger.

The `log` crate is a silent no-op until something registers one, and nothing
did — no `tauri-plugin-log`, no `env_logger`, no `set_logger` anywhere. All
202 call sites across the app were discarded, including 19 `log::error!`.
That is what made the first dogfood failure undiagnosable: a trigger that
failed and a trigger that never fired looked identical from outside.

`env_logger` now initializes in `run()`, defaulting to `kaitencode=warn` and
controllable with `RUST_LOG`. Turning it on immediately showed the full
trigger path — argv, working dir, tmux channel — and the rest of this session
was debuggable as a result.

Also records in the roadmap that critical-now is empty (the stale
/usr/local/bin/claude is gone, verified), and notes the same duplicate-binary
shape now present for codex: /usr/local/bin/codex is 0.130.0 while fnm's shim
is 0.145.0, the version every codex behaviour here was verified against. The
fnm path is per-shell and lives in tmpfs, so a reboot or a launcher start
hands the app the stale one. Checked: not currently breaking anything — both
carry the flags the app uses and both have `resume --last`.
@ANonABento
ANonABento merged commit fbfee03 into main Aug 22, 2026
3 checks passed
@ANonABento
ANonABento deleted the dogfood-fixes branch August 22, 2026 00:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant