Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions reference/ipc-v0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ It is deliberately scoped as a conformance harness:
- it emits deterministic transcript and run receipts
- it includes a small `text.caps` adapter for round-trip tests
- it includes a TritRPC bridge skeleton adapter for remote-transport shape tests
- it includes a dry-run-capable TritRPC Rust CLI wrapper check
- it exposes `tritrpc.fixture.verify` through the bridge adapter as a codec-wrapper operation
- it includes dry-run-capable TritRPC Rust CLI wrapper checks for fixture verification and frame packing
- it exposes `tritrpc.fixture.verify` and `tritrpc.frame.pack` through the bridge adapter as codec-wrapper operations
- it supports explicit JSON invoke arguments via `--args-json` or `--args-file`
- it does not claim to be the production workspace runner or orchestrator

Expand Down Expand Up @@ -51,6 +51,24 @@ python -m src.contract_runner.runner \
--args-json '{"execute":true,"trpc":"/path/to/trpc","fixtures":"/path/to/TriTRPC/fixtures/vectors_hex_unary_rich.txt","nonces":"/path/to/TriTRPC/fixtures/vectors_hex_unary_rich.txt.nonces"}'
```

TritRPC frame pack IPC operation, dry-run wrapper mode:

```bash
python -m src.contract_runner.runner \
--adapter "python -m src.adapters.tritrpc_bridge_adapter" \
--op tritrpc.frame.pack \
--args-json '{"service":"hyper.v1","method":"AddVertex_a.REQ","json":"fixtures/payload-addvertex-a.json","receipt":".workstation/test-reports/tritrpc-frame-pack-ipc.json"}'
```

TritRPC frame pack IPC operation, execute mode with explicit local paths and caller-supplied nonce/key:

```bash
python -m src.contract_runner.runner \
--adapter "python -m src.adapters.tritrpc_bridge_adapter" \
--op tritrpc.frame.pack \
--args-json '{"execute":true,"trpc":"/path/to/trpc","service":"hyper.v1","method":"AddVertex_a.REQ","json":"fixtures/payload-addvertex-a.json","nonce":"000000000000000000000000000000000000000000000000","key":"0000000000000000000000000000000000000000000000000000000000000000"}'
```

TritRPC Rust CLI metadata dry-run:

```bash
Expand All @@ -67,6 +85,15 @@ tools/run-tritrpc-rust-cli-check \
--nonces /path/to/TriTRPC/fixtures/vectors_hex_unary_rich.txt.nonces
```

TritRPC frame pack helper, dry-run mode:

```bash
tools/run-tritrpc-frame-pack-check \
--service hyper.v1 \
--method AddVertex_a.REQ \
--json fixtures/payload-addvertex-a.json
```

Outputs are written under:

```text
Expand All @@ -85,6 +112,8 @@ The production runner/workspace controller may import these semantics, but this

The TritRPC bridge adapter is skeleton-only. It proves IPC-side capability declaration and invocation mapping for a future real TritRPC client; it does not open network connections.

The Rust CLI check is a codec-wrapper conformance helper. It does not fetch external fixtures and does not vendor TriTRPC fixture bytes.
The Rust CLI helpers are codec-wrapper conformance helpers. They do not fetch external fixtures and do not vendor TriTRPC fixture bytes.

The `tritrpc.fixture.verify` IPC operation shells out to the local Rust CLI check helper. Its default mode validates pinned metadata only. Execute mode requires explicit local paths supplied through the invoke arguments; no network transport is introduced here.

The `tritrpc.frame.pack` IPC operation shells out to the local frame-pack helper. Its default mode validates payload and argument shape only. Execute mode requires an explicit local `trpc` path plus caller-provided payload, nonce, and key; the key is redacted in receipts.
7 changes: 7 additions & 0 deletions reference/ipc-v0/fixtures/payload-addvertex-a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"op": "AddVertex",
"vertex": {
"vid": "a",
"label": "A"
}
}
73 changes: 57 additions & 16 deletions reference/ipc-v0/src/adapters/tritrpc_bridge_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

Supported operations:
- remote.echo: skeleton remote call shape
- tritrpc.fixture.verify: invokes the local Rust CLI wrapper helper in dry-run
- tritrpc.fixture.verify: invokes the local Rust CLI verify helper in dry-run
mode by default, or execute mode when explicit local paths are provided
- tritrpc.frame.pack: invokes the local Rust CLI pack helper in dry-run mode by
default, or execute mode when explicit local paths/nonce/key are provided
"""

from __future__ import annotations
Expand All @@ -21,7 +23,8 @@

IPC_VERSION = "ipc.v0"
HARNESS_ROOT = Path(__file__).resolve().parents[2]
WRAPPER = HARNESS_ROOT / "tools" / "run-tritrpc-rust-cli-check"
VERIFY_WRAPPER = HARNESS_ROOT / "tools" / "run-tritrpc-rust-cli-check"
PACK_WRAPPER = HARNESS_ROOT / "tools" / "run-tritrpc-frame-pack-check"


def now_rfc3339() -> str:
Expand Down Expand Up @@ -61,7 +64,7 @@ def send_capabilities() -> None:
"ts": now_rfc3339(),
"type": "capabilities",
"payload": {
"adapter": {"name": "tritrpc-bridge-adapter", "version": "0.2.0"},
"adapter": {"name": "tritrpc-bridge-adapter", "version": "0.3.0"},
"capabilities": [
{
"name": "remote.echo",
Expand All @@ -78,14 +81,22 @@ def send_capabilities() -> None:
"wrapper": "tools/run-tritrpc-rust-cli-check",
"network": False,
},
{
"name": "tritrpc.frame.pack",
"sideEffects": "filesystem",
"timeouts": {"defaultMs": 30000},
"remote": {"protocol": "tritrpc", "method": "frame.pack"},
"wrapper": "tools/run-tritrpc-frame-pack-check",
"network": False,
},
],
},
}
)


def run_fixture_verify(args: dict[str, Any]) -> dict[str, Any]:
cmd = [sys.executable, str(WRAPPER)]
cmd = [sys.executable, str(VERIFY_WRAPPER)]
receipt = args.get("receipt") or ".workstation/test-reports/tritrpc-rust-cli-check-adapter.json"
cmd += ["--receipt", str(receipt)]

Expand All @@ -103,14 +114,42 @@ def run_fixture_verify(args: dict[str, Any]) -> dict[str, Any]:
str(args["nonces"]),
]

return run_wrapper(cmd, receipt, "execute" if args.get("execute") else "dry-run")


def run_frame_pack(args: dict[str, Any]) -> dict[str, Any]:
cmd = [sys.executable, str(PACK_WRAPPER)]
receipt = args.get("receipt") or ".workstation/test-reports/tritrpc-frame-pack-check-adapter.json"
cmd += ["--receipt", str(receipt)]

for key in ["service", "method", "json"]:
if not args.get(key):
raise ValueError(f"tritrpc.frame.pack requires {key}")
cmd += ["--service", str(args["service"]), "--method", str(args["method"]), "--json", str(args["json"])]

if args.get("nonce"):
cmd += ["--nonce", str(args["nonce"])]
if args.get("key"):
cmd += ["--key", str(args["key"])]

if args.get("execute"):
if not args.get("trpc"):
raise ValueError("execute mode requires trpc")
cmd += ["--execute", "--trpc", str(args["trpc"])]

return run_wrapper(cmd, receipt, "execute" if args.get("execute") else "dry-run")


def run_wrapper(cmd: list[str], receipt: str, mode: str) -> dict[str, Any]:
proc = subprocess.run(cmd, cwd=HARNESS_ROOT, capture_output=True, text=True, check=False)
safe_cmd = ["<redacted>" if part and len(part) == 64 and all(c in "0123456789abcdefABCDEF" for c in part) else part for part in cmd]
data: dict[str, Any] = {
"command": cmd,
"command": safe_cmd,
"exitCode": proc.returncode,
"stdout": proc.stdout,
"stderr": proc.stderr,
"receipt": str(receipt),
"mode": "execute" if args.get("execute") else "dry-run",
"mode": mode,
}
if proc.returncode != 0:
data["ok"] = False
Expand Down Expand Up @@ -196,16 +235,18 @@ def main() -> int:
if not data.get("ok"):
send_error(msg_id, "TRITRPC_FIXTURE_VERIFY_FAILED", "fixture verify wrapper failed", data, retryable=False)
continue
send(
{
"v": IPC_VERSION,
"id": new_id(),
"ts": now_rfc3339(),
"type": "result",
"replyTo": msg_id,
"payload": {"ok": True, "data": data},
}
)
send({"v": IPC_VERSION, "id": new_id(), "ts": now_rfc3339(), "type": "result", "replyTo": msg_id, "payload": {"ok": True, "data": data}})
continue
if op == "tritrpc.frame.pack":
try:
data = run_frame_pack(args)
except Exception as exc:
send_error(msg_id, "TRITRPC_FRAME_PACK_FAILED", str(exc), retryable=False)
continue
if not data.get("ok"):
send_error(msg_id, "TRITRPC_FRAME_PACK_FAILED", "frame pack wrapper failed", data, retryable=False)
continue
send({"v": IPC_VERSION, "id": new_id(), "ts": now_rfc3339(), "type": "result", "replyTo": msg_id, "payload": {"ok": True, "data": data}})
continue
send_error(msg_id, "ADAPTER_NO_SUCH_OP", "unknown op", {"op": op})
continue
Expand Down
91 changes: 91 additions & 0 deletions reference/ipc-v0/tests/test_tritrpc_frame_pack_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from __future__ import annotations

import json
import subprocess
import sys
import unittest
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
TOOL = ROOT / "tools" / "run-tritrpc-frame-pack-check"
PAYLOAD = ROOT / "fixtures" / "payload-addvertex-a.json"


class TritRPCFramePackCheckTests(unittest.TestCase):
def test_dry_run_emits_receipt(self) -> None:
receipt = ROOT / ".workstation" / "test-reports" / "tritrpc-frame-pack-check-test.json"
if receipt.exists():
receipt.unlink()
proc = subprocess.run(
[
sys.executable,
str(TOOL),
"--service",
"hyper.v1",
"--method",
"AddVertex_a.REQ",
"--json",
str(PAYLOAD),
"--receipt",
str(receipt),
],
cwd=ROOT,
capture_output=True,
text=True,
check=False,
)
self.assertEqual(proc.returncode, 0, proc.stderr)
payload = json.loads(receipt.read_text(encoding="utf-8"))
self.assertEqual(payload["kind"], "TritRPCFramePackCheckReceipt")
self.assertEqual(payload["mode"], "dry-run")
self.assertEqual(payload["status"], "pass")
self.assertEqual(payload["service"], "hyper.v1")
self.assertEqual(payload["method"], "AddVertex_a.REQ")
self.assertEqual(payload["keyHexRedacted"], "<redacted>")

def test_execute_requires_trpc_path(self) -> None:
proc = subprocess.run(
[
sys.executable,
str(TOOL),
"--service",
"hyper.v1",
"--method",
"AddVertex_a.REQ",
"--json",
str(PAYLOAD),
"--execute",
],
cwd=ROOT,
capture_output=True,
text=True,
check=False,
)
self.assertNotEqual(proc.returncode, 0)
self.assertIn("--execute requires --trpc", proc.stderr)

def test_rejects_bad_nonce(self) -> None:
proc = subprocess.run(
[
sys.executable,
str(TOOL),
"--service",
"hyper.v1",
"--method",
"AddVertex_a.REQ",
"--json",
str(PAYLOAD),
"--nonce",
"not-hex",
],
cwd=ROOT,
capture_output=True,
text=True,
check=False,
)
self.assertNotEqual(proc.returncode, 0)
self.assertIn("nonce", proc.stderr)


if __name__ == "__main__":
unittest.main()
75 changes: 75 additions & 0 deletions reference/ipc-v0/tests/test_tritrpc_frame_pack_op.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from __future__ import annotations

import json
import subprocess
import sys
import unittest
from pathlib import Path


class TritRPCFramePackOperationTests(unittest.TestCase):
def test_frame_pack_dry_run_roundtrip(self) -> None:
root = Path(__file__).resolve().parents[1]
out_dir = root / ".workstation" / "test-reports" / "tritrpc-frame-pack-op"
payload = root / "fixtures" / "payload-addvertex-a.json"
receipt = ".workstation/test-reports/tritrpc-frame-pack-op.json"
invoke_args = {
"service": "hyper.v1",
"method": "AddVertex_a.REQ",
"json": str(payload),
"receipt": receipt,
}
cmd = [
sys.executable,
"-m",
"src.contract_runner.runner",
"--adapter",
f"{sys.executable} -m src.adapters.tritrpc_bridge_adapter",
"--out",
str(out_dir),
"--op",
"tritrpc.frame.pack",
"--args-json",
json.dumps(invoke_args),
]
proc = subprocess.run(cmd, cwd=root, capture_output=True, text=True, check=False)
self.assertEqual(proc.returncode, 0, proc.stderr)

result = json.loads(proc.stdout)
self.assertTrue(result["ok"])
data = result["data"]
self.assertTrue(data["ok"])
self.assertEqual(data["mode"], "dry-run")
self.assertEqual(data["receipt"], receipt)
self.assertEqual(data["receiptPayload"]["kind"], "TritRPCFramePackCheckReceipt")
self.assertEqual(data["receiptPayload"]["service"], "hyper.v1")
self.assertEqual(data["receiptPayload"]["method"], "AddVertex_a.REQ")

transcript = (out_dir / "ipc-transcript.ndjson").read_text(encoding="utf-8")
self.assertIn('"name":"tritrpc.frame.pack"', transcript)
self.assertIn('"type":"invoke"', transcript)
self.assertIn('"type":"result"', transcript)

def test_frame_pack_requires_service_method_and_json(self) -> None:
root = Path(__file__).resolve().parents[1]
out_dir = root / ".workstation" / "test-reports" / "tritrpc-frame-pack-missing-args"
cmd = [
sys.executable,
"-m",
"src.contract_runner.runner",
"--adapter",
f"{sys.executable} -m src.adapters.tritrpc_bridge_adapter",
"--out",
str(out_dir),
"--op",
"tritrpc.frame.pack",
"--args-json",
json.dumps({"service": "hyper.v1"}),
]
proc = subprocess.run(cmd, cwd=root, capture_output=True, text=True, check=False)
self.assertNotEqual(proc.returncode, 0)
self.assertIn("tritrpc.frame.pack requires", proc.stderr)


if __name__ == "__main__":
unittest.main()
Loading
Loading