Complete Step 496: self-annotated modernization workflow
This commit is contained in:
@@ -3343,4 +3343,13 @@ target_link_libraries(step495_test PRIVATE
|
|||||||
tree_sitter_javascript tree_sitter_typescript
|
tree_sitter_javascript tree_sitter_typescript
|
||||||
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
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)
|
# Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies)
|
||||||
|
|||||||
157
editor/src/SelfModernizationWorkflow.h
Normal file
157
editor/src/SelfModernizationWorkflow.h
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Step 496: Self-Annotated Workflow
|
||||||
|
// Models modernization workflow for AnnotationValidator.h.
|
||||||
|
|
||||||
|
#include "Pipeline.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<std::string> dependencies;
|
||||||
|
std::string generatedCode; // deterministic output if executed
|
||||||
|
bool outputValid = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ModernizationWorkflowReport {
|
||||||
|
std::string targetFile;
|
||||||
|
std::vector<ModernizationRuleSpec> rules;
|
||||||
|
std::vector<ModernizationTask> tasks;
|
||||||
|
int deterministicCount = 0;
|
||||||
|
int llmCount = 0;
|
||||||
|
int humanCount = 0;
|
||||||
|
int deterministicValidCount = 0;
|
||||||
|
std::vector<std::string> notes;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SelfModernizationWorkflow {
|
||||||
|
public:
|
||||||
|
static std::vector<ModernizationRuleSpec> 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<ModernizationRuleSpec>& 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<ModernizationTask>& tasks,
|
||||||
|
const std::vector<ModernizationRuleSpec>& 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<ModernizationRuleSpec>& 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<AnnotationValidator::Diagnostic>& 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<ParseDiagnostic> diags;
|
||||||
|
const std::string src =
|
||||||
|
"#include <string>\n#include <vector>\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;
|
||||||
|
}
|
||||||
|
};
|
||||||
159
editor/tests/step496_test.cpp
Normal file
159
editor/tests/step496_test.cpp
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
// Step 496: Self-Annotated Workflow Tests (12 tests)
|
||||||
|
|
||||||
|
#include "SelfModernizationWorkflow.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
38
progress.md
38
progress.md
@@ -7473,3 +7473,41 @@ metrics.
|
|||||||
- `editor/src/SelfHostTranspileAudit.h` within header-size limit (`178` <= `600`)
|
- `editor/src/SelfHostTranspileAudit.h` within header-size limit (`178` <= `600`)
|
||||||
- `editor/tests/step495_test.cpp` within test-file size guidance (`139` lines)
|
- `editor/tests/step495_test.cpp` within test-file size guidance (`139` lines)
|
||||||
- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`
|
- 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`
|
||||||
|
|||||||
Reference in New Issue
Block a user