feat: securely prepare verification roots
This commit is contained in:
@@ -6,6 +6,7 @@ from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
SCRIPT = ROOT / "harness/agents/impl/skills/gitea-issue-rework/scripts/evidence_manifest.py"
|
||||
PREPARE_SCRIPT = ROOT / "harness/lib/verification_root.py"
|
||||
CACHE = ROOT / "harness/operations/repository-cache.md"
|
||||
SKILLS = {
|
||||
"implementation": ROOT / "harness/agents/impl/skills/gitea-issue-implementation/SKILL.md",
|
||||
@@ -39,20 +40,41 @@ class VerificationContractDocumentationTests(unittest.TestCase):
|
||||
assert match is not None
|
||||
block = match.group(1).replace("\\\n", " ")
|
||||
commands = [line for line in block.splitlines() if line.startswith("python3 ")]
|
||||
self.assertEqual(len(commands), 2)
|
||||
for op, command in zip(("run", "validate"), commands):
|
||||
self.assertEqual(len(commands), 3)
|
||||
for op, command in zip(("prepare", "run", "validate"), commands):
|
||||
with self.subTest(skill=path.parent.name, op=op):
|
||||
help_result = subprocess.run([sys.executable, str(SCRIPT), op, "--help"], text=True, capture_output=True)
|
||||
self.assertEqual(help_result.returncode, 0)
|
||||
supported = set(re.findall(r"--[a-z-]+", help_result.stdout))
|
||||
declared = set(re.findall(r"--[a-z-]+", command))
|
||||
required = {"--contract-path", "--repo-root", "--artifact-root"} | ({"--plan", "--output"} if op == "run" else {"--manifest"})
|
||||
self.assertEqual(declared, required)
|
||||
self.assertTrue(declared <= supported)
|
||||
if op == "prepare":
|
||||
self.assertIn("harness/lib/verification_root.py", command)
|
||||
help_result = subprocess.run(
|
||||
[sys.executable, str(PREPARE_SCRIPT), op, "--help"],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
)
|
||||
self.assertEqual(help_result.returncode, 0, help_result.stderr)
|
||||
supported = set(re.findall(r"--[a-z-]+", help_result.stdout))
|
||||
required = {"--root", "--owner", "--repository", "--issue", "--run-id", "--handle"}
|
||||
self.assertEqual(declared, required)
|
||||
self.assertTrue(declared <= supported)
|
||||
else:
|
||||
help_result = subprocess.run([sys.executable, str(SCRIPT), op, "--help"], text=True, capture_output=True)
|
||||
self.assertEqual(help_result.returncode, 0)
|
||||
supported = set(re.findall(r"--[a-z-]+", help_result.stdout))
|
||||
required = {"--contract-path", "--repo-root", "--artifact-root"} | ({"--plan", "--output"} if op == "run" else {"--manifest"})
|
||||
self.assertEqual(declared, required)
|
||||
self.assertTrue(declared <= supported)
|
||||
self.assertIn("exact current HEAD", section)
|
||||
self.assertIn("validate-legacy", section)
|
||||
self.assertIn("exclusion 없음", section)
|
||||
|
||||
def test_prepare_contract_binds_root_and_forbids_recursive_parent_creation(self):
|
||||
for path in (CACHE, SKILLS["implementation"], SKILLS["rework"]):
|
||||
with self.subTest(path=path.name):
|
||||
text = path.read_text(encoding="utf-8")
|
||||
self.assertIn("exact harness root", text)
|
||||
self.assertIn("Path.mkdir(parents=True, mode=0o700)", text)
|
||||
self.assertIn("자동 chmod", text)
|
||||
|
||||
def test_checkout_cleanup_preserves_verification_without_recursive_delete(self):
|
||||
text = CACHE.read_text()
|
||||
cleanup = text.split("## Worktree 실패 처리와 제거", 1)[1].split("## Credential 안전", 1)[0]
|
||||
|
||||
Reference in New Issue
Block a user