Deterministic library dispatch layer. Five new headers: - LibrarySelection: result struct with avoidedLibraries + justification - OperationClassifier: wraps taxonomy with ClassificationResult - PerTaskLibrarySelector: sort by score, pick max, build avoided list - SelectionJustificationLog: append-only auditable selection log - Sprint287IntegrationSummary: 8-task spec, all selections verified 25/25 tests passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
93 lines
3.3 KiB
C++
93 lines
3.3 KiB
C++
// Step 1963: LibrarySelection
|
|
//
|
|
// t1: default LibrarySelection has no selection (hasSelection=false)
|
|
// t2: populated selection fields are correct
|
|
// t3: avoidedLibraries struct fields
|
|
// t4: multiple avoided libraries
|
|
// t5: selection with no avoidedLibraries (only one qualified)
|
|
|
|
#include "LibrarySelection.h"
|
|
#include <iostream>
|
|
|
|
namespace ws = whetstone;
|
|
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(default_selection_has_no_selection);
|
|
ws::LibrarySelection s;
|
|
C(!s.hasSelection(), "hasSelection false by default");
|
|
C(s.selectedLibrary.empty(), "empty selectedLibrary");
|
|
C(s.capabilityScore == 0.0f, "score 0");
|
|
C(s.preferredAPIs.empty(), "no APIs");
|
|
C(s.avoidedLibraries.empty(), "no avoided");
|
|
P();
|
|
}
|
|
|
|
void t2() {
|
|
T(populated_selection_fields);
|
|
ws::LibrarySelection s;
|
|
s.selectedLibrary = "nlohmann_json";
|
|
s.operationDomain = "serialization.json";
|
|
s.capabilityScore = 0.92f;
|
|
s.preferredAPIs = {"nlohmann::json::dump()", "nlohmann::json::parse()"};
|
|
s.justification = "nlohmann_json scores 0.92 vs best alternative protobuf at 0.60";
|
|
C(s.hasSelection(), "hasSelection true");
|
|
C(s.selectedLibrary == "nlohmann_json", "selectedLibrary");
|
|
C(s.capabilityScore == 0.92f, "capabilityScore");
|
|
C(s.preferredAPIs.size() == 2, "2 preferredAPIs");
|
|
C(!s.justification.empty(), "justification set");
|
|
P();
|
|
}
|
|
|
|
void t3() {
|
|
T(avoided_library_struct_fields);
|
|
ws::AvoidedLibrary av;
|
|
av.name = "protobuf";
|
|
av.reason = "score 0.60 < selected 0.92";
|
|
av.score = 0.60f;
|
|
C(av.name == "protobuf", "name");
|
|
C(av.score == 0.60f, "score");
|
|
C(av.reason.find("0.60") != std::string::npos, "reason contains score");
|
|
C(av.reason.find("0.92") != std::string::npos, "reason contains selected score");
|
|
P();
|
|
}
|
|
|
|
void t4() {
|
|
T(multiple_avoided_libraries_sorted_by_score_desc);
|
|
ws::LibrarySelection s;
|
|
s.selectedLibrary = "serde_json";
|
|
s.capabilityScore = 0.98f;
|
|
s.avoidedLibraries = {
|
|
{"nlohmann_json", "score 0.92 < selected 0.98", 0.92f},
|
|
{"protobuf", "score 0.60 < selected 0.98", 0.60f},
|
|
};
|
|
C(s.avoidedLibraries.size() == 2, "2 avoided");
|
|
C(s.avoidedLibraries[0].name == "nlohmann_json", "best avoided first");
|
|
C(s.avoidedLibraries[0].score > s.avoidedLibraries[1].score, "sorted desc");
|
|
P();
|
|
}
|
|
|
|
void t5() {
|
|
T(selection_with_no_avoided_only_one_qualified);
|
|
ws::LibrarySelection s;
|
|
s.selectedLibrary = "thrust";
|
|
s.operationDomain = "compute.parallel";
|
|
s.capabilityScore = 0.97f;
|
|
s.justification = "thrust scores 0.97 (only qualified library)";
|
|
C(s.hasSelection(), "hasSelection");
|
|
C(s.avoidedLibraries.empty(), "no avoided when only one qualifies");
|
|
C(s.justification.find("only") != std::string::npos, "justification says only");
|
|
P();
|
|
}
|
|
|
|
int main() {
|
|
std::cout << "Step 1963: LibrarySelection\n";
|
|
t1(); t2(); t3(); t4(); t5();
|
|
std::cout << "\n" << p << "/" << (p + f) << " passed\n";
|
|
return f > 0 ? 1 : 0;
|
|
}
|