Files
Codewhale/scripts/check-command-session-proof.py
CodeWhale Bot ad5eb28462 refactor(protocol): share Runtime wire contracts and generated SDK types [skip ci]
Refs CW-7704 and CW-7764.

Runtime SDK event/image/dynamic-tool declarations were separate from the
server structs. Move the existing 10-type Runtime family to the serde-only
App Server protocol leaf, migrate all 24 repository Rust consumers and delete
the old module. Keep native Engine/session/pricing/turn authority in place.

Reuse the existing Native host schema renderer for Rust-generated Runtime
JSON/TypeScript exports. Distinguish serialized output required/null fields
from valid input defaults; publish a separate serialized spec view of the
same Rust type. Native host generated output remains byte-identical. Move
the existing UI fixture helper onto App and migrate 23 callers so the
runtime-to-UI boundary ratchet passes without a new allowance.

Validation on 63 logical paths / 2338 frozen input hashes:
- Ordinary CLI build passed 331.682s; five affected lib test builds passed 420.276s.
- 10 moved serialization checks + 2 explicitly authorized schema cases passed.
- Both strict SDK type checks passed, including exactOptionalPropertyTypes.
- Existing focused checks passed: Engine 1, TUI 4, App Server 2; Native host
  generated output is exact. Artifact runner's final kind-count was corrected
  from 2 to 3 after independently verifying all actual subprocess exits/counts;
  no passing test was reexecuted.
- Boundary/config/navigation/session source checks passed; config/navigation
  use actual all-target normal Cargo trees. Prior failed invocations retained.
- Authenticated ordinary Runtime history/info + genuine SSE output-schema
  control passed: 0 model POSTs, process/pipe/socket cleanup gates passed.
  The finite SSE client closes deliberately; no server EOF/resume claim.

Full Codex methods/initialization/WS/tools/subscriptions/interactions,
P04 accounting, installed/native-platform/release evidence remain open.
No hosted CI, paid provider, installation, signing or publication ran.
Source receipt 80afa4de60858786bf67309666aab7447f28095f5a9c6950d91136377b33d015
Patch 0845ad69ed203637e1c7d6059120763b37772fde9481aeef46aab69c89a3d30f
2026-11-02 10:46:56 -08:00

63 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""Require the actual whole session group and a normal graph without host services.
Source inclusion compiles all transitive helpers and inline tests, without stubs.
Cargo compilation remains the authority for Rust name/type resolution. This guard
also catches architecture drift which compiles but imports runtime infrastructure.
"""
from pathlib import Path
import argparse
import re
ROOT = Path(__file__).resolve().parent.parent
GROUP = "crates/tui/src/commands/groups/session/mod.rs"
PROOF = "tests/portable-session/src/commands/groups/mod.rs"
ALLOWED_WORKSPACE = {
"codewhale-portable-session", "codewhale-command-contract",
"codewhale-protocol", "codewhale-app-server-protocol", "codewhale-sanitize",
}
FORBIDDEN_SERVICES = {
"tokio", "reqwest", "hyper", "rusqlite", "sqlx", "keyring", "dbus",
"zbus", "secret-service", "ratatui", "crossterm",
}
def graph_violations(graph):
names = {line.split()[0] for line in graph.splitlines() if line.strip()}
return [f"unapproved normal dependency: {name}" for name in sorted(names)
if (name.startswith("codewhale-") and name not in ALLOWED_WORKSPACE)
or name in FORBIDDEN_SERVICES]
def violations(root):
errors = []
wrapper = root / PROOF
text = wrapper.read_text()
includes = re.findall(r'#\[path\s*=\s*"([^"]+)"\]\s*pub mod session;', text)
if len(includes) != 1 or (wrapper.parent / includes[0]).resolve() != (root / GROUP).resolve():
errors.append("proof must include the actual session group root, not a selected leaf or stub")
for path in sorted((root / GROUP).parent.rglob("*.rs")):
# Exclude comments, but retain cfg(test) code: its dependency closure matters.
source = "\n".join(line.split("//")[0] for line in path.read_text().splitlines())
if re.search(r'\b(?:crate::(?:tui|remote_control|commands::(?:traits|contract|CommandResult))|AppAction|codewhale_(?:core|secrets|tui|runtime))\b', source):
errors.append(f"host dependency in session closure: {path.relative_to(root)}")
return errors
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--graph", type=Path)
args = parser.parse_args()
errors = violations(ROOT)
if args.graph:
errors += graph_violations(args.graph.read_text())
for error in errors:
print(f"[session-proof] FAIL: {error}")
if not errors:
print("[session-proof] PASS: actual complete group and approved dependency boundary")
return bool(errors)
if __name__ == "__main__":
raise SystemExit(main())