diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 8e53f1b..b13158b 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -7364,3 +7364,44 @@ target_link_libraries(step867_test PRIVATE nlohmann_json::nlohmann_json unoffici add_executable(step868_test tests/step868_test.cpp) target_include_directories(step868_test PRIVATE src) target_link_libraries(step868_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) + +# Sprint 64: Cost-Aware Transpilation Planning (Steps 869-878) +add_executable(step869_test tests/step869_test.cpp) +target_include_directories(step869_test PRIVATE src) +target_link_libraries(step869_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) + +add_executable(step870_test tests/step870_test.cpp) +target_include_directories(step870_test PRIVATE src) +target_link_libraries(step870_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) + +add_executable(step871_test tests/step871_test.cpp) +target_include_directories(step871_test PRIVATE src) +target_link_libraries(step871_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) + +add_executable(step872_test tests/step872_test.cpp) +target_include_directories(step872_test PRIVATE src) +target_link_libraries(step872_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) + +add_executable(step873_test tests/step873_test.cpp) +target_include_directories(step873_test PRIVATE src) +target_link_libraries(step873_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) + +add_executable(step874_test tests/step874_test.cpp) +target_include_directories(step874_test PRIVATE src) +target_link_libraries(step874_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) + +add_executable(step875_test tests/step875_test.cpp) +target_include_directories(step875_test PRIVATE src) +target_link_libraries(step875_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) + +add_executable(step876_test tests/step876_test.cpp) +target_include_directories(step876_test PRIVATE src) +target_link_libraries(step876_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) + +add_executable(step877_test tests/step877_test.cpp) +target_include_directories(step877_test PRIVATE src) +target_link_libraries(step877_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) + +add_executable(step878_test tests/step878_test.cpp) +target_include_directories(step878_test PRIVATE src) +target_link_libraries(step878_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) diff --git a/editor/src/MCPServer.h b/editor/src/MCPServer.h index f21a998..5ef66fe 100644 --- a/editor/src/MCPServer.h +++ b/editor/src/MCPServer.h @@ -735,4 +735,8 @@ private: #include "mcp/RegisterFailureTelemetryTools.h" #include "graduation/HintModelInterface.h" #include "mcp/RegisterAdapterHintsTools.h" +#include "graduation/PortingCostModel.h" +#include "graduation/MultiPlanAlternativeGenerator.h" +#include "graduation/BudgetPolicyEnforcer.h" +#include "mcp/RegisterCostPlanningTools.h" #include "mcp/RegisterOnboardingAndAllTools.h" diff --git a/editor/src/Sprint64IntegrationSummary.h b/editor/src/Sprint64IntegrationSummary.h new file mode 100644 index 0000000..03f1e01 --- /dev/null +++ b/editor/src/Sprint64IntegrationSummary.h @@ -0,0 +1,25 @@ +#pragma once +// Step 878: Sprint 64 integration summary — Cost-Aware Transpilation Planning +#include +#include + +struct Sprint64IntegrationSummary { + static constexpr int sprintNumber = 64; + static constexpr int stepsCompleted = 10; + static constexpr const char* theme = "Cost-Aware Transpilation Planning"; + + static bool verify() { + return sprintNumber == 64 && stepsCompleted == 10; + } + + static nlohmann::json toJson() { + return { + {"sprint", sprintNumber}, + {"steps", stepsCompleted}, + {"theme", theme}, + {"status", "complete"}, + {"tools_added", {"whetstone_plan_transpilation_run", "whetstone_estimate_porting_cost"}}, + {"policy_rule", "Over-budget plans require explicit reviewer approval token."} + }; + } +}; diff --git a/editor/src/graduation/BudgetPolicyEnforcer.h b/editor/src/graduation/BudgetPolicyEnforcer.h new file mode 100644 index 0000000..1e8974a --- /dev/null +++ b/editor/src/graduation/BudgetPolicyEnforcer.h @@ -0,0 +1,52 @@ +#pragma once +// Step 873: Budget policy enforcer. +#include +#include + +struct BudgetPolicy { + float maxTotalCost = 1.0f; + bool requireApprovalTokenForOverage = true; +}; + +struct BudgetEnforcementResult { + std::string pairId; + bool withinBudget = false; + bool requiresApprovalToken = false; + float requestedCost = 0.0f; + float budgetLimit = 0.0f; + std::string decision; // "approved", "requires_token", "rejected" +}; + +class BudgetPolicyEnforcer { +public: + static BudgetEnforcementResult enforce(const std::string& pairId, + float requestedCost, + const BudgetPolicy& policy, + bool hasApprovalToken = false) { + BudgetEnforcementResult r; + r.pairId = pairId; + r.requestedCost = requestedCost; + r.budgetLimit = policy.maxTotalCost; + r.withinBudget = requestedCost <= policy.maxTotalCost; + if (r.withinBudget) { + r.decision = "approved"; + } else if (policy.requireApprovalTokenForOverage && hasApprovalToken) { + r.requiresApprovalToken = false; + r.decision = "approved"; + } else if (policy.requireApprovalTokenForOverage) { + r.requiresApprovalToken = true; + r.decision = "requires_token"; + } else { + r.decision = "rejected"; + } + return r; + } + + static nlohmann::json toJson(const BudgetEnforcementResult& r) { + return {{"pair_id", r.pairId}, {"within_budget", r.withinBudget}, + {"requires_approval_token", r.requiresApprovalToken}, + {"requested_cost", r.requestedCost}, + {"budget_limit", r.budgetLimit}, + {"decision", r.decision}}; + } +}; diff --git a/editor/src/graduation/ComputeCostEstimator.h b/editor/src/graduation/ComputeCostEstimator.h new file mode 100644 index 0000000..a407553 --- /dev/null +++ b/editor/src/graduation/ComputeCostEstimator.h @@ -0,0 +1,48 @@ +#pragma once +// Step 871: Compute/runtime cost estimator from prior runs. +#include +#include +#include + +struct PriorRunRecord { + std::string pairId; + int durationMs = 0; + int tokenCount = 0; +}; + +struct ComputeCostEstimate { + std::string pairId; + float estimatedDurationMs = 0.0f; + float estimatedTokens = 0.0f; + int sampleCount = 0; + bool hasHistory = false; +}; + +class ComputeCostEstimator { +public: + static ComputeCostEstimate estimate(const std::string& pairId, + const std::vector& history) { + ComputeCostEstimate e; + e.pairId = pairId; + e.sampleCount = static_cast(history.size()); + e.hasHistory = !history.empty(); + if (e.hasHistory) { + float sumDur = 0, sumTok = 0; + for (const auto& r : history) { + sumDur += r.durationMs; + sumTok += r.tokenCount; + } + e.estimatedDurationMs = sumDur / e.sampleCount; + e.estimatedTokens = sumTok / e.sampleCount; + } + return e; + } + + static nlohmann::json toJson(const ComputeCostEstimate& e) { + return {{"pair_id", e.pairId}, + {"estimated_duration_ms", e.estimatedDurationMs}, + {"estimated_tokens", e.estimatedTokens}, + {"sample_count", e.sampleCount}, + {"has_history", e.hasHistory}}; + } +}; diff --git a/editor/src/graduation/CostQualityTradeoffReport.h b/editor/src/graduation/CostQualityTradeoffReport.h new file mode 100644 index 0000000..6b9d1bc --- /dev/null +++ b/editor/src/graduation/CostQualityTradeoffReport.h @@ -0,0 +1,48 @@ +#pragma once +// Step 874: Cost-vs-quality tradeoff report generator. +#include +#include +#include + +struct TradeoffEntry { + std::string profile; + float cost = 0.0f; + float quality = 0.0f; + float efficiency = 0.0f; // quality / cost +}; + +struct CostQualityReport { + std::string pairId; + std::vector entries; + std::string recommendedProfile; +}; + +class CostQualityTradeoffReport { +public: + static CostQualityReport generate(const std::string& pairId, + const std::vector>& planCosts, + const std::vector>& planQualities) { + CostQualityReport r; + r.pairId = pairId; + float bestEff = -1.0f; + for (size_t i = 0; i < planCosts.size() && i < planQualities.size(); ++i) { + TradeoffEntry e; + e.profile = planCosts[i].first; + e.cost = planCosts[i].second; + e.quality = planQualities[i].second; + e.efficiency = (e.cost > 0.0f) ? e.quality / e.cost : 0.0f; + r.entries.push_back(e); + if (e.efficiency > bestEff) { bestEff = e.efficiency; r.recommendedProfile = e.profile; } + } + return r; + } + + static nlohmann::json toJson(const CostQualityReport& r) { + nlohmann::json arr = nlohmann::json::array(); + for (const auto& e : r.entries) + arr.push_back({{"profile", e.profile}, {"cost", e.cost}, + {"quality", e.quality}, {"efficiency", e.efficiency}}); + return {{"pair_id", r.pairId}, {"entries", arr}, + {"recommended_profile", r.recommendedProfile}}; + } +}; diff --git a/editor/src/graduation/CostTelemetryIntegration.h b/editor/src/graduation/CostTelemetryIntegration.h new file mode 100644 index 0000000..5c8d0db --- /dev/null +++ b/editor/src/graduation/CostTelemetryIntegration.h @@ -0,0 +1,55 @@ +#pragma once +// Step 877: Cost telemetry integration in metrics stack. +#include +#include +#include + +struct CostTelemetryRecord { + std::string pairId; + std::string profile; + float actualCost = 0.0f; + float estimatedCost = 0.0f; + float costError = 0.0f; // |actual - estimated| + bool overBudget = false; +}; + +class CostTelemetryIntegration { +public: + void record(const CostTelemetryRecord& r) { + records_.push_back(r); + } + + float averageCostError() const { + if (records_.empty()) return 0.0f; + float sum = 0.0f; + for (const auto& r : records_) sum += r.costError; + return sum / records_.size(); + } + + int overBudgetCount() const { + int n = 0; + for (const auto& r : records_) if (r.overBudget) ++n; + return n; + } + + static CostTelemetryRecord make(const std::string& pairId, const std::string& profile, + float actual, float estimated) { + CostTelemetryRecord r; + r.pairId = pairId; + r.profile = profile; + r.actualCost = actual; + r.estimatedCost = estimated; + r.costError = std::abs(actual - estimated); + r.overBudget = actual > 1.0f; + return r; + } + + static nlohmann::json toJson(const CostTelemetryRecord& r) { + return {{"pair_id", r.pairId}, {"profile", r.profile}, + {"actual_cost", r.actualCost}, {"estimated_cost", r.estimatedCost}, + {"cost_error", r.costError}, {"over_budget", r.overBudget}}; + } + +private: + std::vector records_; +}; diff --git a/editor/src/graduation/MultiPlanAlternativeGenerator.h b/editor/src/graduation/MultiPlanAlternativeGenerator.h new file mode 100644 index 0000000..ff5fe6f --- /dev/null +++ b/editor/src/graduation/MultiPlanAlternativeGenerator.h @@ -0,0 +1,33 @@ +#pragma once +// Step 872: Multi-plan alternative generator. +#include +#include +#include + +struct TranspilationPlanAlternative { + std::string planId; + std::string profile; // "cheap", "balanced", "rigorous" + float estimatedCost = 0.0f; + float estimatedQuality = 0.0f; + bool requiresReview = false; +}; + +class MultiPlanAlternativeGenerator { +public: + static std::vector generate( + const std::string& pairId, float baseCost) { + (void)pairId; + std::vector plans; + plans.push_back({"plan-cheap", "cheap", baseCost * 0.5f, 0.6f, false}); + plans.push_back({"plan-balanced", "balanced", baseCost, 0.8f, false}); + plans.push_back({"plan-rigorous", "rigorous", baseCost * 2.0f, 0.95f, true}); + return plans; + } + + static nlohmann::json toJson(const TranspilationPlanAlternative& p) { + return {{"plan_id", p.planId}, {"profile", p.profile}, + {"estimated_cost", p.estimatedCost}, + {"estimated_quality", p.estimatedQuality}, + {"requires_review", p.requiresReview}}; + } +}; diff --git a/editor/src/graduation/PortingCostModel.h b/editor/src/graduation/PortingCostModel.h new file mode 100644 index 0000000..3c9bf0d --- /dev/null +++ b/editor/src/graduation/PortingCostModel.h @@ -0,0 +1,34 @@ +#pragma once +// Step 869: Porting cost model v1. +#include +#include + +struct PortingCostEstimate { + std::string pairId; + float computeCost = 0.0f; // normalized 0-1 + float reviewCost = 0.0f; // normalized 0-1 + float totalCost = 0.0f; + std::string tier; // "low", "medium", "high" +}; + +class PortingCostModel { +public: + static PortingCostEstimate estimate(const std::string& pairId, + int linesOfCode, float ambiguityScore) { + PortingCostEstimate e; + e.pairId = pairId; + e.computeCost = std::min(1.0f, linesOfCode / 1000.0f); + e.reviewCost = std::min(1.0f, ambiguityScore); + e.totalCost = (e.computeCost + e.reviewCost) / 2.0f; + if (e.totalCost < 0.33f) e.tier = "low"; + else if (e.totalCost < 0.66f) e.tier = "medium"; + else e.tier = "high"; + return e; + } + + static nlohmann::json toJson(const PortingCostEstimate& e) { + return {{"pair_id", e.pairId}, {"compute_cost", e.computeCost}, + {"review_cost", e.reviewCost}, {"total_cost", e.totalCost}, + {"tier", e.tier}}; + } +}; diff --git a/editor/src/graduation/ReviewEffortEstimator.h b/editor/src/graduation/ReviewEffortEstimator.h new file mode 100644 index 0000000..d22a626 --- /dev/null +++ b/editor/src/graduation/ReviewEffortEstimator.h @@ -0,0 +1,37 @@ +#pragma once +// Step 870: Review effort estimator from ambiguity/risk packets. +#include +#include + +struct ReviewEffortPacket { + std::string pairId; + float ambiguity = 0.0f; + float riskScore = 0.0f; + int estimatedReviewMinutes = 0; + std::string complexityLabel; // "trivial", "simple", "moderate", "complex" +}; + +class ReviewEffortEstimator { +public: + static ReviewEffortPacket estimate(const std::string& pairId, + float ambiguity, float riskScore) { + ReviewEffortPacket p; + p.pairId = pairId; + p.ambiguity = ambiguity; + p.riskScore = riskScore; + float combined = (ambiguity + riskScore) / 2.0f; + p.estimatedReviewMinutes = static_cast(combined * 60.0f) + 5; + if (combined < 0.2f) p.complexityLabel = "trivial"; + else if (combined < 0.4f) p.complexityLabel = "simple"; + else if (combined < 0.7f) p.complexityLabel = "moderate"; + else p.complexityLabel = "complex"; + return p; + } + + static nlohmann::json toJson(const ReviewEffortPacket& p) { + return {{"pair_id", p.pairId}, {"ambiguity", p.ambiguity}, + {"risk_score", p.riskScore}, + {"estimated_review_minutes", p.estimatedReviewMinutes}, + {"complexity_label", p.complexityLabel}}; + } +}; diff --git a/editor/src/mcp/RegisterCostPlanningTools.h b/editor/src/mcp/RegisterCostPlanningTools.h new file mode 100644 index 0000000..cf80e36 --- /dev/null +++ b/editor/src/mcp/RegisterCostPlanningTools.h @@ -0,0 +1,62 @@ +// Sprint 64: Cost-Aware Transpilation Planning MCP tools (Steps 875-876) +// Included inside MCPServer class body. + + void registerCostPlanningTools() { + tools_.push_back({"whetstone_plan_transpilation_run", + "Generate cost-aware plan alternatives for a transpilation run.", + {{"type", "object"}, {"properties", { + {"pair_id", {{"type", "string"}}}, + {"lines_of_code", {{"type", "integer"}}}, + {"ambiguity_score", {{"type", "number"}}}, + {"budget_limit", {{"type", "number"}}} + }}, {"required", nlohmann::json::array({"pair_id"})}} + }); + toolHandlers_["whetstone_plan_transpilation_run"] = + [this](const nlohmann::json& args) { return runPlanTranspilationRun(args); }; + + tools_.push_back({"whetstone_estimate_porting_cost", + "Estimate porting cost for a pair from LOC and ambiguity score.", + {{"type", "object"}, {"properties", { + {"pair_id", {{"type", "string"}}}, + {"lines_of_code", {{"type", "integer"}}}, + {"ambiguity_score", {{"type", "number"}}} + }}, {"required", nlohmann::json::array({"pair_id"})}} + }); + toolHandlers_["whetstone_estimate_porting_cost"] = + [this](const nlohmann::json& args) { return runEstimatePortingCost(args); }; + } + + nlohmann::json runPlanTranspilationRun(const nlohmann::json& args) { + if (!args.is_object()) return {{"success", false}, {"error", "pair_id required"}}; + std::string pairId = args.value("pair_id", ""); + if (pairId.empty()) return {{"success", false}, {"error", "pair_id required"}}; + int loc = args.value("lines_of_code", 100); + float ambiguity = args.value("ambiguity_score", 0.3f); + float budgetLimit = args.value("budget_limit", 1.0f); + auto costEst = PortingCostModel::estimate(pairId, loc, ambiguity); + auto plans = MultiPlanAlternativeGenerator::generate(pairId, costEst.totalCost); + BudgetPolicy pol{budgetLimit, true}; + nlohmann::json planArr = nlohmann::json::array(); + for (const auto& plan : plans) { + auto enforcement = BudgetPolicyEnforcer::enforce(pairId, plan.estimatedCost, pol); + auto pj = MultiPlanAlternativeGenerator::toJson(plan); + pj["budget_decision"] = enforcement.decision; + planArr.push_back(pj); + } + return {{"success", true}, {"pair_id", pairId}, + {"base_cost_tier", costEst.tier}, + {"plans", planArr}, + {"plan_count", (int)plans.size()}}; + } + + nlohmann::json runEstimatePortingCost(const nlohmann::json& args) { + if (!args.is_object()) return {{"success", false}, {"error", "pair_id required"}}; + std::string pairId = args.value("pair_id", ""); + if (pairId.empty()) return {{"success", false}, {"error", "pair_id required"}}; + int loc = args.value("lines_of_code", 100); + float ambiguity = args.value("ambiguity_score", 0.3f); + auto est = PortingCostModel::estimate(pairId, loc, ambiguity); + auto j = PortingCostModel::toJson(est); + j["success"] = true; + return j; + } diff --git a/editor/src/mcp/RegisterOnboardingAndAllTools.h b/editor/src/mcp/RegisterOnboardingAndAllTools.h index 5b5d2c5..79fc522 100644 --- a/editor/src/mcp/RegisterOnboardingAndAllTools.h +++ b/editor/src/mcp/RegisterOnboardingAndAllTools.h @@ -59,6 +59,7 @@ registerCertificationTools(); registerFailureTelemetryTools(); registerAdapterHintsTools(); + registerCostPlanningTools(); registerOnboardingTools(); } }; diff --git a/editor/tests/step869_test.cpp b/editor/tests/step869_test.cpp new file mode 100644 index 0000000..1e5e94e --- /dev/null +++ b/editor/tests/step869_test.cpp @@ -0,0 +1,54 @@ +// Step 869: Porting cost model v1 (12 tests) +#include "graduation/PortingCostModel.h" +#include +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(pair_id_set); + auto e=PortingCostModel::estimate("py->cpp",100,0.3f); + C(e.pairId=="py->cpp","pairId");P();} +void t2(){T(compute_cost_normalized); + auto e=PortingCostModel::estimate("py->cpp",500,0.3f); + C(e.computeCost>=0.0f&&e.computeCost<=1.0f,"range");P();} +void t3(){T(review_cost_from_ambiguity); + auto e=PortingCostModel::estimate("py->cpp",100,0.8f); + C(e.reviewCost==0.8f,"review");P();} +void t4(){T(total_is_average); + auto e=PortingCostModel::estimate("py->cpp",100,0.5f); + C(e.totalCost>=0.0f&&e.totalCost<=1.0f,"total");P();} +void t5(){T(tier_low); + auto e=PortingCostModel::estimate("py->cpp",50,0.1f); + C(e.tier=="low","low");P();} +void t6(){T(tier_high); + auto e=PortingCostModel::estimate("py->cpp",900,0.9f); + C(e.tier=="high","high");P();} +void t7(){T(compute_capped_at_one); + auto e=PortingCostModel::estimate("py->cpp",5000,0.5f); + C(e.computeCost==1.0f,"cap");P();} +void t8(){T(review_capped_at_one); + auto e=PortingCostModel::estimate("py->cpp",100,2.0f); + C(e.reviewCost==1.0f,"cap");P();} +void t9(){T(zero_lines_zero_compute); + auto e=PortingCostModel::estimate("py->cpp",0,0.0f); + C(e.computeCost==0.0f,"zero");P();} +void t10(){T(tier_medium); + auto e=PortingCostModel::estimate("py->cpp",300,0.5f); + C(e.tier=="medium"||e.tier=="low"||e.tier=="high","medium");P();} +void t11(){T(to_json_has_tier); + auto e=PortingCostModel::estimate("py->cpp",100,0.3f); + auto j=PortingCostModel::toJson(e); + C(j.contains("tier"),"tier");P();} +void t12(){T(to_json_has_total_cost); + auto e=PortingCostModel::estimate("py->cpp",100,0.3f); + auto j=PortingCostModel::toJson(e); + C(j.contains("total_cost"),"total_cost");P();} + +int main(){ + std::cout<<"Step 869: Porting cost model v1\n"; + t1();t2();t3();t4();t5();t6();t7();t8();t9();t10();t11();t12(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(pair_id_set); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.3f,0.2f); + C(p2.pairId=="py->cpp","pairId");P();} +void t2(){T(minutes_positive); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.5f,0.5f); + C(p2.estimatedReviewMinutes>0,"minutes");P();} +void t3(){T(trivial_label); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.1f,0.1f); + C(p2.complexityLabel=="trivial","trivial");P();} +void t4(){T(simple_label); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.3f,0.3f); + C(p2.complexityLabel=="simple","simple");P();} +void t5(){T(moderate_label); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.5f,0.5f); + C(p2.complexityLabel=="moderate","moderate");P();} +void t6(){T(complex_label); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.9f,0.9f); + C(p2.complexityLabel=="complex","complex");P();} +void t7(){T(ambiguity_stored); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.4f,0.2f); + C(p2.ambiguity==0.4f,"amb");P();} +void t8(){T(risk_stored); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.2f,0.6f); + C(p2.riskScore==0.6f,"risk");P();} +void t9(){T(to_json_has_complexity); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.3f,0.2f); + auto j=ReviewEffortEstimator::toJson(p2); + C(j.contains("complexity_label"),"label");P();} +void t10(){T(to_json_has_minutes); + auto p2=ReviewEffortEstimator::estimate("py->cpp",0.3f,0.2f); + auto j=ReviewEffortEstimator::toJson(p2); + C(j.contains("estimated_review_minutes"),"minutes");P();} + +int main(){ + std::cout<<"Step 870: Review effort estimator\n"; + t1();t2();t3();t4();t5();t6();t7();t8();t9();t10(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(no_history_no_data); + auto e=ComputeCostEstimator::estimate("py->cpp",{}); + C(!e.hasHistory,"no history");P();} +void t2(){T(with_history_has_data); + auto e=ComputeCostEstimator::estimate("py->cpp",{{"py->cpp",100,500}}); + C(e.hasHistory,"history");P();} +void t3(){T(pair_id_set); + auto e=ComputeCostEstimator::estimate("rust->go",{}); + C(e.pairId=="rust->go","pairId");P();} +void t4(){T(sample_count_correct); + std::vector h={{"py->cpp",100,500},{"py->cpp",200,600}}; + auto e=ComputeCostEstimator::estimate("py->cpp",h); + C(e.sampleCount==2,"count");P();} +void t5(){T(average_duration); + std::vector h={{"py->cpp",100,500},{"py->cpp",200,600}}; + auto e=ComputeCostEstimator::estimate("py->cpp",h); + C(e.estimatedDurationMs==150.0f,"avg");P();} +void t6(){T(average_tokens); + std::vector h={{"py->cpp",100,500},{"py->cpp",200,600}}; + auto e=ComputeCostEstimator::estimate("py->cpp",h); + C(e.estimatedTokens==550.0f,"tokens");P();} +void t7(){T(single_run); + auto e=ComputeCostEstimator::estimate("py->cpp",{{"py->cpp",300,900}}); + C(e.estimatedDurationMs==300.0f,"single");P();} +void t8(){T(zero_history_zero_estimate); + auto e=ComputeCostEstimator::estimate("py->cpp",{}); + C(e.estimatedDurationMs==0.0f,"zero");P();} +void t9(){T(to_json_has_history); + auto e=ComputeCostEstimator::estimate("py->cpp",{{"py->cpp",100,500}}); + auto j=ComputeCostEstimator::toJson(e); + C(j.contains("has_history"),"json");P();} +void t10(){T(to_json_has_sample_count); + auto e=ComputeCostEstimator::estimate("py->cpp",{{"py->cpp",100,500}}); + auto j=ComputeCostEstimator::toJson(e); + C(j.contains("sample_count"),"count");P();} + +int main(){ + std::cout<<"Step 871: Compute cost estimator\n"; + t1();t2();t3();t4();t5();t6();t7();t8();t9();t10(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(generates_three_plans); + auto plans=MultiPlanAlternativeGenerator::generate("py->cpp",0.5f); + C(plans.size()==3,"three");P();} +void t2(){T(has_cheap_plan); + auto plans=MultiPlanAlternativeGenerator::generate("py->cpp",0.5f); + bool found=false; for(auto&p:plans)if(p.profile=="cheap")found=true; + C(found,"cheap");P();} +void t3(){T(has_balanced_plan); + auto plans=MultiPlanAlternativeGenerator::generate("py->cpp",0.5f); + bool found=false; for(auto&p:plans)if(p.profile=="balanced")found=true; + C(found,"balanced");P();} +void t4(){T(has_rigorous_plan); + auto plans=MultiPlanAlternativeGenerator::generate("py->cpp",0.5f); + bool found=false; for(auto&p:plans)if(p.profile=="rigorous")found=true; + C(found,"rigorous");P();} +void t5(){T(cheap_costs_less_than_balanced); + auto plans=MultiPlanAlternativeGenerator::generate("py->cpp",0.5f); + float cheap=0,bal=0; + for(auto&p:plans){if(p.profile=="cheap")cheap=p.estimatedCost;if(p.profile=="balanced")bal=p.estimatedCost;} + C(cheapcpp",0.5f); + float rig=0,bal=0; + for(auto&p:plans){if(p.profile=="rigorous")rig=p.estimatedCost;if(p.profile=="balanced")bal=p.estimatedCost;} + C(rig>bal,"cost");P();} +void t7(){T(rigorous_requires_review); + auto plans=MultiPlanAlternativeGenerator::generate("py->cpp",0.5f); + bool found=false; + for(auto&p:plans)if(p.profile=="rigorous"&&p.requiresReview)found=true; + C(found,"review");P();} +void t8(){T(cheap_no_review); + auto plans=MultiPlanAlternativeGenerator::generate("py->cpp",0.5f); + bool ok=false; + for(auto&p:plans)if(p.profile=="cheap"&&!p.requiresReview)ok=true; + C(ok,"no review");P();} +void t9(){T(quality_increases_with_cost); + auto plans=MultiPlanAlternativeGenerator::generate("py->cpp",0.5f); + float qc=0,qb=0,qr=0; + for(auto&p:plans){if(p.profile=="cheap")qc=p.estimatedQuality;if(p.profile=="balanced")qb=p.estimatedQuality;if(p.profile=="rigorous")qr=p.estimatedQuality;} + C(qccpp",0.5f); + auto j=MultiPlanAlternativeGenerator::toJson(plans[0]); + C(j.contains("profile"),"profile");P();} + +int main(){ + std::cout<<"Step 872: Multi-plan alternative generator\n"; + t1();t2();t3();t4();t5();t6();t7();t8();t9();t10(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(within_budget_approved); + BudgetPolicy pol{1.0f,true}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.5f,pol); + C(r.decision=="approved","approved");P();} +void t2(){T(over_budget_requires_token); + BudgetPolicy pol{0.5f,true}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.8f,pol); + C(r.decision=="requires_token","token");P();} +void t3(){T(over_budget_with_token_approved); + BudgetPolicy pol{0.5f,true}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.8f,pol,true); + C(r.decision=="approved","approved");P();} +void t4(){T(over_budget_no_require_rejected); + BudgetPolicy pol{0.5f,false}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.8f,pol); + C(r.decision=="rejected","rejected");P();} +void t5(){T(within_budget_flag); + BudgetPolicy pol{1.0f,true}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.5f,pol); + C(r.withinBudget,"within");P();} +void t6(){T(over_budget_flag); + BudgetPolicy pol{0.3f,true}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.5f,pol); + C(!r.withinBudget,"over");P();} +void t7(){T(pair_id_set); + BudgetPolicy pol{1.0f,true}; + auto r=BudgetPolicyEnforcer::enforce("rust->go",0.3f,pol); + C(r.pairId=="rust->go","pairId");P();} +void t8(){T(requested_cost_stored); + BudgetPolicy pol{1.0f,true}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.7f,pol); + C(r.requestedCost==0.7f,"cost");P();} +void t9(){T(budget_limit_stored); + BudgetPolicy pol{0.6f,true}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.3f,pol); + C(r.budgetLimit==0.6f,"limit");P();} +void t10(){T(to_json_has_decision); + BudgetPolicy pol{1.0f,true}; + auto r=BudgetPolicyEnforcer::enforce("py->cpp",0.5f,pol); + auto j=BudgetPolicyEnforcer::toJson(r); + C(j.contains("decision"),"json");P();} + +int main(){ + std::cout<<"Step 873: Budget policy enforcer\n"; + t1();t2();t3();t4();t5();t6();t7();t8();t9();t10(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(pair_id_set); + auto r=CostQualityTradeoffReport::generate("py->cpp", + {{"cheap",0.2f},{"rigorous",0.8f}},{{"cheap",0.6f},{"rigorous",0.95f}}); + C(r.pairId=="py->cpp","pairId");P();} +void t2(){T(entries_count); + auto r=CostQualityTradeoffReport::generate("py->cpp", + {{"cheap",0.2f},{"balanced",0.5f}},{{"cheap",0.6f},{"balanced",0.8f}}); + C(r.entries.size()==2,"size");P();} +void t3(){T(recommended_profile_set); + auto r=CostQualityTradeoffReport::generate("py->cpp", + {{"cheap",0.2f},{"balanced",0.5f}},{{"cheap",0.6f},{"balanced",0.8f}}); + C(!r.recommendedProfile.empty(),"rec");P();} +void t4(){T(efficiency_computed); + auto r=CostQualityTradeoffReport::generate("py->cpp", + {{"cheap",0.2f}},{{"cheap",0.6f}}); + C(r.entries[0].efficiency>0.0f,"eff");P();} +void t5(){T(best_efficiency_recommended); + // cheap: 0.6/0.2 = 3.0, balanced: 0.8/0.5 = 1.6 → cheap wins + auto r=CostQualityTradeoffReport::generate("py->cpp", + {{"cheap",0.2f},{"balanced",0.5f}},{{"cheap",0.6f},{"balanced",0.8f}}); + C(r.recommendedProfile=="cheap","cheap");P();} +void t6(){T(to_json_has_entries); + auto r=CostQualityTradeoffReport::generate("py->cpp", + {{"cheap",0.2f}},{{"cheap",0.6f}}); + auto j=CostQualityTradeoffReport::toJson(r); + C(j["entries"].is_array(),"entries");P();} +void t7(){T(to_json_has_recommended); + auto r=CostQualityTradeoffReport::generate("py->cpp", + {{"cheap",0.2f}},{{"cheap",0.6f}}); + auto j=CostQualityTradeoffReport::toJson(r); + C(j.contains("recommended_profile"),"rec");P();} +void t8(){T(empty_plans_empty_entries); + auto r=CostQualityTradeoffReport::generate("py->cpp",{},{}); + C(r.entries.empty(),"empty");P();} + +int main(){ + std::cout<<"Step 874: Cost-vs-quality tradeoff report\n"; + t1();t2();t3();t4();t5();t6();t7();t8(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(tool_registered); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/list"},{"params",{}}}); + bool found=false; + for(auto& t:r["result"]["tools"]) if(t["name"]=="whetstone_plan_transpilation_run") found=true; + C(found,"tool found");P();} + +void t2(){T(no_pair_id_fails); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_plan_transpilation_run"},{"arguments",nlohmann::json::object()}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(!res["success"].get(),"fail");P();} + +void t3(){T(valid_pair_succeeds); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_plan_transpilation_run"},{"arguments",{{"pair_id","py->cpp"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["success"].get(),"success");P();} + +void t4(){T(plans_array); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_plan_transpilation_run"},{"arguments",{{"pair_id","py->cpp"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["plans"].is_array(),"plans");P();} + +void t5(){T(three_plans); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_plan_transpilation_run"},{"arguments",{{"pair_id","py->cpp"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["plan_count"].get()==3,"count");P();} + +void t6(){T(base_cost_tier); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_plan_transpilation_run"},{"arguments",{{"pair_id","py->cpp"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res.contains("base_cost_tier"),"tier");P();} + +void t7(){T(budget_decision_in_plans); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_plan_transpilation_run"},{"arguments",{{"pair_id","py->cpp"},{"budget_limit",0.1}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["plans"][0].contains("budget_decision"),"budget");P();} + +void t8(){T(pair_id_in_response); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_plan_transpilation_run"},{"arguments",{{"pair_id","rust->go"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["pair_id"]=="rust->go","pair_id");P();} + +int main(){ + std::cout<<"Step 875: whetstone_plan_transpilation_run\n"; + t1();t2();t3();t4();t5();t6();t7();t8(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(tool_registered); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/list"},{"params",{}}}); + bool found=false; + for(auto& t:r["result"]["tools"]) if(t["name"]=="whetstone_estimate_porting_cost") found=true; + C(found,"tool found");P();} + +void t2(){T(no_pair_id_fails); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_estimate_porting_cost"},{"arguments",nlohmann::json::object()}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(!res["success"].get(),"fail");P();} + +void t3(){T(valid_pair_succeeds); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_estimate_porting_cost"},{"arguments",{{"pair_id","py->cpp"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["success"].get(),"success");P();} + +void t4(){T(tier_field_present); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_estimate_porting_cost"},{"arguments",{{"pair_id","py->cpp"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res.contains("tier"),"tier");P();} + +void t5(){T(total_cost_present); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_estimate_porting_cost"},{"arguments",{{"pair_id","py->cpp"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res.contains("total_cost"),"total");P();} + +void t6(){T(high_loc_high_compute); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_estimate_porting_cost"},{"arguments",{{"pair_id","py->cpp"},{"lines_of_code",5000},{"ambiguity_score",0.9}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["tier"]=="high","high");P();} + +void t7(){T(low_loc_low_tier); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_estimate_porting_cost"},{"arguments",{{"pair_id","py->cpp"},{"lines_of_code",10},{"ambiguity_score",0.0}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["tier"]=="low","low");P();} + +void t8(){T(pair_id_in_response); + MCPServer srv; + auto r=srv.handleRequest({{"jsonrpc","2.0"},{"id",1},{"method","tools/call"},{"params",{{"name","whetstone_estimate_porting_cost"},{"arguments",{{"pair_id","rust->go"}}}}}}); + auto res=nlohmann::json::parse(r["result"]["content"][0]["text"].get()); + C(res["pair_id"]=="rust->go","pair_id");P();} + +int main(){ + std::cout<<"Step 876: whetstone_estimate_porting_cost\n"; + t1();t2();t3();t4();t5();t6();t7();t8(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(make_record); + auto r=CostTelemetryIntegration::make("py->cpp","balanced",0.5f,0.4f); + C(r.pairId=="py->cpp","pairId");P();} +void t2(){T(cost_error_computed); + auto r=CostTelemetryIntegration::make("py->cpp","balanced",0.5f,0.4f); + C(std::abs(r.costError-0.1f)<0.001f,"error");P();} +void t3(){T(over_budget_flag); + auto r=CostTelemetryIntegration::make("py->cpp","balanced",1.2f,0.4f); + C(r.overBudget,"over");P();} +void t4(){T(not_over_budget); + auto r=CostTelemetryIntegration::make("py->cpp","balanced",0.8f,0.5f); + C(!r.overBudget,"not over");P();} +void t5(){T(record_and_count); + CostTelemetryIntegration cti; + cti.record(CostTelemetryIntegration::make("py->cpp","balanced",0.5f,0.4f)); + cti.record(CostTelemetryIntegration::make("rust->go","cheap",1.5f,0.3f)); + C(cti.overBudgetCount()==1,"count");P();} +void t6(){T(average_cost_error); + CostTelemetryIntegration cti; + cti.record(CostTelemetryIntegration::make("py->cpp","balanced",0.5f,0.3f)); + cti.record(CostTelemetryIntegration::make("py->cpp","balanced",0.7f,0.5f)); + C(std::abs(cti.averageCostError()-0.2f)<0.001f,"avg");P();} +void t7(){T(empty_avg_zero); + CostTelemetryIntegration cti; + C(cti.averageCostError()==0.0f,"zero");P();} +void t8(){T(to_json_has_cost_error); + auto r=CostTelemetryIntegration::make("py->cpp","balanced",0.5f,0.4f); + auto j=CostTelemetryIntegration::toJson(r); + C(j.contains("cost_error"),"json");P();} + +int main(){ + std::cout<<"Step 877: Cost telemetry integration\n"; + t1();t2();t3();t4();t5();t6();t7();t8(); + std::cout<<"\nResults: "< +static int p=0,f=0; +#define T(n) { std::cout << " " << #n << "... "; } +#define P() { std::cout << "PASS\n"; ++p; } +#define F(m) { std::cout << "FAIL: " << m << "\n"; ++f; } +#define C(c,m) if(!(c)){F(m);return;} + +void t1(){T(sprintNumber);C(Sprint64IntegrationSummary::sprintNumber==64,"64");P();} +void t2(){T(stepsCompleted);C(Sprint64IntegrationSummary::stepsCompleted==10,"10");P();} +void t3(){T(theme_not_empty);C(std::string(Sprint64IntegrationSummary::theme).size()>0,"theme");P();} +void t4(){T(verify_true);C(Sprint64IntegrationSummary::verify(),"verify");P();} +void t5(){T(json_has_sprint_key);auto j=Sprint64IntegrationSummary::toJson();C(j.contains("sprint"),"sprint");P();} +void t6(){T(json_sprint_64);auto j=Sprint64IntegrationSummary::toJson();C(j["sprint"]==64,"sprint=64");P();} +void t7(){T(json_steps_10);auto j=Sprint64IntegrationSummary::toJson();C(j["steps"]==10,"steps=10");P();} +void t8(){T(json_status_complete);auto j=Sprint64IntegrationSummary::toJson();C(j["status"]=="complete","complete");P();} + +int main(){ + std::cout<<"Step 878: Sprint64IntegrationSummary\n"; + t1();t2();t3();t4();t5();t6();t7();t8(); + std::cout<<"\nResults: "<