mod common;
use predicates::prelude::*;
use std::path::Path;
use tempfile::tempdir;
fn write_project_block(project: &Path, rel: &str, source: &str) -> std::path::PathBuf {
let path = project.join("blocks").join(rel);
std::fs::create_dir_all(path.parent().expect("block path has a parent")).expect("mkdir");
std::fs::write(&path, source).expect("write block");
path
}
const AGENT_OVERRIDE: &str = r#"
local base = require("embedded.agent")
local M = setmetatable({}, { __index = base })
function M.run(opts)
print("OVERRIDE")
print("BASE_RUN_TYPE=" .. type(base.run))
return { from = "override", prompt = opts.prompt }
end
return M
"#;
#[test]
fn a_project_kernel_fails_the_run_before_the_script() {
let home = tempdir().expect("tempdir");
let project = tempdir().expect("tempdir");
let shadow = write_project_block(project.path(), "knl/init.lua", "return {}\n");
common::agent_block_cmd()
.env("AGENT_BLOCK_HOME", home.path())
.args(["-p", &project.path().to_string_lossy()])
.args(["-s", &common::fixture("hello.lua")])
.assert()
.failure()
.stderr(predicate::str::contains("knl"))
.stderr(predicate::str::contains(shadow.display().to_string()))
.stdout(predicate::str::contains("hello from agent-block").not());
}
#[test]
fn the_refusal_says_why_and_names_the_escape_hatch() {
let home = tempdir().expect("tempdir");
let project = tempdir().expect("tempdir");
write_project_block(project.path(), "knl/init.lua", "return {}\n");
common::agent_block_cmd()
.env("AGENT_BLOCK_HOME", home.path())
.args(["-p", &project.path().to_string_lossy()])
.args(["-s", &common::fixture("hello.lua")])
.assert()
.failure()
.stderr(predicate::str::contains("sealed module"))
.stderr(predicate::str::contains("Change it upstream"))
.stderr(predicate::str::contains("AGENT_BLOCK_UNSEAL=1"));
}
#[test]
fn unseal_downgrades_the_refusal_to_a_warning() {
let home = tempdir().expect("tempdir");
let project = tempdir().expect("tempdir");
write_project_block(project.path(), "knl/init.lua", "return {}\n");
common::agent_block_cmd()
.env("AGENT_BLOCK_HOME", home.path())
.env("AGENT_BLOCK_UNSEAL", "1")
.args(["-p", &project.path().to_string_lossy()])
.args(["-s", &common::fixture("hello.lua")])
.assert()
.success()
.stdout(predicate::str::contains("AGENT_BLOCK_UNSEAL=1"))
.stdout(predicate::str::contains("hello from agent-block"));
}
#[test]
fn a_project_lshape_sub_module_is_sealed_too() {
let home = tempdir().expect("tempdir");
let project = tempdir().expect("tempdir");
write_project_block(project.path(), "lshape/t.lua", "return {}\n");
common::agent_block_cmd()
.env("AGENT_BLOCK_HOME", home.path())
.args(["-p", &project.path().to_string_lossy()])
.args(["-s", &common::fixture("hello.lua")])
.assert()
.failure()
.stderr(predicate::str::contains("lshape.t"));
}
#[test]
fn a_project_agent_can_delegate_to_the_embedded_one() {
let home = tempdir().expect("tempdir");
let project = tempdir().expect("tempdir");
write_project_block(project.path(), "agent/init.lua", AGENT_OVERRIDE);
common::agent_block_cmd()
.env("AGENT_BLOCK_HOME", home.path())
.args(["-p", &project.path().to_string_lossy()])
.args(["-s", &common::fixture("embedded_agent_override.lua")])
.assert()
.success()
.stdout(predicate::str::contains("OVERRIDE"))
.stdout(predicate::str::contains("RESULT_FROM=override"))
.stdout(predicate::str::contains("RESULT_PROMPT=not sent anywhere"))
.stdout(predicate::str::contains("BASE_RUN_TYPE=function"));
}
#[test]
fn the_embedded_alias_resolves_a_sealed_module() {
let home = tempdir().expect("tempdir");
let project = tempdir().expect("tempdir");
common::agent_block_cmd()
.env("AGENT_BLOCK_HOME", home.path())
.args(["-p", &project.path().to_string_lossy()])
.args(["-s", &common::fixture("embedded_alias_knl.lua")])
.assert()
.success()
.stdout(predicate::str::contains("EMBEDDED_KNL_TYPE=table"))
.stdout(predicate::str::contains("HAS_BEAT=function"));
}
#[test]
fn a_filesystem_embedded_directory_does_not_shadow_the_alias() {
let home = tempdir().expect("tempdir");
let project = tempdir().expect("tempdir");
write_project_block(
project.path(),
"embedded/knl.lua",
"return { sentinel = true, beat = 1 }\n",
);
common::agent_block_cmd()
.env("AGENT_BLOCK_HOME", home.path())
.args(["-p", &project.path().to_string_lossy()])
.args(["-s", &common::fixture("embedded_alias_knl.lua")])
.assert()
.success()
.stdout(predicate::str::contains("SENTINEL=nil"))
.stdout(predicate::str::contains("HAS_BEAT=function"));
}