diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index b936464..87aae0c 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -3262,4 +3262,13 @@ target_link_libraries(step486_test PRIVATE tree_sitter_javascript tree_sitter_typescript tree_sitter_java tree_sitter_rust tree_sitter_go) +add_executable(step487_test tests/step487_test.cpp) +target_include_directories(step487_test PRIVATE src) +target_link_libraries(step487_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/SelfHostingIntegration.h b/editor/src/SelfHostingIntegration.h new file mode 100644 index 0000000..f7dac02 --- /dev/null +++ b/editor/src/SelfHostingIntegration.h @@ -0,0 +1,80 @@ +#pragma once + +// Step 487: Phase 23c Integration +// Validates full self-hosting data flow without invoking a real worker agent. + +#include "PriorStepContextInjector.h" +#include "ProjectConventionAnalyzer.h" +#include "StepSpecExpander.h" +#include "TestPlanGenerator.h" + +#include +#include + +struct SelfHostingInput { + std::string repoRoot = "."; + std::string stepMarkdown; + std::string stepNumber; + std::string componentName; + std::vector priorHeaders; + std::vector knownGoodFiles; + std::vector knownBrokenFiles; +}; + +struct SelfHostingResult { + ProjectConventions conventions; + StepContext context; + StepSpec spec; + GeneratedTestPlan testPlan; + ConventionValidationReport goodReport; + ConventionValidationReport brokenReport; + bool workerReady = false; + std::vector notes; +}; + +class SelfHostingIntegration { +public: + static SelfHostingResult run(const SelfHostingInput& in) { + SelfHostingResult out; + out.conventions = ProjectConventionAnalyzer::extract(in.repoRoot); + out.context = PriorStepContextInjector::build(in.priorHeaders); + out.spec = StepSpecExpander::expand({ + in.stepMarkdown, + in.stepNumber, + in.componentName, + "cmake", + {}, + in.priorHeaders + }); + out.testPlan = TestPlanGenerator::generate({ + in.stepMarkdown, + in.stepNumber, + in.componentName, + {}, + StepComplexity::Standard, + false + }); + + out.goodReport = ProjectConventionAnalyzer::validate(out.conventions, in.knownGoodFiles); + out.brokenReport = ProjectConventionAnalyzer::validate(out.conventions, in.knownBrokenFiles); + + out.workerReady = isWorkerReady(out); + out.notes.push_back("Flow executed: conventions -> context -> spec -> test plan"); + out.notes.push_back(out.workerReady + ? "Worker brief sufficiency checks passed" + : "Worker brief sufficiency checks failed"); + return out; + } + +private: + static bool isWorkerReady(const SelfHostingResult& r) { + const bool hasSpec = !r.spec.testPlan.empty() && + !r.spec.headerSkeleton.methods.empty() && + !r.spec.buildEntry.targetName.empty(); + const bool hasContext = !r.context.priorApis.empty(); + const bool hasConventions = r.conventions.sizeLimits.count("header") && + r.conventions.sizeLimits.count("main.cpp"); + const bool hasPlan = !r.testPlan.tests.empty(); + return hasSpec && hasContext && hasConventions && hasPlan; + } +}; diff --git a/editor/tests/step487_test.cpp b/editor/tests/step487_test.cpp new file mode 100644 index 0000000..a0dd9a9 --- /dev/null +++ b/editor/tests/step487_test.cpp @@ -0,0 +1,126 @@ +// Step 487: Phase 23c Integration Tests (integration, regression) + +#include "SelfHostingIntegration.h" + +#include +#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 SelfHostingInput sampleInput() { + SelfHostingInput in; + in.repoRoot = "."; + in.stepMarkdown = + "Run convention extractor, context injector, step expander, and test plan generator " + "for workflow pipeline dispatch validation."; + in.stepNumber = "487"; + in.componentName = "SelfHostingIntegration"; + in.priorHeaders = { + "editor/src/StepSpecExpander.h", + "editor/src/ProjectConventionAnalyzer.h", + "editor/src/PriorStepContextInjector.h", + "editor/src/TestPlanGenerator.h" + }; + in.knownGoodFiles = { + {"editor/src/GoodStep.h", "struct GoodStep { int x; };"}, + {"editor/tests/step900_test.cpp", + "#define CHECK(a,b) do{}while(0)\nint main(){ CHECK(true, \"ok\"); return 0; }"}, + {"editor/CMakeLists.txt", "add_executable(step900_test tests/step900_test.cpp)\n"} + }; + in.knownBrokenFiles = { + {"editor/src/bad_step.h", "struct bad_step { int x; };\n"}, + {"editor/tests/step901_test.cpp", "int main(){ return 0; }\n"}, + {"editor/CMakeLists.txt", "add_executable(other tests/other.cpp)\n"} + }; + return in; +} + +void test_flow_populates_conventions_context_spec_and_testplan() { + TEST(flow_populates_conventions_context_spec_and_testplan); + auto r = SelfHostingIntegration::run(sampleInput()); + CHECK(!r.context.priorApis.empty(), "missing context apis"); + CHECK(!r.spec.testPlan.empty(), "missing step spec test plan"); + CHECK(!r.testPlan.tests.empty(), "missing generated test plan"); + CHECK(r.conventions.buildSystem == "cmake", "missing conventions build system"); + PASS(); +} + +void test_worker_readiness_is_true_for_realistic_step_input() { + TEST(worker_readiness_is_true_for_realistic_step_input); + auto r = SelfHostingIntegration::run(sampleInput()); + CHECK(r.workerReady, "expected workerReady true"); + PASS(); +} + +void test_generated_test_plan_uses_pipeline_integration_heuristic() { + TEST(generated_test_plan_uses_pipeline_integration_heuristic); + auto r = SelfHostingIntegration::run(sampleInput()); + CHECK(r.testPlan.hasType(PlannedTestType::Integration), "expected integration tests"); + PASS(); +} + +void test_good_completed_step_has_zero_convention_violations() { + TEST(good_completed_step_has_zero_convention_violations); + auto r = SelfHostingIntegration::run(sampleInput()); + CHECK(r.goodReport.violations.empty(), "known-good step should have no violations"); + PASS(); +} + +void test_broken_step_triggers_convention_violations() { + TEST(broken_step_triggers_convention_violations); + auto r = SelfHostingIntegration::run(sampleInput()); + CHECK(!r.brokenReport.violations.empty(), "broken step should trigger violations"); + CHECK(r.brokenReport.hasViolation("CLASS_NAMING_MISMATCH"), "missing class naming violation"); + CHECK(r.brokenReport.hasViolation("TEST_ASSERTION_MISSING"), "missing assertion violation"); + CHECK(r.brokenReport.hasViolation("BUILD_TARGET_MISSING"), "missing cmake violation"); + PASS(); +} + +void test_notes_record_data_flow_and_sufficiency_status() { + TEST(notes_record_data_flow_and_sufficiency_status); + auto r = SelfHostingIntegration::run(sampleInput()); + CHECK(r.notes.size() >= 2, "missing notes"); + CHECK(r.notes[0].find("conventions -> context -> spec -> test plan") != std::string::npos, + "missing flow note"); + PASS(); +} + +void test_context_includes_prior_step_api_summaries() { + TEST(context_includes_prior_step_api_summaries); + auto r = SelfHostingIntegration::run(sampleInput()); + bool foundStepSpec = false; + for (const auto& api : r.context.priorApis) { + if (api.name == "StepSpec") foundStepSpec = true; + } + CHECK(foundStepSpec, "expected StepSpec in context summaries"); + PASS(); +} + +void test_regression_step486_still_passes() { + TEST(regression_step486_still_passes); + auto r = SelfHostingIntegration::run(sampleInput()); + CHECK(r.testPlan.tests.size() >= 6, "unexpected plan shrinkage"); + CHECK(r.spec.buildEntry.targetName == "step487_test", "unexpected step build target"); + PASS(); +} + +int main() { + std::cout << "Step 487: Phase 23c Integration Tests\n"; + + test_flow_populates_conventions_context_spec_and_testplan(); // 1 + test_worker_readiness_is_true_for_realistic_step_input(); // 2 + test_generated_test_plan_uses_pipeline_integration_heuristic(); // 3 + test_good_completed_step_has_zero_convention_violations(); // 4 + test_broken_step_triggers_convention_violations(); // 5 + test_notes_record_data_flow_and_sufficiency_status(); // 6 + test_context_includes_prior_step_api_summaries(); // 7 + test_regression_step486_still_passes(); // 8 + + std::cout << "\nResults: " << passed << "/" << (passed + failed) + << " passed\n"; + return failed == 0 ? 0 : 1; +} diff --git a/progress.md b/progress.md index e151a5a..195ef17 100644 --- a/progress.md +++ b/progress.md @@ -7072,3 +7072,70 @@ test counts. - `editor/src/TestPlanGenerator.h` within header-size limit (`191` <= `600`) - `editor/tests/step486_test.cpp` within test-file size guidance (`118` lines) - Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md` + +### Step 487: Phase 23c Integration +**Status:** PASS (8/8 tests) + +Completes Phase 23c by validating the full self-hosting data flow: +sprint step description -> conventions extraction -> prior-context +injection -> step spec expansion -> adaptive test plan generation -> +output validation on known-good and deliberately-broken step artifacts. + +**Files added:** +- `editor/src/SelfHostingIntegration.h` — phase integration composition: + - `SelfHostingInput`, `SelfHostingResult` + - `run(...)` flow: + - `ProjectConventionAnalyzer::extract(...)` + - `PriorStepContextInjector::build(...)` + - `StepSpecExpander::expand(...)` + - `TestPlanGenerator::generate(...)` + - convention validation for known-good and known-broken step files + - worker-readiness sufficiency gate (`workerReady`) over spec/context/ + conventions/test-plan completeness +- `editor/tests/step487_test.cpp` — 8 integration/regression tests covering: + - full flow population of conventions/context/spec/test-plan + - worker readiness sufficiency for realistic step input + - pipeline heuristic propagation into generated test types + - zero-violation validation for known-good step output + - violation detection for deliberately-broken output + - flow-note and context-summary checks + - regression expectation alignment with Step 486 behavior +- `editor/CMakeLists.txt` — `step487_test` target + +**Verification run:** +- `cmake --build editor/build-native --target step487_test step486_test` — PASS +- `./editor/build-native/step487_test` — PASS (8/8) +- `./editor/build-native/step486_test` — PASS (10/10) regression coverage + +**Architecture gate check:** +- `editor/src/SelfHostingIntegration.h` within header-size limit (`80` <= `600`) +- `editor/tests/step487_test.cpp` within test-file size guidance (`126` lines) +- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md` + +**Phase 23c totals (482-487):** +- **Steps:** 6 +- **Tests:** 54/54 passing +- **Headers added:** 6 + - `StepSpecExpander.h` + - `ProjectConventionAnalyzer.h` + - `PriorStepContextInjector.h` + - `WorkerDispatchValidator.h` + - `TestPlanGenerator.h` + - `SelfHostingIntegration.h` +- **Capabilities delivered:** + - step-to-spec expansion with complexity-bounded test planning + - machine-readable convention extraction + warning validator + - prior-step API context briefing for worker prompts + - dispatch/retry/escalation protocol model for architect-worker handoff + - adaptive typed test-plan generation (taxonomy-aware) + - end-to-end self-hosting protocol validation + +**Final Sprint 23 totals (471-487):** +- **Steps:** 17 +- **Tests:** 178/178 passing +- **Headers added:** 16 +- **Outcome:** architect mode now spans full planning stack and self-hosting + protocol: requirements -> decomposition -> stack selection -> skeleton -> + review -> templates/scaffolding -> build/dependency awareness -> + multi-language orchestration -> step spec/context/convention/test-plan + synthesis -> dispatch/validation -> phase-level integration validation.