From 95d0986bf038b4c2aa2c2c7aea19de0d15af286d Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 22 May 2026 08:36:56 -0400 Subject: [PATCH 1/3] Add AgentPlane sp-run facade delegation --- src/prophet_cli/cli.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/prophet_cli/cli.py b/src/prophet_cli/cli.py index 675b88e..6edee7a 100644 --- a/src/prophet_cli/cli.py +++ b/src/prophet_cli/cli.py @@ -1,8 +1,8 @@ """Prophet facade CLI. The `prophet` command is a stable operator-facing facade. It delegates local -SourceOS implementation work to the owning CLIs instead of duplicating engine -logic here. +SourceOS and AgentPlane implementation work to the owning CLIs instead of +duplicating engine logic here. """ from __future__ import annotations @@ -19,6 +19,7 @@ DELEGATES = { "sourceosctl": "Install sourceos-devtools from SocioProphet/homebrew-prophet or run it from SourceOS-Linux/sourceos-devtools.", "agent-term": "Install agent-term from SocioProphet/homebrew-prophet or run it from SourceOS-Linux/agent-term.", + "sp-run": "Install AgentPlane so the sp-run delegate is available on PATH, or run it from SocioProphet/agentplane.", } @@ -66,6 +67,9 @@ def build_parser() -> argparse.ArgumentParser: agent_term = sourceos_sub.add_parser("agent-term", help="Delegate AgentTerm commands") agent_term.add_argument("args", nargs=argparse.REMAINDER, help="Arguments passed to agent-term") + agentplane = sub.add_parser("agentplane", help="Delegate AgentPlane governed-runner commands") + agentplane.add_argument("args", nargs=argparse.REMAINDER, help="Arguments passed to sp-run") + return parser @@ -87,9 +91,12 @@ def main(argv: list[str] | None = None) -> int: if args.sourceos_command == "agent-term": return _delegate("agent-term", list(args.args)) + if args.command == "agentplane": + return _delegate("sp-run", list(args.args)) + parser.error("unknown command") return 2 if __name__ == "__main__": - raise SystemExit(main(sys.argv[1:])) + raise SystemExit(main(sys.argv[1:])) \ No newline at end of file From 34551c5a581d459eacb69956a74b4d6beaea79ec Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 22 May 2026 08:38:30 -0400 Subject: [PATCH 2/3] Test AgentPlane sp-run facade delegation --- tests/test_cli.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/tests/test_cli.py b/tests/test_cli.py index c34c14e..666d577 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -118,6 +118,76 @@ def fake_run(cmd, check=False): assert calls == [["/usr/bin/agent-term", "office", "inspect", "!prophet-workspace", "/tmp/demo.pptx"]] +def test_agentplane_doctor_delegates_to_sp_run(monkeypatch): + calls: list[list[str]] = [] + + monkeypatch.setattr("shutil.which", lambda binary: f"/usr/bin/{binary}") + + def fake_run(cmd, check=False): + calls.append(cmd) + assert check is False + return Completed(0) + + monkeypatch.setattr(subprocess, "run", fake_run) + + rc = main(["agentplane", "doctor"]) + + assert rc == 0 + assert calls == [["/usr/bin/sp-run", "doctor"]] + + +def test_agentplane_preflight_delegates_to_sp_run(monkeypatch): + calls: list[list[str]] = [] + + monkeypatch.setattr("shutil.which", lambda binary: f"/usr/bin/{binary}") + + def fake_run(cmd, check=False): + calls.append(cmd) + assert check is False + return Completed(0) + + monkeypatch.setattr(subprocess, "run", fake_run) + + rc = main(["agentplane", "preflight", "contract.json"]) + + assert rc == 0 + assert calls == [["/usr/bin/sp-run", "preflight", "contract.json"]] + + +def test_agentplane_admit_delegates_to_sp_run(monkeypatch): + calls: list[list[str]] = [] + + monkeypatch.setattr("shutil.which", lambda binary: f"/usr/bin/{binary}") + + def fake_run(cmd, check=False): + calls.append(cmd) + assert check is False + return Completed(0) + + monkeypatch.setattr(subprocess, "run", fake_run) + + rc = main([ + "agentplane", + "admit", + "contract.json", + "--preflight", + "preflight.json", + "--authority-state", + "authority.json", + ]) + + assert rc == 0 + assert calls == [[ + "/usr/bin/sp-run", + "admit", + "contract.json", + "--preflight", + "preflight.json", + "--authority-state", + "authority.json", + ]] + + def test_missing_delegate_returns_127(monkeypatch, capsys): monkeypatch.setattr("shutil.which", lambda binary: None) @@ -127,3 +197,14 @@ def test_missing_delegate_returns_127(monkeypatch, capsys): assert rc == 127 assert "required delegate not found: sourceosctl" in captured.err assert "sourceos-devtools" in captured.err + + +def test_missing_sp_run_delegate_returns_127(monkeypatch, capsys): + monkeypatch.setattr("shutil.which", lambda binary: None) + + rc = main(["agentplane", "doctor"]) + + captured = capsys.readouterr() + assert rc == 127 + assert "required delegate not found: sp-run" in captured.err + assert "AgentPlane" in captured.err \ No newline at end of file From f9ed8a620037ac53143fa16cf358afffde80cead Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 22 May 2026 08:39:02 -0400 Subject: [PATCH 3/3] Document AgentPlane sp-run facade delegation --- README.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b29d838..8c7c8fe 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # prophet-cli -Façade repo for Prophet command surface and SourceOS bootstrap delegation. +Façade repo for Prophet command surface and SourceOS / AgentPlane bootstrap delegation. -`prophet` is the stable operator-facing command. It does not duplicate implementation logic that belongs in SourceOS or AgentTerm repositories. +`prophet` is the stable operator-facing command. It does not duplicate implementation logic that belongs in SourceOS, AgentTerm, or AgentPlane repositories. ## Delegation model @@ -14,6 +14,7 @@ Façade repo for Prophet command surface and SourceOS bootstrap delegation. | `prophet sourceos agent-machine ...` | `sourceosctl agent-machine ...` | `SourceOS-Linux/sourceos-devtools` | | `prophet sourceos office ...` | `sourceosctl office ...` | `SourceOS-Linux/sourceos-devtools` | | `prophet sourceos agent-term ...` | `agent-term ...` | `SourceOS-Linux/agent-term` | +| `prophet agentplane ...` | `sp-run ...` | `SocioProphet/agentplane` | ## Examples @@ -34,6 +35,11 @@ prophet sourceos office plan --artifact-type slide-deck --format pptx --title "D prophet sourceos office generate --dry-run --artifact-type document --format docx --title "Demo Report" prophet sourceos office convert ./example.docx --to pdf --dry-run prophet sourceos agent-term office create-deck '!prophet-workspace' --workroom workroom-demo-0001 --title 'Demo Briefing Deck' +prophet agentplane doctor +prophet agentplane preflight ./governed-run-contract.json +prophet agentplane admit ./governed-run-contract.json --preflight ./preflight-receipt.json --authority-state ./agent-authority-current-state.json --projected-cost-usd 0.25 +prophet agentplane dossier ./.socioprophet/runs/governed-run-alpha-001 +prophet agentplane validate-dossier ./run-dossier.json ``` ## Install path @@ -49,6 +55,14 @@ brew install agent-term `prophet-cli` only provides the `prophet` facade. The delegated binaries must also be installed or available on `PATH`. +For AgentPlane governed-runner commands, install or expose the AgentPlane-owned `sp-run` delegate from `SocioProphet/agentplane`: + +```bash +python3 -m pip install -e /path/to/agentplane +sp-run doctor +prophet agentplane doctor +``` + ## Boundary This repo does not own: @@ -64,7 +78,10 @@ This repo does not own: - LibreOffice, Collabora, ONLYOFFICE, Microsoft Graph, or Google Workspace adapters; - AgentTerm event log semantics; - AgentPlane evidence contracts; -- Agent Registry grants; +- AgentPlane governed-runner implementation; +- Agent Registry grants or authority state; - Homebrew formulae. Those remain in their owning repositories. + +`prophet agentplane ...` is a facade over `sp-run ...`; the implementation remains in `SocioProphet/agentplane`.