{"record":{"id":"107786d1946e4088","repo":"Hmbown/CodeWhale","slug":"sentinel","errorCode":null,"errorMessage":"sentinel","messagePattern":"sentinel","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/tests.rs","lineNumber":8588,"sourceCode":"    );\n    for command in [\"pwd\", \"git status --short\", \"rg needle crates\"] {\n        assert!(\n            registry\n                .envelope_refusal(\"bash\", &json!({\"command\": command}))\n                .is_none(),\n            \"planner should admit {command}\"\n        );\n    }\n    for command in [\"rm -rf crates\", \"git push origin main\", \"bash -lc 'id'\"] {\n        assert!(\n            registry\n                .envelope_refusal(\"bash\", &json!({\"command\": command}))\n                .is_some(),\n            \"planner must refuse {command}\"\n        );\n    }\n    let sentinel = \"PLANNER_PROBE_SENTINEL\";\n    std::fs::write(tmp.path().join(\"sentinel.txt\"), sentinel).expect(\"sentinel\");\n    let output = registry\n        .execute(\n            \"agent_planner\",\n            \"bash\",\n            json!({\"command\": \"cat sentinel.txt\"}),\n        )\n        .await\n        .expect(\"planner must dispatch a bounded read\");\n    assert_eq!(output, sentinel);\n}\n\n#[tokio::test]\nasync fn scout_shell_respects_parent_shell_and_network_ceilings() {\n    let tmp = tempdir().expect(\"tempdir\");\n    let mut shell_off =\n        stub_runtime().with_agent_tool_surface_options(enabled_agent_surface_options());\n    shell_off.context = ToolContext::new(tmp.path().to_path_buf());\n    shell_off.allow_shell = false;","sourceCodeStart":8570,"sourceCodeEnd":8606,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/tools/subagent/tests.rs#L8570-L8606","documentation":"A panic from `.expect(\"sentinel\")` on `std::fs::write(tmp.path().join(\"sentinel.txt\"), sentinel)` in crates/tui/src/tools/subagent/tests.rs:8588. The planner test writes a sentinel file to prove that `agent_planner` may dispatch a bounded read (`cat sentinel.txt`); failure of the fixture write panics the test before dispatch. The expect message is the test's claim that writing the sentinel is trivially safe setup.","triggerScenarios":"Writing the sentinel into the temp workspace when the TempDir has already been dropped, the path exists as a directory, the filesystem is full or read-only, or permission bits on the temp dir deny the write.","commonSituations":"TMPDIR on a full tmpfs in CI, tests refactored so `tmp` is consumed/moved before the write, or sandbox policies restricting writes outside whitelisted paths.","solutions":["Ensure the TempDir guard outlives the write — keep `tmp` alive for the whole test body.","Confirm TMPDIR is writable and has free space; set TMPDIR explicitly if the default is constrained.","Check no earlier code replaced sentinel.txt with a directory or removed the temp dir.","Wrap the write with context (unwrap_or_else) so future failures name the path and io error."],"exampleFix":"// before\nstd::fs::write(tmp.path().join(\"sentinel.txt\"), sentinel).expect(\"sentinel\");\n// after\nlet p = tmp.path().join(\"sentinel.txt\");\nstd::fs::write(&p, sentinel).unwrap_or_else(|e| panic!(\"sentinel write failed at {}: {e}\", p.display()));","handlingStrategy":"try-catch","validationCode":"let p = tmp.path().join(\"sentinel.txt\");\nassert!(!p.exists() || p.is_file(), \"sentinel path must not be a directory\");\nassert!(tmp.path().is_dir(), \"tempdir must exist before sentinel write\");","typeGuard":"fn can_write(dir: &std::path::Path) -> bool {\n    let probe = dir.join(\".probe\");\n    std::fs::write(&probe, b\"\").is_ok().then(|| std::fs::remove_file(&probe).ok()).is_some()\n}","tryCatchPattern":"std::fs::write(&p, sentinel)\n    .unwrap_or_else(|e| panic!(\"sentinel fixture failed at {}: {e}\", p.display()));","preventionTips":["Order fixture writes immediately after tempdir creation, before any code that could drop `tmp`.","Include the failing path and io error in the panic message.","Ensure CI temp mounts are writable and sized for parallel test load.","Prove reads with sentinels only after confirming the write succeeded (assert on metadata)."],"tags":["rust","test-fixture","file-write","planner"],"backgroundTag":"file-write-failed","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}