fix(family): a decision read as precedent says its reason once - to_brief for precedents and idea history; the decision log keeps the full row (#5131)
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 1m13s
CI & Build / Python tests (push) Successful in 1m54s
CI & Build / Build & push image (push) Successful in 40s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 1m13s
CI & Build / Python tests (push) Successful in 1m54s
CI & Build / Build & push image (push) Successful in 40s
Each decision stored its reason three times (reason, before.reason, after.reason) and a promotion carried the whole criteria reasoning in evidence. Precedents (assess, promote, get_family_adoption, get_family_idea) and get_family_idea's history now serve FamilyDecision.to_brief(): reason once, before/after as status, canon_version and platforms, evidence as the cited list. list_family_decisions and the decision echoed back by a write keep to_dict. The precedent count was already bounded at five. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -357,3 +357,37 @@ class FamilyDecision(Base, CreatedAtMixin):
|
||||
"user_id": self.user_id,
|
||||
"created_at": iso(self.created_at),
|
||||
}
|
||||
|
||||
def to_brief(self) -> dict:
|
||||
"""The decision as a reader WEIGHING it needs it: what was decided,
|
||||
why — once — and the state it moved between.
|
||||
|
||||
Precedents and an idea's history are read in bulk, a handful per
|
||||
call, and the full row repeats itself: an assessment's reason is
|
||||
stored again inside `after` (and the prior one inside `before`), and
|
||||
a promotion's evidence carries the whole criteria reasoning. So a
|
||||
state here is its status, version and platforms only, and evidence is
|
||||
the cited list alone (#5131). The full row is `to_dict`, which the
|
||||
decision log serves.
|
||||
"""
|
||||
return {
|
||||
"id": self.id,
|
||||
"idea_id": self.idea_id,
|
||||
"project_id": self.project_id,
|
||||
"action": self.action,
|
||||
"reason": self.reason,
|
||||
"before": _brief_state(self.before),
|
||||
"after": _brief_state(self.after),
|
||||
"evidence": list((self.evidence or {}).get("evidence") or []),
|
||||
"created_at": iso(self.created_at),
|
||||
}
|
||||
|
||||
|
||||
# What a decision's before/after keeps in its brief: the state, not the prose.
|
||||
_BRIEF_STATE_KEYS = ("status", "canon_version", "platforms")
|
||||
|
||||
|
||||
def _brief_state(state: dict | None) -> dict | None:
|
||||
if state is None:
|
||||
return None
|
||||
return {k: state[k] for k in _BRIEF_STATE_KEYS if k in state}
|
||||
|
||||
Reference in New Issue
Block a user