Skip to content

fix: make agentic-git publishable + close 3 run bugs + smoke tests#9

Merged
suzuke merged 3 commits into
mainfrom
fix/publishable-and-run-bugs
Jul 4, 2026
Merged

fix: make agentic-git publishable + close 3 run bugs + smoke tests#9
suzuke merged 3 commits into
mainfrom
fix/publishable-and-run-bugs

Conversation

@suzuke

@suzuke suzuke commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Adversarial code review (fugu) of main found 3 real defects; all fixed with regression coverage + a CI publish gate + end-to-end smoke tests.

  1. agentic-git crate wasn't publishable (the real cause the shim never published): include_str!("../../../assets/hooks/…") reached workspace-root assets that cargo package excludes from the tarball → verify build failed. Moved assets/hooks/ into the crate; cargo package -p agentic-git now verifies clean.
  2. run could launch UNGUARDED: child PATH join_paths(...).unwrap_or(path_env) silently fell back to the real PATH if AGENTIC_GIT_HOME had a : → shim bypassed. Now a hard EX_CONFIG refusal.
  3. .agend-managed defeated skip-when-clean: the marker made every fresh session's tree look dirty. is_clean now treats a marker-only tree as clean.

Plus: smoke tests (real agentic-git run flow: routing→trailer→snapshot→recover→deny + #2/#3), CI cargo package gate (both crates), release.yml set +e fix (bash -e no longer aborts idempotent publish).

150 tests green, clippy clean, both crates package+verify. Adversarial re-review: fugu.

🤖 Generated with Claude Code

suzuke and others added 3 commits July 5, 2026 01:42
Adversarial code review (fugu) of main found 3 real defects; all fixed with
regression coverage, plus a CI publish gate and end-to-end smoke tests.

1. **agentic-git crate was not publishable** (the real cause of the failed
   release run). `cli.rs`/`shim_phase1.rs` did `include_str!("../../../assets/
   hooks/…")` — workspace-ROOT assets that `cargo package` does not put in the
   crate tarball, so the verify build failed. Move `assets/hooks/` INTO the
   crate (`crates/agentic-git/assets/`), fix the 6 include paths. `cargo
   package -p agentic-git` now verifies clean.
2. **`run` could launch UNGUARDED.** `spawn_agent`'s child PATH used
   `join_paths(...).unwrap_or(path_env)`; a home path containing ':' made
   join fail → silent fallback to the real PATH → the agent's git bypassed the
   shim entirely. Now a hard EX_CONFIG refusal.
3. **`.agend-managed` defeated skip-when-clean.** The provisioned marker is an
   untracked file, so every fresh session's tree looked dirty and clean-tree
   destructive ops still snapshotted. `is_clean` now treats a tree whose only
   untracked entry is the marker as clean.

Also: **smoke tests** (`tests/smoke.rs`) drive the shipped binary through the
real `agentic-git run` flow (routing→trailer→snapshot→recover→deny) + pin #2/#3;
**CI `cargo package` gate** (both crates, verify build) so #1 can't regress;
**release.yml `set +e`** so `bash -e` no longer aborts the idempotent publish
on an already-uploaded crate.

cargo test --workspace: 150 green (+3 smoke); clippy clean; both crates package.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…#4)

fugu verified the 3 packaging/run fixes, then found a real usability
blocker: the recovery layer's OWN documented restore —
`git checkout <snapshot-ref> -- .` — was DENIED by the shim. The
cross-branch guard reads args[1] as a branch target, so a snapshot ref
tripped 'cross-branch — cannot switch to refs/agentic-git/snapshots/...',
leaving snapshots un-restorable unless the user knew to set
AGENTIC_GIT_BYPASS=1. The recovery feature was effectively broken for a
docs-following user.

Fix: a `checkout <tree-ish> -- <pathspec>` is a working-tree path restore,
not a branch switch (the bound branch is unchanged), so the cross-branch
guard must not deny it. Recognize the `--` pathspec form and skip the
cross-branch check for checkout.

+smoke test run_session_documented_restore_works_without_bypass_smoke: full
real-session round-trip (dirty+untracked → reset --hard snapshot → delete
untracked → `git checkout <snap> -- .` through the shim, NO bypass → both
recovered).

Also harden legacy_env_adoption's bypass assertion: check the deny SIGNATURE
('cross-branch'), not the loose word 'denied' (the #2158 bypass audit dumps
process ancestry to stderr, which a parent command's text could false-trip).

cargo test --workspace: green; clippy clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The new smoke tests + Linux CI caught a real cross-platform bug invisible on
macOS: on a runner/container/fresh machine with NO git user.name/user.email
(ubuntu-latest has none; macOS derives a default), the snapshot's
`git commit-tree` — which REQUIRES an author+committer — silently failed,
so a real session's destructive op created NO snapshot (SNAPS=0, fail-open),
i.e. the recovery layer didn't work exactly where it's supposed to. And the
agent's own `git commit` failed (TRAILER=no).

Fix: the snapshot forces a fixed GIT_AUTHOR/COMMITTER_NAME+EMAIL
('agentic-git <agentic-git@localhost>') alongside the dates it already
forces, making snapshots environment-independent. The smoke session also
sets an identity so the agent's own commits succeed on bare runners.

Verified by reproducing the failure on macOS with GIT_CONFIG_GLOBAL=/dev/null
+ empty HOME: smoke now passes (previously SNAP=NONE, as on ubuntu CI).

cargo test --workspace: green; smoke green under a no-git-identity env.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@suzuke suzuke merged commit 326b4eb into main Jul 4, 2026
3 of 4 checks passed
@suzuke suzuke deleted the fix/publishable-and-run-bugs branch July 4, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant