c0re: address argus review nits on #434

This commit is contained in:
damocles 2026-05-25 23:36:18 +02:00 committed by Mara
commit 57a753d80a
2 changed files with 18 additions and 8 deletions

View file

@ -53,14 +53,15 @@ async fn read_lock_at_tag(repo: &Path, tag: &str) -> Result<Option<String>> {
.with_context(|| format!("git show {spec} in {}", repo.display()))?;
if !out.status.success() {
let stderr = String::from_utf8_lossy(&out.stderr);
// git uses different messages for "path not in tree" depending
// on version + whether the path collides with an on-disk file.
// Treat any of them as "no flake.lock in this commit" rather
// than a hard failure — an agent with empty `inputs = { }` is
// a legitimate, dedup-clean state.
// git uses two different messages for "path not in tree"
// depending on whether the path also collides with an on-disk
// file. Both translate to "no flake.lock in this commit" —
// a legitimate, dedup-clean state for an agent with empty
// `inputs = { }`. Any other git failure (permission denied,
// ref-not-found, etc.) propagates as a hard error rather than
// being silently swallowed.
if stderr.contains("does not exist")
|| stderr.contains("exists on disk, but not in")
|| stderr.contains("Path '")
{
return Ok(None);
}
@ -242,6 +243,12 @@ async fn lock_in_sync_inner(worktree: &Path) -> Result<()> {
.await
.ok();
// An agent that declares inputs in flake.nix but ships no
// flake.lock at all hits this branch (committed = None,
// regenerated = Some(...)). That's a deliberate reject: every
// agent with inputs MUST commit its lock, otherwise meta's
// dedup pass has nothing to introspect and the broken state
// leaks downstream. Treated identically to a stale lock.
if committed.as_deref() != regenerated.as_deref() {
anyhow::bail!(
"flake.lock is out of sync with flake.nix — `nix flake lock` produces a different lock. \

View file

@ -635,8 +635,11 @@ async fn submit_apply_commit(
.map_err(|e| anyhow::anyhow!("persist fetched_sha: {e:#}"))?;
// #317 pre-flight gates: both reject the apply before approval if
// the agent's flake state would inflate meta's lock with duplicates
// or lie about what nix will fetch. Order matters — sync first so
// the dedup pass acts on the lock nix would actually produce.
// or lie about what nix will fetch. Both checks independently read
// `<tag>:flake.lock` via git — they don't share state. Order matters
// only for early-exit + messaging: sync first means a stale lock
// bails with the actionable "run `nix flake lock`" hint rather than
// a dedup pass on a lock nix would never produce.
//
// Runs after `set_fetched_sha` so the failed row carries the sha
// that broke. Both failure paths mark + emit, then bail.