Lab 02: First AI Coding Agent
Elementary
Due: 2026-03-17
Terminal window
1.
Section titled “1. governance.py — Governance Layer”
2.
Section titled “2. agent.py — Agent Main Loop”
3.
Section titled “3. test_governance.py — Policy Tests”
test_governance.py
Objectives
Section titled “Objectives”- Implement a first agent using the
anthropicPython SDK - Build a HOTL governance layer with 4-level risk classification (
LOW,MEDIUM,HIGH,CRITICAL) - Construct a structured audit logging system in JSON Lines format
- Validate governance logic with policy tests
Environment Setup
Section titled “Environment Setup”mkdir lab-02 && cd lab-02python -m venv venvsource venv/bin/activate # Windows: venv\Scripts\activatepip install anthropic python-dotenv pytestImplementation Requirements
Section titled “Implementation Requirements”1. governance.py — Governance Layer
Section titled “1. governance.py — Governance Layer”from enum import Enumimport jsonimport sysfrom datetime import datetime, timezone
class ActionRisk(Enum): LOW = "low" MEDIUM = "medium" HIGH = "high" CRITICAL = "critical"
def log_action(action: str, risk: ActionRisk, approved: bool, reason: str = "") -> dict: """Records an audit log entry in JSON Lines format.""" entry = { "timestamp": datetime.now(timezone.utc).isoformat(), "action": action[:100], "risk": risk.value, "approved": approved, "reason": reason, } with open("audit.jsonl", "a") as f: f.write(json.dumps(entry, ensure_ascii=False) + "\n") return entry
def require_human_approval(action: str) -> bool: """Requests user approval for HIGH risk actions.""" print(f"\n⚠️ HIGH RISK ACTION detected:\n{action}\n") response = input("Do you approve? (yes/no): ") return response.lower() == "yes"
def governance_check(action: str, risk: ActionRisk) -> bool: """Allows or denies an action based on its risk level.""" # CRITICAL: always deny if risk == ActionRisk.CRITICAL: log_action(action, risk, False, reason="CRITICAL auto-denied") print(f"\n🚫 CRITICAL ACTION auto-denied: {action[:50]}") return False
# HIGH: requires human approval if risk == ActionRisk.HIGH: approved = require_human_approval(action) log_action(action, risk, approved, reason="human approved" if approved else "human denied") return approved
# LOW, MEDIUM: auto-approved log_action(action, risk, True, reason="auto-approved") return True2. agent.py — Agent Main Loop
Section titled “2. agent.py — Agent Main Loop”Implement a Claude API agent that integrates the governance layer.
3. test_governance.py — Policy Tests
Section titled “3. test_governance.py — Policy Tests”import jsonfrom pathlib import Pathfrom governance import ActionRisk, governance_check, log_action
AUDIT_FILE = "audit.jsonl"
def setup_function(): """Reset audit log before each test.""" Path(AUDIT_FILE).unlink(missing_ok=True)
def test_critical_always_denied(): """CRITICAL risk actions must always be denied.""" result = governance_check("rm -rf /", ActionRisk.CRITICAL) assert result is False logs = Path(AUDIT_FILE).read_text().strip().split("\n") entry = json.loads(logs[-1]) assert entry["approved"] is False assert entry["risk"] == "critical"
def test_low_auto_approved(): """LOW risk actions must be auto-approved.""" result = governance_check("read file", ActionRisk.LOW) assert result is True logs = Path(AUDIT_FILE).read_text().strip().split("\n") entry = json.loads(logs[-1]) assert entry["approved"] is True
def test_audit_log_is_jsonl(): """Audit log must be valid JSON Lines format.""" log_action("test action", ActionRisk.LOW, True) log_action("test action 2", ActionRisk.MEDIUM, True) logs = Path(AUDIT_FILE).read_text().strip().split("\n") assert len(logs) == 2 for line in logs: entry = json.loads(line) # Test fails if parsing fails assert "timestamp" in entry assert "action" in entry assert "risk" in entry- Implement code (
governance.py,agent.py) - Run execution test with
python agent.py - Verify Hard Interrupt behavior when a HIGH risk action is triggered
- Confirm that CRITICAL risk actions are auto-denied
- Confirm policy tests pass with
pytest test_governance.py -v - Verify
audit.jsonlcontent is valid JSON Lines - Submit PR
Deliverables
Section titled “Deliverables”Submit a PR to assignments/lab-02/[student-id]/:
-
governance.py— 4-level risk classification + JSON Lines logging -
agent.py— Governance-integrated agent -
test_governance.py— Policy tests (minimum 3) -
audit.jsonlsample — Minimum 5 action records (valid JSON Lines) -
README.md— Design decisions and test results