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
8 changes: 5 additions & 3 deletions depone/verify/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,11 @@ def _health_entry_matches_gate(
return (
entry.code == "ERR_HEALTH_GATE_VIOLATION"
and gate.get("exit_code_path") == entry.evidence_path
and f"gate={gate.get('gate')!r}" in entry.message
and f"tool={gate.get('tool')!r}" in entry.message
and f"enforcement={gate.get('enforcement')!r}" in entry.message
and entry.health_gate == {
"gate": gate.get("gate"),
"tool": gate.get("tool"),
"enforcement": gate.get("enforcement"),
}
)


Expand Down
6 changes: 6 additions & 0 deletions depone/verify/evidence_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class EvidenceContractEntry:
code: str
message: str
evidence_path: str
health_gate: dict[str, str] | None = None


_EVIDENCE_CONTRACT_FILENAME = "evidence-contract.json"
Expand Down Expand Up @@ -852,6 +853,11 @@ def _validate_code_health(
f"expected={expected_exit_code}, got={actual_exit_code}"
),
evidence_path=exit_code_path,
health_gate={
"gate": gate["gate"],
"tool": gate["tool"],
"enforcement": enforcement,
},
)
)
return results
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "depone"
version = "0.2.9"
version = "0.2.10"
description = "Workflow designer + cross-platform evidence verifier for AI agent orchestration"
license = { text = "MIT" }
readme = "README.md"
Expand Down
52 changes: 50 additions & 2 deletions tests/test_code_health_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@

from depone.verify.adapters.base import EvidenceContext, EvidenceFile
from depone.verify.adapters.generic import read_evidence
from depone.verify.engine import _health_conformance, run_verification
from depone.verify.evidence_contract import validate_evidence_contract
from depone.verify.engine import (
_health_conformance,
_health_entry_matches_gate,
_is_advisory_health_entry,
run_verification,
)
from depone.verify.evidence_contract import EvidenceContractEntry, validate_evidence_contract


def _sha(text: str) -> str:
Expand Down Expand Up @@ -94,10 +99,53 @@ def test_advisory_gate_failure_records_health_violation_details(self) -> None:

self.assertEqual([entry.code for entry in errors], ["ERR_HEALTH_GATE_VIOLATION"])
self.assertEqual(errors[0].evidence_path, "health/complexity.exit")
self.assertEqual(
errors[0].health_gate,
{
"gate": "complexity",
"tool": "ruff-c901",
"enforcement": "advisory",
},
)
self.assertIn("gate='complexity'", errors[0].message)
self.assertIn("tool='ruff-c901'", errors[0].message)
self.assertIn("enforcement='advisory'", errors[0].message)

def test_health_classification_uses_typed_metadata_not_message(self) -> None:
gate = _gate("complexity", "ruff-c901", "advisory")
matching = EvidenceContractEntry(
code="ERR_HEALTH_GATE_VIOLATION",
message="mangled operator message",
evidence_path="health/complexity.exit",
health_gate={
"gate": "complexity",
"tool": "ruff-c901",
"enforcement": "advisory",
},
)
conflicting = EvidenceContractEntry(
code="ERR_HEALTH_GATE_VIOLATION",
message=(
"code health gate exit code mismatch: gate='complexity', "
"tool='ruff-c901', enforcement='advisory'"
),
evidence_path="health/complexity.exit",
health_gate={
"gate": "complexity",
"tool": "ruff-c901",
"enforcement": "block",
},
)

self.assertTrue(_health_entry_matches_gate(matching, gate))
self.assertTrue(
_is_advisory_health_entry({"code_health": {"gates": [gate]}}, matching)
)
self.assertFalse(_health_entry_matches_gate(conflicting, gate))
self.assertFalse(
_is_advisory_health_entry({"code_health": {"gates": [gate]}}, conflicting)
)

def test_block_gate_failure_records_health_violation(self) -> None:
errors = validate_evidence_contract(
_evidence(
Expand Down
Loading