fix(rectification): hold time cards until propose gate and interview stop
Keep representative-time cards off while method coverage is still open. New cases bind Skill 10.0.9; existing 10.0.8 packages stay hashed. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -84,6 +84,7 @@ def score_candidates(request: RectificationRequest) -> dict[str, Any]:
|
||||
"display_allowed": decision_receipt["display_allowed"],
|
||||
"selection_allowed": decision_receipt["selection_allowed"],
|
||||
"acceptance_allowed": decision_receipt["acceptance_allowed"],
|
||||
"propose_allowed": decision_receipt["propose_allowed"],
|
||||
"confirmation_allowed": decision_receipt["confirmation_allowed"],
|
||||
"representative_candidate_id": representative["candidate_id"] if representative else None,
|
||||
"representative_time": representative["time"] if representative else None,
|
||||
@@ -111,6 +112,7 @@ def diagnostics(request: RectificationRequest) -> dict[str, Any]:
|
||||
"display_allowed": scored["display_allowed"],
|
||||
"selection_allowed": scored["selection_allowed"],
|
||||
"acceptance_allowed": scored["acceptance_allowed"],
|
||||
"propose_allowed": scored["propose_allowed"],
|
||||
"confirmation_allowed": scored["confirmation_allowed"],
|
||||
"representative_candidate_id": scored["representative_candidate_id"],
|
||||
"representative_time": scored["representative_time"],
|
||||
|
||||
@@ -33,6 +33,7 @@ MIN_ACCEPTANCE_DOMAINS = 2
|
||||
MIN_DATE_QUALITY_MEAN = Decimal("0.65")
|
||||
MIN_DIAGNOSTIC_RETENTION = Decimal("0.75")
|
||||
MIN_ACCEPTANCE_MARGIN_PERCENT = Decimal("10")
|
||||
POLICY_SKIPPED_LAYERS = frozenset({"KP_cusps"})
|
||||
|
||||
_BAD_DATE_RELIABILITY = frozenset({"low", "uncertain", "unreliable"})
|
||||
_CLEAR_DATE_CONFLICT = frozenset({"", "none", "resolved", "no_conflict"})
|
||||
@@ -271,7 +272,7 @@ def build_technique_audit(
|
||||
rows.append({
|
||||
"technique": "KP 宫头",
|
||||
"status": "blocked",
|
||||
"note": "KP 宫头本轮未计算。",
|
||||
"note": "KP 宫头政策跳过,不参与提出门或确认门。",
|
||||
})
|
||||
rows.extend((
|
||||
vedastro_audit_row(vedastro_status),
|
||||
@@ -335,6 +336,14 @@ def _gate(passed: bool, **details: Any) -> dict[str, Any]:
|
||||
return {"passed": passed, **details}
|
||||
|
||||
|
||||
def _actionable_missing_layers(layers: Any) -> list[str]:
|
||||
return sorted({
|
||||
str(layer)
|
||||
for layer in (layers or [])
|
||||
if str(layer) not in POLICY_SKIPPED_LAYERS
|
||||
})
|
||||
|
||||
|
||||
def _date_quality(events: Sequence[dict[str, Any]]) -> dict[str, Any]:
|
||||
weights = [_decimal(precision_weight(str(event["precision"]))) for event in events]
|
||||
total = sum(weights, Decimal(0))
|
||||
@@ -405,9 +414,16 @@ def build_decision_receipt(
|
||||
top_tied_count = candidate_decisions[0]["tied_minute_count"] if candidate_decisions else 0
|
||||
unique_top = _gate(top_tied_count == 1, tied_minute_count=top_tied_count)
|
||||
diagnostic_quality = _diagnostic_quality(diagnostics)
|
||||
skipped_layers = sorted(
|
||||
str(layer)
|
||||
for layer in (built.get("missing_layers") or [])
|
||||
if str(layer) in POLICY_SKIPPED_LAYERS
|
||||
)
|
||||
actionable_missing_layers = _actionable_missing_layers(built.get("missing_layers"))
|
||||
required_layers = _gate(
|
||||
not built.get("missing_layers"),
|
||||
missing_layers=sorted(built.get("missing_layers") or []),
|
||||
not actionable_missing_layers,
|
||||
missing_layers=actionable_missing_layers,
|
||||
skipped_by_policy=skipped_layers,
|
||||
)
|
||||
|
||||
# Adoption is the session result when a representative time exists.
|
||||
@@ -472,15 +488,18 @@ def build_decision_receipt(
|
||||
confirmation_reasons.append("insufficient_confirmation_margin")
|
||||
if not adjacent_passed:
|
||||
confirmation_reasons.append("adjacent_minutes_indistinguishable")
|
||||
engine_granted = all((
|
||||
propose_allowed = all((
|
||||
acceptance_allowed,
|
||||
unique_top["passed"],
|
||||
diagnostic_quality["passed"],
|
||||
required_layers["passed"],
|
||||
confirmation_event_quality,
|
||||
confirmation_domain_quality,
|
||||
confirmation_margin,
|
||||
adjacent_passed,
|
||||
))
|
||||
engine_granted = all((
|
||||
propose_allowed,
|
||||
confirmation_margin,
|
||||
not dasha_conflict,
|
||||
))
|
||||
if not engine_granted:
|
||||
@@ -506,6 +525,7 @@ def build_decision_receipt(
|
||||
"display_allowed": bool(candidate_decisions),
|
||||
"selection_allowed": acceptance_allowed,
|
||||
"acceptance_allowed": acceptance_allowed,
|
||||
"propose_allowed": propose_allowed,
|
||||
"confirmation_allowed": False,
|
||||
"accept_allowed": acceptance_allowed,
|
||||
"confirm_allowed": False,
|
||||
|
||||
Reference in New Issue
Block a user