All checks were successful
ci / validate (push) Successful in 2m51s
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0726e-5232-73f2-aaca-2c05ceb62efb
212 lines
9.7 KiB
Python
212 lines
9.7 KiB
Python
"""Real-rein acceptance fixture for GLAS-WP-0012; never overrides readiness."""
|
|
|
|
import argparse
|
|
import json
|
|
import subprocess
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
from sandboxer.core.manager import SandboxManager
|
|
from sandboxer.lifecycle.store import SandboxStore
|
|
from sandboxer.payments.credits import CreditsStore
|
|
from sandboxer.snapshots.store import SnapshotStore
|
|
|
|
from glas_harness.contract import ExecutionRequest, Rein
|
|
from glas_harness.gateway import run_execution
|
|
from glas_harness.profiles import ProfileCatalog
|
|
from glas_harness.reins.rein_aharness import ReinAharness
|
|
|
|
|
|
# Executed inside the sandbox; results contain only booleans and a Git object id.
|
|
INSPECTOR = r'''
|
|
import json, os, stat, subprocess, sys
|
|
from pathlib import Path
|
|
baseline, source, task, request_id = sys.argv[1:]
|
|
def git(*args):
|
|
return subprocess.check_output(['git', *args], stderr=subprocess.DEVNULL,
|
|
timeout=10)
|
|
head = git('rev-parse', 'HEAD').decode().strip()
|
|
artifact = Path('PROOF.md')
|
|
expected = b'Glas local profile proof.\n'
|
|
checks = {
|
|
'one_commit': git('rev-list', '--parents', '-n', '1', 'HEAD').decode().split()
|
|
== [head, baseline],
|
|
'only_expected_path': git('diff-tree', '--no-commit-id', '--name-only', '-r',
|
|
'-z', 'HEAD') == b'PROOF.md\x00',
|
|
'clean_worktree': not git('status', '--porcelain', '--untracked-files=all',
|
|
'--ignored=matching').strip(),
|
|
'regular_artifact': artifact.is_file() and not artifact.is_symlink(),
|
|
'worktree_content': artifact.is_file() and artifact.read_bytes() == expected,
|
|
'committed_content': git('show', 'HEAD:PROOF.md') == expected,
|
|
'source_absent': not Path(source).exists(),
|
|
'task_private': stat.S_IMODE(Path(task).stat().st_mode) == 0o600,
|
|
'identity_exact': os.environ.get('SANDBOXER_ACTOR') == 'agt'
|
|
and os.environ.get('SANDBOXER_PROJECT') == 'glas-local-proof'
|
|
and os.environ.get('SANDBOXER_RUN_ID') == request_id,
|
|
}
|
|
print(json.dumps({'head': head, 'checks': checks}))
|
|
'''
|
|
|
|
CHECKS = {
|
|
"one_commit", "only_expected_path", "clean_worktree", "regular_artifact",
|
|
"worktree_content", "committed_content", "source_absent", "task_private",
|
|
"identity_exact",
|
|
}
|
|
|
|
|
|
class ObservedRein(Rein):
|
|
"""Observe the catalog-built adapter without replacing its agent dispatch."""
|
|
|
|
def __init__(self, delegate, source):
|
|
self.delegate = delegate
|
|
self.source = source
|
|
self.workspace = None
|
|
self.request_id = None
|
|
self.checks = {}
|
|
self.task_removed = False
|
|
|
|
def start_session(self, profile, inputs, sandbox):
|
|
reachability = sandbox.reachability
|
|
if not reachability.get("workspace_dir") or reachability.get("ssh"):
|
|
raise RuntimeError("local proof requires an owner-managed local workspace")
|
|
self.workspace = reachability["workspace_dir"]
|
|
self.request_id = inputs["request_id"]
|
|
return self.delegate.start_session(profile, inputs, sandbox)
|
|
|
|
def dispatch_tool(self, session, tool_call):
|
|
return self.delegate.dispatch_tool(session, tool_call)
|
|
|
|
def end_session(self, session):
|
|
summary = self.delegate.end_session(session)
|
|
if summary.outcome != "succeeded":
|
|
return summary
|
|
result = session["transport"].run(
|
|
["/usr/bin/python3", "-c", INSPECTOR, session["head_before"],
|
|
str(self.source), session["task_file"], self.request_id], timeout=30,
|
|
)
|
|
if result.returncode:
|
|
raise RuntimeError("sandbox artifact inspection failed")
|
|
try:
|
|
report = json.loads(result.stdout)
|
|
checks = report["checks"]
|
|
self.checks = {key: checks.get(key) is True for key in CHECKS}
|
|
self.checks["head_matches_summary"] = report["head"] == summary.commit_sha
|
|
except (ValueError, KeyError, TypeError, AttributeError) as exc:
|
|
raise RuntimeError("invalid sandbox artifact inspection") from exc
|
|
if not all(self.checks.values()):
|
|
raise RuntimeError("sandbox artifact acceptance failed")
|
|
return summary
|
|
|
|
def cleanup_session(self, session):
|
|
self.delegate.cleanup_session(session)
|
|
proc = session["transport"].run(
|
|
["test", "!", "-e", session["task_file"]], timeout=15
|
|
)
|
|
self.task_removed = proc.returncode == 0
|
|
if not self.task_removed:
|
|
raise RuntimeError("generated task file survived cleanup")
|
|
|
|
|
|
def select_candidate(reference, catalog):
|
|
if "@" not in reference:
|
|
raise ValueError("proof requires an exact version-pinned profile")
|
|
profile, descriptor = catalog.resolve(reference)
|
|
catalog.require_operational(profile)
|
|
if (profile.id != "harness.agent-dev-local" or descriptor.id != "rein-aharness"
|
|
or profile.model.route != "claude-code-cli"
|
|
or profile.model.provider != "anthropic"):
|
|
raise ValueError("proof requires the reviewed local Claude route")
|
|
if not profile.credential_route_refs:
|
|
raise ValueError("proof requires declared credential route references")
|
|
if (not profile.limits.timeout_seconds or profile.limits.timeout_seconds > 900
|
|
or not profile.limits.budget_tokens or profile.limits.budget_tokens > 60000):
|
|
raise ValueError("proof requires explicit bounded token and time limits")
|
|
delegate = catalog.build_rein(profile, descriptor)
|
|
if type(delegate) is not ReinAharness:
|
|
raise ValueError("proof requires the actual ReinAharness adapter")
|
|
return profile, delegate
|
|
|
|
|
|
def git(source, *args):
|
|
return subprocess.check_output(["git", *args], cwd=source,
|
|
stderr=subprocess.DEVNULL, timeout=15)
|
|
|
|
|
|
def prove(reference, catalog):
|
|
# This gate precedes even the disposable fixture and sandbox manager.
|
|
profile, delegate = select_candidate(reference, catalog)
|
|
with tempfile.TemporaryDirectory(prefix="glas-real-rein-proof-") as directory:
|
|
root = Path(directory)
|
|
source = root / "source"
|
|
source.mkdir()
|
|
git(source, "init", "-q")
|
|
git(source, "config", "user.name", "Glas Acceptance")
|
|
git(source, "config", "user.email", "proof@example.invalid")
|
|
(source / "sentinel").write_bytes(b"unchanged\n")
|
|
git(source, "add", "sentinel")
|
|
git(source, "commit", "-qm", "fixture")
|
|
source_head = git(source, "rev-parse", "HEAD")
|
|
manager = SandboxManager(
|
|
store=SandboxStore(path=root / "sandboxes.json"),
|
|
credits=CreditsStore(path=root / "credits.json"),
|
|
snapshots=SnapshotStore(path=root / "snapshots.json"),
|
|
)
|
|
observed = ObservedRein(delegate, source)
|
|
result = run_execution(ExecutionRequest(
|
|
harness_profile_ref=reference, repo=str(source), title="local profile proof",
|
|
description=("Create only PROOF.md containing exactly 'Glas local profile proof.' "
|
|
"followed by one newline. Make exactly one local commit. "
|
|
"Leave the working tree clean. Do not push or change other files."),
|
|
actor="agt", project="glas-local-proof", report_to_hub=False,
|
|
), catalog=catalog, rein=observed, manager=manager)
|
|
source_unchanged = (
|
|
(source / "sentinel").read_bytes() == b"unchanged\n"
|
|
and git(source, "rev-parse", "HEAD") == source_head
|
|
and not git(source, "status", "--porcelain", "--untracked-files=all",
|
|
"--ignored=matching").strip()
|
|
)
|
|
status = manager.store.get(result.evidence.sandbox_id) if result.evidence.sandbox_id else None
|
|
destroyed = status is not None and status.state.value == "destroyed"
|
|
workspace_removed = bool(observed.workspace) and not Path(observed.workspace).exists()
|
|
passed = (result.ok and bool(observed.checks) and all(observed.checks.values())
|
|
and observed.task_removed and source_unchanged and destroyed
|
|
and workspace_removed)
|
|
# Do not print tool_output, tool_error, exceptions, prompts, or raw owner stdout.
|
|
return {
|
|
"acceptance_passed": passed, "profile_ref": reference,
|
|
"profile_readiness": profile.operational_readiness.status,
|
|
"sandbox_profile": profile.sandbox_profile,
|
|
"requested_model": profile.model.model,
|
|
"model_route": profile.model.route,
|
|
"credential_route_refs": profile.credential_route_refs,
|
|
"limits": profile.limits.model_dump(exclude_none=True),
|
|
"request_id": result.evidence.request_id,
|
|
"sandbox_id": result.evidence.sandbox_id,
|
|
"commit_sha": result.evidence.commit_sha,
|
|
"outcome": result.evidence.outcome,
|
|
"failure_stage": result.evidence.failure_stage,
|
|
"artifact_checks": observed.checks,
|
|
"source_unchanged": source_unchanged,
|
|
"task_removed_before_teardown": observed.task_removed,
|
|
"destroyed": destroyed, "workspace_removed": workspace_removed,
|
|
"readiness_review_required": True,
|
|
}
|
|
|
|
|
|
def main(argv=None):
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--harness-profile", required=True)
|
|
parser.add_argument("--profile-dir", type=Path)
|
|
args = parser.parse_args(argv)
|
|
try:
|
|
report = prove(args.harness_profile, ProfileCatalog(profile_dir=args.profile_dir))
|
|
except Exception as exc:
|
|
# Configuration/provider errors can contain secret values; expose only the type.
|
|
report = {"acceptance_passed": False, "error_type": type(exc).__name__,
|
|
"readiness_review_required": True}
|
|
print(json.dumps(report, indent=2))
|
|
return 0 if report["acceptance_passed"] else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|