Attribution Engine¶
Confidence aggregation with conformal calibration: ResolvedEntity[] → AttributionRecord.
Aggregator¶
aggregator
¶
Multi-source credit aggregation for attribution.
Core component of Pipeline 3 (Attribution Engine). Aggregates credits from
multiple ResolvedEntity objects into a single AttributionRecord.
Handles disagreements between sources using weighted voting based on
source reliability.
Default source reliability weights (from constants.SOURCE_RELIABILITY_WEIGHTS):
- MusicBrainz -- highest weight (community-curated, structured data)
- Discogs -- medium weight (community-curated, less structured)
- AcoustID -- medium weight (acoustic fingerprint-based)
- File metadata -- lowest weight (often incomplete or incorrect)
- Artist input -- high weight (authoritative but potentially biased)
Notes
Implements the multi-source aggregation described in Teikari (2026), Section 5.1. The weighted voting approach ensures that higher-quality sources have more influence on the final attribution, while still incorporating evidence from all available sources.
See Also
music_attribution.attribution.conformal : Calibration of aggregated scores. music_attribution.attribution.persistence : Storage of attribution records. music_attribution.constants : Source reliability weight definitions.
CreditAggregator
¶
CreditAggregator(
source_weights: dict[SourceEnum, float] | None = None,
)
Aggregate credits from resolved entities into attribution records.
Uses weighted voting based on source reliability to handle
disagreements between sources. Produces a complete AttributionRecord
with credits, confidence, assurance level, and provenance chain.
| PARAMETER | DESCRIPTION |
|---|---|
source_weights
|
Per-source reliability weight overrides. If
TYPE:
|
| ATTRIBUTE | DESCRIPTION |
|---|---|
_source_weights |
Active source reliability weights.
TYPE:
|
See Also
music_attribution.attribution.conformal.ConformalScorer : Calibrate the aggregated score. music_attribution.attribution.priority_queue.ReviewPriorityQueue : Prioritize records for review.
Source code in src/music_attribution/attribution/aggregator.py
aggregate
async
¶
aggregate(
work_entity: ResolvedEntity,
contributor_entities: list[ResolvedEntity],
roles: dict[UUID, CreditRoleEnum],
) -> AttributionRecord
Aggregate resolved entities into a single AttributionRecord.
Builds per-credit confidence scores from source reliability weights, computes overall attribution confidence and source agreement, and initializes the provenance chain with a SCORE event.
Records with confidence below REVIEW_THRESHOLD are automatically
flagged for human review with priority = 1.0 - confidence.
| PARAMETER | DESCRIPTION |
|---|---|
work_entity
|
The work or recording entity being attributed.
TYPE:
|
contributor_entities
|
Resolved contributor entities (artists, producers, etc.).
TYPE:
|
roles
|
Mapping of contributor
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
AttributionRecord
|
Complete attribution record with credits, confidence, assurance level, conformal set placeholder, and provenance. |
See Also
music_attribution.attribution.conformal.ConformalScorer.score : Apply conformal calibration to the aggregated record.
Source code in src/music_attribution/attribution/aggregator.py
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | |
Conformal Prediction¶
conformal
¶
Conformal prediction confidence scoring for attribution.
Wraps attribution confidence in conformal prediction sets to ensure calibrated uncertainty quantification. When the system says "90% confident", this module guarantees that the prediction set covers the true label at least 90% of the time.
Implements the Adaptive Prediction Sets (APS) method:
- Sort candidate labels by decreasing confidence.
- Include labels in the prediction set until cumulative confidence reaches the target coverage level.
- The resulting set size reflects true uncertainty: larger sets mean more ambiguity.
The CalibrationReport tracks Expected Calibration Error (ECE) using
equal-width binning to detect systematic over- or under-confidence.
Notes
Implements the conformal prediction framework described in Teikari (2026), Section 5.2. Based on the theoretical foundations of Vovk et al. (2005), "Algorithmic Learning in a Random World."
References
.. [1] Vovk, V., Gammerman, A., & Shafer, G. (2005). "Algorithmic Learning in a Random World." Springer. .. [2] Romano, Y., Sesia, M., & Candes, E. (2020). "Classification with Valid and Adaptive Coverage." NeurIPS.
See Also
music_attribution.attribution.aggregator : Upstream confidence aggregation. music_attribution.schemas.attribution.ConformalSet : Pydantic model for prediction sets.
CalibrationReport
¶
Bases: BaseModel
Report on calibration quality using equal-width binning.
Tracks Expected Calibration Error (ECE) and per-bin accuracy vs. confidence, enabling detection of systematic over- or under-confidence in the scoring model.
| ATTRIBUTE | DESCRIPTION |
|---|---|
ece |
Expected Calibration Error -- weighted average of per-bin
TYPE:
|
marginal_coverage |
Achieved coverage (fraction of correct predictions) in [0, 1].
TYPE:
|
target_coverage |
Target coverage level (e.g., 0.9 for 90% coverage).
TYPE:
|
calibration_method |
Name of the calibration method (e.g.,
TYPE:
|
calibration_set_size |
Number of samples used for calibration.
TYPE:
|
bin_accuracies |
Per-bin accuracy values (10 bins by default).
TYPE:
|
bin_confidences |
Per-bin mean confidence values (10 bins by default).
TYPE:
|
timestamp |
When the calibration was computed (UTC).
TYPE:
|
ConformalScorer
¶
Conformal prediction scorer for attribution confidence.
Uses the Adaptive Prediction Sets (APS) method to produce calibrated prediction sets at specified coverage levels. The prediction set includes the minimum number of candidate labels needed to achieve the target coverage.
Notes
A well-calibrated model produces small prediction sets (often just 1 label) for high-confidence predictions and larger sets for ambiguous cases. The set size itself is a useful uncertainty signal.
See Also
music_attribution.attribution.aggregator.CreditAggregator : Produces the raw confidence scores that are calibrated here.
score
¶
score(
predictions: list[tuple[CreditRoleEnum, float]],
coverage: float = 0.9,
) -> ConformalSet
Produce a conformal prediction set at the specified coverage level.
Sorts candidate roles by confidence descending, then includes roles until cumulative confidence reaches the target coverage. If total confidence across all candidates is less than the target, all candidates are included.
| PARAMETER | DESCRIPTION |
|---|---|
predictions
|
List of
TYPE:
|
coverage
|
Target coverage level. Default is 0.90 (90% coverage).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ConformalSet
|
Prediction set with coverage metadata. The |
Source code in src/music_attribution/attribution/conformal.py
calibrate
¶
calibrate(
predictions: list[tuple[float, bool]],
) -> CalibrationReport
Compute calibration metrics from predictions vs. actual outcomes.
Uses equal-width binning (10 bins spanning [0, 1]) to compute:
- ECE (Expected Calibration Error): weighted average of
per-bin
|accuracy - confidence|. - Per-bin accuracy: fraction of correct predictions in each bin.
- Per-bin confidence: mean predicted probability in each bin.
- Marginal coverage: overall fraction of correct predictions.
| PARAMETER | DESCRIPTION |
|---|---|
predictions
|
List of
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
CalibrationReport
|
Calibration metrics including ECE and per-bin breakdowns. Returns an empty report (ECE=0) if no predictions are provided. |
Notes
A perfectly calibrated model has ECE=0 and bin accuracies that match bin confidences (i.e., the reliability diagram is a 45-degree line). See Naeini et al. (2015) for ECE methodology.
Source code in src/music_attribution/attribution/conformal.py
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | |
Persistence¶
persistence
¶
AttributionRecord persistence repositories.
Provides two repository implementations for AttributionRecord storage:
AttributionRecordRepository: In-memory storage for development and testing. No database required; data is lost on process exit.AsyncAttributionRepository: Async PostgreSQL storage via SQLAlchemyAsyncSession. Production-grade with ACID guarantees.
Both repositories expose the same async interface:
store()-- persist a new attribution record.update()-- update an existing record (auto-increments version).find_by_id()-- lookup by attribution UUID.find_by_work_entity_id()-- lookup by work entity UUID.find_needs_review()-- fetch records flagged for human review.
Every update appends a ProvenanceEvent to the record's provenance
chain, creating an immutable audit trail.
Notes
The provenance chain is a key component of the attribution-by-design philosophy described in Teikari (2026), Section 5.3. Every change to an attribution record is recorded with timestamp, agent, and details.
See Also
music_attribution.schemas.attribution : Pydantic models for attribution. music_attribution.db.models.AttributionRecordModel : SQLAlchemy ORM model.
AttributionRecordRepository
¶
In-memory repository for AttributionRecord persistence.
Provides the same async interface as AsyncAttributionRepository
so that dev/test code can be written against the same API. Records
are stored as deep copies to prevent mutation through references.
| ATTRIBUTE | DESCRIPTION |
|---|---|
_records |
In-memory record storage keyed by
TYPE:
|
Source code in src/music_attribution/attribution/persistence.py
store
async
¶
store(record: AttributionRecord) -> UUID
Store an attribution record (deep copy).
| PARAMETER | DESCRIPTION |
|---|---|
record
|
The attribution record to store.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
UUID
|
The |
Source code in src/music_attribution/attribution/persistence.py
update
async
¶
update(record: AttributionRecord) -> UUID
Update an existing attribution record with provenance tracking.
Increments the version number, updates the timestamp, and appends
an UPDATE provenance event to the record's provenance chain.
| PARAMETER | DESCRIPTION |
|---|---|
record
|
The record to update.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
UUID
|
The |
Source code in src/music_attribution/attribution/persistence.py
find_by_id
async
¶
find_by_id(
attribution_id: UUID,
) -> AttributionRecord | None
Find an attribution record by its UUID.
| PARAMETER | DESCRIPTION |
|---|---|
attribution_id
|
The attribution record UUID to look up.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
AttributionRecord | None
|
Deep copy of the record if found, |
Source code in src/music_attribution/attribution/persistence.py
find_by_work_entity_id
async
¶
find_by_work_entity_id(
work_entity_id: UUID,
) -> AttributionRecord | None
Find an attribution record by work entity ID.
| PARAMETER | DESCRIPTION |
|---|---|
work_entity_id
|
The work entity UUID.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
AttributionRecord | None
|
Deep copy of the first matching record, or |
Source code in src/music_attribution/attribution/persistence.py
find_needs_review
async
¶
find_needs_review(
limit: int = 50,
) -> list[AttributionRecord]
Find records that need human review, sorted by priority descending.
| PARAMETER | DESCRIPTION |
|---|---|
limit
|
Maximum number of records to return. Default is 50.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[AttributionRecord]
|
Deep copies of records with |
Source code in src/music_attribution/attribution/persistence.py
AsyncAttributionRepository
¶
Async PostgreSQL repository for AttributionRecord persistence.
Production-grade repository using SQLAlchemy AsyncSession for
database access. All methods require an active session; the caller
is responsible for transaction management (commit/rollback).
Provides the same logical operations as AttributionRecordRepository
but backed by PostgreSQL with ACID guarantees and JSONB storage for
nested Pydantic models.
store
async
¶
store(
record: AttributionRecord, session: AsyncSession
) -> UUID
Store an attribution record in PostgreSQL.
| PARAMETER | DESCRIPTION |
|---|---|
record
|
The attribution record to store.
TYPE:
|
session
|
Active async database session.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
UUID
|
The |
Source code in src/music_attribution/attribution/persistence.py
update
async
¶
update(
record: AttributionRecord, session: AsyncSession
) -> UUID
Update an existing attribution record with provenance tracking.
Increments the version number, updates the timestamp, appends an
UPDATE provenance event, and persists changes via
session.flush().
| PARAMETER | DESCRIPTION |
|---|---|
record
|
The record to update.
TYPE:
|
session
|
Active async database session.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
UUID
|
The |
| RAISES | DESCRIPTION |
|---|---|
NoResultFound
|
If no record with the given |
Source code in src/music_attribution/attribution/persistence.py
find_by_id
async
¶
find_by_id(
attribution_id: UUID, session: AsyncSession
) -> AttributionRecord | None
Find an attribution record by its UUID.
| PARAMETER | DESCRIPTION |
|---|---|
attribution_id
|
The attribution record UUID to look up.
TYPE:
|
session
|
Active async database session.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
AttributionRecord | None
|
The validated Pydantic record if found, |
Source code in src/music_attribution/attribution/persistence.py
find_by_work_entity_id
async
¶
find_by_work_entity_id(
work_entity_id: UUID, session: AsyncSession
) -> AttributionRecord | None
Find the most recent attribution record for a work entity.
Returns the record with the highest version number if multiple versions exist for the same work entity.
| PARAMETER | DESCRIPTION |
|---|---|
work_entity_id
|
The work entity UUID.
TYPE:
|
session
|
Active async database session.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
AttributionRecord | None
|
The most recent record for this work, or |
Source code in src/music_attribution/attribution/persistence.py
find_needs_review
async
¶
find_needs_review(
limit: int = 50, *, session: AsyncSession
) -> list[AttributionRecord]
Find records that need human review, sorted by priority descending.
| PARAMETER | DESCRIPTION |
|---|---|
limit
|
Maximum number of records to return. Default is 50.
TYPE:
|
session
|
Active async database session.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[AttributionRecord]
|
Records with |
Source code in src/music_attribution/attribution/persistence.py
list_all
async
¶
list_all(
limit: int = 50,
offset: int = 0,
*,
session: AsyncSession,
) -> list[AttributionRecord]
List all attribution records with pagination.
Returns records ordered by created_at ascending (oldest first).
| PARAMETER | DESCRIPTION |
|---|---|
limit
|
Maximum number of records to return. Default is 50.
TYPE:
|
offset
|
Number of records to skip for pagination. Default is 0.
TYPE:
|
session
|
Active async database session.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[AttributionRecord]
|
Paginated list of attribution records. |
Source code in src/music_attribution/attribution/persistence.py
Priority Queue¶
priority_queue
¶
Active learning priority queue for attribution review.
Ranks AttributionRecord objects by review priority for human experts.
Uses a multi-factor priority formula combining five signals:
- Boundary proximity (weight=0.30): Records near the 0.5 confidence decision boundary are most informative for active learning, as human feedback on these cases maximally reduces model uncertainty.
- Source disagreement (weight=0.25): Low inter-source agreement indicates conflicting evidence that needs human arbitration.
- Ambiguity (weight=0.15): Large conformal prediction set sizes indicate genuine uncertainty about the credit role.
- Never-reviewed penalty (weight=0.15): Records that have never been reviewed (version=1) are prioritized over already-reviewed ones.
- Staleness (weight=0.15): Records not updated for 30+ days are prioritized to ensure periodic re-validation.
Notes
This implements the active learning review queue described in Teikari (2026), Section 5.4. The boundary proximity criterion follows the uncertainty sampling strategy from Settles (2009), "Active Learning Literature Survey."
See Also
music_attribution.attribution.persistence : Persistence layer that provides
find_needs_review() for initial candidate retrieval.
music_attribution.attribution.aggregator : Produces the confidence and
agreement scores used for priority computation.
ReviewPriorityQueue
¶
Priority queue for attribution review.
Ranks records by a composite priority score combining five factors that indicate review urgency. Higher scores mean higher priority for human expert review.
| PARAMETER | DESCRIPTION |
|---|---|
weights
|
Override the default factor weights. Keys must be:
TYPE:
|
| ATTRIBUTE | DESCRIPTION |
|---|---|
_weights |
Active priority factor weights.
TYPE:
|
Source code in src/music_attribution/attribution/priority_queue.py
compute_priority
¶
compute_priority(record: AttributionRecord) -> float
Compute review priority score for an attribution record.
Combines five weighted factors into a single priority score. Higher scores indicate higher review urgency.
| PARAMETER | DESCRIPTION |
|---|---|
record
|
The attribution record to prioritize.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
float
|
Priority score clamped to range [0.0, 1.0]. |
Source code in src/music_attribution/attribution/priority_queue.py
next_for_review
¶
next_for_review(
records: list[AttributionRecord], limit: int = 10
) -> list[AttributionRecord]
Return top records needing review, sorted by priority.
Scores all input records and returns the top limit by
descending priority. Does not filter by needs_review flag;
the caller should pre-filter if desired.
| PARAMETER | DESCRIPTION |
|---|---|
records
|
All attribution records to consider.
TYPE:
|
limit
|
Maximum number of records to return. Default is 10.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[AttributionRecord]
|
Records sorted by priority (highest first), limited to
|