fix(work): import hashlib and wire heal subparser into main CLI

This commit is contained in:
operator
2026-10-09 23:13:43 +00:00
parent c3b4b1cd28
commit f75977ca6e
202 changed files with 4185 additions and 4142 deletions
+82 -25
View File
@@ -25,6 +25,58 @@ import approvals
import gravity
def _load(name, relpath):
import importlib.util
spec = importlib.util.spec_from_file_location(name, REPO_ROOT / relpath)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
box_ctl = _load("box_ctl_approvaltest", "bin/box-ctl.py")
super_cli = _load("super_cli_approvaltest", "bin/super-cli.py")
class _InProcResult:
"""Minimal CompletedProcess stand-in (returncode/stdout only)."""
def __init__(self, returncode, stdout):
self.returncode = returncode
self.stdout = stdout
def _box_ctl_inproc(*args):
"""In-process box-ctl call (proven pattern from test_box_loop_https).
Real main(argv): identical parsing, dispatch, audit, stdout JSON.
"""
import io
from contextlib import redirect_stdout
buf = io.StringIO()
returncode = 0
with redirect_stdout(buf):
try:
box_ctl.main(["box-ctl.py", *args])
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
return _InProcResult(returncode, buf.getvalue())
def _super_cli_inproc(*args):
"""In-process super-cli call (main() reads sys.argv; patch it)."""
import io
from contextlib import redirect_stdout
buf = io.StringIO()
returncode = 0
with mock.patch.object(sys, "argv", ["super-cli.py", *args]):
with redirect_stdout(buf):
try:
super_cli.main()
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
return _InProcResult(returncode, buf.getvalue())
class TestApprovalsModule(unittest.TestCase):
"""Test approvals.py core module functionality."""
@@ -79,8 +131,7 @@ class TestBoxApprovalsCli(unittest.TestCase):
"""Test 'box approvals' and 'box approval' CLI commands."""
def test_box_approvals_check_json(self):
cmd = [sys.executable, str(BIN_DIR / "super-cli.py"), "approvals", "check", "--json"]
r = subprocess.run(cmd, capture_output=True, text=True)
r = _super_cli_inproc("approvals", "check", "--json")
self.assertEqual(r.returncode, 0)
data = json.loads(r.stdout)
self.assertTrue(data.get("ok"))
@@ -88,15 +139,13 @@ class TestBoxApprovalsCli(unittest.TestCase):
self.assertIsInstance(data["approvals"], list)
def test_box_approval_alias(self):
cmd = [sys.executable, str(BIN_DIR / "super-cli.py"), "approval", "--json"]
r = subprocess.run(cmd, capture_output=True, text=True)
r = _super_cli_inproc("approval", "--json")
self.assertEqual(r.returncode, 0)
data = json.loads(r.stdout)
self.assertTrue(data.get("ok"))
def test_box_approvals_auto_json(self):
cmd = [sys.executable, str(BIN_DIR / "super-cli.py"), "approvals", "auto", "--node", "pip", "--json"]
r = subprocess.run(cmd, capture_output=True, text=True)
r = _super_cli_inproc("approvals", "auto", "--node", "pip", "--json")
self.assertEqual(r.returncode, 0)
data = json.loads(r.stdout)
self.assertTrue(data.get("ok"))
@@ -106,16 +155,14 @@ class TestBoxCtlApprovals(unittest.TestCase):
"""Test box-ctl.py allowlisted RPC actions."""
def test_box_ctl_approval_check(self):
cmd = [sys.executable, str(BIN_DIR / "box-ctl.py"), "approval-check"]
r = subprocess.run(cmd, capture_output=True, text=True)
r = _box_ctl_inproc("approval-check")
self.assertEqual(r.returncode, 0)
data = json.loads(r.stdout)
self.assertTrue(data.get("ok"))
self.assertIn("approvals", data)
def test_box_ctl_approval_auto(self):
cmd = [sys.executable, str(BIN_DIR / "box-ctl.py"), "approval-auto", "pip"]
r = subprocess.run(cmd, capture_output=True, text=True)
r = _box_ctl_inproc("approval-auto", "pip")
self.assertEqual(r.returncode, 0)
data = json.loads(r.stdout)
self.assertTrue(data.get("ok"))
@@ -162,6 +209,22 @@ class TestApprovalsReplySafety(unittest.TestCase):
class TestKeyApprovalsAndPasskey(unittest.TestCase):
"""Test key approval workflow and passkey retrieval architecture."""
def test_key_scan_tail_fallback_finds_old_request(self):
# A live request older than the tail cap must still resolve via the
# full-scan fallback (synthetic log; never touches real audit state).
with tempfile.TemporaryDirectory() as td:
p = Path(td) / "box-ctl.jsonl"
old = {"ts": "2026-01-01T00:00:00Z", "action": "key-approval-request",
"type": "key", "name": "dev", "reason": "buried-old-request",
"caller": "t", "expires_at": "2030-01-01T00:00:00Z"}
filler = {"ts": "2026-06-01T00:00:00Z", "action": "noop", "name": "x"}
lines = [json.dumps(old)] + [json.dumps(filler)] * (approvals.KEY_SCAN_TAIL_LINES + 10)
p.write_text("\n".join(lines) + "\n")
with mock.patch.object(approvals, "CTL_LOG", p):
res = approvals.check_node_key_request("dev")
self.assertIsNotNone(res)
self.assertEqual(res.get("reason"), "buried-old-request")
def test_request_and_resolve_key_approval(self):
req = approvals.request_key_approval("dev", reason="UnitTest passkey verification", caller="unit-test")
self.assertTrue(req.get("ok"))
@@ -188,8 +251,7 @@ class TestKeyApprovalsAndPasskey(unittest.TestCase):
self.assertIsNone(cleared)
def test_box_passkey_info_json(self):
cmd = [sys.executable, str(BIN_DIR / "super-cli.py"), "passkey", "--json"]
r = subprocess.run(cmd, capture_output=True, text=True)
r = _super_cli_inproc("passkey", "--json")
self.assertEqual(r.returncode, 0)
data = json.loads(r.stdout)
self.assertTrue(data.get("ok"))
@@ -199,8 +261,7 @@ class TestKeyApprovalsAndPasskey(unittest.TestCase):
self.assertEqual(data["key_location"]["canonical_path"], "/srv/box/passkey.txt")
def test_box_passkey_fetch_json(self):
cmd = [sys.executable, str(BIN_DIR / "super-cli.py"), "passkey", "fetch", "--json"]
r = subprocess.run(cmd, capture_output=True, text=True)
r = _super_cli_inproc("passkey", "fetch", "--json")
self.assertEqual(r.returncode, 0)
data = json.loads(r.stdout)
self.assertIn("operator_pin", data)
@@ -210,8 +271,7 @@ class TestKeyApprovalsAndPasskey(unittest.TestCase):
self.assertIn("operator_command", data)
def test_box_lookup_key(self):
cmd = [sys.executable, str(BIN_DIR / "super-cli.py"), "lookup", "key", "--json"]
r = subprocess.run(cmd, capture_output=True, text=True)
r = _super_cli_inproc("lookup", "key", "--json")
self.assertEqual(r.returncode, 0)
data = json.loads(r.stdout)
self.assertTrue(data.get("ok"))
@@ -219,29 +279,26 @@ class TestKeyApprovalsAndPasskey(unittest.TestCase):
def test_cli_request_key_lifecycle(self):
# 1. Request key
r_req = subprocess.run([
sys.executable, str(BIN_DIR / "super-cli.py"),
r_req = _super_cli_inproc(
"approvals", "request-key", "dev", "--reason", "CLI lifecycle test", "--json"
], capture_output=True, text=True)
)
self.assertEqual(r_req.returncode, 0)
req_data = json.loads(r_req.stdout)
self.assertTrue(req_data.get("ok"))
# 2. Check shows KEY_APPROVAL
r_check = subprocess.run([
sys.executable, str(BIN_DIR / "super-cli.py"),
r_check = _super_cli_inproc(
"approvals", "check", "--node", "dev", "--json"
], capture_output=True, text=True)
)
self.assertEqual(r_check.returncode, 0)
check_data = json.loads(r_check.stdout)
dev_app = next(a for a in check_data["approvals"] if a["node"] == "dev")
self.assertEqual(dev_app["status"], "KEY_APPROVAL")
# 3. Deny key
r_deny = subprocess.run([
sys.executable, str(BIN_DIR / "super-cli.py"),
r_deny = _super_cli_inproc(
"approvals", "deny", "dev", "--json"
], capture_output=True, text=True)
)
self.assertEqual(r_deny.returncode, 0)
deny_data = json.loads(r_deny.stdout)
self.assertTrue(deny_data.get("ok"))
+32 -3
View File
@@ -31,6 +31,7 @@ def _load(name, relpath):
exec_constrained = _load("exec_constrained_approvals",
"bin/exec-constrained.py")
box_ctl = _load("box_ctl_approvalstest", "bin/box-ctl.py")
def _box_ctl(*args):
@@ -39,6 +40,34 @@ def _box_ctl(*args):
capture_output=True, text=True, timeout=180)
class _InProcResult:
"""Minimal CompletedProcess stand-in (returncode/stdout only)."""
def __init__(self, returncode, stdout):
self.returncode = returncode
self.stdout = stdout
def _box_ctl_inproc(*args):
"""In-process _box_ctl (same proven pattern as test_box_loop_https).
Calls the real main(argv) -- identical argv parsing, dispatch, audit,
and stdout JSON -- amortizing per-spawn interpreter cost over one
import. Node order in fleet scans is nondeterministic either way
(concurrent fan-out); per-node content is identical.
"""
import io
from contextlib import redirect_stdout
buf = io.StringIO()
returncode = 0
with redirect_stdout(buf):
try:
box_ctl.main(["box-ctl.py", *args])
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
return _InProcResult(returncode, buf.getvalue())
class ExecApprovalOpsTests(unittest.TestCase):
def test_ops_registered_and_side_effecting(self):
spec = exec_constrained.OPS
@@ -155,14 +184,14 @@ class BoxCtlApprovalTests(unittest.TestCase):
["approval-allow", "badnode", "--message", "m"],
["approval-deny", "badnode", "--message", "m"],
["approval-auto", "badnode"]):
r = _box_ctl(*args)
r = _box_ctl_inproc(*args)
self.assertNotEqual(r.returncode, 0, args)
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NODE",
args)
def test_rejects_missing_node(self):
for args in (["approval-allow"], ["approval-deny"]):
r = _box_ctl(*args)
r = _box_ctl_inproc(*args)
self.assertNotEqual(r.returncode, 0, args)
self.assertEqual(json.loads(r.stdout)["code"], "BAD_ARGS",
args)
@@ -194,7 +223,7 @@ class BoxCtlApprovalTests(unittest.TestCase):
(["approval-auto", "a", "b"], False),
]
for args, valid in cases:
r = _box_ctl("quality-validate", *args)
r = _box_ctl_inproc("quality-validate", *args)
self.assertEqual(json.loads(r.stdout)["valid"], valid, args)
+45 -9
View File
@@ -30,6 +30,7 @@ def _load(name, relpath):
exec_constrained = _load("exec_constrained_dev", "bin/exec-constrained.py")
box_ctl = _load("box_ctl_devtest", "bin/box-ctl.py")
def _box_ctl(*args):
@@ -38,6 +39,35 @@ def _box_ctl(*args):
capture_output=True, text=True, timeout=120)
class _InProcResult:
"""Minimal CompletedProcess stand-in (returncode/stdout/stderr)."""
def __init__(self, returncode, stdout, stderr=""):
self.returncode = returncode
self.stdout = stdout
self.stderr = stderr
def _box_ctl_inproc(*args):
"""In-process _box_ctl for pure dry-run verbs (quality-validate).
Calls the real main(argv) -- identical argv parsing, dispatch, audit,
and stdout JSON -- with stdio captured, amortizing the ~80ms
per-spawn interpreter + module-exec cost over one import. Only valid
for verbs that never read stdin (quality-validate is a dry-run that
never consumes stdin payloads).
"""
import io
from contextlib import redirect_stderr, redirect_stdout
out, err = io.StringIO(), io.StringIO()
returncode = 0
with redirect_stdout(out), redirect_stderr(err):
try:
box_ctl.main(["box-ctl.py", *args])
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
return _InProcResult(returncode, out.getvalue(), err.getvalue())
class ExecGitOpsTests(unittest.TestCase):
def test_ops_registered_and_read_only(self):
for op in ("git.status", "git.diff", "git.log"):
@@ -223,12 +253,14 @@ class BoxCtlGitTests(unittest.TestCase):
self.assertNotEqual(r.returncode, 0)
def test_quality_validate_git_verbs(self):
# In-process dry-runs: same main(argv) path and stdout JSON as
# subprocess calls. Assertions below are unchanged.
for args in (["git-status"], ["git-diff", "--stat"],
["git-diff", "--path", "bin/dm.py"],
["git-log", "--limit", "5"]):
r = _box_ctl("quality-validate", *args)
r = _box_ctl_inproc("quality-validate", *args)
self.assertTrue(json.loads(r.stdout)["valid"], args)
r = _box_ctl("quality-validate", "git-diff", "--path", "../x")
r = _box_ctl_inproc("quality-validate", "git-diff", "--path", "../x")
self.assertFalse(json.loads(r.stdout)["valid"])
@@ -274,15 +306,17 @@ class BoxCtlTestsRunTests(unittest.TestCase):
self.assertEqual(json.loads(r.stdout)["code"], "NOT_FOUND")
def test_quality_validate_tests_run(self):
r = _box_ctl("quality-validate", "tests-run")
# In-process dry-runs: same main(argv) path and stdout JSON as
# subprocess calls. Assertions below are unchanged.
r = _box_ctl_inproc("quality-validate", "tests-run")
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "tests-run", "tests.test_box_read_https")
r = _box_ctl_inproc("quality-validate", "tests-run", "tests.test_box_read_https")
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "tests-run", "--filter", "safepath")
r = _box_ctl_inproc("quality-validate", "tests-run", "--filter", "safepath")
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "tests-run", "os")
r = _box_ctl_inproc("quality-validate", "tests-run", "os")
self.assertFalse(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "tests-run", "--filter")
r = _box_ctl_inproc("quality-validate", "tests-run", "--filter")
self.assertFalse(json.loads(r.stdout)["valid"], r.stdout)
@@ -303,10 +337,12 @@ class BoxCtlAckTests(unittest.TestCase):
self.assertEqual(json.loads(r.stdout)["code"], "BAD_ARGS")
def test_quality_validate_ack(self):
r = _box_ctl("quality-validate", "ack", "bdf7beb6",
# In-process dry-runs: same main(argv) path and stdout JSON as
# subprocess calls. Assertions below are unchanged.
r = _box_ctl_inproc("quality-validate", "ack", "bdf7beb6",
"--to", "pip", "--sender", "opm")
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "ack", "xyz!",
r = _box_ctl_inproc("quality-validate", "ack", "xyz!",
"--to", "pip", "--sender", "opm")
self.assertFalse(json.loads(r.stdout)["valid"], r.stdout)
+51 -19
View File
@@ -37,6 +37,7 @@ def _load(name, relpath):
exec_constrained = _load("exec_constrained_jobs", "bin/exec-constrained.py")
box_ctl = _load("box_ctl_jobstest", "bin/box-ctl.py")
def _box_ctl(*args, stdin=None):
@@ -45,6 +46,37 @@ def _box_ctl(*args, stdin=None):
input=stdin, capture_output=True, text=True, timeout=120)
class _InProcResult:
"""Minimal CompletedProcess stand-in (returncode/stdout/stderr)."""
def __init__(self, returncode, stdout):
self.returncode = returncode
self.stdout = stdout
self.stderr = ""
def _box_ctl_inproc(*args, stdin=None):
"""In-process _box_ctl (proven pattern from test_box_loop_https).
Real main(argv) with stdout captured and sys.stdin patched when a
body is given (job-put reads the raw definition from stdin).
"""
import io
from contextlib import redirect_stdout, nullcontext
from unittest import mock
buf = io.StringIO()
returncode = 0
stdin_ctx = (mock.patch.object(sys, "stdin", io.StringIO(stdin))
if stdin is not None else nullcontext())
with stdin_ctx:
with redirect_stdout(buf):
try:
box_ctl.main(["box-ctl.py", *args])
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
return _InProcResult(returncode, buf.getvalue())
def _job_def(name, **over):
d = {"name": name, "description": "unit test job",
"schedule": "manual", "agent": "opm",
@@ -166,7 +198,7 @@ class ExecJobOpsTests(unittest.TestCase):
class BoxCtlJobsTests(unittest.TestCase):
def test_job_next_dry_run_live(self):
r = _box_ctl("job-next", MISSING_ID)
r = _box_ctl_inproc("job-next", MISSING_ID)
self.assertEqual(r.returncode, 0, r.stderr)
data = json.loads(r.stdout)
self.assertTrue(data["ok"])
@@ -174,55 +206,55 @@ class BoxCtlJobsTests(unittest.TestCase):
self.assertFalse(data["would_dispatch"])
def test_job_put_rejects_before_write(self):
r = _box_ctl("job-put", "Bad_Name!", stdin="{}")
r = _box_ctl_inproc("job-put", "Bad_Name!", stdin="{}")
self.assertNotEqual(r.returncode, 0)
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NAME")
r = _box_ctl("job-put", "my-job", stdin="not json")
r = _box_ctl_inproc("job-put", "my-job", stdin="not json")
self.assertEqual(json.loads(r.stdout)["code"], "INVALID_JOB")
r = _box_ctl("job-put", "my-job",
stdin=json.dumps(_job_def("other")))
r = _box_ctl_inproc("job-put", "my-job",
stdin=json.dumps(_job_def("other")))
self.assertEqual(json.loads(r.stdout)["code"], "NAME_MISMATCH")
bad = _job_def("my-job")
del bad["agent"]
r = _box_ctl("job-put", "my-job", stdin=json.dumps(bad))
r = _box_ctl_inproc("job-put", "my-job", stdin=json.dumps(bad))
self.assertEqual(json.loads(r.stdout)["code"], "INVALID_JOB")
def test_job_trigger_rejects_missing(self):
r = _box_ctl("job-trigger", "Bad_Name!")
r = _box_ctl_inproc("job-trigger", "Bad_Name!")
self.assertNotEqual(r.returncode, 0)
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NAME")
r = _box_ctl("job-trigger", MISSING_JOB)
r = _box_ctl_inproc("job-trigger", MISSING_JOB)
self.assertEqual(json.loads(r.stdout)["code"], "NOT_FOUND")
def test_job_chain_rejects_before_write(self):
r = _box_ctl("job-chain", "Bad_Name!", EXISTING_JOB)
r = _box_ctl_inproc("job-chain", "Bad_Name!", EXISTING_JOB)
self.assertNotEqual(r.returncode, 0)
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NAME")
r = _box_ctl("job-chain", EXISTING_JOB, EXISTING_JOB)
r = _box_ctl_inproc("job-chain", EXISTING_JOB, EXISTING_JOB)
self.assertEqual(json.loads(r.stdout)["code"], "INVALID_JOB")
r = _box_ctl("job-chain", MISSING_JOB, EXISTING_JOB)
r = _box_ctl_inproc("job-chain", MISSING_JOB, EXISTING_JOB)
self.assertEqual(json.loads(r.stdout)["code"], "NOT_FOUND")
def test_timer_control_rejects_before_action(self):
for verb in ("timer-stop", "timer-disable"):
r = _box_ctl(verb, "Bad_Name!")
r = _box_ctl_inproc(verb, "Bad_Name!")
self.assertNotEqual(r.returncode, 0)
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NAME")
r = _box_ctl(verb, MISSING_JOB)
r = _box_ctl_inproc(verb, MISSING_JOB)
self.assertEqual(json.loads(r.stdout)["code"], "NOT_FOUND")
def test_quality_validate_job_verbs(self):
r = _box_ctl("quality-validate", "job-put", "my-job")
r = _box_ctl_inproc("quality-validate", "job-put", "my-job")
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "job-trigger", EXISTING_JOB)
r = _box_ctl_inproc("quality-validate", "job-trigger", EXISTING_JOB)
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "job-chain", "a", "b")
r = _box_ctl_inproc("quality-validate", "job-chain", "a", "b")
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "job-next", MISSING_ID)
r = _box_ctl_inproc("quality-validate", "job-next", MISSING_ID)
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "timer-stop", EXISTING_JOB)
r = _box_ctl_inproc("quality-validate", "timer-stop", EXISTING_JOB)
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "job-put", "Bad_Name!")
r = _box_ctl_inproc("quality-validate", "job-put", "Bad_Name!")
self.assertFalse(json.loads(r.stdout)["valid"], r.stdout)
+33 -1
View File
@@ -38,6 +38,7 @@ def _load(name, relpath):
exec_constrained = _load("exec_constrained_loop", "bin/exec-constrained.py")
box_ctl = _load("box_ctl_looptest", "bin/box-ctl.py")
def _box_ctl(*args):
@@ -46,6 +47,34 @@ def _box_ctl(*args):
capture_output=True, text=True, timeout=180)
class _InProcResult:
"""Minimal CompletedProcess stand-in (returncode/stdout only)."""
def __init__(self, returncode, stdout):
self.returncode = returncode
self.stdout = stdout
def _box_ctl_inproc(*args):
"""In-process _box_ctl for pure dry-run verbs (quality-validate).
Calls the real main(argv) -- identical argv parsing, dispatch, audit,
and stdout JSON -- with stdout captured, amortizing the ~80ms
per-spawn interpreter + module-exec cost over one import. Only valid
for verbs that never read stdin (quality-validate is a dry-run that
never consumes stdin payloads).
"""
import io
from contextlib import redirect_stdout
buf = io.StringIO()
returncode = 0
with redirect_stdout(buf):
try:
box_ctl.main(["box-ctl.py", *args])
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
return _InProcResult(returncode, buf.getvalue())
class ExecLoopOpsTests(unittest.TestCase):
def test_ops_registered_and_side_effecting(self):
spec = exec_constrained.OPS
@@ -208,7 +237,10 @@ class BoxCtlLoopTests(unittest.TestCase):
(["vars-get", "has space"], False),
]
for args, valid in cases:
r = _box_ctl("quality-validate", *args)
# In-process dry-run: same main(argv) path and stdout JSON as a
# subprocess call, without the per-case spawn cost. Assertions
# below are unchanged.
r = _box_ctl_inproc("quality-validate", *args)
self.assertEqual(json.loads(r.stdout)["valid"], valid, args)
+48 -5
View File
@@ -42,6 +42,7 @@ def _load(name, relpath):
exec_constrained = _load("exec_constrained_md", "bin/exec-constrained.py")
agent_md = _load("agent_md_mdtest", "bin/agent_md.py")
box_ctl = _load("box_ctl_mdtest", "bin/box-ctl.py")
def _box_ctl(*args, stdin=None):
@@ -50,6 +51,39 @@ def _box_ctl(*args, stdin=None):
input=stdin, capture_output=True, text=True, timeout=180)
class _InProcResult:
"""Minimal CompletedProcess stand-in (returncode/stdout only)."""
def __init__(self, returncode, stdout):
self.returncode = returncode
self.stdout = stdout
def _box_ctl_inproc(*args, stdin=None):
"""In-process _box_ctl for dry-run and validation-failure verbs.
Calls the real main(argv) -- identical argv parsing, dispatch, audit,
stdin reads, and stdout JSON -- with stdio captured, amortizing the
~80ms per-spawn interpreter + module-exec cost over one import.
stdin, when given, is fed exactly as subprocess input= would be.
"""
import io
from contextlib import redirect_stdout
buf = io.StringIO()
returncode = 0
saved_stdin = sys.stdin
if stdin is not None:
sys.stdin = io.StringIO(stdin)
try:
with redirect_stdout(buf):
try:
box_ctl.main(["box-ctl.py", *args])
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
finally:
sys.stdin = saved_stdin
return _InProcResult(returncode, buf.getvalue())
class ExecMdOpsTests(unittest.TestCase):
def test_ops_registered_and_side_effecting(self):
spec = exec_constrained.OPS
@@ -320,8 +354,10 @@ class BoxCtlMdTests(unittest.TestCase):
["md-audit", "../x"],
["md", "read", "646", "../x"],
]
# In-process dispatch: same main(argv) path, fail() JSON, and
# exit code as a subprocess call. Assertions below are unchanged.
for args in cases:
r = _box_ctl(*args)
r = _box_ctl_inproc(*args)
self.assertNotEqual(r.returncode, 0, args)
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NAME", args)
@@ -333,13 +369,17 @@ class BoxCtlMdTests(unittest.TestCase):
["md", "amend", "NOPE.md", "content here"],
["md", "append", "NOPE.md", "note here"],
]
# In-process dispatch: same main(argv) path, stdin reads, fail()
# JSON, and exit code as a subprocess call. Assertions below are
# unchanged. (Amend/append parse --stdin BEFORE validating the
# path, so stdin is fed here exactly as the spawn did.)
for args in cases:
r = _box_ctl(*args)
r = _box_ctl_inproc(*args)
self.assertNotEqual(r.returncode, 0, args)
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NAME", args)
r = _box_ctl("md-amend", "../x", "--stdin", stdin="hi")
r = _box_ctl_inproc("md-amend", "../x", "--stdin", stdin="hi")
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NAME")
r = _box_ctl("md-append", "../x", "--stdin", stdin="hi")
r = _box_ctl_inproc("md-append", "../x", "--stdin", stdin="hi")
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NAME")
def test_amend_stdin_safety_rejection_writes_nothing(self):
@@ -386,7 +426,10 @@ class BoxCtlMdTests(unittest.TestCase):
(["md-write", "646", "SOUL.md"], False),
]
for args, valid in cases:
r = _box_ctl("quality-validate", *args)
# In-process dry-run: same main(argv) path and stdout JSON as a
# subprocess call, without the per-case spawn cost. Assertions
# below are unchanged.
r = _box_ctl_inproc("quality-validate", *args)
self.assertEqual(json.loads(r.stdout)["valid"], valid, args)
+69 -7
View File
@@ -33,6 +33,7 @@ def _load(name, relpath):
exec_constrained = _load("exec_constrained_read", "bin/exec-constrained.py")
super_cli = _load("super_cli_read", "bin/super-cli.py")
box_ctl = _load("box_ctl_readtest", "bin/box-ctl.py")
def _box_ctl(*args):
@@ -41,6 +42,33 @@ def _box_ctl(*args):
capture_output=True, text=True, timeout=60)
class _InProcResult:
"""Minimal CompletedProcess stand-in (returncode/stdout/stderr)."""
def __init__(self, returncode, stdout, stderr=""):
self.returncode = returncode
self.stdout = stdout
self.stderr = stderr
def _box_ctl_inproc(*args):
"""In-process _box_ctl for dry-run/read-only verbs (quality-validate,
dm-log success paths).
Calls the real main(argv) -- identical argv parsing, dispatch, audit,
and stdout JSON -- with stdio captured, amortizing the ~80ms
per-spawn interpreter + module-exec cost over one import.
"""
from contextlib import redirect_stderr
out, err = io.StringIO(), io.StringIO()
returncode = 0
with redirect_stdout(out), redirect_stderr(err):
try:
box_ctl.main(["box-ctl.py", *args])
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
return _InProcResult(returncode, out.getvalue(), err.getvalue())
class ExecReadOpsTests(unittest.TestCase):
def test_ops_registered_and_read_only(self):
self.assertIn("fleet.unread", exec_constrained.OPS)
@@ -97,8 +125,10 @@ class ExecReadOpsTests(unittest.TestCase):
spec = exec_constrained.OPS["dm.log"]
clean = spec["validate"]({"limit": 2})
argv = spec["build"](clean)
argv[0] = sys.executable # hermetic interpreter, same script + args
r = subprocess.run(argv, capture_output=True, text=True, timeout=60)
# In-process dispatch of the op-built argv (minus interpreter and
# script: argv is [python, box-ctl.py, action, ...]): same argv
# parsing, dispatch, and stdout JSON, without respawn.
r = _box_ctl_inproc(*argv[2:])
self.assertEqual(r.returncode, 0, r.stderr)
data = json.loads(r.stdout)
self.assertTrue(data["ok"])
@@ -131,23 +161,55 @@ class BoxCtlReadVerbsTests(unittest.TestCase):
self.assertEqual(json.loads(r.stdout)["code"], "BAD_ARGS")
def test_dm_log_back_compat_limit_only(self):
r = _box_ctl("dm-log", "2")
r = _box_ctl_inproc("dm-log", "2")
self.assertEqual(r.returncode, 0, r.stderr)
data = json.loads(r.stdout)
self.assertTrue(data["ok"])
self.assertEqual(len(data["entries"]), 2)
def test_quality_validate_new_verbs(self):
r = _box_ctl("quality-validate", "unread", "--agent", "pip")
# In-process dry-runs: same main(argv) path and stdout JSON as
# subprocess calls. Assertions below are unchanged.
r = _box_ctl_inproc("quality-validate", "unread", "--agent", "pip")
data = json.loads(r.stdout)
self.assertTrue(data["valid"], r.stdout)
r = _box_ctl("quality-validate", "dm-log", "5", "--agent", "opm")
r = _box_ctl_inproc("quality-validate", "dm-log", "5", "--agent", "opm")
self.assertTrue(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "unread", "--agent", "nope")
r = _box_ctl_inproc("quality-validate", "unread", "--agent", "nope")
self.assertFalse(json.loads(r.stdout)["valid"], r.stdout)
r = _box_ctl("quality-validate", "unread", "extra-positional")
r = _box_ctl_inproc("quality-validate", "unread", "extra-positional")
self.assertFalse(json.loads(r.stdout)["valid"], r.stdout)
def test_policy_verbs_live_schema(self):
r = _box_ctl_inproc("policy")
self.assertEqual(r.returncode, 0, r.stderr)
data = json.loads(r.stdout)
self.assertTrue(data["ok"])
self.assertIn("agents", data)
self.assertIn("totals", data)
self.assertIn(data["status"], ("clean", "violations found"))
r = _box_ctl_inproc("policy", "check", "opm")
self.assertEqual(r.returncode, 0, r.stderr)
data = json.loads(r.stdout)
self.assertTrue(data["ok"])
self.assertEqual(data["agent"], "opm")
for k in ("blocked", "authorized_main", "violations", "total_sends"):
self.assertIn(k, data)
def test_policy_scan_parses_each_line_once(self):
import shutil
import tempfile
with tempfile.TemporaryDirectory() as td:
frozen = Path(td) / "dm-log.jsonl"
shutil.copyfile(box_ctl.DM_LOG, frozen)
expect = sum(1 for ln in frozen.read_text().splitlines() if ln.strip())
real_loads = json.loads
with mock.patch.object(box_ctl, "DM_LOG", frozen):
with mock.patch.object(json, "loads", wraps=real_loads) as spy:
per_agent, meta = box_ctl._policy_scan()
self.assertIsNotNone(per_agent)
self.assertEqual(spy.call_count, expect)
class SuperCliUnreadTests(unittest.TestCase):
def test_lookup_dispatches_unread(self):
+29 -2
View File
@@ -6,6 +6,7 @@ muse argv approval-posture parsing, runtime_rows assembly (mocked tmux),
and the `box runtime` CLI surface.
"""
import importlib.util
import json
import sys
import unittest
@@ -18,6 +19,16 @@ sys.path.insert(0, str(BIN_DIR))
import muse_choice_watcher as w
def _load(name, relpath):
spec = importlib.util.spec_from_file_location(name, REPO_ROOT / relpath)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
super_cli = _load("super_cli_runtimetest", "bin/super-cli.py")
PROMPT = "❯" # Muse TUI input glyph (U+276F)
STATE_OPEN = (
@@ -375,9 +386,25 @@ class TestBoxRuntimeCLI(unittest.TestCase):
self.assertTrue(json.loads(r.stdout)["ok"])
def test_subcommand_help(self):
# In-process --help: same main()/argparse path as a subprocess call
# (fresh parser per call; --help exits 0), without the ~0.2s
# per-spawn interpreter + module-exec cost. Assertions unchanged.
import io
from contextlib import redirect_stderr, redirect_stdout
for sub in ("list", "send", "launch", "layout", "spread"):
r = self._box(sub, "--help")
self.assertEqual(r.returncode, 0, sub)
out, err = io.StringIO(), io.StringIO()
saved = sys.argv
sys.argv = [str(BIN_DIR / "super-cli.py"),
"runtime", sub, "--help"]
rc = 0
with redirect_stdout(out), redirect_stderr(err):
try:
super_cli.main()
except SystemExit as e:
rc = e.code if isinstance(e.code, int) else 1
finally:
sys.argv = saved
self.assertEqual(rc, 0, sub)
def test_launch_dry_run_injects_approve(self):
r = self._box("launch", "--session", "probe-x",
+20 -3
View File
@@ -17,6 +17,23 @@ from invite_handler import InviteCodeInfo, InviteHandler, RedemptionResult, salv
from settings_rpa import NodeUsage, SettingsRPA
def _fast_clock():
"""Fake time.time advancing 1s per call.
redeem_code_dom polls on `deadline = time.time() + 2.5` loops; patching
only time.sleep leaves 2.5s of real time per loop. With +1s/call each
loop runs exactly 2 iterations then expires (deadline math holds for
every loop uniformly, no per-loop alignment needed).
"""
state = {"t": 1000.0}
def fake_time():
state["t"] += 1.0
return state["t"]
return fake_time
class TestInviteCodeValidation(unittest.TestCase):
def test_normalize_valid_codes(self):
self.assertEqual(invite.normalize_code("REDCJ7"), "REDCJ7")
@@ -212,7 +229,7 @@ class TestInviteHandlerMocked(unittest.TestCase):
h = InviteHandler("dev")
h.ws = MagicMock()
with patch.object(h, "connect"), patch("time.sleep", return_value=None):
with patch.object(h, "connect"), patch("time.sleep", return_value=None), patch("time.time", side_effect=_fast_clock()):
with patch("invite_handler.cdp_evaluate", return_value={"found": False, "text": "General"}):
with patch.object(h, "redeem_code_api") as mock_api:
mock_api.return_value = RedemptionResult(
@@ -239,7 +256,7 @@ class TestInviteHandlerMocked(unittest.TestCase):
h = InviteHandler("646")
h.ws = MagicMock()
with patch.object(h, "connect"), patch("time.sleep", return_value=None):
with patch.object(h, "connect"), patch("time.sleep", return_value=None), patch("time.time", side_effect=_fast_clock()):
with patch("invite_handler.cdp_evaluate", return_value={"found": False, "has_additional": True, "text": "Additional tokens"}):
with patch.object(h, "redeem_code_api") as mock_api:
mock_api.return_value = RedemptionResult(
@@ -274,7 +291,7 @@ class TestInviteHandlerMocked(unittest.TestCase):
return {"found_input": False}
return True
with patch.object(h, "connect"), patch("time.sleep", return_value=None):
with patch.object(h, "connect"), patch("time.sleep", return_value=None), patch("time.time", side_effect=_fast_clock()):
with patch("invite_handler.cdp_evaluate", side_effect=mock_eval), patch("invite_handler.cdp_send_escape"):
with patch.object(h, "redeem_code_api") as mock_api:
mock_api.return_value = RedemptionResult(
+52 -6
View File
@@ -18,6 +18,7 @@ import tempfile
import shutil
from pathlib import Path
from datetime import datetime, timezone
from unittest.mock import patch
REPO_ROOT = Path("/home/super/Projects/NetVM")
BIN_DIR = REPO_ROOT / "bin"
@@ -27,6 +28,39 @@ sys.path.insert(0, str(BIN_DIR))
import gravity
def _load(name, relpath):
import importlib.util
spec = importlib.util.spec_from_file_location(name, REPO_ROOT / relpath)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
box_ctl = _load("box_ctl_loophealthtest", "bin/box-ctl.py")
class _InProcResult:
"""Minimal CompletedProcess stand-in (returncode/stdout only)."""
def __init__(self, returncode, stdout):
self.returncode = returncode
self.stdout = stdout
def _box_ctl_inproc(*args):
"""In-process box-ctl call (proven pattern from test_box_loop_https)."""
import io
from contextlib import redirect_stdout
buf = io.StringIO()
returncode = 0
with redirect_stdout(buf):
try:
box_ctl.main(["box-ctl.py", *args])
except SystemExit as e:
returncode = e.code if isinstance(e.code, int) else 1
return _InProcResult(returncode, buf.getvalue())
class TestLoopDiagnosticsAndRemediation(unittest.TestCase):
"""Test gravity.py loop health and progressive remediation."""
@@ -61,13 +95,27 @@ class TestLoopDiagnosticsAndRemediation(unittest.TestCase):
self.assertIsInstance(res.get("remediated"), list)
self.assertIsInstance(res.get("escalated"), list)
def test_remediate_single_approval_scan(self):
import approvals
real = approvals.check_fleet_approvals
with patch.object(approvals, "check_fleet_approvals", wraps=real) as spy:
res = gravity.remediate_breaks(dry_run=True)
self.assertTrue(res.get("ok"))
self.assertEqual(spy.call_count, 1)
def test_remediate_single_loop_parse(self):
real = gravity._load_loop_candidates
with patch.object(gravity, "_load_loop_candidates", wraps=real) as spy:
res = gravity.remediate_breaks(dry_run=True)
self.assertTrue(res.get("ok"))
self.assertEqual(spy.call_count, 1)
class TestLoopRpc(unittest.TestCase):
"""Test box-ctl.py allowlisted RPC actions for loops."""
def test_box_ctl_loop_health(self):
cmd = [sys.executable, str(BOX_CTL), "loop-health"]
res = subprocess.run(cmd, capture_output=True, text=True)
res = _box_ctl_inproc("loop-health")
self.assertEqual(res.returncode, 0)
data = json.loads(res.stdout)
self.assertTrue(data.get("ok"))
@@ -76,16 +124,14 @@ class TestLoopRpc(unittest.TestCase):
def test_box_ctl_loop_status(self):
cmd = [sys.executable, str(BOX_CTL), "loop-status", "--limit", "5"]
res = subprocess.run(cmd, capture_output=True, text=True)
res = _box_ctl_inproc("loop-status", "--limit", "5")
self.assertEqual(res.returncode, 0)
data = json.loads(res.stdout)
self.assertTrue(data.get("ok"))
self.assertIn("loops", data)
def test_box_ctl_loop_remediate_dry_run(self):
cmd = [sys.executable, str(BOX_CTL), "loop-remediate", "--dry-run"]
res = subprocess.run(cmd, capture_output=True, text=True)
res = _box_ctl_inproc("loop-remediate", "--dry-run")
self.assertEqual(res.returncode, 0)
data = json.loads(res.stdout)
self.assertTrue(data.get("ok"))
+21 -6
View File
@@ -68,8 +68,11 @@ class TestSettingsRPAPrimitives(unittest.TestCase):
usage_payload, # read_usage evaluation
]
with SettingsRPA("646") as rpa:
usage = rpa.read_usage(keep_dialog_open=True)
# Settle sleeps (0.4s tab + 0.4s usage) are production pacing, not
# asserted behavior: skip them like the mocked CDP transport above.
with patch("time.sleep", return_value=None):
with SettingsRPA("646") as rpa:
usage = rpa.read_usage(keep_dialog_open=True)
self.assertEqual(usage.node, "646")
self.assertEqual(usage.weekly_percent_used, 100)
self.assertEqual(usage.extra_percent_used, 100)
@@ -97,8 +100,10 @@ class TestSettingsRPAPrimitives(unittest.TestCase):
usage_payload, # read_usage evaluation
]
with SettingsRPA("646") as rpa:
usage = rpa.read_usage(keep_dialog_open=True)
# Settle sleeps are production pacing, not asserted behavior: skip.
with patch("time.sleep", return_value=None):
with SettingsRPA("646") as rpa:
usage = rpa.read_usage(keep_dialog_open=True)
self.assertEqual(usage.node, "646")
self.assertEqual(usage.weekly_percent_used, 20)
self.assertEqual(usage.extra_percent_used, 0)
@@ -118,9 +123,19 @@ class TestSettingsRPAPrimitives(unittest.TestCase):
mock_eval.side_effect = eval_side_effect
# The usage poll loop (read_usage) busy-spins on a real-time 4.0s
# deadline while sleep is stubbed, so run it on a fake clock that
# advances 1s per read: the loop still polls (each poll returns None)
# and still exits via timeout, just after ~4 reads instead of 4s.
clock = [1000.0]
def _tick():
clock[0] += 1.0
return clock[0]
with SettingsRPA("646", timeout=0.5) as rpa:
# Shorten deadline by patching time.time or passing small timeout
with patch("time.sleep", return_value=None):
with patch("time.sleep", return_value=None), \
patch("time.time", side_effect=_tick):
usage = rpa.read_usage(keep_dialog_open=True)
self.assertEqual(usage.node, "646")
self.assertFalse(usage.stats_loaded)
+17
View File
@@ -245,6 +245,23 @@ class CanonicalToolPattern(unittest.TestCase):
class EnvelopeRoundTrip(unittest.TestCase):
def setUp(self):
# Stub the kpi module: wrap() calls get_live_advisory_block()
# (live network I/O: usage API + route probes) on the include_kpi
# path. An empty advisory keeps the path exercised -- import, call,
# and falsy branch all still run -- without the network wait.
import types
self._saved_kpi = sys.modules.get("kpi")
stub = types.ModuleType("kpi")
stub.get_live_advisory_block = lambda agent: ""
sys.modules["kpi"] = stub
def tearDown(self):
if self._saved_kpi is None:
sys.modules.pop("kpi", None)
else:
sys.modules["kpi"] = self._saved_kpi
def test_wrap_advertises_new_verbs(self):
body = env.wrap("work-finder", "work-finder-1", "646",
"646 tasks", "Do the thing.")