From 676145141e1411f7e82efde88b0979ee00479361 Mon Sep 17 00:00:00 2001 From: Bill Date: Tue, 17 Feb 2026 11:43:00 -0700 Subject: [PATCH] Step 598: integrate phase 34a policy governance cycle --- editor/CMakeLists.txt | 9 +++ editor/src/Phase34aIntegration.h | 90 +++++++++++++++++++++++++++ editor/tests/step598_test.cpp | 102 +++++++++++++++++++++++++++++++ progress.md | 37 +++++++++++ 4 files changed, 238 insertions(+) create mode 100644 editor/src/Phase34aIntegration.h create mode 100644 editor/tests/step598_test.cpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 6c0dc1e..9fd0306 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -4261,4 +4261,13 @@ target_link_libraries(step597_test PRIVATE tree_sitter_javascript tree_sitter_typescript tree_sitter_java tree_sitter_rust tree_sitter_go) +add_executable(step598_test tests/step598_test.cpp) +target_include_directories(step598_test PRIVATE src) +target_link_libraries(step598_test PRIVATE + nlohmann_json::nlohmann_json + unofficial::tree-sitter::tree-sitter + tree_sitter_python tree_sitter_cpp tree_sitter_elisp + tree_sitter_javascript tree_sitter_typescript + tree_sitter_java tree_sitter_rust tree_sitter_go) + # Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies) diff --git a/editor/src/Phase34aIntegration.h b/editor/src/Phase34aIntegration.h new file mode 100644 index 0000000..018334a --- /dev/null +++ b/editor/src/Phase34aIntegration.h @@ -0,0 +1,90 @@ +#pragma once +// Step 598: Phase 34a Integration + +#include "ApprovalEscalationPlanner.h" +#include "EscalationAuditLedger.h" +#include "GuardrailDriftMonitor.h" +#include "PolicyGuardrailCatalog.h" + +#include +#include + +struct Phase34aResult { + bool guardrailCatalogReady = false; + bool escalationPlannerReady = false; + bool auditLedgerReady = false; + bool driftMonitorReady = false; + bool phase34aPass = false; + int driftScore = 0; + std::vector notes; +}; + +class Phase34aIntegration { +public: + static Phase34aResult run() { + Phase34aResult r; + std::string error; + + PolicyGuardrailCatalog catalog; + r.guardrailCatalogReady = + catalog.addRule({"allow-push", "git push", GuardrailDecision::Allow, "safe push"}, &error) && + catalog.addRule({"review-deploy", "deploy", GuardrailDecision::RequireReview, "deploy review"}, &error) && + catalog.addRule({"deny-rm", "rm -rf", GuardrailDecision::Deny, "destructive"}, &error); + if (!r.guardrailCatalogReady) { + r.notes.push_back("fail:guardrail_catalog"); + return finalize(r); + } + + auto plan = ApprovalEscalationPlanner::planFor(catalog, "deploy prod"); + r.escalationPlannerReady = plan.level == EscalationLevel::Reviewer && + plan.requiresJustification && + !plan.approverRoles.empty(); + if (!r.escalationPlannerReady) { + r.notes.push_back("fail:escalation_planner"); + return finalize(r); + } + + EscalationAuditLedger ledger; + EscalationAuditEntry entry; + entry.entryId = "audit-1"; + entry.operation = "deploy prod"; + entry.decision = plan.decision; + entry.level = plan.level; + entry.actor = "architect"; + entry.outcome = "approved"; + entry.riskScore = ApprovalEscalationPlanner::riskScore(plan); + r.auditLedgerReady = ledger.record(entry, &error) && + ledger.averageRiskScore() > 0; + if (!r.auditLedgerReady) { + r.notes.push_back("fail:audit_ledger"); + return finalize(r); + } + + std::vector observations = { + {"git push origin", "allow"}, + {"deploy prod", "require_review"}, + {"rm -rf /tmp/x", "allow"} + }; + auto drift = GuardrailDriftMonitor::detect(catalog, observations); + r.driftScore = GuardrailDriftMonitor::driftScore(drift, static_cast(observations.size())); + r.driftMonitorReady = !drift.empty() && r.driftScore > 0 && + !GuardrailDriftMonitor::remediationHints(drift).empty(); + if (!r.driftMonitorReady) { + r.notes.push_back("fail:drift_monitor"); + return finalize(r); + } + + r.notes.push_back("phase34a:policy_governance_cycle_ready"); + return finalize(r); + } + +private: + static Phase34aResult finalize(Phase34aResult r) { + r.phase34aPass = r.guardrailCatalogReady && + r.escalationPlannerReady && + r.auditLedgerReady && + r.driftMonitorReady; + if (!r.phase34aPass) r.notes.push_back("phase34a:blocked"); + return r; + } +}; diff --git a/editor/tests/step598_test.cpp b/editor/tests/step598_test.cpp new file mode 100644 index 0000000..c28993b --- /dev/null +++ b/editor/tests/step598_test.cpp @@ -0,0 +1,102 @@ +// Step 598: Phase 34a Integration (8 tests) + +#include "Phase34aIntegration.h" + +#include + +static int passed = 0, failed = 0; +#define TEST(name) { std::cout << " " << #name << "... "; } +#define PASS() { std::cout << "PASS\n"; ++passed; } +#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; } +#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {} + +static bool hasNote(const Phase34aResult& r, const std::string& note) { + for (const auto& n : r.notes) if (n == note) return true; + return false; +} + +void test_full_phase34a_cycle_passes() { + TEST(full_phase34a_cycle_passes); + auto r = Phase34aIntegration::run(); + CHECK(r.phase34aPass, "phase should pass"); + CHECK(r.guardrailCatalogReady, "catalog should be ready"); + CHECK(r.escalationPlannerReady, "planner should be ready"); + CHECK(r.auditLedgerReady, "ledger should be ready"); + CHECK(r.driftMonitorReady, "drift monitor should be ready"); + CHECK(hasNote(r, "phase34a:policy_governance_cycle_ready"), "success note missing"); + PASS(); +} + +void test_guardrail_catalog_signal_true_on_pass() { + TEST(guardrail_catalog_signal_true_on_pass); + auto r = Phase34aIntegration::run(); + CHECK(r.phase34aPass, "phase should pass"); + CHECK(r.guardrailCatalogReady, "catalog flag should be true"); + PASS(); +} + +void test_escalation_planner_signal_true_on_pass() { + TEST(escalation_planner_signal_true_on_pass); + auto r = Phase34aIntegration::run(); + CHECK(r.phase34aPass, "phase should pass"); + CHECK(r.escalationPlannerReady, "planner flag should be true"); + PASS(); +} + +void test_audit_ledger_signal_true_on_pass() { + TEST(audit_ledger_signal_true_on_pass); + auto r = Phase34aIntegration::run(); + CHECK(r.phase34aPass, "phase should pass"); + CHECK(r.auditLedgerReady, "ledger flag should be true"); + PASS(); +} + +void test_drift_monitor_signal_true_on_pass() { + TEST(drift_monitor_signal_true_on_pass); + auto r = Phase34aIntegration::run(); + CHECK(r.phase34aPass, "phase should pass"); + CHECK(r.driftMonitorReady, "drift flag should be true"); + CHECK(r.driftScore > 0, "drift score should be positive"); + PASS(); +} + +void test_no_blocked_note_on_success() { + TEST(no_blocked_note_on_success); + auto r = Phase34aIntegration::run(); + CHECK(r.phase34aPass, "phase should pass"); + CHECK(!hasNote(r, "phase34a:blocked"), "blocked note should not appear"); + PASS(); +} + +void test_notes_include_only_success_marker_on_pass() { + TEST(notes_include_only_success_marker_on_pass); + auto r = Phase34aIntegration::run(); + CHECK(r.phase34aPass, "phase should pass"); + CHECK(r.notes.size() == 1, "expected one success note"); + PASS(); +} + +void test_phase_flag_matches_component_conjunction() { + TEST(phase_flag_matches_component_conjunction); + auto r = Phase34aIntegration::run(); + const bool conjunction = r.guardrailCatalogReady && r.escalationPlannerReady && + r.auditLedgerReady && r.driftMonitorReady; + CHECK(r.phase34aPass == conjunction, "phase flag should equal conjunction"); + PASS(); +} + +int main() { + std::cout << "Step 598: Phase 34a Integration\n"; + + test_full_phase34a_cycle_passes(); // 1 + test_guardrail_catalog_signal_true_on_pass(); // 2 + test_escalation_planner_signal_true_on_pass(); // 3 + test_audit_ledger_signal_true_on_pass(); // 4 + test_drift_monitor_signal_true_on_pass(); // 5 + test_no_blocked_note_on_success(); // 6 + test_notes_include_only_success_marker_on_pass();// 7 + test_phase_flag_matches_component_conjunction(); // 8 + + std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n"; + return failed == 0 ? 0 : 1; +} diff --git a/progress.md b/progress.md index e6acc1e..4caf480 100644 --- a/progress.md +++ b/progress.md @@ -11471,3 +11471,40 @@ observed runtime outcomes, with remediation hint generation. - `editor/src/GuardrailDriftMonitor.h` within header-size limit (`58` <= `600`) - `editor/tests/step597_test.cpp` within test-file size guidance (`156` lines) - Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md` + +### Step 598: Phase 34a Integration +**Status:** PASS (8/8 tests) + +Integrates Phase 34a governance components into one policy lifecycle: +guardrail evaluation, escalation planning, audit capture, and drift detection. + +**Files added:** +- `editor/src/Phase34aIntegration.h` - Phase 34a integration module: + - guardrail catalog bootstrap and evaluation + - escalation plan validation path + - audit ledger recording and risk aggregation path + - drift detection/scoring/remediation path + - phase pass synthesis with readiness notes +- `editor/tests/step598_test.cpp` - 8 tests covering: + - full phase pass path + - component readiness signal behavior + - note emission behavior + - phase flag conjunction behavior + +**Files modified:** +- `editor/CMakeLists.txt` - `step598_test` target + +**Verification run:** +- `cmake -S editor -B editor/build-native` - PASS +- `cmake --build editor/build-native --target step598_test step597_test` - PASS +- `./editor/build-native/step598_test` - PASS (8/8) +- `./editor/build-native/step597_test` - PASS (12/12) regression coverage + +**Architecture gate check:** +- `editor/src/Phase34aIntegration.h` within header-size limit (`90` <= `600`) +- `editor/tests/step598_test.cpp` within test-file size guidance (`102` lines) +- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md` + +**Phase 34a totals (594-598):** +- **Steps completed:** 5 +- **New tests in this phase plan:** 56/56 passing