diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1cc8270 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 3.14) +project(CuraFrame VERSION 3.0.0 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# All constraint-bundle translation units +set(BUNDLE_SOURCES + constraints/anti_infective/AntiInfectiveBundle.cpp + constraints/cardiac/CardiacBundle.cpp + constraints/cns/CNSBundle.cpp + constraints/formulation/FormulationBundle.cpp + constraints/hepatic/HepaticBundle.cpp + constraints/immunologic/ImmunologicBundle.cpp + constraints/metabolic/MetabolicBundle.cpp + constraints/oncology/OncologyBundle.cpp + constraints/pkpd/PKPDBundle.cpp + constraints/renal/RenalBundle.cpp + constraints/safety/SafetyBundle.cpp + constraints/systemic_exposure/SystemicExposureBundle.cpp +) + +# Scoring subsystem translation units +set(SCORING_SOURCES + scoring/WeightProfile.cpp + scoring/WeightedScoringEngine.cpp + scoring/ScoringPipeline.cpp +) + +# Static library bundling all C++ constraint and scoring logic. +# The repository root is exposed as the include root so that all relative +# includes (e.g. "constraint_core/Candidate.hpp" or "../scoring/...") resolve +# correctly regardless of which translation unit is being compiled. +add_library(curaframe_cpp STATIC + ${BUNDLE_SOURCES} + ${SCORING_SOURCES} +) + +target_include_directories(curaframe_cpp PUBLIC + $ +) + +target_compile_options(curaframe_cpp PRIVATE + $<$:-Wall -Wextra -Wpedantic> + $<$:/W4> +) + +# NOTE: Each bundle uses the REGISTER_CONSTRAINT_BUNDLE self-registration macro, +# which installs a static initialiser in its own translation unit. When linking +# this library into an executable, force the linker to include every object file +# so that all initialisers run, even those with no externally referenced symbols: +# +# GCC / Clang (Linux): +# target_link_libraries(my_app PRIVATE +# -Wl,--whole-archive curaframe_cpp -Wl,--no-whole-archive) +# +# Clang (macOS): +# target_link_libraries(my_app PRIVATE +# -Wl,-force_load,$) +# +# MSVC: +# target_link_libraries(my_app PRIVATE /WHOLEARCHIVE:curaframe_cpp) diff --git a/constraint_core/MultiBundleEvaluator.hpp b/constraint_core/MultiBundleEvaluator.hpp index 515a6de..384e7c2 100644 --- a/constraint_core/MultiBundleEvaluator.hpp +++ b/constraint_core/MultiBundleEvaluator.hpp @@ -5,13 +5,14 @@ #include "EvaluationReport.hpp" #include "ConstraintRegistry.hpp" #include "../scoring/ScoringPipeline.hpp" +#include "../scoring/ScoringReport.hpp" #include "../scoring/WeightProfile.hpp" #include // Unified Evaluation Layer class MultiBundleEvaluator { public: - EvaluationReport evaluate(const Candidate& candidate) { + EvaluationReport evaluate(const Candidate& candidate) const { EvaluationReport report; report.candidate_id = candidate.id; diff --git a/constraints/anti_infective/AntiInfectiveBundle.cpp b/constraints/anti_infective/AntiInfectiveBundle.cpp index c3bf9c3..d577abc 100644 --- a/constraints/anti_infective/AntiInfectiveBundle.cpp +++ b/constraints/anti_infective/AntiInfectiveBundle.cpp @@ -1 +1,4 @@ #include "AntiInfectiveBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("AntiInfective", AntiInfectiveBundle) diff --git a/constraints/anti_infective/AntiInfectiveBundle.hpp b/constraints/anti_infective/AntiInfectiveBundle.hpp index 492a5f9..b55161b 100644 --- a/constraints/anti_infective/AntiInfectiveBundle.hpp +++ b/constraints/anti_infective/AntiInfectiveBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_ANTI_INFECTIVE_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class AntiInfectiveBundle : public ConstraintBundle { @@ -58,6 +57,4 @@ class AntiInfectiveBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("AntiInfective", AntiInfectiveBundle) - #endif // CURAFRAME_ANTI_INFECTIVE_BUNDLE_HPP diff --git a/constraints/cardiac/CardiacBundle.cpp b/constraints/cardiac/CardiacBundle.cpp index 83bb004..079c467 100644 --- a/constraints/cardiac/CardiacBundle.cpp +++ b/constraints/cardiac/CardiacBundle.cpp @@ -1 +1,4 @@ #include "CardiacBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("Cardiac", CardiacBundle) diff --git a/constraints/cardiac/CardiacBundle.hpp b/constraints/cardiac/CardiacBundle.hpp index c5970a1..ad468fb 100644 --- a/constraints/cardiac/CardiacBundle.hpp +++ b/constraints/cardiac/CardiacBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_CARDIAC_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class CardiacBundle : public ConstraintBundle { @@ -59,6 +58,4 @@ class CardiacBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("Cardiac", CardiacBundle) - #endif // CURAFRAME_CARDIAC_BUNDLE_HPP diff --git a/constraints/cns/CNSBundle.cpp b/constraints/cns/CNSBundle.cpp index 7799f4a..27a936c 100644 --- a/constraints/cns/CNSBundle.cpp +++ b/constraints/cns/CNSBundle.cpp @@ -1 +1,4 @@ #include "CNSBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("CNS", CNSBundle) diff --git a/constraints/cns/CNSBundle.hpp b/constraints/cns/CNSBundle.hpp index eb905ba..1b6a41c 100644 --- a/constraints/cns/CNSBundle.hpp +++ b/constraints/cns/CNSBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_CNS_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class CNSBundle : public ConstraintBundle { @@ -59,6 +58,4 @@ class CNSBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("CNS", CNSBundle) - #endif // CURAFRAME_CNS_BUNDLE_HPP diff --git a/constraints/formulation/FormulationBundle.cpp b/constraints/formulation/FormulationBundle.cpp index 8c4a77e..7bd233a 100644 --- a/constraints/formulation/FormulationBundle.cpp +++ b/constraints/formulation/FormulationBundle.cpp @@ -1 +1,4 @@ #include "FormulationBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("Formulation", FormulationBundle) diff --git a/constraints/formulation/FormulationBundle.hpp b/constraints/formulation/FormulationBundle.hpp index 67e7e37..764db16 100644 --- a/constraints/formulation/FormulationBundle.hpp +++ b/constraints/formulation/FormulationBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_FORMULATION_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class FormulationBundle : public ConstraintBundle { @@ -57,6 +56,4 @@ class FormulationBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("Formulation", FormulationBundle) - #endif // CURAFRAME_FORMULATION_BUNDLE_HPP diff --git a/constraints/hepatic/HepaticBundle.cpp b/constraints/hepatic/HepaticBundle.cpp index 6ae01b8..676a73b 100644 --- a/constraints/hepatic/HepaticBundle.cpp +++ b/constraints/hepatic/HepaticBundle.cpp @@ -1 +1,4 @@ #include "HepaticBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("Hepatic", HepaticBundle) diff --git a/constraints/hepatic/HepaticBundle.hpp b/constraints/hepatic/HepaticBundle.hpp index 83b3cd8..74bff01 100644 --- a/constraints/hepatic/HepaticBundle.hpp +++ b/constraints/hepatic/HepaticBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_HEPATIC_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class HepaticBundle : public ConstraintBundle { @@ -59,6 +58,4 @@ class HepaticBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("Hepatic", HepaticBundle) - #endif // CURAFRAME_HEPATIC_BUNDLE_HPP diff --git a/constraints/immunologic/ImmunologicBundle.cpp b/constraints/immunologic/ImmunologicBundle.cpp index 4e81579..18d6559 100644 --- a/constraints/immunologic/ImmunologicBundle.cpp +++ b/constraints/immunologic/ImmunologicBundle.cpp @@ -1 +1,4 @@ #include "ImmunologicBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("Immunologic", ImmunologicBundle) diff --git a/constraints/immunologic/ImmunologicBundle.hpp b/constraints/immunologic/ImmunologicBundle.hpp index 350383b..b7de918 100644 --- a/constraints/immunologic/ImmunologicBundle.hpp +++ b/constraints/immunologic/ImmunologicBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_IMMUNOLOGIC_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class ImmunologicBundle : public ConstraintBundle { @@ -60,6 +59,4 @@ class ImmunologicBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("Immunologic", ImmunologicBundle) - #endif // CURAFRAME_IMMUNOLOGIC_BUNDLE_HPP diff --git a/constraints/metabolic/MetabolicBundle.cpp b/constraints/metabolic/MetabolicBundle.cpp index 78b1499..cb9d111 100644 --- a/constraints/metabolic/MetabolicBundle.cpp +++ b/constraints/metabolic/MetabolicBundle.cpp @@ -1 +1,4 @@ #include "MetabolicBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("Metabolic", MetabolicBundle) diff --git a/constraints/metabolic/MetabolicBundle.hpp b/constraints/metabolic/MetabolicBundle.hpp index 6cef2b8..472f264 100644 --- a/constraints/metabolic/MetabolicBundle.hpp +++ b/constraints/metabolic/MetabolicBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_METABOLIC_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class MetabolicBundle : public ConstraintBundle { @@ -75,6 +74,4 @@ class MetabolicBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("Metabolic", MetabolicBundle) - #endif // CURAFRAME_METABOLIC_BUNDLE_HPP diff --git a/constraints/oncology/OncologyBundle.cpp b/constraints/oncology/OncologyBundle.cpp index afb96a3..64cbea8 100644 --- a/constraints/oncology/OncologyBundle.cpp +++ b/constraints/oncology/OncologyBundle.cpp @@ -1 +1,4 @@ #include "OncologyBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("Oncology", OncologyBundle) diff --git a/constraints/oncology/OncologyBundle.hpp b/constraints/oncology/OncologyBundle.hpp index ca397e2..d0fc14c 100644 --- a/constraints/oncology/OncologyBundle.hpp +++ b/constraints/oncology/OncologyBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_ONCOLOGY_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class OncologyBundle : public ConstraintBundle { @@ -59,6 +58,4 @@ class OncologyBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("Oncology", OncologyBundle) - #endif // CURAFRAME_ONCOLOGY_BUNDLE_HPP diff --git a/constraints/pkpd/PKPDBundle.cpp b/constraints/pkpd/PKPDBundle.cpp index 052b0c8..fbfd8dd 100644 --- a/constraints/pkpd/PKPDBundle.cpp +++ b/constraints/pkpd/PKPDBundle.cpp @@ -1 +1,4 @@ #include "PKPDBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("PKPD", PKPDBundle) diff --git a/constraints/pkpd/PKPDBundle.hpp b/constraints/pkpd/PKPDBundle.hpp index bc9f10a..871bfd6 100644 --- a/constraints/pkpd/PKPDBundle.hpp +++ b/constraints/pkpd/PKPDBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_PKPD_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class PKPDBundle : public ConstraintBundle { @@ -58,6 +57,4 @@ class PKPDBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("PKPD", PKPDBundle) - #endif // CURAFRAME_PKPD_BUNDLE_HPP diff --git a/constraints/renal/RenalBundle.cpp b/constraints/renal/RenalBundle.cpp index accf5f9..47e9969 100644 --- a/constraints/renal/RenalBundle.cpp +++ b/constraints/renal/RenalBundle.cpp @@ -1 +1,4 @@ #include "RenalBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("Renal", RenalBundle) diff --git a/constraints/renal/RenalBundle.hpp b/constraints/renal/RenalBundle.hpp index 938cb76..1829c88 100644 --- a/constraints/renal/RenalBundle.hpp +++ b/constraints/renal/RenalBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_RENAL_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class RenalBundle : public ConstraintBundle { @@ -59,6 +58,4 @@ class RenalBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("Renal", RenalBundle) - #endif // CURAFRAME_RENAL_BUNDLE_HPP diff --git a/constraints/safety/SafetyBundle.cpp b/constraints/safety/SafetyBundle.cpp index b2ae7ab..c2ab937 100644 --- a/constraints/safety/SafetyBundle.cpp +++ b/constraints/safety/SafetyBundle.cpp @@ -1 +1,4 @@ #include "SafetyBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("Safety", SafetyBundle) diff --git a/constraints/safety/SafetyBundle.hpp b/constraints/safety/SafetyBundle.hpp index b8b29e2..80545f7 100644 --- a/constraints/safety/SafetyBundle.hpp +++ b/constraints/safety/SafetyBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_SAFETY_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class SafetyBundle : public ConstraintBundle { @@ -56,6 +55,4 @@ class SafetyBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("Safety", SafetyBundle) - #endif // CURAFRAME_SAFETY_BUNDLE_HPP diff --git a/constraints/systemic_exposure/SystemicExposureBundle.cpp b/constraints/systemic_exposure/SystemicExposureBundle.cpp index b66a32a..1aa5b45 100644 --- a/constraints/systemic_exposure/SystemicExposureBundle.cpp +++ b/constraints/systemic_exposure/SystemicExposureBundle.cpp @@ -1 +1,4 @@ #include "SystemicExposureBundle.hpp" +#include "../../constraint_core/ConstraintRegistry.hpp" + +REGISTER_CONSTRAINT_BUNDLE("SystemicExposure", SystemicExposureBundle) diff --git a/constraints/systemic_exposure/SystemicExposureBundle.hpp b/constraints/systemic_exposure/SystemicExposureBundle.hpp index 326b281..7d95762 100644 --- a/constraints/systemic_exposure/SystemicExposureBundle.hpp +++ b/constraints/systemic_exposure/SystemicExposureBundle.hpp @@ -2,7 +2,6 @@ #define CURAFRAME_SYSTEMIC_EXPOSURE_BUNDLE_HPP #include "../../constraint_core/ConstraintBundle.hpp" -#include "../../constraint_core/ConstraintRegistry.hpp" #include class SystemicExposureBundle : public ConstraintBundle { @@ -64,6 +63,4 @@ class SystemicExposureBundle : public ConstraintBundle { std::string narrative_summary() const override { return summary; } }; -REGISTER_CONSTRAINT_BUNDLE("SystemicExposure", SystemicExposureBundle) - #endif // CURAFRAME_SYSTEMIC_EXPOSURE_BUNDLE_HPP diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 1e9bb12..e64b07c 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to the C++ parallel evaluation universe will be documented in this file. -## [3.0.0] - Weighted Scoring Engine +## [3.0.0] - 2026-04-10 - Weighted Scoring Engine ### Added - **Weighted Multi-Constraint Scoring Engine**: Introduced a unified scoring engine that computes a Composite Stability Score (0-100) from constraint bundle outputs. @@ -14,7 +14,7 @@ All notable changes to the C++ parallel evaluation universe will be documented i ### Changed - Bumped project version to 3.0.0. -## [2.5.0] - Constraint-Bundle Universe +## [2.5.0] - 2026-04-10 - Constraint-Bundle Universe ### Added - **C++ Core Architecture:** Introduced `Candidate.hpp`, `EvaluationReport.hpp`, `ConstraintBundle.hpp`, `ConstraintRegistry.hpp`, and `MultiBundleEvaluator.hpp` in the `constraint_core/` directory to serve as the unified parallel evaluation layer. diff --git a/docs/constraint_bundles.md b/docs/constraint_bundles.md index 94fadc3..dbbb3fa 100644 --- a/docs/constraint_bundles.md +++ b/docs/constraint_bundles.md @@ -25,4 +25,4 @@ CuraFrame features a parallel C++ constraint-bundle universe evaluating therapeu ### Physicochemical & Pharmacological - **Formulation (`FormulationBundle`):** Solubility deficits, chemical instability, delivery-vector incompatibilities. - **PK/PD (`PKPDBundle`):** Dose-response slope analysis, receptor saturation, effect-window decoupling flags. -- **Global Safety (`SafetyBundle`):** Multi-organ stress aggregation, systemic catastrophe triggers. +- **Safety (`SafetyBundle`):** Multi-organ stress aggregation, systemic catastrophe triggers. diff --git a/docs/evaluation_pipeline.md b/docs/evaluation_pipeline.md index b5823a0..f2d0b66 100644 --- a/docs/evaluation_pipeline.md +++ b/docs/evaluation_pipeline.md @@ -27,13 +27,13 @@ int main() { EvaluationReport report = evaluator.evaluate(c); if (!report.is_viable()) { - std::cout << "Candidate Falsified. Triggers:\\n"; + std::cout << "Candidate Falsified. Triggers:\n"; for (const auto& flag : report.falsification_flags) { - std::cout << "- " << flag << "\\n"; + std::cout << "- " << flag << "\n"; } } - std::cout << "\\nNarrative Summary:\\n" << report.combined_narrative << "\\n"; + std::cout << "\nNarrative Summary:\n" << report.combined_narrative << "\n"; return 0; } ``` diff --git a/pyproject.toml b/pyproject.toml index 638dd9c..d7796c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,9 @@ [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" + +[project] +name = "CuraFrame" +version = "3.0.0" +description = "Constraint-driven therapeutic design reasoning framework." +requires-python = ">=3.9" diff --git a/scoring/ScoringReport.hpp b/scoring/ScoringReport.hpp index cd5430f..f7da643 100644 --- a/scoring/ScoringReport.hpp +++ b/scoring/ScoringReport.hpp @@ -11,7 +11,8 @@ struct ScoringReport { // Per-bundle weighted contributions std::map bundle_contributions; - // Breakdowns + // Breakdowns — keys are formatted as "domain_name::signal_name" + // (e.g. "Cardiac::qt_prolongation_risk"). std::map penalty_breakdown; std::map bonus_breakdown; diff --git a/scoring/WeightProfile.cpp b/scoring/WeightProfile.cpp index 5374b30..6e5b637 100644 --- a/scoring/WeightProfile.cpp +++ b/scoring/WeightProfile.cpp @@ -1,4 +1,8 @@ #include "WeightProfile.hpp" -// Intentionally left blank or simple implementations if needed. -// Weight profiles are currently fully implemented inline in the header for simplicity and polymorphism. +// All WeightProfile methods are implemented inline in WeightProfile.hpp because +// the class relies entirely on virtual dispatch with small, default-valued +// implementations that benefit from inlining. This translation unit exists to +// compile the header as part of the curaframe_cpp static library, ensuring that +// the vtable and RTTI for WeightProfile, DefaultResearchProfile, and +// HighSafetyProfile are emitted exactly once. diff --git a/scoring/WeightProfile.hpp b/scoring/WeightProfile.hpp index e88a6c3..01f07a0 100644 --- a/scoring/WeightProfile.hpp +++ b/scoring/WeightProfile.hpp @@ -24,11 +24,19 @@ class WeightProfile { virtual double penalty_multiplier() const { return 1.0; } virtual double bonus_multiplier() const { return 1.0; } - // Global scaling factor + // Global scaling factor applied to the raw score after all penalties and + // bonuses have been applied. Override to uniformly scale the entire score + // up (> 1.0) or down (< 1.0) for this profile, e.g. to reflect a general + // conservatism level that goes beyond per-signal adjustments. virtual double global_scaling_factor() const { return 1.0; } // Falsification penalty virtual double falsification_penalty() const { return 50.0; } // Heavy penalty for falsification + + // Optional narrative annotation appended to the scoring summary. Override + // to provide profile-specific commentary that appears at the end of the + // generated narrative without hard-coding profile names in the engine. + virtual std::string narrative_annotation() const { return ""; } }; class DefaultResearchProfile : public WeightProfile { @@ -40,7 +48,7 @@ class DefaultResearchProfile : public WeightProfile { return 1.0; } - double signal_weight(const std::string& bundle_name, const std::string& signal_name) const override { + double signal_weight(const std::string& /*bundle_name*/, const std::string& /*signal_name*/) const override { return 1.0; } }; @@ -56,7 +64,7 @@ class HighSafetyProfile : public WeightProfile { return 1.0; } - double signal_weight(const std::string& bundle_name, const std::string& signal_name) const override { + double signal_weight(const std::string& /*bundle_name*/, const std::string& signal_name) const override { if (signal_name.find("toxicity") != std::string::npos || signal_name.find("risk") != std::string::npos) { return 1.5; } @@ -66,6 +74,9 @@ class HighSafetyProfile : public WeightProfile { double penalty_multiplier() const override { return 1.5; } double bonus_multiplier() const override { return 0.5; } // Conservative double falsification_penalty() const override { return 100.0; } // Immediate zero or near-zero + std::string narrative_annotation() const override { + return "The HighSafetyProfile heavily penalized safety and toxicity signals, resulting in a conservative stability score."; + } }; #endif // CURAFRAME_WEIGHT_PROFILE_HPP diff --git a/scoring/WeightedScoringEngine.cpp b/scoring/WeightedScoringEngine.cpp index fe2b89d..a663291 100644 --- a/scoring/WeightedScoringEngine.cpp +++ b/scoring/WeightedScoringEngine.cpp @@ -94,8 +94,13 @@ std::string WeightedScoringEngine::generate_narrative(const ScoringReport& repor oss << "Bonuses were applied which mitigated some risk factors.\n"; } - if (report.weight_profile_name == "HighSafetyProfile") { - oss << "The HighSafetyProfile heavily penalized safety and toxicity signals, resulting in a conservative stability score.\n"; + std::string annotation = profile_->narrative_annotation(); + if (!annotation.empty()) { + oss << annotation << "\n"; + } + + if (!eval_report.combined_narrative.empty()) { + oss << "\nDomain Evaluations:\n" << eval_report.combined_narrative; } return oss.str();