chore: rename packages/ to crates/
Move all 29 workspace members from packages/<name>/ to crates/<name>/. Updates: workspace Cargo.toml (members + path deps), justfile, root CLAUDE.md, scripts/build/CARGO_INSTALL.md, docs/architecture/crates.md (renamed from packages.md), structural references in docs/architecture and docs/configuration, per-crate CLAUDE.md self-references. Historical plans, reports, and building/ docs are left untouched. No behavior change; just check-all stays green and fermata tests pass.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
//! Smoke-test contract from `docs/workpad/brainstorm/fermata.md` Appendix A.4.
|
||||
|
||||
use dirigent_fermata::core::{Decision, Op, Policy};
|
||||
use std::fs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn fixture() -> TempDir {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let root = tmp.path();
|
||||
fs::write(root.join(".botignore"), ".env\n.env.*\nconf/cert/**\nconf/mitmproxy/**\n").unwrap();
|
||||
fs::write(
|
||||
root.join("botignore.toml"),
|
||||
r#"
|
||||
[read]
|
||||
patterns = [
|
||||
"conf/localtestsettings.yaml",
|
||||
"conf/localsettings.yaml",
|
||||
"conf/default-secrets.yaml",
|
||||
".claude/self-reflections/**",
|
||||
]
|
||||
|
||||
[write]
|
||||
patterns = [
|
||||
"conf/localtestsettings.yaml",
|
||||
"conf/localsettings.yaml",
|
||||
"conf/default-secrets.yaml",
|
||||
]
|
||||
|
||||
[bash]
|
||||
deny = ["localtestsettings.yaml", "localsettings.yaml", "default-secrets.yaml", ".env"]
|
||||
ask = ["rm *", "mv *"]
|
||||
allow_prefixes = ["make test"]
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
fs::create_dir_all(root.join("conf")).unwrap();
|
||||
fs::create_dir_all(root.join("datatap")).unwrap();
|
||||
fs::create_dir_all(root.join(".claude/self-reflections")).unwrap();
|
||||
for f in [".env", "conf/localsettings.yaml", "datatap/foo.py", ".claude/self-reflections/x.md"] {
|
||||
fs::write(root.join(f), "").unwrap();
|
||||
}
|
||||
tmp
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_dot_env_denied() {
|
||||
let t = fixture();
|
||||
let p = Policy::load(t.path()).unwrap();
|
||||
assert!(matches!(p.check(Op::Read, &t.path().join(".env")).unwrap(), Decision::Deny(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bash_cat_dot_env_denied() {
|
||||
let t = fixture();
|
||||
let p = Policy::load(t.path()).unwrap();
|
||||
assert!(matches!(p.check_command("cat ./.env").unwrap(), Decision::Deny(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bash_rm_localsettings_denied() {
|
||||
let t = fixture();
|
||||
let p = Policy::load(t.path()).unwrap();
|
||||
assert!(matches!(
|
||||
p.check_command("rm ./conf/localsettings.yaml").unwrap(),
|
||||
Decision::Deny(_)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_localsettings_denied() {
|
||||
let t = fixture();
|
||||
let p = Policy::load(t.path()).unwrap();
|
||||
assert!(matches!(
|
||||
p.check(Op::Write, &t.path().join("conf/localsettings.yaml")).unwrap(),
|
||||
Decision::Deny(_)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn edit_datatap_foo_py_allowed() {
|
||||
let t = fixture();
|
||||
let p = Policy::load(t.path()).unwrap();
|
||||
assert_eq!(
|
||||
p.check(Op::Write, &t.path().join("datatap/foo.py")).unwrap(),
|
||||
Decision::Allow
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bash_make_test_allowed() {
|
||||
let t = fixture();
|
||||
let p = Policy::load(t.path()).unwrap();
|
||||
assert_eq!(p.check_command("make test").unwrap(), Decision::Allow);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bash_rm_somefile_asks() {
|
||||
let t = fixture();
|
||||
let p = Policy::load(t.path()).unwrap();
|
||||
assert!(matches!(p.check_command("rm somefile").unwrap(), Decision::Ask(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_self_reflections_asks() {
|
||||
// Note: A.4 has self-reflections under "ask" — current toml schema uses `[read].patterns`
|
||||
// for hard reads. This documents the gap; once toml has a `[read].ask`, switch to Ask.
|
||||
let t = fixture();
|
||||
let p = Policy::load(t.path()).unwrap();
|
||||
let d = p.check(Op::Read, &t.path().join(".claude/self-reflections/x.md")).unwrap();
|
||||
assert!(matches!(d, Decision::Deny(_)));
|
||||
}
|
||||
Reference in New Issue
Block a user