From bb58442087b4c0a254ce566208902db208cd4ef9 Mon Sep 17 00:00:00 2001 From: claude Date: Sun, 12 Jul 2026 18:54:11 +0200 Subject: [PATCH] =?UTF-8?q?test(cli):=20RED=20=E2=80=94=20a=20fresh=20scaf?= =?UTF-8?q?fold=20leaves=20no=20resolvable=20HEAD=20(#243)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit aura new git-inits but never commits, so the first run stamps empty project provenance. RED pin: new_outside_a_work_tree_leaves_a_resolvable_head. refs #243 --- crates/aura-cli/tests/project_new.rs | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/crates/aura-cli/tests/project_new.rs b/crates/aura-cli/tests/project_new.rs index 521632d..f289d8b 100644 --- a/crates/aura-cli/tests/project_new.rs +++ b/crates/aura-cli/tests/project_new.rs @@ -220,6 +220,57 @@ fn new_outside_a_work_tree_initializes_git() { let _ = std::fs::remove_dir_all(&base); } +/// Property (#243): a freshly scaffolded project stamps resolvable +/// provenance from its very first run. Outside any enclosing work tree +/// `aura new` owns the scaffold's history, so it must leave the project with +/// a HEAD — `git rev-parse HEAD` resolves — and the first advertised +/// quickstart `aura run` therefore stamps a `manifest.project.commit`, rather +/// than the empty `"project":{}` that a bare `git init` with no commit yields +/// (a first manifest that is silently un-reproducible-by-commit). This is the +/// property the neighbouring loop headline can only reach today via a manual +/// `init_and_commit` on the enclosing tree. +#[test] +fn new_outside_a_work_tree_leaves_a_resolvable_head() { + let base = tmp("headprov"); + let out = aura(&["new", "demo-lab"], &base); + assert!( + out.status.success(), + "aura new failed: {}", + String::from_utf8_lossy(&out.stderr) + ); + let proj = base.join("demo-lab"); + + // The scaffold has its own repo (guarded elsewhere) AND that repo has a + // HEAD: `git rev-parse HEAD` resolves. A bare `git init` with no commit + // leaves HEAD unborn and this fails. + let head = Command::new("git") + .args(["rev-parse", "HEAD"]) + .current_dir(&proj) + .output() + .expect("run git rev-parse HEAD"); + assert!( + head.status.success(), + "fresh scaffold has no HEAD (`git rev-parse HEAD` failed): {}", + String::from_utf8_lossy(&head.stderr) + ); + + // ...so the first quickstart run stamps a commit into the manifest, not + // an empty provenance block. + let run = aura(&["run", "blueprints/signal.json"], &proj); + assert!( + run.status.success(), + "run failed: {}", + String::from_utf8_lossy(&run.stderr) + ); + let v: serde_json::Value = serde_json::from_slice(&run.stdout).expect("report is JSON"); + let p = &v["manifest"]["project"]; + assert!( + p.get("commit").is_some(), + "first run of a fresh scaffold must stamp a commit, not empty provenance: {p}" + ); + let _ = std::fs::remove_dir_all(&base); +} + #[test] fn new_works_inside_an_unbuilt_project_tree() { // Scaffold once, then scaffold AGAIN from inside that tree: the