Repository navigation
v1.14.1
Patch Changes
-
7342e5d: Fix the review→PR preflight so its documented flow can satisfy itself, and scope review freshness to the reviewed content.
- PR preflight binds reviews to content, not session identity. A passing secondary review now satisfies
gh pr create/az repos pr createwhen its binding (same repository, same commit hash, same tracked-content worktree fingerprint) matches the tree the PR publishes, regardless of which session records the verdict or creates the PR. The gate previously also required the review's target session to equal the PR-creating session's ID; sincerecord_reviewrecords from a secondary session and sessions can move between directories (session_move) or spawn subagents from other roots, a review recorded from a subagent rooted in a linked worktree could never satisfy a PR created there. The review-before-PR requirement itself is unchanged, and the failing preflight now names the actual cause (changes requested / unreadable worktree / tracked content changed after review / commit hash drifted while tracked content stayed identical). - Review freshness is scoped to the reviewed diff. Recorded approvals are bound to tracked repository content (index + worktree-vs-index fingerprint + commit hash) instead of the full worktree fingerprint that also hashed untracked file contents. Creating, editing, or deleting an untracked scratch file no longer invalidates an approval, and mutations (including in sibling worktrees) no longer erase the whole review record; any tracked edit or new commit still does. Untracked scratch cleanup therefore keeps
guard_statusfresh and the PR preflight passing. record_reviewaccepts recorders of any session type and reports its binding. Reviewer agents are commonly configured with a read-only toolset (glob/grep/question/read/webfetch/websearch) that excludesrecord_review, while the tool previously rejected root/orchestrator sessions - leaving no session type able to both produce the verdict and record it. The tool now accepts any recorder session, binds the verdict to the recording session's resolved directory, echoes that binding (directory, commit, fingerprint) in its result, and audits the binding key plus recorder lineage (recorderRole: root | subagent) on everyrecord_review.verdictentry. Relaying a verdict through a root session is allowed but flagged in the result; independent secondary reviewer subagents remain the recommended flow. A verdict whose directory has no computable tracked fingerprint (not a git repository) is rejected loudly with the exact reason instead of silently not binding. If your reviewer agent's toolset can include plugin tools, prefer addingrecord_review(andguard_review_rubric) to it so the reviewer records directly.pr createpreflight acceptance is audited. When a PR preflight accepts a review, an auditablepr-preflight.review-bindingentry records the evidence ID and binding key so mismatches are diagnosable fromguard_audit.guard_worktree_createreports git exit status and rolls back partial failures.git worktree addcreates the branch ref before the checkout, so failures after that point (path collisions, killed checkouts on large repositories) previously surfaced only stderr progress text and left the created branch behind. Failures now include the exit status (null/timeout/signal when killed), the branch created by the failed call is deleted (branches that already existed are preserved), a pre-existing target path is left intact (including a live registered worktree whose sanitized name collides, which must never be force-removed as rollback), and stale worktree admin entries are pruned only for the new-path case so a retry starts clean. Large checkouts can raise the timeout withWORKFLOW_GUARD_WORKTREE_TIMEOUT_MS(default 15s).
- PR preflight binds reviews to content, not session identity. A passing secondary review now satisfies
-
776913f:
guard_review_rubricnow embeds the real branch diff. The tool passed--before the revision (git diff -- <base>...HEADandgit diff -- HEAD~1), so git parsed the revision as a pathspec and every rubric prompt carried an empty "Code Diff Under Review" block — reviewers were handed the 5-axis rubric with no diff to evaluate. Fix the argument order (revision before--) and add--no-ext-diff, matching the verification fingerprint convention. A regression test pins that a real change's content and path appear in the rubric. -
ea3cab7: Interactive monitor detection now only flags a monitor in command position, so a monitor name used as an argument no longer blocks a benign command. The detector matched
top/htop/btop/atop/glancesanywhere as a whitespace-delimited token, soaz keyvault secret show --vault-name x --name top(observed live in the device audit) andecho topwere rejected as an "interactive process monitor".It now unwraps shell wrappers (
sudo,env,timeout,command, …), splits quote-aware, and checks each segment's executable:top,htop,… | top,sudo top,timeout 5 top,busybox top,eval top, andsh -c topare still blocked, whileaz … --name top,echo top,ls top-level-dir,top -b, andsh -c '… top …'quoting stay allowed.top's batch-mode exemption is scoped to its own arguments sosudo -b topis not mistaken for batch mode. Indirection this does not model (watch/xargs/man,find -exec/su -c, and shell loop bodies such aswhile true; do top; done) is a known limitation, documented in the policy doc alongside the existing "pager names in arguments are not execution" rule. -
75d233c: A successful
edit/writenow records the session's stale-write observation of the bytes it just authored, so iterating on a file the session created or modified no longer demands a redundant re-read. Previously onlyreadseeded the observation, so a follow-upeditto a just-written file was blocked with "has not been read by this session" (the most common guard block in local audit logs, including agent-authored temp scripts).- The observation is seeded only when the file content actually changed (the pre/post digest differs), so a no-op or failed mutation seeds nothing; an external change after the mutation still fails the next comparison and blocks the edit. V2 additionally skips errored calls outright.
- Observations remain per-session and are cleared on session idle/deletion.
apply_patchresults also seed the session observation, while its clobbering pre-check remains outside this bounded mechanism as documented.
-
009bf78:
guard_worktree_cleanup/cleanupGitWorktreeis now idempotent for a registered worktree whose directory is missing — the prunable admin entry thatgit worktree listshows after a manual removal, a crashed add, or external cleanup. It deregisters the stale entry instead of failing with "does not exist". Paths outside the configured storage directory, and paths that are not registered worktrees of the repository, are still refused; a failed prune is reported with its git exit status.The deregistration runs a repo-wide
git worktree prunefor the current repository: every worktree whose directory is missing at that moment is deregistered, so a temporarily unavailable path's admin entry can be dropped. Worktree contents are never touched, andgit worktree repairrestores admin entries if a path returns.