From e8c8c56115ef21aedeb05a73f71369d918841b12 Mon Sep 17 00:00:00 2001 From: Bill Date: Mon, 16 Feb 2026 22:20:51 -0700 Subject: [PATCH] Complete Step 496: self-annotated modernization workflow --- editor/CMakeLists.txt | 9 ++ editor/src/SelfModernizationWorkflow.h | 157 ++++++++++++++++++++++++ editor/tests/step496_test.cpp | 159 +++++++++++++++++++++++++ progress.md | 38 ++++++ 4 files changed, 363 insertions(+) create mode 100644 editor/src/SelfModernizationWorkflow.h create mode 100644 editor/tests/step496_test.cpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index c0a8d28..2a4604a 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -3343,4 +3343,13 @@ target_link_libraries(step495_test PRIVATE tree_sitter_javascript tree_sitter_typescript tree_sitter_java tree_sitter_rust tree_sitter_go) +add_executable(step496_test tests/step496_test.cpp) +target_include_directories(step496_test PRIVATE src) +target_link_libraries(step496_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/SelfModernizationWorkflow.h b/editor/src/SelfModernizationWorkflow.h new file mode 100644 index 0000000..f6682ef --- /dev/null +++ b/editor/src/SelfModernizationWorkflow.h @@ -0,0 +1,157 @@ +#pragma once + +// Step 496: Self-Annotated Workflow +// Models modernization workflow for AnnotationValidator.h. + +#include "Pipeline.h" + +#include +#include + +enum class ModernizationRuleKind { + SimpleRule, + ComplexRule, + NewDiagnosticCode +}; + +struct ModernizationRuleSpec { + std::string ruleId; + std::string description; + ModernizationRuleKind kind = ModernizationRuleKind::SimpleRule; + std::string targetDiagnosticCode; // e.g. E1491 +}; + +struct ModernizationTask { + std::string taskId; + std::string ruleId; + std::string routeTo; // deterministic | llm | human + bool reviewRequired = false; + std::string priority; + std::vector dependencies; + std::string generatedCode; // deterministic output if executed + bool outputValid = false; +}; + +struct ModernizationWorkflowReport { + std::string targetFile; + std::vector rules; + std::vector tasks; + int deterministicCount = 0; + int llmCount = 0; + int humanCount = 0; + int deterministicValidCount = 0; + std::vector notes; +}; + +class SelfModernizationWorkflow { +public: + static std::vector defaultRules() { + return { + {"rule_owner_single_alias_guard", + "Add explicit owner aliasing diagnostic for nested assignment chains", + ModernizationRuleKind::SimpleRule, "E1491"}, + {"rule_deallocate_location_required", + "Strengthen deallocate validation with location semantics", + ModernizationRuleKind::SimpleRule, "E1492"}, + {"rule_cross_subject_consistency", + "Validate cross-subject annotation consistency between risk/owner/lifetime", + ModernizationRuleKind::ComplexRule, "E1493"}, + {"rule_recursive_tailcall_guard", + "Validate recursive visitor tail-call annotations across nested traversals", + ModernizationRuleKind::ComplexRule, "E1494"}, + {"rule_new_diagnostic_code_registry", + "Reserve and validate new diagnostic code range for modernization rules", + ModernizationRuleKind::NewDiagnosticCode, "E1495"} + }; + } + + static ModernizationWorkflowReport createAndRun(const std::string& targetFile, + const std::vector& rules = + defaultRules()) { + ModernizationWorkflowReport out; + out.targetFile = targetFile; + out.rules = rules; + + for (size_t i = 0; i < rules.size(); ++i) { + ModernizationTask t; + t.taskId = "self-modernize-" + std::to_string(i + 1); + t.ruleId = rules[i].ruleId; + routeTask(rules[i], t); + out.tasks.push_back(t); + } + + executeDeterministic(out.tasks, rules, out); + out.notes.push_back("Modernization workflow created for AnnotationValidator self-improvement"); + return out; + } + +private: + static void routeTask(const ModernizationRuleSpec& rule, ModernizationTask& task) { + if (rule.kind == ModernizationRuleKind::SimpleRule) { + task.routeTo = "deterministic"; + task.priority = "high"; + task.reviewRequired = false; + return; + } + if (rule.kind == ModernizationRuleKind::ComplexRule) { + task.routeTo = "llm"; + task.priority = "high"; + task.reviewRequired = true; + return; + } + task.routeTo = "human"; + task.priority = "critical"; + task.reviewRequired = true; + } + + static void executeDeterministic(std::vector& tasks, + const std::vector& rules, + ModernizationWorkflowReport& out) { + for (auto& task : tasks) { + if (task.routeTo == "deterministic") { + const auto* rule = findRule(rules, task.ruleId); + task.generatedCode = generateDeterministicSnippet(*rule); + task.outputValid = validateSnippet(task.generatedCode); + out.deterministicCount++; + if (task.outputValid) out.deterministicValidCount++; + } else if (task.routeTo == "llm") { + out.llmCount++; + } else if (task.routeTo == "human") { + out.humanCount++; + } + } + } + + static const ModernizationRuleSpec* findRule(const std::vector& rules, + const std::string& ruleId) { + for (const auto& r : rules) if (r.ruleId == ruleId) return &r; + return &rules.front(); + } + + static std::string generateDeterministicSnippet(const ModernizationRuleSpec& rule) { + std::string fn = "validate_" + rule.ruleId; + for (auto& c : fn) if (c == '-') c = '_'; + return + "bool " + fn + "(const ASTNode* node, std::vector& diags) {\n" + " if (!node) return true;\n" + " // STUB: " + rule.description + "\n" + " if (node->id.empty()) {\n" + " diags.push_back({\"warning\", \"" + rule.targetDiagnosticCode + ": missing node id\", \"\"});\n" + " return false;\n" + " }\n" + " return true;\n" + "}\n"; + } + + static bool validateSnippet(const std::string& snippet) { + Pipeline p; + std::vector diags; + const std::string src = + "#include \n#include \n" + "struct ASTNode { std::string id; };\n" + "struct AnnotationValidator { struct Diagnostic { std::string severity; std::string message; std::string nodeId; }; };\n" + + snippet; + auto mod = p.parse(src, "cpp", diags); + return mod != nullptr; + } +}; diff --git a/editor/tests/step496_test.cpp b/editor/tests/step496_test.cpp new file mode 100644 index 0000000..c8d4e84 --- /dev/null +++ b/editor/tests/step496_test.cpp @@ -0,0 +1,159 @@ +// Step 496: Self-Annotated Workflow Tests (12 tests) + +#include "SelfModernizationWorkflow.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 ModernizationWorkflowReport runDefault() { + return SelfModernizationWorkflow::createAndRun("editor/src/AnnotationValidator.h"); +} + +void test_workflow_targets_annotationvalidator_header() { + TEST(workflow_targets_annotationvalidator_header); + auto r = runDefault(); + CHECK(r.targetFile.find("AnnotationValidator.h") != std::string::npos, "wrong target file"); + PASS(); +} + +void test_default_rules_include_simple_complex_and_new_diagnostic_categories() { + TEST(default_rules_include_simple_complex_and_new_diagnostic_categories); + auto rules = SelfModernizationWorkflow::defaultRules(); + bool hasSimple = false, hasComplex = false, hasNewDiag = false; + for (const auto& rule : rules) { + if (rule.kind == ModernizationRuleKind::SimpleRule) hasSimple = true; + if (rule.kind == ModernizationRuleKind::ComplexRule) hasComplex = true; + if (rule.kind == ModernizationRuleKind::NewDiagnosticCode) hasNewDiag = true; + } + CHECK(hasSimple && hasComplex && hasNewDiag, "missing expected rule categories"); + PASS(); +} + +void test_simple_rules_route_to_deterministic() { + TEST(simple_rules_route_to_deterministic); + auto r = runDefault(); + bool found = false; + for (const auto& t : r.tasks) if (t.routeTo == "deterministic") found = true; + CHECK(found, "expected deterministic tasks"); + PASS(); +} + +void test_complex_rules_route_to_llm() { + TEST(complex_rules_route_to_llm); + auto r = runDefault(); + bool found = false; + for (const auto& t : r.tasks) if (t.routeTo == "llm") found = true; + CHECK(found, "expected llm tasks"); + PASS(); +} + +void test_new_diagnostic_code_rules_route_to_human_review() { + TEST(new_diagnostic_code_rules_route_to_human_review); + auto r = runDefault(); + bool found = false; + for (const auto& t : r.tasks) { + if (t.routeTo == "human") { + found = true; + CHECK(t.reviewRequired, "human routed task must require review"); + } + } + CHECK(found, "expected human-routed task"); + PASS(); +} + +void test_deterministic_execution_generates_nonempty_code() { + TEST(deterministic_execution_generates_nonempty_code); + auto r = runDefault(); + for (const auto& t : r.tasks) { + if (t.routeTo == "deterministic") { + CHECK(!t.generatedCode.empty(), "deterministic task missing generated code"); + } + } + PASS(); +} + +void test_deterministic_generated_code_parses_as_valid_cpp() { + TEST(deterministic_generated_code_parses_as_valid_cpp); + auto r = runDefault(); + for (const auto& t : r.tasks) { + if (t.routeTo == "deterministic") { + CHECK(t.outputValid, "deterministic output should parse"); + } + } + PASS(); +} + +void test_workflow_summary_counts_match_task_routing() { + TEST(workflow_summary_counts_match_task_routing); + auto r = runDefault(); + int det = 0, llm = 0, human = 0; + for (const auto& t : r.tasks) { + if (t.routeTo == "deterministic") det++; + else if (t.routeTo == "llm") llm++; + else if (t.routeTo == "human") human++; + } + CHECK(r.deterministicCount == det, "deterministic count mismatch"); + CHECK(r.llmCount == llm, "llm count mismatch"); + CHECK(r.humanCount == human, "human count mismatch"); + PASS(); +} + +void test_deterministic_valid_count_is_not_greater_than_deterministic_count() { + TEST(deterministic_valid_count_is_not_greater_than_deterministic_count); + auto r = runDefault(); + CHECK(r.deterministicValidCount <= r.deterministicCount, "invalid deterministic valid count"); + PASS(); +} + +void test_each_task_has_stable_task_id_and_rule_id() { + TEST(each_task_has_stable_task_id_and_rule_id); + auto r = runDefault(); + for (const auto& t : r.tasks) { + CHECK(t.taskId.find("self-modernize-") == 0, "task id prefix mismatch"); + CHECK(!t.ruleId.empty(), "rule id missing"); + } + PASS(); +} + +void test_rule_diagnostic_codes_use_e149x_range() { + TEST(rule_diagnostic_codes_use_e149x_range); + auto rules = SelfModernizationWorkflow::defaultRules(); + for (const auto& r : rules) { + CHECK(r.targetDiagnosticCode.find("E149") == 0, "diagnostic code range mismatch"); + } + PASS(); +} + +void test_report_contains_completion_note() { + TEST(report_contains_completion_note); + auto r = runDefault(); + CHECK(!r.notes.empty(), "missing notes"); + CHECK(r.notes[0].find("self-improvement") != std::string::npos, "missing completion note"); + PASS(); +} + +int main() { + std::cout << "Step 496: Self-Annotated Workflow Tests\n"; + + test_workflow_targets_annotationvalidator_header(); // 1 + test_default_rules_include_simple_complex_and_new_diagnostic_categories(); // 2 + test_simple_rules_route_to_deterministic(); // 3 + test_complex_rules_route_to_llm(); // 4 + test_new_diagnostic_code_rules_route_to_human_review(); // 5 + test_deterministic_execution_generates_nonempty_code(); // 6 + test_deterministic_generated_code_parses_as_valid_cpp(); // 7 + test_workflow_summary_counts_match_task_routing(); // 8 + test_deterministic_valid_count_is_not_greater_than_deterministic_count(); // 9 + test_each_task_has_stable_task_id_and_rule_id(); // 10 + test_rule_diagnostic_codes_use_e149x_range(); // 11 + test_report_contains_completion_note(); // 12 + + std::cout << "\nResults: " << passed << "/" << (passed + failed) + << " passed\n"; + return failed == 0 ? 0 : 1; +} diff --git a/progress.md b/progress.md index 82a9928..9646f99 100644 --- a/progress.md +++ b/progress.md @@ -7473,3 +7473,41 @@ metrics. - `editor/src/SelfHostTranspileAudit.h` within header-size limit (`178` <= `600`) - `editor/tests/step495_test.cpp` within test-file size guidance (`139` lines) - Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md` + +### Step 496: Self-Annotated Workflow +**Status:** PASS (12/12 tests) + +Adds a self-modernization workflow model targeting +`editor/src/AnnotationValidator.h`, with rule-level routing across +deterministic, LLM, and human-review paths and deterministic output +validity checks. + +**Files added:** +- `editor/src/SelfModernizationWorkflow.h` — self-improvement workflow layer: + - `ModernizationRuleSpec`, `ModernizationTask`, `ModernizationWorkflowReport` + - `defaultRules()` for validator modernization rule set + - routing policy: + - simple rules -> `deterministic` + - complex rules -> `llm` + review + - new diagnostic code rules -> `human` + critical priority + - deterministic execution path generating validator rule stubs + - deterministic output validation via C++ parser (`Pipeline::parse`) + - aggregate routing and deterministic-validity metrics +- `editor/tests/step496_test.cpp` — 12 tests covering: + - target file and default rule taxonomy + - routing behavior by rule complexity/type + - deterministic code generation and parser-valid output checks + - workflow summary/count consistency + - diagnostic-code range semantics + - completion-note presence +- `editor/CMakeLists.txt` — `step496_test` target + +**Verification run:** +- `cmake --build editor/build-native --target step496_test step495_test` — PASS +- `./editor/build-native/step496_test` — PASS (12/12) +- `./editor/build-native/step495_test` — PASS (12/12) regression coverage + +**Architecture gate check:** +- `editor/src/SelfModernizationWorkflow.h` within header-size limit (`157` <= `600`) +- `editor/tests/step496_test.cpp` within test-file size guidance (`159` lines) +- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`