-
Notifications
You must be signed in to change notification settings - Fork 1
fix(lineage): require exact calibrated active channel profiles #638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
|
|
||
| from __future__ import annotations | ||
|
|
||
| import math | ||
| from collections import defaultdict | ||
|
|
||
| import rankweave as rw | ||
|
|
@@ -25,8 +26,10 @@ | |
| # today, TEPP when integrated) -- product paths load the persisted | ||
| # corpus estimate, and the library demo estimates from its declared | ||
| # generative design (channel_weight_estimation.estimate_fixture_channel_weights). | ||
| # Every reconstruct() caller passes weights explicitly; the llm entry | ||
| # renormalizes away when no client is configured (see active_weights()). | ||
| # Every reconstruct() caller passes weights for the exact channel set it can | ||
| # execute; a vector estimated for another set is never repaired or renormalized. | ||
|
|
||
| _CORE_WEIGHT_CHANNELS = frozenset({"temporal", "secondary_key", "text"}) | ||
|
|
||
| # ponytail: only the most recent WINDOW prior records in a group are | ||
| # considered as candidate parents, bounding per-group cost to O(n*window) | ||
|
|
@@ -47,12 +50,23 @@ | |
| def active_weights( | ||
| llm: AdjudicationClient, weights: dict[str, float] | ||
| ) -> dict[str, float]: | ||
| """Drop and renormalize the llm channel's weight when no client is configured.""" | ||
| active = dict(weights) | ||
| if not getattr(llm, "available", False): | ||
| active.pop("llm", None) | ||
| total = sum(active.values()) | ||
| return {channel: weight / total for channel, weight in active.items()} | ||
| """Validate and return the calibrated vector for the exact active channels.""" | ||
|
|
||
| expected = set(_CORE_WEIGHT_CHANNELS) | ||
| if getattr(llm, "available", False): | ||
| expected.add("llm") | ||
| if set(weights) != expected: | ||
| raise ValueError("weights must exactly match the active lineage channels") | ||
|
Comment on lines
+55
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: Exact-match change is consistent across all callers Switching from drop-and-renormalize to exact-match-or-raise could break a caller passing a four-channel vector with an unavailable llm. Every caller derives its channel set from the same Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| values = tuple(weights.values()) | ||
| if any( | ||
| isinstance(value, bool) | ||
| or not isinstance(value, (int, float)) | ||
| or not math.isfinite(float(value)) | ||
| or float(value) <= 0.0 | ||
| for value in values | ||
| ) or not math.isclose(sum(values), 1.0, abs_tol=1e-9): | ||
| raise ValueError("active lineage weights must be finite, positive, and sum to one") | ||
|
Comment on lines
+67
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: Sum-to-one tolerance matches the weight loader The new Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| return dict(weights) | ||
|
Comment on lines
+55
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Code contradicts the mandatory pluggable-channel convention
Prompt for agentsWas this helpful? React with 👍 or 👎 to provide feedback. |
||
|
|
||
|
|
||
| def _group_by(records: list[Record]) -> dict[str, list[Record]]: | ||
|
|
@@ -159,10 +173,10 @@ def reconstruct( | |
| records: every record across every group; grouping happens here. | ||
| llm: adjudication channel client; defaults to | ||
| :class:`~lineageweave.adjudication_client.NullAdjudicationClient` | ||
| (the llm channel is then dropped, not faked). | ||
| weights: per-channel fusion weights before llm-availability | ||
| renormalization. Required, and always a psychometric | ||
| estimate (ADR 0145, second amendment): the persisted | ||
| (the supplied vector must therefore omit the llm channel). | ||
| weights: fusion weights calibrated for exactly the channels this call | ||
| executes. Required, and always a psychometric estimate (ADR 0145, | ||
| second amendment): the persisted | ||
| fast-mlsirm corpus estimate on product paths, or | ||
| :func:`~lineageweave.channel_weight_estimation.estimate_fixture_channel_weights` | ||
| for the library demo. No hand-picked default exists. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
llmis absent or reportsavailable = False, callers supplying a vector that includesllmnow receiveValueErrorinstead of reconstructing with that unavailable channel removed. Restore droppingllmand renormalizing the remaining weights, as required forNullAdjudicationClient; otherwise the documented missing-signal fallback is broken.AGENTS.md reference: AGENTS.md:L189-L195
Useful? React with 👍 / 👎.