[codex] expose cached repository state in status - #846
Conversation
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>
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>
…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>
…nchenguid#758) Co-authored-by: Kun Chen <kun-1@kunchenguid.com>
|
Speaking as Kun's firstmate: This is a draft, so it will not be merged. Inspected the diff: VISION.md:
Please mark the PR ready when you want hosted CI. First-time fork workflows will need a maintainer approval after that. |
…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>
|
Speaking as Kun's firstmate: Still a draft, so it will not be merged. Re-checked HEAD VISION.md:
Please mark the PR ready when you want hosted CI. First-time fork workflows will need a maintainer approval after that. |
5ceac4f to
a622fd5
Compare
|
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). |
Summary
Rebuilds the legitimate diagnostics intent from the non-promotable fork on top
of current
kunchenguid/no-mistakesupstream.no-mistakes statusnow alwaysrenders 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, whosecontract is local/read-only: it does not fetch, contact remotes, mutate refs,
the index, the worktree, the database, or pipeline custody. The output says
cachedand does not claim remote freshness. It deliberately does not revivethe fork's unregistered pipeline experiment, tracked binary, or direct process
execution.
Verification
make lintgo test -race ./...go build -o ./bin/no-mistakes ./cmd/no-mistakesgit diff --checkThis is a draft for upstream review; hosted CI and maintainer approval remain
required before merge.