Step 548: integrate phase 29a routing and cost policy flow
This commit is contained in:
@@ -3811,4 +3811,13 @@ target_link_libraries(step547_test PRIVATE
|
||||
tree_sitter_javascript tree_sitter_typescript
|
||||
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
||||
|
||||
add_executable(step548_test tests/step548_test.cpp)
|
||||
target_include_directories(step548_test PRIVATE src)
|
||||
target_link_libraries(step548_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)
|
||||
|
||||
69
editor/src/Phase29aIntegration.h
Normal file
69
editor/src/Phase29aIntegration.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
// Step 548: Phase 29a Integration
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ConstrainedRoutingRulesetExtension.h"
|
||||
#include "ContextBundleMinimizer.h"
|
||||
#include "ConstrainedConfidenceCalibrator.h"
|
||||
#include "CostPolicyGuard.h"
|
||||
|
||||
struct Phase29aRequest {
|
||||
ConstrainedRoutingInput routing;
|
||||
ContextBundleInput context;
|
||||
double baseConfidence = 0.0;
|
||||
std::string preferredRoute;
|
||||
std::map<std::string, int> successes;
|
||||
std::map<std::string, int> attempts;
|
||||
std::map<std::string, int> postApplyFailures;
|
||||
CostPolicyInput cost;
|
||||
};
|
||||
|
||||
struct Phase29aResult {
|
||||
bool passed = false;
|
||||
ConstrainedRoutingDecision routingDecision;
|
||||
ContextBundleOutput minimizedContext;
|
||||
CalibratedConfidence calibrated;
|
||||
CostPolicyResult costPolicy;
|
||||
std::vector<std::string> errors;
|
||||
};
|
||||
|
||||
class Phase29aIntegration {
|
||||
public:
|
||||
static Phase29aResult run(const Phase29aRequest& request) {
|
||||
Phase29aResult out;
|
||||
out.routingDecision = ConstrainedRoutingRulesetExtension::decide(request.routing);
|
||||
out.minimizedContext = ContextBundleMinimizer::minimize(request.context);
|
||||
out.calibrated = ConstrainedConfidenceCalibrator::calibrate(
|
||||
request.baseConfidence,
|
||||
request.successes,
|
||||
request.attempts,
|
||||
request.postApplyFailures,
|
||||
request.preferredRoute);
|
||||
out.costPolicy = CostPolicyGuard::evaluate(request.cost);
|
||||
|
||||
if (!out.costPolicy.allowed) {
|
||||
out.errors.push_back("cost_policy_blocked");
|
||||
}
|
||||
|
||||
if (out.routingDecision.route == "escalate") {
|
||||
out.errors.push_back("routing_escalated");
|
||||
}
|
||||
|
||||
if (request.context.narrowOperation &&
|
||||
out.minimizedContext.minimalContext.size() >
|
||||
request.context.fileContext.size() + 2) {
|
||||
out.errors.push_back("context_not_sufficiently_minimized");
|
||||
}
|
||||
|
||||
if (out.calibrated.adjustedConfidence < 0.40 &&
|
||||
out.routingDecision.route == "deterministic_template") {
|
||||
out.errors.push_back("low_calibrated_confidence_for_template_route");
|
||||
}
|
||||
|
||||
out.passed = out.errors.empty();
|
||||
return out;
|
||||
}
|
||||
};
|
||||
132
editor/tests/step548_test.cpp
Normal file
132
editor/tests/step548_test.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
// Step 548: Phase 29a Integration (8 tests)
|
||||
|
||||
#include "Phase29aIntegration.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 Phase29aRequest baseRequest() {
|
||||
Phase29aRequest r;
|
||||
r.routing = {"rename", 0.9, true, true, false};
|
||||
r.context.taskitemId = "ti-548";
|
||||
r.context.contractTargets = {"Function"};
|
||||
r.context.contractSymbols = {"cursor"};
|
||||
r.context.contractOps = {"rename"};
|
||||
r.context.fileContext = {"file:main.cpp", "ast:Function cursor", "diag:none"};
|
||||
r.context.projectContext = {"module:cursor helpers", "module:theme"};
|
||||
r.context.dependencyContext = {"dep:cursor_utils", "dep:sdl2"};
|
||||
r.context.narrowOperation = true;
|
||||
|
||||
r.baseConfidence = 0.8;
|
||||
r.preferredRoute = "deterministic_template";
|
||||
r.successes = {{"deterministic_template", 8}};
|
||||
r.attempts = {{"deterministic_template", 10}};
|
||||
r.postApplyFailures = {{"deterministic_template", 1}};
|
||||
|
||||
r.cost = {120, 500, 200, 1000, false, false};
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool hasError(const Phase29aResult& r, const std::string& e) {
|
||||
for (const auto& x : r.errors) if (x == e) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void test_pass_path_with_lower_context_and_cost_compliance() {
|
||||
TEST(pass_path_with_lower_context_and_cost_compliance);
|
||||
auto r = Phase29aIntegration::run(baseRequest());
|
||||
CHECK(r.passed, "expected pass path");
|
||||
CHECK(r.costPolicy.allowed, "cost policy should allow");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_cost_policy_block_fails_integration() {
|
||||
TEST(cost_policy_block_fails_integration);
|
||||
auto req = baseRequest();
|
||||
req.cost = {400, 1500, 200, 1000, false, false};
|
||||
auto r = Phase29aIntegration::run(req);
|
||||
CHECK(!r.passed, "cost-blocked path should fail integration");
|
||||
CHECK(hasError(r, "cost_policy_blocked"), "cost error expected");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_routing_escalation_fails_integration() {
|
||||
TEST(routing_escalation_fails_integration);
|
||||
auto req = baseRequest();
|
||||
req.routing.hasRecentPostApplyFailures = true;
|
||||
auto r = Phase29aIntegration::run(req);
|
||||
CHECK(!r.passed, "routing escalation should fail integration");
|
||||
CHECK(hasError(r, "routing_escalated"), "routing escalation error expected");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_narrow_context_is_minimized() {
|
||||
TEST(narrow_context_is_minimized);
|
||||
auto req = baseRequest();
|
||||
auto r = Phase29aIntegration::run(req);
|
||||
CHECK(r.minimizedContext.removedContext.size() > 0, "narrow mode should remove irrelevant context");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_low_calibrated_confidence_blocks_template_route() {
|
||||
TEST(low_calibrated_confidence_blocks_template_route);
|
||||
auto req = baseRequest();
|
||||
req.baseConfidence = 0.2;
|
||||
req.successes = {{"deterministic_template", 0}};
|
||||
req.attempts = {{"deterministic_template", 10}};
|
||||
req.postApplyFailures = {{"deterministic_template", 8}};
|
||||
auto r = Phase29aIntegration::run(req);
|
||||
CHECK(!r.passed, "low calibrated confidence should block");
|
||||
CHECK(hasError(r, "low_calibrated_confidence_for_template_route"), "calibration error expected");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_calibration_can_shift_route_recommendation() {
|
||||
TEST(calibration_can_shift_route_recommendation);
|
||||
auto req = baseRequest();
|
||||
req.successes = {{"deterministic_template", 1}, {"constrained_worker", 9}};
|
||||
req.attempts = {{"deterministic_template", 10}, {"constrained_worker", 10}};
|
||||
req.postApplyFailures = {{"deterministic_template", 6}, {"constrained_worker", 0}};
|
||||
auto r = Phase29aIntegration::run(req);
|
||||
CHECK(r.calibrated.recommendedRoute == "constrained_worker", "calibration should prefer stronger route");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_cost_guard_allows_when_rationale_and_approval_present() {
|
||||
TEST(cost_guard_allows_when_rationale_and_approval_present);
|
||||
auto req = baseRequest();
|
||||
req.cost = {300, 1300, 200, 1000, true, true};
|
||||
auto r = Phase29aIntegration::run(req);
|
||||
CHECK(r.costPolicy.allowed, "approved overage should be allowed");
|
||||
PASS();
|
||||
}
|
||||
|
||||
void test_phase29a_handles_non_narrow_context_without_minimization_error() {
|
||||
TEST(phase29a_handles_non_narrow_context_without_minimization_error);
|
||||
auto req = baseRequest();
|
||||
req.context.narrowOperation = false;
|
||||
auto r = Phase29aIntegration::run(req);
|
||||
CHECK(!hasError(r, "context_not_sufficiently_minimized"), "non-narrow mode should not trigger strict minimization error");
|
||||
PASS();
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "Step 548: Phase 29a Integration\n";
|
||||
|
||||
test_pass_path_with_lower_context_and_cost_compliance(); // 1
|
||||
test_cost_policy_block_fails_integration(); // 2
|
||||
test_routing_escalation_fails_integration(); // 3
|
||||
test_narrow_context_is_minimized(); // 4
|
||||
test_low_calibrated_confidence_blocks_template_route(); // 5
|
||||
test_calibration_can_shift_route_recommendation(); // 6
|
||||
test_cost_guard_allows_when_rationale_and_approval_present(); // 7
|
||||
test_phase29a_handles_non_narrow_context_without_minimization_error(); // 8
|
||||
|
||||
std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n";
|
||||
return failed == 0 ? 0 : 1;
|
||||
}
|
||||
43
progress.md
43
progress.md
@@ -9507,3 +9507,46 @@ controls for overage execution.
|
||||
- `editor/src/CostPolicyGuard.h` within header-size limit (`60` <= `600`)
|
||||
- `editor/tests/step547_test.cpp` within test-file size guidance (`132` lines)
|
||||
- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`
|
||||
|
||||
### Step 548: Phase 29a Integration
|
||||
**Status:** PASS (8/8 tests)
|
||||
|
||||
Integrates Phase 29a routing intelligence, context minimization, confidence
|
||||
calibration, and cost policy enforcement into a unified constrained orchestration
|
||||
decision flow.
|
||||
|
||||
**Files added:**
|
||||
- `editor/src/Phase29aIntegration.h` - Phase 29a integration gate:
|
||||
- composes Step 544 routing policy, Step 545 context minimizer,
|
||||
Step 546 confidence calibration, and Step 547 cost guard
|
||||
- emits integrated pass/fail signal with structured error reasons
|
||||
- guards template routing when calibrated confidence is too low
|
||||
- enforces cost-policy and escalation outcomes in final decision
|
||||
- `editor/tests/step548_test.cpp` - 8 tests covering:
|
||||
- pass-path with reduced context and cost compliance
|
||||
- cost-policy block behavior
|
||||
- routing-escalation block behavior
|
||||
- narrow-context minimization behavior
|
||||
- low-calibrated-confidence template block behavior
|
||||
- calibration route-shift behavior
|
||||
- approved overage path behavior
|
||||
- non-narrow context tolerance behavior
|
||||
|
||||
**Files modified:**
|
||||
- `editor/CMakeLists.txt` - `step548_test` target
|
||||
|
||||
**Verification run:**
|
||||
- `cmake -S editor -B editor/build-native` - PASS
|
||||
- `cmake --build editor/build-native --target step548_test step547_test` - PASS
|
||||
- `./editor/build-native/step548_test` - PASS (8/8)
|
||||
- `./editor/build-native/step547_test` - PASS (12/12) regression coverage
|
||||
|
||||
**Architecture gate check:**
|
||||
- `editor/src/Phase29aIntegration.h` within header-size limit (`69` <= `600`)
|
||||
- `editor/tests/step548_test.cpp` within test-file size guidance (`132` lines)
|
||||
- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`
|
||||
|
||||
**Phase 29a totals (544-548):**
|
||||
- **Steps completed:** 5
|
||||
- **New tests in phase plan:** 56/56 passing
|
||||
- **Routing/context/cost optimization integration:** PASS
|
||||
|
||||
Reference in New Issue
Block a user