Skip to content

Commit 9006a4f

Browse files
authored
Merge pull request #53 from dfeen87/jules-add-scoring-engine-11354591928326284294
Add Weighted Multi-Constraint Scoring Engine
2 parents aa8f1da + 02d22a0 commit 9006a4f

15 files changed

Lines changed: 367 additions & 5 deletions

CITATION.cff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ keywords:
2929
- risk mitigation
3030
- transparent reasoning
3131

32-
version: "2.5.0"
32+
version: "3.0.0"
3333
license: non-commercial
3434
repository-code: https://github.com/dfeen87/CuraFrame
3535
url: https://github.com/dfeen87/CuraFrame
@@ -40,6 +40,6 @@ preferred-citation:
4040
- given-names: Don Michael
4141
family-names: Feeney Jr.
4242
title: CuraFrame
43-
version: "2.5.0"
43+
version: "3.0.0"
4444
year: 2026
4545
url: https://github.com/dfeen87/CuraFrame

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ If CuraFrame is used in research, publications, or technical reports, please cit
799799
title = {CuraFrame: Constraint-Driven Therapeutic Design Reasoning},
800800
author = {Feeney, Don Michael},
801801
year = {2026},
802-
version = {2.5.0},
802+
version = {3.0.0},
803803
url = {https://github.com/dfeen87/CuraFrame},
804804
license = {Non-Commercial}
805805
}

constraint_core/MultiBundleEvaluator.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "Candidate.hpp"
55
#include "EvaluationReport.hpp"
66
#include "ConstraintRegistry.hpp"
7+
#include "../scoring/ScoringPipeline.hpp"
8+
#include "../scoring/WeightProfile.hpp"
79
#include <sstream>
810

911
// Unified Evaluation Layer
@@ -46,6 +48,18 @@ class MultiBundleEvaluator {
4648
report.combined_narrative = combined_narrative.str();
4749
return report;
4850
}
51+
52+
// Pass evaluation results to the scoring engine using the default profile
53+
ScoringReport score(const EvaluationReport& report) const {
54+
ScoringPipeline pipeline(std::make_shared<DefaultResearchProfile>());
55+
return pipeline.execute(report);
56+
}
57+
58+
// Pass evaluation results to the scoring engine using a specific profile
59+
ScoringReport score_with_profile(const EvaluationReport& report, std::shared_ptr<WeightProfile> profile) const {
60+
ScoringPipeline pipeline(profile);
61+
return pipeline.execute(report);
62+
}
4963
};
5064

5165
#endif // CURAFRAME_MULTI_BUNDLE_EVALUATOR_HPP

cura_frame/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
See docs/PHILOSOPHY.md and docs/ETHICAL_USE.md for guiding principles.
1212
"""
1313

14-
__version__ = "2.5.0"
14+
__version__ = "3.0.0"
1515

1616
from .core import (
1717
CuraFrame,

docs/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
All notable changes to the C++ parallel evaluation universe will be documented in this file.
44

5+
## [3.0.0] - Weighted Scoring Engine
6+
7+
### Added
8+
- **Weighted Multi-Constraint Scoring Engine**: Introduced a unified scoring engine that computes a Composite Stability Score (0-100) from constraint bundle outputs.
9+
- **Scoring Pipeline & Reports**: Added `ScoringPipeline` and `ScoringReport` to aggregate penalties, bonuses, falsification impacts, and generate narrative summaries.
10+
- **Weight Profiles**: Introduced configurable `WeightProfile` abstractions, including `DefaultResearchProfile` and `HighSafetyProfile`, for dynamic domain and signal weighting.
11+
- **Integration**: Updated `MultiBundleEvaluator` to seamlessly pass evaluation reports into the scoring engine via `score` and `score_with_profile` methods without altering underlying constraint logic.
12+
- **Documentation**: Added `scoring_engine.md` and `weight_profiles.md` detailing the scoring architecture and weight profile designs.
13+
14+
### Changed
15+
- Bumped project version to 3.0.0.
16+
517
## [2.5.0] - Constraint-Bundle Universe
618

719
### Added

docs/scoring_engine.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# CuraFrame Weighted Multi-Constraint Scoring Engine (v3.0.0)
2+
3+
## Overview
4+
5+
The Weighted Multi-Constraint Scoring Engine is a subsystem added in v3.0.0 that sits above the existing constraint bundles. It takes the output (signals, falsifications, and narrative summaries) from all bundles and distills them into a unified, modular, and configurable **Composite Stability Score**.
6+
7+
This system does not alter or modify the underlying deterministic bundle evaluation logic. Instead, it aggregates results and applies domain-specific weighting, penalties, and bonuses to produce a nuanced report of therapeutic candidate viability.
8+
9+
## Architecture
10+
11+
1. **WeightProfile (`scoring/WeightProfile.hpp`)**: An interface (with default implementations) that defines the weights, penalties, multipliers, and scaling factors for different domains and specific signals.
12+
2. **WeightedScoringEngine (`scoring/WeightedScoringEngine.hpp/.cpp`)**: The core engine that ingests the outputs from all bundles (`EvaluationReport`), applies the provided `WeightProfile`, computes the final score, and generates a structured summary.
13+
3. **ScoringPipeline (`scoring/ScoringPipeline.hpp/.cpp`)**: A wrapper pipeline managing the execution of the scoring engine with a specified weight profile.
14+
4. **ScoringReport (`scoring/ScoringReport.hpp`)**: The structured output structure, detailing penalty breakdowns, bonus breakdowns, falsification impacts, and a narrative summary.
15+
16+
## Composite Stability Score
17+
18+
The Composite Stability Score is a numerical representation of candidate stability scaled between 0 and 100:
19+
- **100**: Perfect theoretical safety baseline, zero constraint violations or penalized signals.
20+
- **< 100**: Progressive deterioration of the score based on domain-weighted penalties, amplified by specific severity levels, or falsification flags.
21+
- **Falsification impact**: Candidate falsification triggers massive penalty deductions (configurable per weight profile), severely lowering the final score.
22+
23+
Higher scores indicate more stable candidates, and lower scores indicate more risk-burdened candidates.
24+
25+
## Example Report Execution
26+
27+
```cpp
28+
MultiBundleEvaluator evaluator;
29+
EvaluationReport eval_report = evaluator.evaluate(candidate);
30+
31+
// Generate standard composite scoring
32+
ScoringReport score = evaluator.score(eval_report);
33+
34+
// Generate with an aggressive safety profile
35+
ScoringReport safety_score = evaluator.score_with_profile(eval_report, std::make_shared<HighSafetyProfile>());
36+
```

docs/weight_profiles.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Weight Profiles (v3.0.0)
2+
3+
## Design and Intent
4+
5+
Weight Profiles allow the CuraFrame Scoring Engine to view candidates under different lenses of scrutiny. Instead of hardcoded aggregation metrics, `WeightProfile` provides a configurable approach to amplifying certain domains (e.g., Cardiac or CNS safety) based on the context of the evaluation.
6+
7+
## Built-in Profiles
8+
9+
### 1. `DefaultResearchProfile`
10+
- A balanced, general-purpose profile.
11+
- Mildly emphasizes safety parameters but treats most domains with an equal base weight.
12+
13+
### 2. `HighSafetyProfile`
14+
- Designed for late-stage conservative screening.
15+
- Applies heavy multipliers to `Safety`, `Cardiac`, `CNS`, and `SystemicExposure` domains.
16+
- Heavily amplifies specific toxicity signals.
17+
- Punishes falsification flags almost entirely zeroing out candidate viability.
18+
19+
## Extending Weight Profiles
20+
21+
To create a new weight profile, inherit from the `WeightProfile` abstract base class and implement the necessary configuration hooks.
22+
23+
```cpp
24+
class PediatricSafetyProfile : public WeightProfile {
25+
public:
26+
std::string name() const override { return "PediatricSafetyProfile"; }
27+
28+
double bundle_weight(const std::string& bundle_name) const override {
29+
// Significantly amplify systemic exposure and safety for pediatric focus
30+
if (bundle_name == "SystemicExposure" || bundle_name == "Safety") return 3.0;
31+
return 1.0;
32+
}
33+
34+
double signal_weight(const std::string& bundle_name, const std::string& signal_name) const override {
35+
if (signal_name.find("clearance") != std::string::npos) return 2.0;
36+
return 1.0;
37+
}
38+
39+
double falsification_penalty() const override { return 100.0; }
40+
};
41+
```

scoring/ScoringPipeline.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include "ScoringPipeline.hpp"
2+
3+
ScoringPipeline::ScoringPipeline(std::shared_ptr<WeightProfile> profile)
4+
: engine_(std::move(profile)) {}
5+
6+
ScoringReport ScoringPipeline::execute(const EvaluationReport& eval_report) const {
7+
// In a more complex pipeline, normalization or pre-processing could happen here
8+
// Currently, the WeightedScoringEngine handles everything deterministically
9+
return engine_.score(eval_report);
10+
}

scoring/ScoringPipeline.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef CURAFRAME_SCORING_PIPELINE_HPP
2+
#define CURAFRAME_SCORING_PIPELINE_HPP
3+
4+
#include "../constraint_core/EvaluationReport.hpp"
5+
#include "ScoringReport.hpp"
6+
#include "WeightedScoringEngine.hpp"
7+
#include "WeightProfile.hpp"
8+
#include <memory>
9+
10+
class ScoringPipeline {
11+
public:
12+
ScoringPipeline(std::shared_ptr<WeightProfile> profile);
13+
14+
ScoringReport execute(const EvaluationReport& eval_report) const;
15+
16+
private:
17+
WeightedScoringEngine engine_;
18+
};
19+
20+
#endif // CURAFRAME_SCORING_PIPELINE_HPP

scoring/ScoringReport.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef CURAFRAME_SCORING_REPORT_HPP
2+
#define CURAFRAME_SCORING_REPORT_HPP
3+
4+
#include <string>
5+
#include <vector>
6+
#include <map>
7+
8+
struct ScoringReport {
9+
double composite_score = 0.0; // 0 to 100
10+
11+
// Per-bundle weighted contributions
12+
std::map<std::string, double> bundle_contributions;
13+
14+
// Breakdowns
15+
std::map<std::string, double> penalty_breakdown;
16+
std::map<std::string, double> bonus_breakdown;
17+
18+
// Falsification
19+
std::vector<std::string> falsification_flags;
20+
double falsification_impact = 0.0;
21+
22+
// Metadata
23+
std::string weight_profile_name;
24+
25+
// Narrative summary
26+
std::string narrative_summary;
27+
};
28+
29+
#endif // CURAFRAME_SCORING_REPORT_HPP

0 commit comments

Comments
 (0)