Skip to content

[codex] expose cached repository state in status - #846

Draft
KooshaPari wants to merge 61 commits into
kunchenguid:mainfrom
KooshaPari:worktrees/upstream-diagnostics-rebuild-20260826
Draft

[codex] expose cached repository state in status#846
KooshaPari wants to merge 61 commits into
kunchenguid:mainfrom
KooshaPari:worktrees/upstream-diagnostics-rebuild-20260826

Conversation

@KooshaPari

Copy link
Copy Markdown

Summary

Rebuilds the legitimate diagnostics intent from the non-promotable fork on top
of current kunchenguid/no-mistakes upstream. no-mistakes status now always
renders an explicitly labelled cached local repository state: branch, short
HEAD, clean/dirty evidence, and the existing branch-sync guidance.

Safety boundary

The implementation only uses branchsync.Service.InspectCached, whose
contract is local/read-only: it does not fetch, contact remotes, mutate refs,
the index, the worktree, the database, or pipeline custody. The output says
cached and does not claim remote freshness. It deliberately does not revive
the fork's unregistered pipeline experiment, tracked binary, or direct process
execution.

Verification

  • Focused red-green tests for the new presenter and telemetry fingerprint.
  • make lint
  • go test -race ./...
  • go build -o ./bin/no-mistakes ./cmd/no-mistakes
  • git diff --check

This is a draft for upstream review; hosted CI and maintainer approval remain
required before merge.

KooshaPari and others added 30 commits August 1, 2026 18:47
Co-authored-by: KooshaPari <koosha@example.com>
… tests (#3)

* fix(daemon): preserve run state under event stream pressure (kunchenguid#626)

* feat(daemon): bound run event subscriptions without losing state

A bounded subscriber queue cannot guarantee delivery of every payload
without either blocking the executor or growing without limit, so the
old drop-newest policy silently discarded lifecycle transitions and left
consumers rendering state the daemon had already left behind.

Stop trying to conserve payloads and conserve effects instead. Every
state event is reconstructable from get_run, so the stream only has to
carry the fact that state changed:

- internal/ipc/events.go owns the taxonomy (activity is droppable,
  state is not, control is broker-generated, unknown fails safe to
  state), so the daemon's overflow policy and each consumer's
  reconciliation policy cannot drift apart.
- internal/daemon/eventmailbox.go owns overflow: a per-subscriber ring
  bounded at 64 events and 1 MiB, non-blocking publish, activity as the
  only evictable class, and everything else folded into one sticky
  coalescing stream_gap that drains ahead of queued payload. A reserved
  slot fails at the second simultaneous transition; a coalescing scalar
  absorbs any number. The queue is a ring under a mutex because a
  producer-side channel receive races the reader for the same slot.
- Every state event and every get_run snapshot carries a monotonic
  StateRev, sampled before the database read. Consumers apply a delta
  only when it is newer, so deltas queued before a snapshot cannot
  regress state after it.
- Every subscription opens gapped, so attach and reconnect always
  reconcile first.

AXI needed one function: it already treats payloads as wakeup hints and
reads authority from get_run. The TUI gains the revision guard,
authoritative snapshot application, coalesced gap-triggered
reconciliation, and bounded resubscribe on stream loss, replacing a path
that froze the live view on any dropped connection.

The fix-review working-tree diff moves off the stream to get_step_diff.
It was the only unbounded payload, and one frame past the 1 MiB
transport line limit ends the subscription and hides every later event,
including the run's terminal frame.

* no-mistakes(review): Fix event-stream reconciliation and approval-state persistence

* no-mistakes(review): Close residual reconciliation and approval-state gaps

* no-mistakes(review): Add manual retry for review evidence failures

* no-mistakes(review): Preserve concurrent review retries and disclose recovery

* no-mistakes(review): Gate responses and retire stale diff requests

* no-mistakes(document): Document bounded event-stream recovery behavior

* no-mistakes: apply CI fixes

* fix(cimonitor): require trusted no-CI evidence for readiness (kunchenguid#628)

* fix(ci): require trusted no_ci evidence for empty checks

Stop treating an unproven empty forge check list as checks-passed. Ready
now requires observed all-green checks, or trusted default-branch
no_ci: true with zero registered checks. Feature branches cannot
self-declare; delayed registration, pending, and failing checks stay
not-ready even on declared no-CI repos. AXI help names the declaration
when that path applies.

* no-mistakes(review): Persist CI provenance and fail closed on unresolved checks

* no-mistakes(review): Restore cimonitor-owned CI readiness event flow

* no-mistakes(review): Guarantee CI readiness events through saturated subscriber buffers

* no-mistakes(review): Integrated PR 626 mailbox and removed blind eviction

* no-mistakes(review): Classify diff reads and reset stale TUI gate state

* no-mistakes(review): Compare authoritative snapshots against prior gate findings

* no-mistakes(review): Retry stale TUI snapshots through single-flight reconciliation

* no-mistakes(document): Document no-CI readiness semantics

* no-mistakes: apply agent fixes

* no-mistakes: apply CI fixes

* chore(main): release 1.44.2 (kunchenguid#627)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(cli): confirm abort truth before releasing branch custody (kunchenguid#631)

* fix(branchsync): release ownership after a pre-push abort with an unchanged head

A run cancelled through the supported abort before the pipeline changed the
submitted head (for example when delivery switches to a direct PR
mid-validation) was invisible to branch-sync run selection: axi status and the
home view omitted the branch_sync object entirely, and axi sync --check
refused with wrong-branch ambiguity, leaving the worker no supported answer
about branch ownership.

Cancellation releases ownership. A terminal never-pushed run whose head_sha
still equals submitted_head_sha now stays selectable and classifies as the new
user_owned branch-sync state: public structured status identifies the run and
reports the exact branch, local head, submitted and current pipeline heads,
and relation as user-owned and immediately usable, with no next_action. Check
and sync treat it as a non-blocking no-op, --recover on a released branch is
an idempotent no-op that mutates no file, ref, or database row, a repeated
abort is an idempotent no-op returning the same final ownership truth, and
nothing blocks a separately authorized direct push or PR.

Only a terminal run with unpublished pipeline commits (moved head) keeps the
guarded adopt-versus-keep-local custody recovery, unchanged, including every
refusal cell. An active run on an unmoved head now reports plain pipeline
custody (continue_active_run) instead of the misleading legacy_unbound, abort
attaches the final structured ownership state after waiting for the terminal
transition, and pipeline-owned classifications now expose the local-vs-run
head relation whenever it is computable locally.

* no-mistakes(review): Preserve cancelled pipeline commits before releasing custody

* no-mistakes(review): Make terminal custody release evidence atomic and fail-safe

* no-mistakes(review): Stamp verified head in CLI abort fixture

* no-mistakes(review): Verify heads on every successful terminal path

* no-mistakes(document): Document released branch custody semantics

* no-mistakes: apply CI fixes

* fix(cli): report abort success only after confirmed terminal quiescence

Both abort surfaces could claim a completed cancellation before the run
actually reached a terminal state: the branch-scoped abort ignored the result
of its bounded terminal wait and printed aborted: true regardless, and the
explicit --run cancellation never waited at all. A delayed terminalization or
a failed status read could therefore present final ownership guidance for a
run that was still active.

waitForTerminalRun now reports positive confirmation with the last observed
run state and a precise reason when confirmation was not reached. Both abort
surfaces report aborted: true, the terminal run_status, and any ownership
guidance only after that positive confirmation; otherwise they exit nonzero,
state explicitly that cancellation was requested but terminal quiescence is
unconfirmed, include the last structured run state when one is available, and
present no released or recoverable ownership claim. The no-op paths for an
already-quiescent branch or id are unchanged, and repeated abort stays
idempotent.

Public CLI regressions drive both surfaces against a scripted daemon that
delays terminalization past the bounded wait, fails the status read, and
confirms the terminal path still reports completion.

* no-mistakes(review): Bound abort status reads by quiescence deadline

* no-mistakes(document): Document confirmed abort before restart

* fix(cli): resolve durable terminal truth for explicit-run abort

A cancel_run result of no-active-run was treated as a successful no-op by
itself, so axi abort --run for a known already-terminal run returned no
terminal truth, a daemon-state inconsistency where the run record is still
nonterminal was reported as success, and the daemon-unavailable early path
claimed no active run for any id without evidence.

The no-active result is now resolved against the exact run's durable state.
With the daemon up, one bounded cancellation-aware get_run read decides: an
already-terminal run returns an idempotent success carrying its terminal
run_status with no fabricated new cancellation, the daemon's explicit
run-not-found lookup is the only proof that preserves the documented
unknown-id no-op, and a still-nonterminal or unreadable run returns the
nonzero terminal-unconfirmed contract. With the daemon down, nothing can be
cancelled and abort never starts one: the durable run record alone decides
the same three outcomes, and a recorded nonterminal run reports that
cancellation could not be requested rather than claiming it was.

Public CLI regressions cover idempotent terminal-truth resolution, the
inconsistent no-active-but-running case, unknown-id preservation on both
paths, unreadable-record refusals, and the daemon-unavailable treatment.
Branch-scoped abort, bounded reads, verified-head evidence, guarded recovery,
and all refusal cells are unchanged.

* no-mistakes(review): Require exact run identity for abort terminal proof

* no-mistakes(document): Document durable abort terminal resolution

* feat(pipeline): re-run provider-cancelled CI checks before escalating (kunchenguid#595)

Re-run provider-cancelled, timed-out, or stale CI checks once before escalating, so the gate does not spend a fix-agent round on infrastructure noise. Default off (rerun budget 0), trusted-only opt-in, durable per-run reservation before the provider call, and cancelled/unknown checks never read green.

* chore(main): release 1.45.0 (kunchenguid#632)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(pipeline): independently review automatic fixes (kunchenguid#634)

* fix(pipeline): review turns never resume the session that prescribed their fixes

A rereview certifies fix-round code that implements the previous review
turn's findings. Resuming the durable reviewer session seated the
prescriber as certifier, so the rereview verified that its own
prescription was implemented instead of independently judging the
pipeline-authored code: one fix round shipped a correctness defect plus
the test blessing it, and the resumed session passed both with zero
findings.

Review turns (initial and every rereview) now run session-free; only the
fixer keeps a durable session, since it certifies nothing. Cross-round
review context travels solely in the explicit sanitized round history,
and the rereview prompt reframes fix-round changes as pipeline-authored
code under the same adversarial standard as the author's changes: prior
findings, fix summaries, and same-round tests are claims, not evidence.
SessionRoleReviewer remains only so crash recovery accepts legacy
persisted rows, which are never resumed.

* no-mistakes(review): Allow recovery past legacy reviewer sessions

* no-mistakes(document): Correct stale review-session documentation

* chore(main): release 1.45.1 (kunchenguid#635)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(pipeline): stop polling terminal cancelled CI checks (kunchenguid#637)

* fix(pipeline): decide terminal cancelled CI checks instead of polling them

A provider-cancelled check is terminal: the forge has already published
its conclusion for that check and will not publish another one on its
own. kunchenguid#628 started counting every non pass/fail/skip bucket as "pending"
so an unknown or empty check state could never read green, and in doing
so routed that terminal cancellation into the wait-for-more-results
branch it can never leave. kunchenguid#595 built the right gate for it, but only
reaches it once the run has spent a rerun on the check, and the rerun
budget is 0 by default - so on a default-configured repository the CI
monitor polls an already-final rollup until its whole ci_timeout
elapses.

Observed on firstmate PR 1495 (v1.44.2, the first release carrying
kunchenguid#628): eight jobs green, one job killed by its own timeout-minutes,
which GitHub reports as CANCELLED. The monitor logged "CI checks
running, waiting for results..." and kept polling that unchanging
rollup until the run was aborted by hand. Before kunchenguid#628 the same shape
read as checks-passed - wrong, but it ended.

A cancelled check with no rerun outstanding now reaches the same
ask-user gate as one that came back cancelled after its rerun, and each
finding says which of the two it is. Checks that can still finish on
their own still keep the monitor waiting, and an unrecognized bucket is
deliberately left on the wait-then-timeout path: unknown is not
evidence of terminal.

* test(e2e): stop timing the init-rollback guard against machine speed

TestInitRollsBackWhenDaemonStartFails measures a whole CLI subprocess -
spawn, git work, opening the database, and the rollback - and failed the
run whenever that took a second. What it is guarding is that init
honored the injected 200ms daemon start timeout rather than falling back
to the 45s production budget, and a second of slack does not distinguish
those; it only distinguishes a loaded machine. It flaked at 1.21s inside
the parallel e2e suite while passing in isolation.

Widen the bound to 10s and say what it is for. A run that actually fell
back to the production budget still fails it by a wide margin.

* no-mistakes(document): Clarify cancelled-check approval and rerun behavior

* fix(update): authenticate GitHub release requests (kunchenguid#636)

* fix(update): authenticate GitHub release fetch with env token

no-mistakes update fetched releases anonymously and failed with a
403 once the shared IP's anonymous GitHub rate limit was exhausted.
Read GITHUB_TOKEN then GH_TOKEN from the environment and send it as
the Authorization: Bearer header on release-list and asset-download
requests, falling back to anonymous when no token is set.

* no-mistakes(document): document updater GitHub token authentication

* no-mistakes: apply CI fixes

* chore(main): release 1.45.2 (kunchenguid#638)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: Kun Chen <3233006+kunchenguid@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Van Horn <mvanhorn@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…nguid#631)

* fix(branchsync): release ownership after a pre-push abort with an unchanged head

A run cancelled through the supported abort before the pipeline changed the
submitted head (for example when delivery switches to a direct PR
mid-validation) was invisible to branch-sync run selection: axi status and the
home view omitted the branch_sync object entirely, and axi sync --check
refused with wrong-branch ambiguity, leaving the worker no supported answer
about branch ownership.

Cancellation releases ownership. A terminal never-pushed run whose head_sha
still equals submitted_head_sha now stays selectable and classifies as the new
user_owned branch-sync state: public structured status identifies the run and
reports the exact branch, local head, submitted and current pipeline heads,
and relation as user-owned and immediately usable, with no next_action. Check
and sync treat it as a non-blocking no-op, --recover on a released branch is
an idempotent no-op that mutates no file, ref, or database row, a repeated
abort is an idempotent no-op returning the same final ownership truth, and
nothing blocks a separately authorized direct push or PR.

Only a terminal run with unpublished pipeline commits (moved head) keeps the
guarded adopt-versus-keep-local custody recovery, unchanged, including every
refusal cell. An active run on an unmoved head now reports plain pipeline
custody (continue_active_run) instead of the misleading legacy_unbound, abort
attaches the final structured ownership state after waiting for the terminal
transition, and pipeline-owned classifications now expose the local-vs-run
head relation whenever it is computable locally.

* no-mistakes(review): Preserve cancelled pipeline commits before releasing custody

* no-mistakes(review): Make terminal custody release evidence atomic and fail-safe

* no-mistakes(review): Stamp verified head in CLI abort fixture

* no-mistakes(review): Verify heads on every successful terminal path

* no-mistakes(document): Document released branch custody semantics

* no-mistakes: apply CI fixes

* fix(cli): report abort success only after confirmed terminal quiescence

Both abort surfaces could claim a completed cancellation before the run
actually reached a terminal state: the branch-scoped abort ignored the result
of its bounded terminal wait and printed aborted: true regardless, and the
explicit --run cancellation never waited at all. A delayed terminalization or
a failed status read could therefore present final ownership guidance for a
run that was still active.

waitForTerminalRun now reports positive confirmation with the last observed
run state and a precise reason when confirmation was not reached. Both abort
surfaces report aborted: true, the terminal run_status, and any ownership
guidance only after that positive confirmation; otherwise they exit nonzero,
state explicitly that cancellation was requested but terminal quiescence is
unconfirmed, include the last structured run state when one is available, and
present no released or recoverable ownership claim. The no-op paths for an
already-quiescent branch or id are unchanged, and repeated abort stays
idempotent.

Public CLI regressions drive both surfaces against a scripted daemon that
delays terminalization past the bounded wait, fails the status read, and
confirms the terminal path still reports completion.

* no-mistakes(review): Bound abort status reads by quiescence deadline

* no-mistakes(document): Document confirmed abort before restart

* fix(cli): resolve durable terminal truth for explicit-run abort

A cancel_run result of no-active-run was treated as a successful no-op by
itself, so axi abort --run for a known already-terminal run returned no
terminal truth, a daemon-state inconsistency where the run record is still
nonterminal was reported as success, and the daemon-unavailable early path
claimed no active run for any id without evidence.

The no-active result is now resolved against the exact run's durable state.
With the daemon up, one bounded cancellation-aware get_run read decides: an
already-terminal run returns an idempotent success carrying its terminal
run_status with no fabricated new cancellation, the daemon's explicit
run-not-found lookup is the only proof that preserves the documented
unknown-id no-op, and a still-nonterminal or unreadable run returns the
nonzero terminal-unconfirmed contract. With the daemon down, nothing can be
cancelled and abort never starts one: the durable run record alone decides
the same three outcomes, and a recorded nonterminal run reports that
cancellation could not be requested rather than claiming it was.

Public CLI regressions cover idempotent terminal-truth resolution, the
inconsistent no-active-but-running case, unknown-id preservation on both
paths, unreadable-record refusals, and the daemon-unavailable treatment.
Branch-scoped abort, bounded reads, verified-head evidence, guarded recovery,
and all refusal cells are unchanged.

* no-mistakes(review): Require exact run identity for abort terminal proof

* no-mistakes(document): Document durable abort terminal resolution
…kunchenguid#595)

Re-run provider-cancelled, timed-out, or stale CI checks once before escalating, so the gate does not spend a fix-agent round on infrastructure noise. Default off (rerun budget 0), trusted-only opt-in, durable per-run reservation before the provider call, and cancelled/unknown checks never read green.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…#637)

* fix(pipeline): decide terminal cancelled CI checks instead of polling them

A provider-cancelled check is terminal: the forge has already published
its conclusion for that check and will not publish another one on its
own. kunchenguid#628 started counting every non pass/fail/skip bucket as "pending"
so an unknown or empty check state could never read green, and in doing
so routed that terminal cancellation into the wait-for-more-results
branch it can never leave. kunchenguid#595 built the right gate for it, but only
reaches it once the run has spent a rerun on the check, and the rerun
budget is 0 by default - so on a default-configured repository the CI
monitor polls an already-final rollup until its whole ci_timeout
elapses.

Observed on firstmate PR 1495 (v1.44.2, the first release carrying
which GitHub reports as CANCELLED. The monitor logged "CI checks
running, waiting for results..." and kept polling that unchanging
rollup until the run was aborted by hand. Before kunchenguid#628 the same shape
read as checks-passed - wrong, but it ended.

A cancelled check with no rerun outstanding now reaches the same
ask-user gate as one that came back cancelled after its rerun, and each
finding says which of the two it is. Checks that can still finish on
their own still keep the monitor waiting, and an unrecognized bucket is
deliberately left on the wait-then-timeout path: unknown is not
evidence of terminal.

* test(e2e): stop timing the init-rollback guard against machine speed

TestInitRollsBackWhenDaemonStartFails measures a whole CLI subprocess -
spawn, git work, opening the database, and the rollback - and failed the
run whenever that took a second. What it is guarding is that init
honored the injected 200ms daemon start timeout rather than falling back
to the 45s production budget, and a second of slack does not distinguish
those; it only distinguishes a loaded machine. It flaked at 1.21s inside
the parallel e2e suite while passing in isolation.

Widen the bound to 10s and say what it is for. A run that actually fell
back to the production budget still fails it by a wide margin.

* no-mistakes(document): Clarify cancelled-check approval and rerun behavior
* fix(update): authenticate GitHub release fetch with env token

no-mistakes update fetched releases anonymously and failed with a
403 once the shared IP's anonymous GitHub rate limit was exhausted.
Read GITHUB_TOKEN then GH_TOKEN from the environment and send it as
the Authorization: Bearer header on release-list and asset-download
requests, falling back to anonymous when no token is set.

* no-mistakes(document): document updater GitHub token authentication

* no-mistakes: apply CI fixes
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* perf(ci): keep the Windows test job well inside its timeout

The windows-latest test job repeatedly overran timeout-minutes and was
cancelled (twice on PR kunchenguid#636). It is not a hang: no test exceeds ~32s, the
per-binary `go test -timeout=15m` never fired, and every package that
completed reported a normal duration. The job is process-spawn bound.
Git-backed packages cost roughly 10x their Linux time on the Windows
runner (internal/git 5.7s -> 53s, internal/branchsync 31s -> 415s)
because Defender scans every git.exe spawn and every file the temp repos
create, and internal/branchsync ran all 52 tests serially, making it the
job's 7-minute wall floor. Observed windows job runtimes over 20 recent
runs: 10.7-25.3m against a 25m cap, median ~14m.

Excludes the ephemeral build and test trees this job creates from
Defender scanning, and takes internal/branchsync off the serial critical
path with t.Parallel. Locally the package drops from 49.5s to 19.5s with
-race clean over repeated runs; no coverage is skipped or weakened.

* no-mistakes(review): Harden Windows workflow contract tests

* no-mistakes(document): Windows CI documentation already accurate

* no-mistakes: apply CI fixes
…#647)

* fix(ci): retire a rerun record once the provider answers it

A CI check the provider cancelled earns a deterministic rerun, and the
step records that rerun in `checkRerunBudget.rollup` so a later poll can
tell a rollup that has not refreshed yet from a rerun that came back
cancelled again. Nothing ever retired that record, so it outlived the
rerun it described.

`cancelledAfterRerun` treats every name still in the rollup as a rerun
awaiting publication, so any later poll where that name is absent from
the check list is attributed to a rerun that was already answered. The
bounded rollup grace then runs out and the check latches as "cancelled
again after its rerun" for the rest of the run. From then on the CI
step reports an issue on every poll: readiness is cleared, the run
either parks on a cancellation the provider already replaced or keeps
cycling in the fixing state, and a head whose every reported check is
green can never reach checks-passed.

The trigger is a cancelled job plus a rerun that succeeds on that head;
the masking condition is the leftover rerun record; the symptom is a
run stuck fixing until the CI idle timeout. Confirmed against a control
with the identical check sequence and no cancellation, which stays
ready throughout.

`retireResolvedReruns` drops the record on the first poll that publishes
a conclusive bucket for that check name, and persists the change so a
recovered run does not resurrect it. Retirement needs positive evidence:
pending, cancelled, and unrecognized buckets stay tracked, so the
transitional-gap protection still covers a rerun the provider has not
published, and a same-named check still outstanding blocks retirement.
It removes only this run's claim that a rerun is outstanding, never a
check's own bucket, so no cancelled, failing, or pending check can be
promoted to green by it, and the spent budget is left intact so a later
cancellation cannot earn more reruns than `ci.rerun_transient` allows.

* no-mistakes(review): Harden rerun retirement against cancelled and same-name checks

* no-mistakes(review): Persist provider identities for safe rerun retirement

* no-mistakes(review): Persist rerun retirement before committing live state

* no-mistakes(review): Scope rerun retirement to advancing pipeline heads

* no-mistakes(review): Restore safe same-head rerun retirement

* no-mistakes(document): Document resolved CI rerun transitions
…nguid#649)

* fix(branchsync): auto-recover custody for a rebase-superset preserved head

A cancelled validation whose default branch advanced leaves the preserved
pipeline head as a rebase of the operator's branch: the same logical commits
under different SHAs. Recovery's decision matrix tested only equality and
ancestry, so that shape fell through to the diverged refusal and escalated a
custody return where nothing could be lost.

A clean diverged worktree is now adopted when preservedContainsLocalWork
proves the preserved head carries every local change, by either sufficient
proof: each local commit replayed patch-identically (git rev-list
--cherry-mark, which survives the fix rounds that supersede operator lines),
or the preserved head already holding the local branch's exact content
(merge-tree, anchored on the merge-base rather than runs.base_sha, which is
the previous gate head). Adoption anchors the pre-recovery local head at
refs/no-mistakes/recover-local/<run> before resetting.

The unlanded-work protection is unchanged and deliberately fail-closed:
unique local commits, a conflict-resolved replay, a squash that also rewrote
operator lines, and a dirty worktree all still escalate, because only
escalation can tell a deliberate pipeline fix apart from a dropped change.

Reproduced end to end through the real binary in
TestAxiCustodyRecoveryAfterRebaseJourney, with both directions pinned in
internal/branchsync/recover_test.go.

* no-mistakes(review): Harden custody recovery against duplicate patches and anchor races

* no-mistakes(review): Correct recovery guidance and failed-reset reporting

* no-mistakes(review): Qualify conflict-resolved custody recovery guidance

* no-mistakes(review): Reject ambiguous recovery patches and close reset race

* fix(branchsync): narrow custody adoption to a provable containment check

Reshapes the rebase custody recovery to the narrowest contract that still
fixes the reported bug, after three review rounds showed the previous
containment proof was not one.

Containment is now proven only by an executable three-way merge whose result
is exactly the preserved head's tree. The patch-identity arm is gone: patch
IDs discard hunk locations and whitespace, so they cannot tell a genuine
replay from a same-shaped edit to another identical block, and a containment
claim built on them is not a proof. An ordinary rebase that carries the
operator's content forward intact recovers automatically; a rebase whose fix
rounds also rewrote the operator's own lines now escalates, because nothing
available to recovery separates a deliberate pipeline fix from a dropped
change. No-data-loss outranks convenience.

The branch move no longer observes branch, HEAD, and cleanliness and then
runs an unconditional reset --hard. That is check-then-act, and anything
landing in the gap is destroyed no matter how often it is re-observed. The
two Git operations now carry the guard themselves: an atomic update-ref
compare-and-swap against the observed head, so a concurrent commit refuses
with nothing touched, and read-tree -m -u, which aborts rather than
overwriting a modified or untracked file and is rolled back by the same
compare-and-swap in reverse.

Also reverts the internal/git/git.go patch-identity helper, which was scope
drift outside the custody-return decision.

Regression coverage: rebased auto-recover, unique local work escalates,
rewritten operator lines escalate, squash-equivalent adopts, squash-drop
escalates, concurrent commit refuses without losing the commit, concurrent
worktree edit aborts the move and rolls the branch back, dirty refuses,
keep-local unchanged. TestAxiCustodyRecoveryAfterRebaseJourney drives the
whole thing through the real binary and fails before this change.

* no-mistakes(review): Harden cancelled custody adoption recovery

* no-mistakes(document): Document custody recovery reach limit

* no-mistakes(document): Clarify diverged custody recovery guidance
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix(pipeline): restore Risk Assessment, Testing, and rich Pipeline PR sections

PR kunchenguid#605 silently dropped the deterministic Risk Assessment and Testing
sections (passed as literal empty strings) and swapped the rich per-step
Pipeline detail for a compact, evidence-free status summary, all while
leaving their composer functions unit-tested but production-dead. Rewire
buildPRContent to thread riskLine, testingMD, and BuildPipelineSummary's
rich per-step detail back into every PR body path, while keeping kunchenguid#605's
actually-intended change: the agent-authored What Changed narrative stays
scoped to the final branch diff rather than commit history.

* no-mistakes(review): Restore tested commands in rich pipeline details

* no-mistakes(document): Document restored deterministic PR body evidence
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…nguid#670)

* feat(pipeline): attest PR step statuses

* no-mistakes(review): Preserve pipeline attestations across PR body truncation

* no-mistakes(review): Bind pipeline attestations to recorded head SHA

* no-mistakes(document): Document pipeline step attestation contract
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(evidence): publish test evidence to an orphan branch

Test evidence used to be committed into the pushed branch when
test.evidence.store_in_repo was enabled, so every merged PR carried its
screenshots and logs into the default branch's history forever.

Evidence is now always collected outside the worktree and published to a
dedicated orphan branch in the same repository, with the PR body linking
the artifacts by evidence commit. Same access control, binaries welcome,
no external host, and nothing lands in the PR branch or main.

- internal/evidence owns the mechanism: git plumbing against a scratch
  index, so HEAD, the index, and the worktree are untouched and a
  detached or shallow clone works; the parent is the freshly fetched
  remote tip, so the push is a plain fast-forward and never a force.
- Fail-closed: an unreadable remote, a refused push, or a branch of that
  name without the .no-mistakes-evidence marker publishes nothing, and
  the PR body keeps local-path references instead of dead links.
- test.evidence.branch configures the name (default no-mistakes/evidence),
  is validated as a git branch name at config parse time, and is
  trusted-only because it names a ref the daemon pushes to.

* no-mistakes(review): Harden evidence ownership and artifact links

* no-mistakes(document): Document GitHub orphan evidence publication limits

* no-mistakes: apply CI fixes
…process group (kunchenguid#685)

* fix(daemon): reap pipeline children that escape their process group

A process group only contains descendants that stayed in it. Anything
that calls setsid(2) or setpgid(2) - agent CLIs sandboxing their tool
runners, any daemonizing worker script - leaves the group, so the
teardown no-mistakes runs on cancellation and on every exit path cannot
reach it. Once its parent exits it reparents to init and no lineage-based
mechanism can name it again: it keeps burning CPU and holds a deleted
worktree open through its cwd, indefinitely.

internal/procreap is the identity-based backstop. It matches a process by
the run worktree its working directory resolves under - the one identity
that survives lineage loss - and deliberately never by argv, which a
legitimate `git worktree remove` also carries. It never signals pid<=1,
itself, or its ancestors, spares any worktree whose run is still pending
or running, and escalates SIGTERM to SIGKILL only after a grace period.
A process working outside ~/.no-mistakes/worktrees is out of reach by
construction, so unrelated long-lived workers cannot be hit.

Two call sites: run cleanup sweeps that one run's worktree with no age
floor before the directory is removed, and daemon startup sweeps every
inactive worktree older than ten minutes, cleaning up after a predecessor
that died without tearing anything down. Windows needs neither - job
objects contain the whole tree - so its platform layer reports an empty
process table.

shellenv's group teardown now asks before killing: survivors get SIGTERM
and are SIGKILLed only if still alive after the grace period, so a test
runner or worker script can flush output and clean up after itself. The
cancellation path escalates out of band because cmd.Cancel runs on the
goroutine that owns cmd.Wait.

* no-mistakes(document): docs already accurate for process reaper change
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
kunchenguid and others added 18 commits August 21, 2026 19:56
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(eval): score findings as true/false positives, not park/pass

Park/pass treated skip and approve as a pass and asked the wrong question.
Capture now writes finding-level gold from recorded Fix and add-finding
evidence, and replay/report score TP/FN with unmatched findings left pending.

* no-mistakes(review): Capture user-added eval gold independently

* no-mistakes(review): Remove duplicate eval guidance

* no-mistakes(review): Persist eval decision provenance atomically

* no-mistakes(review): Make eval finding scoring evidence-safe

* no-mistakes(review): Make eval scoring evidence-safe and relabel recall range

* no-mistakes(review): Keep eval matching and recall evidence-safe

* no-mistakes(test): Match eval findings by finding ID

* no-mistakes(document): Document finding-level eval scoring
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…id#735)

* fix(daemon): keep run evidence off shared /tmp and reap it ourselves

The test step wrote evidence to os.TempDir()/no-mistakes-evidence. The
daemon's service unit exports only HOME, PATH, and proxy variables, so
TMPDIR is unset and that resolved to the shared /tmp - which Ubuntu has
mounted as a systemd tmpfs since 24.10, putting every screenshot and
rendered-HTML artifact in RAM.

Nothing in this program ever removed it, either. The directory was a
fixed name that accumulated one subdirectory per run, cleaned only by an
OS timer we do not control and that has no equivalent on Windows. On one
developer machine that was 876 run directories over ten days, 823 of them
empty: the test step creates the directory before the agent decides
whether it has anything to write.

Evidence now lives at <NM_HOME>/evidence/<runID>, owned by internal/paths
like every other location. The app root is disk backed on macOS, Linux,
and Windows alike, so there is no runtime.GOOS branch and the macOS path
is not regressed - it improves, since /var/folders is periodically purged
and that silently broke the local artifact paths older PR bodies fall
back to.

Cleanup is now ours, in three layers: a finished run's empty directory is
removed at run cleanup, a reaper bounds the directory by age and count
oldest-first after every run and at daemon startup, and the
pre-relocation temp directory is drained under the same policy. All three
reuse the existing pending/running guard, so a run still in flight is
never touched.

test.evidence gains local_root, retention, and max_runs. They are
global-only: a repository does not get to name a filesystem path this
machine's daemon writes to, nor set the retention budget for a directory
every repository on the machine shares. There is deliberately no
environment variable - the service unit preserves only proxy keys, so an
env-gated value would be dropped on the next update.

Also removes the second, independent copy of the evidence path in the
agent steering preamble, which rebuilt it from os.TempDir() on its own.
The executor now resolves the path once and both consumers read it.

* no-mistakes(review): Protect unowned directories from evidence reaping

* no-mistakes(document): Clarify managed evidence storage scope

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes

* fix(daemon): clean run evidence at the recovered-run completion boundary

Evidence ownership claims cleanup runs after each run, but only the
fresh-run defer called cleanupRunEvidence. A run parked at an approval
gate when the daemon stopped is finished by resumeRecoveredRun, which has
its own completion defer, so a resumed run kept its empty evidence
directory until some later run or a restart happened to sweep it.

There are exactly two completion boundaries and both are now covered. The
regression test drives resumeRecoveredRun and asserts the directory is
gone afterwards; every outcome of a resumed run shares that defer, so the
boundary is the thing worth asserting on.

* ci: give the test job a budget the Windows leg actually fits in

The Windows leg was cancelled at timeout-minutes twice in a row with no
verdict, on a suite where every package that reported had passed. It is
process-spawn bound rather than compute bound, so it compiles every test
binary and then runs the git-backed packages at roughly 10x their Linux
cost, and 25 minutes no longer covered that.

An evidence-free cancellation is worse than a slow job: it is reported as
a check failure and reads as a defect in the change under test, which is
exactly how it was read here.

The cap stays a runaway guard rather than a target. Linux and macOS
finish far inside it, 40 minutes still keeps a wedged runner well short
of the six-hour default, and go test -timeout is deliberately unchanged
so a genuine hang still produces a goroutine dump first.

This does not close the coherence gap behind it: -timeout bounds each
test binary while timeout-minutes bounds the whole job including compile,
so total wall can still exceed the cap with no binary reaching its own
deadline. Bounding per-job wall properly is follow-up work.

* chore: pin review auto-fix to the product default in this repo

The code default for auto_fix.review is 0 so review findings park for a
human decision, but this repo carried no auto_fix block and therefore
inherited whatever an operator set globally.

With it enabled, a one-line CI timeout change drew a speculative review
finding that the auto-fixer answered with a new DB table, a schema
migration, and a new package, then spent three rounds finding errors in
its own invention. None of it was asked for, and a parked finding would
have surfaced the question instead of quietly answering it.

Only review is pinned. The deterministic steps keep whatever the operator
configured, because a lint or test finding has an objective checker and
does not need a human to decide whether the fix belongs.

* no-mistakes(review): Reject evidence roots inside managed worktrees

* no-mistakes(document): Clarify evidence storage constraints
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
)

A single Windows ./... job could exceed timeout-minutes without any binary hitting go test -timeout. Split git-heavy packages from the remainder, replace the bash SIGTERM trap that macOS still raced, and cancel parked executor tests so Windows can unlink lint.log.
…chenguid#739)

* feat(eval): pin gold-only diversified holdout and real precision

Keep unlabeled cases out of the official set, auto-label merged auto-fixes as true positives and shipped-unfixed findings as false positives, and headline F1 only when false-positive gold exists so precision is not recall in disguise.

* no-mistakes(review): Skip later-fixed shipped-unfixed gold labels

* no-mistakes(document): Fix leftover stale eval documentation

* fix(eval): honor last-round shipped-unfixed, live holdout cap, and optimal matching

Stop labeling findings that were gone before merge as false positives, trim diversified pins on ListCases when the cap shrinks, and assign candidates by exact-then-fuzzy maximum matching so gold order cannot undercount.

* no-mistakes(document): Align eval docs with merge-derived gold

* test(eval): prove relabel clears a stored shipped-unfixed false positive

Cover the retention path separately from the write trigger: a labels.json shipped-unfixed FP must be removed when recomputed gold no longer supports it, both in mergeGold and on disk after RelabelRun.

* no-mistakes(document): Correct stale eval daemon-entry comments

* fix(eval): keep at most one diversified pin per stratum when the cap shrinks

Zero and lowered caps now collapse existing pins to one official case per stratum on ListCases, so a prior Hamilton allocation cannot leave extras in the holdout or steal them from tune.

* no-mistakes(document): Eval Phase A documentation already current

* fix(eval): do not reallocate multiple holdout seats into one stratum

After a lower cap collapses duplicate-stratum pins, leftover seats may fill new strata but Hamilton must not recreate k>1 in one of them.

* no-mistakes(document): Holdout cap docs already current
…wrong-result risks (kunchenguid#743)

* feat(review): ungate counterexample tracing and name silent-wrong-result risks

Review was reconstructing failing sequences only for claimed durable fixes, so feature changes never got that discipline, and silently wrong values, labels, or sets were unnamed in the risk vocabulary. Make tracing a short general principle for any new or changed logic, and keep intent conformance from substituting for correctness.

* no-mistakes(document): Clarify conformance does not replace correctness
…unchenguid#744)

* feat(eval): ingest confirmed post-PR misses as false-negative gold

A green review that later proved wrong was unscorable: capture only labels from gate decisions, and there was no way to record the greptile-caught class. Add eval miss ingest so a vetted finding becomes FN gold on the last non-blocking review pass, skip incomplete sibling rounds, and refuse parked or blocking reviews.

* no-mistakes(document): Align eval docs with post-PR miss ingest
…l review (kunchenguid#745)

* feat(review): persist uncertified fixer commits for the next initial review

A cancelled re-review left pipeline-authored commits with no marker, so the replacement run reviewed them as ordinary author code. Persist the per-branch uncertified range and feed fix-round provenance on the next initial review; rerun still proceeds.

* no-mistakes(review): Preserve uncertified range across runs and rebases

* no-mistakes(document): Document uncertified review provenance across runs
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…ly (kunchenguid#753)

* feat(eval): key finding gold on the recorded decision and match gold globally

Labeling a review finding used to key on whether a later review round still
raised it, which conflates the two decisions that matter: a finding the human
chose to fix and a finding they chose to ship both disappear from later rounds.
Gold now follows the round's own recorded fix-vs-skip decision plus the source
run's merge state. Selecting a finding for fix on a merged run is true-positive
gold even if a later round re-raised or rewrote it; leaving one unselected on a
merged run is shipped-unfixed false-positive gold; a round whose gate decision
was never recorded stays unlabeled.

The false-positive half deliberately reverses the earlier "never auto-label FP
from a skip" stance: in this operator's corpus, a finding they approve and ship
without fixing is a false positive. It still needs both halves - a recorded
decision and the merge - and no-op findings are never labeled.

Scoring replaces per-strength-tier greedy assignment with one globally optimal
bipartite matching over all gold and candidate findings, weighted so an exact
match outweighs any number of fuzzy ones. The tiered matcher could hand a
candidate to a gold that had alternatives and strand a gold that had none,
understating recall for reasons unrelated to the review under test.

* no-mistakes: apply CI fixes
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate:

This is a draft, so it will not be merged. Inspected the diff: no-mistakes status always renders branchsync.Service.InspectCached (local/read-only, labelled cached). No fetch, no ref/index/worktree mutation, no pipeline.

VISION.md:

  • R1: aligns. Status output only; core pipeline unchanged.
  • R2: aligns. InspectCached is read-only.
  • R3: aligns.
  • R4: aligns.
  • R5: aligns. Output says cached and the telemetry fingerprint includes the rendered evidence.
  • R6: aligns. Humans and agents see the same local state.
  • R7: aligns.

Please mark the PR ready when you want hosted CI. First-time fork workflows will need a maintainer approval after that.

karotkriss and others added 6 commits August 26, 2026 01:26
…chenguid#841)

* fix(scm/gitlab): drop unsupported --yes flag from glab mr update

glab v1.5x's `mr update` has no -y/--yes confirmation-skip flag (unlike
`mr create`, which does), so passing it fails the whole command with
"unknown flag: --yes" and every GitLab UpdatePR call errors.

* docs(agents): note glab mr update's missing --yes flag in the drift list

Extends the existing GitLab Backend drift summary alongside the mr list
--state opened and detached-HEAD ci get traps.
…: no-mistakes status description now reflects the new cached local repository state display (branch, short HEAD, clean/dirty, sync guidance) instead of the old "relevant cached local-branch synchronization status" phrasing. No other stale duplicates found.
…nt.go

The base commit e0cf74d had corrupted ci.go and ci_transient.go files with
embedded merge conflict markers. Fix by:
- Removing duplicate code blocks wrapped in conflict markers in ci.go
- Adding missing cancelledWithoutRerun method to ci_transient.go
- Adding missing unresolvedCancelledDescription function to ci_transient.go
- Fixing corrupted doc comment on ciUnresolvedCancelledOutcome

This allows the code to compile and CI checks to pass.

Co-Authored-By: Claude <noreply@anthropic.com>
@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate:

Still a draft, so it will not be merged. Re-checked HEAD 5ceac4f6 (docs/cli.md added on top of the cached InspectCached status presenter). Still local/read-only, labelled cached.

VISION.md:

  • R1: aligns. Status output only.
  • R2: aligns. No mutation.
  • R3: aligns.
  • R4: aligns.
  • R5: aligns. Output says cached.
  • R6: aligns.
  • R7: aligns.

Please mark the PR ready when you want hosted CI. First-time fork workflows will need a maintainer approval after that.

@KooshaPari
KooshaPari force-pushed the worktrees/upstream-diagnostics-rebuild-20260826 branch from 5ceac4f to a622fd5 Compare August 26, 2026 08:58
@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate:

Re-checked after newer activity. Still a draft, and now DIRTY/CONFLICTING vs main (9694fff, #844). I will not rebase a draft.

#849 looks like the same cached-status change on a clean branch. If that is the successor, please close this PR so we do not track two copies. Otherwise mark this one ready after rebasing.

VISION.md unchanged from the earlier pass (status presenter, read-only InspectCached).

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.

4 participants