Skip to content

Commit 02c324b

Browse files
test: make atomic snapshot gate non-vacuous
agent-session-id: dev3.dotfiles-cos-misc-agent-runtime-simplification agent-tool: Codex agent-tool-version: 0.145.0 agent-model: gpt-5.6-sol agent-runtime-profile: /home/schickling/.config/coding-agents/profile.json agent-skills-manifest: /nix/store/nk9iml2841l1yjjg0f6f0d3y60zkg1nn-agent-skills-corpus/share/agent-skills/manifest.json tooling-profile: dotfiles@4a0515f
1 parent 0503b88 commit 02c324b

3 files changed

Lines changed: 57 additions & 34 deletions

File tree

flake.nix

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,13 @@
125125

126126
# Narrow sandbox-safe integration gate for the atomic snapshot boundary. The main package
127127
# deliberately omits the broad doctor suite because some doctor cases exercise facilities
128-
# unavailable in the Nix sandbox; this derivation executes the one hermetic regression by
129-
# its unique test name so it cannot be present-but-invisible to CI.
128+
# unavailable in the Nix sandbox. A dedicated target containing exactly one test makes the
129+
# gate structurally non-vacuous: a missing target is a cargo error, never a zero-match pass.
130130
st2AtomicPtySnapshot = st2.overrideAttrs (_: {
131131
pname = "st2-atomic-pty-snapshot-check";
132132
cargoTestFlags = [
133133
"--test"
134-
"doctor"
135-
"doctor_rejects_a_partial_pty_snapshot_atomically"
134+
"atomic_pty_snapshot"
136135
];
137136
});
138137

tests/atomic_pty_snapshot.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#![cfg(unix)]
2+
3+
//! Hermetic producer-consumer boundary: a truncated `pty list --json` response is never consumed
4+
//! as a valid prefix. This is a dedicated single-test target so CI cannot pass on a vacuous libtest
5+
//! name filter.
6+
7+
use std::fs;
8+
use std::os::unix::fs::PermissionsExt;
9+
use std::path::Path;
10+
use std::process::Command;
11+
12+
fn executable(path: &Path, body: &str) {
13+
fs::write(path, body).unwrap();
14+
fs::set_permissions(path, fs::Permissions::from_mode(0o755)).unwrap();
15+
}
16+
17+
#[test]
18+
fn doctor_rejects_a_partial_pty_snapshot_atomically() {
19+
let tmp = tempfile::tempdir().unwrap();
20+
let catalog = tmp.path().join("catalog");
21+
let declaration = catalog.join("agents/h/gone/agent.kdl");
22+
let bin = tmp.path().join("bin");
23+
fs::create_dir_all(declaration.parent().unwrap()).unwrap();
24+
fs::create_dir_all(&bin).unwrap();
25+
fs::write(
26+
declaration,
27+
"agent \"gone\" { host \"h\"; retired #true; command \"true\" }\n",
28+
)
29+
.unwrap();
30+
executable(
31+
&bin.join("pty"),
32+
"#!/bin/sh\nprintf '[{\"name\":\"h.gone.agent\",\"status\":\"running\"},'\n",
33+
);
34+
35+
let output = Command::new(env!("CARGO_BIN_EXE_st2"))
36+
.arg("doctor")
37+
.arg("--catalog")
38+
.arg(&catalog)
39+
.args(["--host", "h"])
40+
.env("PATH", &bin)
41+
.env("XDG_STATE_HOME", tmp.path().join("state"))
42+
.env("PTY_ROOT", tmp.path().join("pty"))
43+
.output()
44+
.unwrap();
45+
46+
assert!(!output.status.success());
47+
let stdout = String::from_utf8_lossy(&output.stdout);
48+
assert!(stdout.contains("✗ task runtime readable"), "{stdout}");
49+
assert!(stdout.contains("parsing `pty list --json`"), "{stdout}");
50+
assert!(
51+
!stdout.contains("retirement complete"),
52+
"a valid prefix must never be consumed as a partial snapshot:\n{stdout}"
53+
);
54+
}

tests/doctor.rs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -193,36 +193,6 @@ fn doctor_bounds_a_hung_pty_probe_and_reports_the_runtime_error() {
193193
assert!(stdout.contains("timed out after 2.0s"), "{stdout}");
194194
}
195195

196-
#[test]
197-
fn doctor_rejects_a_partial_pty_snapshot_atomically() {
198-
let tmp = tempfile::tempdir().unwrap();
199-
let catalog = tmp.path().join("catalog");
200-
let declaration = catalog.join("agents/h/gone/agent.kdl");
201-
let bin = tmp.path().join("bin");
202-
fs::create_dir_all(declaration.parent().unwrap()).unwrap();
203-
fs::create_dir_all(&bin).unwrap();
204-
fs::write(
205-
declaration,
206-
"agent \"gone\" { host \"h\"; retired #true; command \"true\" }\n",
207-
)
208-
.unwrap();
209-
executable(
210-
&bin.join("pty"),
211-
"#!/bin/sh\nprintf '[{\"name\":\"h.gone.agent\",\"status\":\"running\"},'\n",
212-
);
213-
214-
let output = doctor(&catalog, &bin, &tmp.path().join("state"));
215-
216-
assert!(!output.status.success());
217-
let stdout = String::from_utf8_lossy(&output.stdout);
218-
assert!(stdout.contains("✗ task runtime readable"), "{stdout}");
219-
assert!(stdout.contains("parsing `pty list --json`"), "{stdout}");
220-
assert!(
221-
!stdout.contains("retirement complete"),
222-
"a valid prefix must never be consumed as a partial snapshot:\n{stdout}"
223-
);
224-
}
225-
226196
#[test]
227197
fn retired_declaration_is_healthy_when_tasks_and_presence_are_absent() {
228198
let tmp = tempfile::tempdir().unwrap();

0 commit comments

Comments
 (0)