diff --git a/bin/box-relay.sh b/bin/box-relay.sh index f190baa..a331173 100755 --- a/bin/box-relay.sh +++ b/bin/box-relay.sh @@ -445,6 +445,9 @@ case "$cmd" in relay-health) call_exec "relay.health" "{}" ;; + quality|quality-check) + call_exec "quality.check" "{}" + ;; ping) call_exec "exec.ping" "{}" ;; diff --git a/bin/exec-constrained.py b/bin/exec-constrained.py index de3b0ec..f23f62f 100755 --- a/bin/exec-constrained.py +++ b/bin/exec-constrained.py @@ -464,6 +464,22 @@ def _relay_health_build(a): return [sys.executable, os.path.join(BIN_DIR, 'box-ctl.py'), 'relay-health'] +def _quality_check_validate(raw): + if raw not in ({}, None): + if isinstance(raw, dict): + allowed = {'scope'} + for k in raw: + if k not in allowed: + raise OpError(f'unknown arg: {k}') + else: + raise OpError('quality.check args must be an object or empty') + return {} + + +def _quality_check_build(a): + return [sys.executable, os.path.join(BIN_DIR, 'box-ctl.py'), 'quality-check'] + + def _subagent_spawn_validate(raw): if not isinstance(raw, dict): raise OpError('args must be an object') @@ -906,6 +922,11 @@ OPS = { 'timeout': 30, 'side_effecting': False, 'desc': 'Check systemd relay service status across all node ports (read-only)', }, + 'quality.check': { + 'validate': _quality_check_validate, 'build': _quality_check_build, + 'timeout': 30, 'side_effecting': False, + 'desc': 'Run box quality gates and self-diagnostics suite (read-only)', + }, 'subagent.spawn': { 'validate': _subagent_spawn_validate, 'build': _subagent_spawn_build, 'timeout': 120, 'side_effecting': True,