Skip to content

Releases: AltDoug/found-issues

v3.10.6

Choose a tag to compare

@github-actions github-actions released this 23 Oct 04:47
c8f5105

An entry logged on a branch that changes only the ledger is fixed on the default branch, and a fixer's failure report now shows vitest and jest failures.

Fixed

  • A fix no longer lands on a ledger-only branch (ledger lib/autofix-queue.sh:469). An entry logged with --fix in its own PR, or on any branch whose only change against the default branch is docs/found-issues.md or its archive, queued an item whose landing branch was that branch: the fix started from it and aimed its PR at a branch deleted as soon as the ledger PR merged. When the landing branch's diff against the default branch touches only the ledger files, the fix now lands on the default branch and the claim log says <branch> changes only the ledger; landing on <default>. A branch with code changes, or no change at all, keeps its own base.
  • Vitest and jest failures reach the fixer (ledger lib/autofix-ship.sh:160, #282, fixed by auto-fix). The "Failing tests:" report and the "re-running once" log line read only TAP, pytest, go and jest FAIL lines; the indented × name 12ms / ✕ name (5 ms) lines vitest and jest print were missed, so a cosmo fixer saw only the last 20 lines of output.

v3.10.5

Choose a tag to compare

@github-actions github-actions released this 22 Oct 21:54
c80581d

A base whose two test runs fail different tests counts as flaky, not red, so a flaky suite no longer blocks auto-fix on its branch.

Fixed

  • Flaky base tests no longer block a branch (ledger lib/autofix-queue.sh:694). The base suite already re-ran once on a failure; when both runs failed but named no failing test in common, the base was still recorded as known red for that commit, and every later item into the branch retired tests fail at base without running. On cosmo main two unit tests failed on the first run and one e2e test on the second. Now disjoint failures mean a flaky base: no red-base memo is written, the item goes ahead, its run log says flaky base, and a fix that then fails ends with ; base tests flaky in its result. Failing test names are read from TAP, pytest, go test, jest and vitest output (cosmo prints only vitest's × name 12ms lines); a run that names no failing test still counts as red.

v3.10.4

Choose a tag to compare

@github-actions github-actions released this 21 Oct 06:21
ffbc9f4

A red base says when its branch is behind the default branch, the hint naming the test-command setting survives long commands, old red-base memos are pruned, and the once-a-day notices honor a pinned date.

Fixed

  • A red base on a branch behind the default branch says so (ledger lib/autofix-queue.sh:640, #276). When the landing branch is not the default branch and origin/<default> has commits it lacks, the result adds landing branch is N commits behind origin/<default>; merge it in. On cosmo every item retired tests fail at base for two days while main already fixed both failing tests.
  • The test-command hint is no longer clipped (ledger lib/autofix-queue.sh:1080). Results are cut at 160 characters, so a guessed test chain longer than about 86 characters lost the set found-issues.autofix.testCommand part. The setting now comes first: tests fail at base (set found-issues.autofix.testCommand; auto-detected: <cmd>).
  • Red-base memos of deleted or abandoned branches are pruned (ledger lib/autofix-queue.sh:621). A branch's memo was removed only when that branch later ran green. Writing a memo now removes the ones nobody wrote or read for 14 days (FI_AF_REDMEMO_DAYS); a branch still red after that runs its suite once more.
  • Once-a-day notices honor FOUND_ISSUES_TODAY (ledger hooks/session-start.sh:291). The statusline, missing-jq and Codex wiring notices keyed their daily marker on the wall clock only, so their tests failed when the two runs straddled midnight (seen in an auto-fix ship gate at 00:10). The markers now use the same pinned day as the ledger ages, and the tests pin it.

v3.10.3

Choose a tag to compare

@github-actions github-actions released this 16 Oct 07:35
2b62467

doctor warns when a repo pins its toolchain but the auto-fix test command does not use it.

Fixed

  • A pinned toolchain is no longer bypassed silently (ledger lib/autofix-queue.sh:612). Auto-fix runs the test command on the PATH of the session that triggered it, so a repo pinned with mise or asdf could be tested with other Node or npm versions and read red at base only because of that session (seen on a repo pinned to npm 10 tested with npm 12). doctor now warns when the repo has .mise.toml, mise.toml or .tool-versions and the test command is not wrapped in mise exec or asdf exec, and prints the wrapped command to set. The autofix.testCommand docs say the same.

v3.10.2

Choose a tag to compare

@github-actions github-actions released this 15 Oct 03:13
fb7f8f2

The known-red base block tracks each landing branch and the configured test command, a red base under a guessed test command says so, and the last places that assumed a lowercase ledger are fixed.

Fixed

  • The known-red memo is kept per landing branch (ledger lib/autofix-sweep.sh:159). 3.10.1 kept one base-red file per repo, shared by spot fixes and sweeps on every branch, so a spot fix on a session branch could rewrite or clear it and lift a sweep's red-base block on main. Each landing branch now has its own memo; the 3.10.1 single file is ignored and removed on the next write.
  • Removing a configured testCommand lifts a red-base sweep block (ledger lib/autofix-sweep.sh:163). The block's marker now records the configured command, so setting, changing or removing it unblocks the next sweep. Before, removing it (falling back to auto-detection) left sweeps blocked until the base commit moved.
  • The red-base remote check cannot hang on ssh (ledger lib/autofix-sweep.sh:170). The git ls-remote that log, tag, decide and SessionStart sync run while a block is in effect now uses ssh BatchMode=yes and a 5-second connect timeout, unless GIT_SSH_COMMAND, GIT_SSH or core.sshCommand is set. If it fails, the local ref decides, as before.
  • A red base under a guessed test command says so (ledger lib/autofix-queue.sh:651). With no found-issues.autofix.testCommand set, the result reads tests fail at base (auto-detected: <cmd>; set found-issues.autofix.testCommand), so a repo whose guessed command skips a build step its CI runs is told what to configure. autofix status and the stuck streak still match it as a red base.
  • A nested differently-cased ledger resolves paths against its own package at session start (ledger hooks/first-touch.sh:51, #164). The lean SessionStart render found the root of Docs/Found-Issues.md at the git toplevel, so in a monorepo package it showed real-file entries as pathless. The first-touch hook and the statusline cache already handled the recased ledger since 3.10.0; the 3.10.1 note saying they still assumed lowercase was wrong.
  • Auto-fix restores a differently-cased archive instead of deleting it (ledger lib/autofix-ship.sh:74). Before shipping, the ledger reset checked and removed the literal docs/found-issues-archive.md; on a case-insensitive filesystem that deleted a tracked Docs/found-issues-archive.md, and the deletion was committed. It now restores the archive in the spelling git tracks.
  • uninstall-statusline --target stages its stripped copy beside the target (ledger lib/statusline-uninstall.sh:129). It used $TMPDIR and then moved the file onto the target, a non-atomic copy when $TMPDIR is on another volume and a failure when $TMPDIR is unusable. The move is now a same-directory rename, and a failed move cleans up and exits 14.
  • Dead code removed (ledger lib/autofix-ship.sh:34): fi_af_ledger_paths had no callers since 3.10.0.

v3.10.1

Choose a tag to compare

@github-actions github-actions released this 14 Oct 03:54
b007a6a

A differently-cased ledger counts as the ledger everywhere, sync stops probing held entries, and a sweep skipped at a known-red base keeps the day's slot.

Fixed

  • A differently-cased docs ledger is the ledger in every hook and auto-fix path (ledger hooks/pre-commit.sh:27, hooks/format-enforcer.sh:66, lib/autofix-ship.sh:34; follow-up to #164). 3.10.0 taught the lookup to find Docs/Found-Issues.md and similar, but several sites still matched only the literal docs/found-issues.md. The pre-commit format check now validates a staged differently-cased ledger. The Write/Edit format enforcer (including its fast gate and apply_patch hunks) matches the ledger case-insensitively. Auto-fix uses the ledger's real spelling when it annotates a PR branch, reads the base branch's ledger, allows a ledger-only merge conflict, and annotates in fix ship; the branch-delete guard does too, reading the same ledger file on the branch as on the default branch. A staged docs ledger in any case is validated ahead of a root .found-issues.md. A new fi_docs_ledger_at_ref resolves the ledger's tracked spelling at a git ref. The first-touch hook and statusline root still assume lowercase on a case-sensitive filesystem (logged as hooks/first-touch.sh:51).
  • sync stops probing entries that are already on hold (ledger lib/sync.sh:505). An entry carrying a (hold: ...) marker, set by a human or added by sync to a critical entry, was probed like any other on every sync (a gh PR call, git history and tombstone checks) and then walked back. It now skips the closure probes: no git history or tombstone closure check, and a gh call only when it cites a PR, to demote one closed without merging. Renamed files are still followed. A critical ([!]) entry without a marker is unchanged from 3.10.0: it is probed, and only when a closure would have fired does it get the hold marker instead of closing. The Held: summary is unchanged.
  • A sweep stopped by the known-red memo keeps the day's sweep slot (ledger lib/autofix-sweep.sh:313). When the base was already known red at its commit, the sweep ran no tests but still spent a daily slot, so a repo could burn every slot on skips and then could not sweep the same day after its base was fixed. A memo skip now records a red-at-base marker instead: no new sweep queues while the base is still red at that commit. The check asks the remote (one git ls-remote, only while a block is in effect), so a fix merged on GitHub unblocks the next trigger even before anything fetches; offline, the local ref decides. Changing a configured testCommand unblocks too. A base whose tests actually ran red still spends the slot, and spot fixes are unaffected.
  • FAQ: the end-of-turn check runs on Codex (ledger docs/faq.md:116). It has since 2.10.0, reading the marker from Codex's last_assistant_message; the FAQ still listed it as a Claude-only gap.

v3.10.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 01:18
fd51699

Critical entries wait for a human, the end-of-turn check goes quiet, and fixes for the issues reported by @jbelmana.

Added

  • Held closures (issues #161, #169; the hold from @jbelmana's PR #171, re-seated on current main). sync no longer auto-closes a critical ([!]) entry, or one carrying a (hold: <reason>) marker, by any automatic route (merged PR, landed commit, git-confirmed tombstone). The entry stays [open], a critical one gains (hold: needs human verify) once, and sync prints Held: N entries for human verification (NOT closed): with each one. Close it with found-issues resolve "<loc>" --verified review, which also drops the hold; resolve with ai (its default) refuses a held entry (exit 2), so an agent cannot close what the hold reserves for a human. found-issues tag "<loc>" --hold "<reason>" puts any entry on hold and --unhold takes it off. hold is a recognised annotation key, so a held entry keeps its (PR: ...) and (commit: ...) annotations (the plain-text marker in #171 hid them from the parser). An auto-fix that finds a held or critical entry already fixed leaves it open the same way, and auto-fix never queues, sweeps or classifies a held entry, so a held entry costs no daily fixer run.

Changed

  • The end-of-turn check is silent by default. In a session that edited code, the Stop hook used to block once and ask for a <!-- found-issues-checked: ... --> marker, which Claude Code shows as a "Stop hook error" the user has to scroll past, and most of those blocks only bought a marker-only turn. Now every session gets the same silent reminder: it reaches the model with your next prompt, asks it to log anything it noticed out of scope, and asks for no reply marker. FOUND_ISSUES_STOP_REMINDER=block restores the visible block (FOUND_ISSUES_STOP_REMINDER_EVERY_TURN=on implies it); off still turns the check off. The injected rules say the marker is needed only when a block asks for it. Codex is unchanged.

Fixed

  • A symlinked ledger stays a symlink (#160). Ledger writes replaced the link with a regular file; they now resolve the link chain and write the target in place, with the temp file beside the target so the rename stays atomic.
  • A differently-cased ledger is found (#164). Docs/Found-Issues.md, docs/FOUND-ISSUES.md and other casings are the ledger, with the exact-case name preferred, in the CLI, the statusline fast path and the first-touch hook; log no longer creates a second lowercase ledger next to one, and an auto-fix worktree reverts a differently-cased ledger before it ships.
  • resolve --verified human is read back (#161). It wrote a token the parser ignored; review is now canonical and human is an alias for it.
  • The SessionStart statusline check parses a quoted path with spaces (#165), using the same parser as doctor and install-statusline (3.6.2).
  • No mktemp -t left (#174). The statusline install, uninstall and target code used it at 14 sites, which fails under a sandboxed macOS shell; temp files now go beside their target or in ${TMPDIR:-/tmp}, and a test fails if mktemp -t comes back.
  • A commit in another repository no longer annotates this ledger (#166). The PostToolUse hook decided by the command text and only caught a leading cd/pushd; it now reads the sha git printed and annotates only a commit that exists in the ledger's repo (that exact sha, not HEAD), and with no sha it follows the payload's cwd, cd/pushd and git -C. git -C <this repo> commit and git -c k=v commit, which never reached the annotator before, now do. A commit made in a linked worktree (which shares the object store but has its own ledger) is not annotated here.
  • annotate-pr says --pick is what closes, and a bare N follows the picked entry's repo (#168). The usage and --help show --pick as the closing form. A bare PR number is looked up in the git repository that contains the picked entry's path (a ../sibling/ or absolute path) when that is not the ledger's repo; picks spanning repos, or a sibling with no GitHub origin, are refused with a hint to pass org/repo#N. A path inside a git submodule of the ledger repo counts as the ledger repo.
  • The Stop hook finds a marker anywhere in the current turn (#167), not just in the last 8 KB of the transcript, so a verbose turn that wrote it early is not asked again. Only the assistant's own text counts: the literal string inside a tool result or a tool call's input (a cat of the rules, an edited fixture) no longer satisfies the check. Once a session has its reminder queued or delivered, the silent default exits before reading the transcript.

v3.9.3

Choose a tag to compare

@github-actions github-actions released this 12 Oct 22:47
b94d81c

Auto-fix runs a repo's tests on the caller's PATH.

Fixed

  • The repo test command no longer runs the installed CLI ahead of the worktree's (ledger lib/autofix-engine.sh:80). Every auto-fix child puts the plugin's own bin first on PATH so the fixer can call found-issues, and the test command inherited that order. In an auto-fix of found-issues itself, a test or hook script that finds found-issues via PATH (session-start.sh does) ran the installed release instead of the worktree's bin/found-issues, so a fix could look red or green depending on which version was installed. The test command (at base, after a fix, at sweep ship, retarget, readiness and fix ship) now runs on the PATH auto-fix was started with, also when a fixer calls autofix test from inside its own run (launcher B), where the plugin bin was already first; the fixer, verifier and classifier keep the plugin bin first.

v3.9.2

Choose a tag to compare

@github-actions github-actions released this 12 Oct 11:37
90d93ad

Auto-fix runs a repo's tests the way a developer would, without the session's project directory.

Fixed

  • A hook-launched auto-fix run no longer runs the repo's tests against the main checkout (ledger tests/cli-list.bats:28). A run started from a Claude Code hook inherited the session's CLAUDE_PROJECT_DIR, which points at the main checkout, not the fix worktree. found-issues' own list and status resolve the ledger from it before the current directory, so their tests read the real ledger: a base run of this repo went 46 red while main CI and local runs passed, and every item retired stale: tests fail at base. Every auto-fix child (the test command at base, post-fix, sweep ship, retarget, readiness and fix ship, and the fixer, verifier and classifier) now runs without CLAUDE_PROJECT_DIR, so a found-issues call inside the fix worktree reads that worktree's ledger. The test helpers unset it too, so the suite is hermetic when run from a hook.
  • fix ship's gate limit no longer reaches the repo's tests. fix ship sets FOUND_ISSUES_AUTOFIX_TIMEOUT_SECS for its own 60-min gate, and the test command inherited it, overriding the limit this repo's readiness and watchdog tests compute. The test command now runs without it, as it already ran without FOUND_ISSUES_AUTOFIX_CHILD; the watchdog still applies the limit.

v3.9.1

Choose a tag to compare

@github-actions github-actions released this 12 Oct 10:12
72db477

Sweeps get the superseded check: a sweep no longer ships a fix a live session already made.

Fixed

  • A sweep no longer ships a fix a live session already made (ledger lib/autofix-sweep.sh:747). 3.9.0 added the superseded check to spot runs only. A sweep now applies the same check, against the commit it was cut from, at three points. When an entry is handed to a fixer (launcher A's loop, launcher B's autofix next), an entry whose cited code changed on the landing branch is skipped without a paid fixer. Before an approved fix is committed, a change made while its fixer ran skips it. Before ship, a committed fix whose code changed since is dropped: the commit stack is rebuilt without its commit, a later commit that no longer applies without it goes too, and the rebuilt stack still faces the ship-time test run. A rebuilt stack that fails those tests ends failed with its branch kept, with no ship retries. Dropped entries show as skipped with the reason in the PR table, stay open in the ledger, and are not closed by the PR. A sweep whose every fix was dropped ends stale with no PR and still queues the next batch of a chain. Launcher B's other commands (search, test, verify, release, brief) never move past the entry a fixer is working on. A ship retry keeps its stack as it is.
  • A readiness timing test no longer fails on a loaded host. "a base run that passed only on its re-run records one run's time" allowed at most 3 s for a 2 s run, and the full suite once recorded more. It now sleeps 3 s and asserts under 6 s (two runs would take 6+).