#!/usr/bin/env python3 """ Pipeline Demo — end-to-end walkthrough of all pipeline modules. Demonstrates: 1. Confidence Ladder (5-level Verdict) 2. Rejection Envelope (4-field blocked action) 3. State Gate (pre-merge completeness check) 4. Expertise file (per-cron compounding memory) Run: python -m pipeline.demo """ import json import sys import os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from pipeline.confidence_ladder import Verdict, VerdictLevel, VerdictReport from pipeline.rejection_envelope import RejectionEnvelope, Blocker from pipeline.state_gate import StateGate, FieldSpec, PipelineState from pipeline.expertise import append_entry, render_context, purge_domain def hr(title: str): print(f"\n{'=' * 60}") print(f" {title}") print(f"{'=' * 60}") # ═══════════════════════════════════════════════════════════════════════════════ # 1. STATE INIT # ═══════════════════════════════════════════════════════════════════════════════ hr("1. STATE INIT — PipelineState with core_fields") state = PipelineState( { "plan_file": "plans/feat-123.md", "branch_name": "feat/instant-polls", "issue_number": 42, "rogue_field": "should be silently dropped", }, core_fields=["plan_file", "branch_name", "issue_number", "backend_port", "frontend_port"], ) print(f" plan_file: {state.get('plan_file')}") print(f" branch_name: {state.get('branch_name')}") print(f" issue_number: {state.get('issue_number')}") print(f" rogue dropped: {state.get('rogue_field')}") # should be None assert state.get("rogue_field") is None, "rogue fields are silently dropped" # ═══════════════════════════════════════════════════════════════════════════════ # 2. PLAN PHASE — PERFECT # ═══════════════════════════════════════════════════════════════════════════════ hr("2. PLAN PHASE — Verdict: PERFECT") report = VerdictReport(pipeline_id="demo-2026-06-11") report.add(Verdict( VerdictLevel.PERFECT, "Plan covers all acceptance criteria with test coverage map", evidence=["AC1 coverage: tests/test_instant_polls.py", "AC2 coverage: tests/test_instant_polls.py"], source="plan-review", )) print(f" Ve rdict: {report.aggregate_label}") print(f" Pass? {report.passed}") # ═══════════════════════════════════════════════════════════════════════════════ # 3. BUILD PHASE — VERIFIED # ═══════════════════════════════════════════════════════════════════════════════ hr("3. BUILD PHASE — Verdict: VERIFIED") state.update(backend_port=9105, frontend_port=9205) report.add(Verdict( VerdictLevel.VERIFIED, "Build completed, CI confirmed all 14 tests pass", evidence=["exit code 0", "CI run #4185: all tests green"], source="ci", )) print(f" Verdict: {report.aggregate_label}") print(f" Pass? {report.passed}") print(f" Verdicts: {len(report.verdicts)} phases so far") # ═══════════════════════════════════════════════════════════════════════════════ # 4. SECURITY REVIEW — PARTIAL (the critical gate) # ═══════════════════════════════════════════════════════════════════════════════ hr("4. SECURITY REVIEW — Verdict: PARTIAL (green-but-dead check)") report.add(Verdict( VerdictLevel.PARTIAL, "Static analysis clean, dependency scan clean — but no live penetration test was run", evidence=["semgrep: 0 findings", "pip audit: 0 known vulns", "NOTE: no live pen test — needs staging env"], source="security-review", )) print(f" Verdict: {report.aggregate_label}") print(f" Pass? {report.passed} (PARTIAL = green + documented gap)") print(f" Blocked for merge? {report.aggregate.is_blocking}") print() print(" ▶ THIS is the green-but-dead prevention:") print(" The pipeline passes (green) but the security gap is") print(" documented, not forgotten. The reviewer knows what's missing.") assert report.aggregate == VerdictLevel.PARTIAL assert report.passed is True assert report.aggregate.is_blocking is False # ═══════════════════════════════════════════════════════════════════════════════ # 5. REJECTION ENVELOPE — leader tries to write a file # ═══════════════════════════════════════════════════════════════════════════════ hr("5. REJECTION ENVELOPE — leader blocked from writing files") blocker = Blocker( name="no_direct_write", match=lambda a: a.get("tool") in ("write_file", "patch", "execute_code"), reject=lambda a: RejectionEnvelope.block( received=a.get("tool", "unknown"), reason="LEADER_MUST_NOT_WRITE_FILES", allowed="Use delegate_task with a writer subagent", hint="Leaders read, delegate, synthesize. Delegate file writes.", ), ) # This gets blocked blocked = blocker.evaluate({"tool": "write_file", "path": "src/main.py"}) print(f" Action: write_file('src/main.py')") print(f" Result: BLOCKED") print(f" Reason: {blocked.reason}") print(f" Allowed: {blocked.allowed}") print(f" Hint: {blocked.hint}") print(f" Timestamp: {blocked.timestamp}") assert blocked is not None # This passes through allowed = blocker.evaluate({"tool": "read_file", "path": "state.json"}) print(f"\n Action: read_file('state.json')") print(f" Result: {'PASSES THROUGH (not blocked)' if allowed is None else 'BLOCKED'}") # ═══════════════════════════════════════════════════════════════════════════════ # 6. STATE GATE — pre-merge completeness check # ═══════════════════════════════════════════════════════════════════════════════ hr("6. STATE GATE — pre-merge completeness check") ship_gate = StateGate( FieldSpec("plan_file", required=True, predicate=lambda v: isinstance(v, str) and v.startswith("plans/")), FieldSpec("branch_name", required=True), FieldSpec("issue_number", required=True, type_hint=int), FieldSpec("backend_port", required=True, type_hint=int), FieldSpec("frontend_port", required=True, type_hint=int), label="pre-ship", ) # Complete state should pass result = ship_gate.validate(state) print(f" Fields checked: {result.fields_checked}") print(f" Pass: {result.passed}") if result.missing: print(f" Missing: {result.missing}") assert result.passed, "Complete state should pass ship gate" # Incomplete state should fail incomplete = PipelineState( {"plan_file": "plans/feat-123.md", "branch_name": "feat/instant-polls"}, core_fields=["plan_file", "branch_name", "issue_number", "backend_port", "frontend_port"], ) fail_result = ship_gate.validate(incomplete) print(f"\n --- With missing fields ---") print(f" Pass: {fail_result.passed}") print(f" Missing: {fail_result.missing}") assert not fail_result.passed assert "issue_number" in fail_result.missing # ═══════════════════════════════════════════════════════════════════════════════ # 7. EXPERTISE — store what was learned # ═══════════════════════════════════════════════════════════════════════════════ hr("7. EXPERTISE — store what the run learned") append_entry( "demo-pipeline", domain="pipeline", insight="PARTIAL verdict is the key innovation — it lets documented gaps pass without blocking, preventing green-but-dead", source="cron:pipeline-demo", verified=True, ) append_entry( "demo-pipeline", domain="confidence-ladder", insight="VERIFIED level requires independent confirmation (CI, review) — the agent trusting itself is only PERFECT", source="cron:pipeline-demo", verified=True, ) append_entry( "demo-pipeline", domain="state-gate", insight="Core_fields filter ensures no rogue keys leak into pipeline state — strict struct, not a dict", source="cron:pipeline-demo", verified=False, ) print(render_context("demo-pipeline")) # ═══════════════════════════════════════════════════════════════════════════════ # 8. JSON PORTABILITY # ═══════════════════════════════════════════════════════════════════════════════ hr("8. JSON PORTABILITY — serializable for cron/API delivery") serialized = report.to_json() restored = VerdictReport.from_json(serialized) print(f" Round-trip aggregate matches: {restored.aggregate == report.aggregate}") print(f" Verdict count: {len(restored.verdicts)}") print(f"\n Final JSON payload (compact):") print(f" {json.dumps(json.loads(serialized), indent=2)}") # ═══════════════════════════════════════════════════════════════════════════════ # CLEANUP # ═══════════════════════════════════════════════════════════════════════════════ purge_domain("demo-pipeline", "pipeline") purge_domain("demo-pipeline", "confidence-ladder") purge_domain("demo-pipeline", "state-gate") if __name__ == "__main__": print(f"\n{'=' * 60}") print(f" ✅ DEMO COMPLETE — all 8 stages verified") print(f"{'=' * 60}")