From 026283f53cfd47b2f70ce3c787c1cbc103704708 Mon Sep 17 00:00:00 2001 From: Bill Date: Mon, 16 Feb 2026 21:08:33 -0700 Subject: [PATCH] Complete Step 481: phase 23b integration --- editor/CMakeLists.txt | 9 ++ editor/src/ArchitectProjectPipeline.h | 58 ++++++++++ editor/tests/step481_test.cpp | 156 ++++++++++++++++++++++++++ progress.md | 60 ++++++++++ 4 files changed, 283 insertions(+) create mode 100644 editor/src/ArchitectProjectPipeline.h create mode 100644 editor/tests/step481_test.cpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 9b7bf33..f4f2510 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -3208,4 +3208,13 @@ target_link_libraries(step480_test PRIVATE tree_sitter_javascript tree_sitter_typescript tree_sitter_java tree_sitter_rust tree_sitter_go) +add_executable(step481_test tests/step481_test.cpp) +target_include_directories(step481_test PRIVATE src) +target_link_libraries(step481_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/ArchitectProjectPipeline.h b/editor/src/ArchitectProjectPipeline.h new file mode 100644 index 0000000..9699ddc --- /dev/null +++ b/editor/src/ArchitectProjectPipeline.h @@ -0,0 +1,58 @@ +#pragma once + +// Step 481: Phase 23b Integration Pipeline +// Composes templates, scaffold planning, dependency awareness, and orchestration. + +#include "ArchitectMultiLanguageOrchestrator.h" +#include "ArchitectScaffoldGenerator.h" +#include "ArchitectTemplates.h" + +#include + +struct ArchitectPipelineResult { + TemplateOutput templated; + ScaffoldPlan scaffold; + BuildAwarenessReport awareness; + MultiLanguageWorkflowPlan workflow; +}; + +class ArchitectProjectPipeline { +public: + static ArchitectPipelineResult fromTemplate(ArchitectureTemplateKind kind, + const TemplateInput& input, + const std::string& workspaceRoot) { + ArchitectPipelineResult out; + out.templated = ArchitectTemplates::instantiate(kind, input); + out.scaffold = ArchitectScaffoldGenerator::buildPlan( + {workspaceRoot, input.projectName, out.templated.skeleton, true}); + out.awareness = ArchitectBuildAwareness::annotate(out.templated.skeleton); + out.workflow = ArchitectMultiLanguageOrchestrator::createWorkflow( + out.templated.skeleton, out.awareness); + return out; + } + + static ArchitectPipelineResult fromSkeleton(const SkeletonProjectSpec& skeleton, + const std::string& projectName, + const std::string& workspaceRoot) { + ArchitectPipelineResult out; + out.templated.kind = ArchitectureTemplateKind::RestApi; + out.templated.skeleton = skeleton; + out.templated.notes.push_back("Generated from provided skeleton"); + out.scaffold = ArchitectScaffoldGenerator::buildPlan( + {workspaceRoot, projectName, skeleton, true}); + out.awareness = ArchitectBuildAwareness::annotate(skeleton); + out.workflow = ArchitectMultiLanguageOrchestrator::createWorkflow( + skeleton, out.awareness); + return out; + } + + static SkeletonProjectSpec overrideModuleLanguage(const SkeletonProjectSpec& in, + const std::string& moduleName, + const std::string& language) { + SkeletonProjectSpec out = in; + for (auto& m : out.modules) { + if (m.moduleName == moduleName) m.language = language; + } + return out; + } +}; diff --git a/editor/tests/step481_test.cpp b/editor/tests/step481_test.cpp new file mode 100644 index 0000000..0d93639 --- /dev/null +++ b/editor/tests/step481_test.cpp @@ -0,0 +1,156 @@ +// Step 481: Phase 23b Integration + Sprint Summary Tests (8 tests) + +#include "ArchitectProjectPipeline.h" + +#include +#include + +namespace fs = std::filesystem; + +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 int sourceFileCount(const ScaffoldPlan& plan) { + int count = 0; + for (const auto& f : plan.files) { + if (f.relativePath.find("/src/") != std::string::npos || + f.relativePath.find("/internal/") != std::string::npos || + f.relativePath.find("/db/") != std::string::npos) { + ++count; + } + } + return count; +} + +void test_rest_api_template_to_scaffold_to_workflow() { + TEST(rest_api_template_to_scaffold_to_workflow); + TemplateInput in{"bookstore", "Book", {"title", "author"}, "jwt"}; + auto result = ArchitectProjectPipeline::fromTemplate( + ArchitectureTemplateKind::RestApi, in, "/tmp"); + CHECK(!result.templated.skeleton.modules.empty(), "missing skeleton modules"); + CHECK(sourceFileCount(result.scaffold) >= 5, "expected scaffold source files"); + CHECK(!result.workflow.tasks.empty(), "missing workflow tasks"); + PASS(); +} + +void test_multi_language_project_python_rust_sql_orchestrates_as_single_plan() { + TEST(multi_language_project_python_rust_sql_orchestrates_as_single_plan); + SkeletonProjectSpec sk; + sk.modules.push_back({"service", "python", "", "", {"core"}, {}}); + sk.modules.push_back({"core", "rust", "", "", {"schema"}, {}}); + sk.modules.push_back({"schema", "sql", "", "", {}, {}}); + auto result = ArchitectProjectPipeline::fromSkeleton(sk, "polyglot", "/tmp"); + CHECK(result.workflow.tasks.size() == 3, "expected 3 tasks"); + CHECK(result.workflow.links.size() >= 2, "expected cross-language links"); + CHECK(result.workflow.notes[0].find("single project plan") != std::string::npos, + "missing single-plan note"); + PASS(); +} + +void test_architect_language_change_mid_planning_replans_scaffold() { + TEST(architect_language_change_mid_planning_replans_scaffold); + TemplateInput in{"uiapp", "Widget", {"id"}, "none"}; + auto base = ArchitectProjectPipeline::fromTemplate( + ArchitectureTemplateKind::FullStack, in, "/tmp"); + auto changed = ArchitectProjectPipeline::overrideModuleLanguage( + base.templated.skeleton, "backend", "typescript"); + auto replanned = ArchitectProjectPipeline::fromSkeleton(changed, "uiapp", "/tmp"); + bool hasBackendTs = replanned.scaffold.hasFile("uiapp/src/backend/backend.ts"); + CHECK(hasBackendTs, "expected regenerated backend ts file after language change"); + PASS(); +} + +void test_all_scaffolded_source_files_contain_semanno_annotations() { + TEST(all_scaffolded_source_files_contain_semanno_annotations); + TemplateInput in{"authsvc", "Session", {"token"}, "jwt"}; + auto result = ArchitectProjectPipeline::fromTemplate( + ArchitectureTemplateKind::RestApi, in, "/tmp"); + int checked = 0; + for (const auto& f : result.scaffold.files) { + if (f.relativePath.find("/src/") == std::string::npos && + f.relativePath.find("/internal/") == std::string::npos && + f.relativePath.find("/db/") == std::string::npos) { + continue; + } + CHECK(f.content.find("@Intent") != std::string::npos, "missing @Intent in scaffolded source"); + ++checked; + } + CHECK(checked > 0, "no source files checked"); + PASS(); +} + +void test_scaffold_apply_materializes_files_and_whetstone_state() { + TEST(scaffold_apply_materializes_files_and_whetstone_state); + fs::path root = fs::temp_directory_path() / "whetstone_step481_apply"; + fs::remove_all(root); + fs::create_directories(root); + + TemplateInput in{"phase23b_apply", "Order", {"id"}, "none"}; + auto result = ArchitectProjectPipeline::fromTemplate( + ArchitectureTemplateKind::CliTool, in, root.string()); + std::string err; + CHECK(ArchitectScaffoldGenerator::applyPlan(result.scaffold, &err), ("apply failed: " + err).c_str()); + CHECK(fs::exists(root / "phase23b_apply/.whetstone/workflow_state.json"), "missing workflow state"); + CHECK(fs::exists(root / "phase23b_apply/.gitignore"), "missing .gitignore"); + fs::remove_all(root); + PASS(); +} + +void test_cross_language_links_emit_shim_and_review_flags() { + TEST(cross_language_links_emit_shim_and_review_flags); + SkeletonProjectSpec sk; + sk.modules.push_back({"frontend", "typescript", "", "", {"backend"}, {}}); + sk.modules.push_back({"backend", "python", "", "", {"data"}, {}}); + sk.modules.push_back({"data", "sql", "", "", {}, {}}); + auto result = ArchitectProjectPipeline::fromSkeleton(sk, "links", "/tmp"); + CHECK(!result.workflow.links.empty(), "expected links"); + CHECK(result.workflow.links[0].shimAnnotation.find("@Shim(") != std::string::npos, "missing shim"); + CHECK(result.workflow.links[0].reviewRequired, "expected reviewRequired"); + PASS(); +} + +void test_sidecar_files_exist_for_all_modules_in_scaffold_plan() { + TEST(sidecar_files_exist_for_all_modules_in_scaffold_plan); + TemplateInput in{"sidecars", "Entry", {"id"}, "none"}; + auto result = ArchitectProjectPipeline::fromTemplate( + ArchitectureTemplateKind::Library, in, "/tmp"); + int sidecars = 0; + for (const auto& m : result.templated.skeleton.modules) { + const std::string path = "sidecars/.whetstone/sidecars/" + m.moduleName + ".ast.json"; + if (result.scaffold.hasFile(path)) ++sidecars; + } + CHECK(sidecars == (int)result.templated.skeleton.modules.size(), "missing sidecar entries"); + PASS(); +} + +void test_phase23b_pipeline_outputs_remain_structured_for_mcp_consumers() { + TEST(phase23b_pipeline_outputs_remain_structured_for_mcp_consumers); + TemplateInput in{"mcp_shape", "Doc", {"id"}, "none"}; + auto result = ArchitectProjectPipeline::fromTemplate( + ArchitectureTemplateKind::Microservice, in, "/tmp"); + CHECK(!result.scaffold.operations.empty(), "missing operation plan"); + CHECK(result.scaffold.operations[0].method == "fileCreate", "expected fileCreate op"); + CHECK(!result.awareness.modules.empty(), "missing awareness modules"); + CHECK(!result.workflow.tasks.empty(), "missing workflow tasks"); + PASS(); +} + +int main() { + std::cout << "Step 481: Phase 23b Integration + Sprint Summary Tests\n"; + + test_rest_api_template_to_scaffold_to_workflow(); // 1 + test_multi_language_project_python_rust_sql_orchestrates_as_single_plan(); // 2 + test_architect_language_change_mid_planning_replans_scaffold(); // 3 + test_all_scaffolded_source_files_contain_semanno_annotations(); // 4 + test_scaffold_apply_materializes_files_and_whetstone_state(); // 5 + test_cross_language_links_emit_shim_and_review_flags(); // 6 + test_sidecar_files_exist_for_all_modules_in_scaffold_plan(); // 7 + test_phase23b_pipeline_outputs_remain_structured_for_mcp_consumers(); // 8 + + std::cout << "\nResults: " << passed << "/" << (passed + failed) + << " passed\n"; + return failed == 0 ? 0 : 1; +} diff --git a/progress.md b/progress.md index 194f79a..3e6836e 100644 --- a/progress.md +++ b/progress.md @@ -6816,3 +6816,63 @@ interface boundaries (`@Link`, `@Shim`) flagged for human review. - `editor/src/ArchitectMultiLanguageOrchestrator.h` within header-size limit (`175` <= `600`) - `editor/tests/step480_test.cpp` within test-file size guidance (`203` lines) - Header-only and naming conventions remain aligned with `ARCHITECTURE.md` + +### Step 481: Phase 23b Integration + Sprint Summary +**Status:** PASS (8/8 tests) + +Adds an integrated architect pipeline for Phase 23b that composes: +template instantiation, scaffold file planning/application, dependency/build +awareness, and multi-language orchestration into a single structured flow. + +**Files added:** +- `editor/src/ArchitectProjectPipeline.h` — integration composition layer: + - `ArchitectPipelineResult` aggregate output model + - `fromTemplate(...)`: + - `ArchitectTemplates` -> `ArchitectScaffoldGenerator` -> + `ArchitectBuildAwareness` -> `ArchitectMultiLanguageOrchestrator` + - `fromSkeleton(...)` for direct skeleton-based orchestration + - `overrideModuleLanguage(...)` for mid-planning stack adjustment/replan flow +- `editor/tests/step481_test.cpp` — 8 integration tests covering: + - REST API template -> scaffold -> workflow end-to-end + - multi-language Python+Rust+SQL orchestration as one project plan + - mid-planning language override and scaffold regeneration + - Semanno annotations present in scaffolded source files + - scaffold apply materialization (`.whetstone` + project files) + - cross-language shim/review flags + - sidecar generation completeness + - structured output shape for MCP consumers +- `editor/CMakeLists.txt` — `step481_test` target + +**Verification run:** +- `cmake --build editor/build-native --target step481_test step480_test` — PASS +- `./editor/build-native/step481_test` — PASS (8/8) +- `./editor/build-native/step480_test` — PASS (12/12) regression coverage + +**Architecture gate check:** +- `editor/src/ArchitectProjectPipeline.h` within header-size limit (`58` <= `600`) +- `editor/tests/step481_test.cpp` within test-file size guidance (`156` lines) +- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md` + +**Phase 23b totals (477-481):** +- **Steps:** 5 +- **Tests:** 56/56 passing +- **Headers added:** 5 + - `ArchitectTemplates.h` + - `ArchitectScaffoldGenerator.h` + - `ArchitectBuildAwareness.h` + - `ArchitectMultiLanguageOrchestrator.h` + - `ArchitectProjectPipeline.h` +- **Capabilities delivered:** + - reusable architecture templates for common project archetypes + - scaffold planning/application via `fileCreate`/`fileWrite`-compatible ops + - language-specific dependency/build hint annotation layer + - single-plan orchestration across multi-language module graphs with `@Link/@Shim` + - integrated Phase 23b pipeline with mid-planning language override/replan support + +**Sprint 23 totals (471-481):** +- **Steps:** 11 +- **Tests:** 124/124 passing +- **Headers added:** 10 +- **Outcome:** architect mode now supports requirement parsing, decomposition, + stack selection, skeleton generation, review/approval, template/scaffold + generation, dependency-aware build hints, and multi-language orchestration.