Upload 14 files
Browse files- src/timeline_model.py +24 -14
src/timeline_model.py
CHANGED
|
@@ -443,14 +443,12 @@ def _archive_warning(bundle: dict[str, Any], *, terminal: bool) -> dict[str, Any
|
|
| 443 |
status = _eval_publish(bundle)
|
| 444 |
if not status or status.get("published") is True:
|
| 445 |
return None
|
| 446 |
-
# record_not_ready is
|
| 447 |
-
# It
|
| 448 |
-
if
|
| 449 |
return None
|
| 450 |
if status.get("attempted"):
|
| 451 |
return {"code": "eval_archive_not_published", "label": "Eval archive not published", "detail": str(status.get("reason") or "Backend archive copy did not complete.")}
|
| 452 |
-
if terminal:
|
| 453 |
-
return {"code": "eval_archive_pending", "label": "Eval archive pending", "detail": "Backend archive copy has not been confirmed yet."}
|
| 454 |
return None
|
| 455 |
|
| 456 |
|
|
@@ -513,7 +511,7 @@ def _build_phase_details(bundle: dict[str, Any], phase: str) -> list[dict[str, A
|
|
| 513 |
details.append({"label": str(eval_status.get("archive_relative_path")), "status": "info"})
|
| 514 |
elif eval_status.get("attempted"):
|
| 515 |
if _is_record_not_ready(eval_status):
|
| 516 |
-
details.append({"label": "Eval archive
|
| 517 |
else:
|
| 518 |
details.append({"label": f"Eval archive not published: {eval_status.get('reason') or 'unknown'}", "status": "warning"})
|
| 519 |
else:
|
|
@@ -542,9 +540,11 @@ def _build_phase_details(bundle: dict[str, Any], phase: str) -> list[dict[str, A
|
|
| 542 |
|
| 543 |
def _phase_summary(bundle: dict[str, Any], phase: str, status: str) -> str:
|
| 544 |
if phase == "agent":
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
|
|
|
|
|
|
|
| 548 |
if phase == "hardware":
|
| 549 |
warning = _hardware_warning(bundle)
|
| 550 |
if warning:
|
|
@@ -587,6 +587,8 @@ def _phase_summary(bundle: dict[str, Any], phase: str, status: str) -> str:
|
|
| 587 |
return "Eval archive published"
|
| 588 |
if eval_status.get("attempted") and not _is_record_not_ready(eval_status):
|
| 589 |
return "Eval archive attempted"
|
|
|
|
|
|
|
| 590 |
return "Archive pending" if status in {"pending", "running"} else "Final artifacts written"
|
| 591 |
if phase == "done":
|
| 592 |
label, _ = _status_label(_verdict(bundle))
|
|
@@ -632,6 +634,15 @@ def _phase_status(bundle: dict[str, Any], phase: str, verdict: str) -> str:
|
|
| 632 |
pi_run = latest_by_step.get("pi_run") or {}
|
| 633 |
if _lower(pi_run.get("status")) in RUNNING_STATUSES and not terminal:
|
| 634 |
return "running"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 635 |
|
| 636 |
if phase == "deploy":
|
| 637 |
blocker = _final_blocker_label(bundle)
|
|
@@ -654,18 +665,17 @@ def _phase_status(bundle: dict[str, Any], phase: str, verdict: str) -> str:
|
|
| 654 |
if eval_status.get("published") is True:
|
| 655 |
return "complete"
|
| 656 |
if eval_status.get("attempted"):
|
| 657 |
-
if
|
| 658 |
-
return "pending"
|
| 659 |
return "warning"
|
| 660 |
if terminal:
|
| 661 |
-
return "
|
| 662 |
return "pending"
|
| 663 |
|
| 664 |
if phase == "deploy" and _build_error_observation(bundle):
|
| 665 |
return "failed"
|
| 666 |
|
| 667 |
-
|
| 668 |
-
return "warning"
|
| 669 |
if phase == "hardware" and _hardware_warning(bundle):
|
| 670 |
return "warning"
|
| 671 |
|
|
|
|
| 443 |
status = _eval_publish(bundle)
|
| 444 |
if not status or status.get("published") is True:
|
| 445 |
return None
|
| 446 |
+
# record_not_ready is expected during the terminal write/reconcile window.
|
| 447 |
+
# It is a neutral finalization state, not an action required for users.
|
| 448 |
+
if _is_record_not_ready(status):
|
| 449 |
return None
|
| 450 |
if status.get("attempted"):
|
| 451 |
return {"code": "eval_archive_not_published", "label": "Eval archive not published", "detail": str(status.get("reason") or "Backend archive copy did not complete.")}
|
|
|
|
|
|
|
| 452 |
return None
|
| 453 |
|
| 454 |
|
|
|
|
| 511 |
details.append({"label": str(eval_status.get("archive_relative_path")), "status": "info"})
|
| 512 |
elif eval_status.get("attempted"):
|
| 513 |
if _is_record_not_ready(eval_status):
|
| 514 |
+
details.append({"label": "Eval archive finalizing", "status": "info"})
|
| 515 |
else:
|
| 516 |
details.append({"label": f"Eval archive not published: {eval_status.get('reason') or 'unknown'}", "status": "warning"})
|
| 517 |
else:
|
|
|
|
| 540 |
|
| 541 |
def _phase_summary(bundle: dict[str, Any], phase: str, status: str) -> str:
|
| 542 |
if phase == "agent":
|
| 543 |
+
# A Pi model mismatch is an audit note rendered in Run notes, not a
|
| 544 |
+
# phase-level issue. Keep the Agent phase focused on Pi execution and
|
| 545 |
+
# trace collection so successful terminal runs do not show a misleading
|
| 546 |
+
# NEEDS ATTENTION state.
|
| 547 |
+
pass
|
| 548 |
if phase == "hardware":
|
| 549 |
warning = _hardware_warning(bundle)
|
| 550 |
if warning:
|
|
|
|
| 587 |
return "Eval archive published"
|
| 588 |
if eval_status.get("attempted") and not _is_record_not_ready(eval_status):
|
| 589 |
return "Eval archive attempted"
|
| 590 |
+
if eval_status.get("attempted") and _is_record_not_ready(eval_status):
|
| 591 |
+
return "Finalizing archive" if status in {"pending", "running"} else "Final artifacts written"
|
| 592 |
return "Archive pending" if status in {"pending", "running"} else "Final artifacts written"
|
| 593 |
if phase == "done":
|
| 594 |
label, _ = _status_label(_verdict(bundle))
|
|
|
|
| 634 |
pi_run = latest_by_step.get("pi_run") or {}
|
| 635 |
if _lower(pi_run.get("status")) in RUNNING_STATUSES and not terminal:
|
| 636 |
return "running"
|
| 637 |
+
if terminal:
|
| 638 |
+
material_events = [e for e in _events_for_phase(bundle, phase) if _lower(e.get("step")) != "pi_model_resolution"]
|
| 639 |
+
material_statuses = {_lower(e.get("status")) for e in material_events}
|
| 640 |
+
if material_statuses.intersection(FAILED_STATUSES):
|
| 641 |
+
return "failed"
|
| 642 |
+
if material_statuses.intersection(RUNNING_STATUSES):
|
| 643 |
+
return "running"
|
| 644 |
+
if material_statuses.intersection(SUCCESS_STATUSES) or _has_downstream_proof(bundle, phase):
|
| 645 |
+
return "complete"
|
| 646 |
|
| 647 |
if phase == "deploy":
|
| 648 |
blocker = _final_blocker_label(bundle)
|
|
|
|
| 665 |
if eval_status.get("published") is True:
|
| 666 |
return "complete"
|
| 667 |
if eval_status.get("attempted"):
|
| 668 |
+
if _is_record_not_ready(eval_status):
|
| 669 |
+
return "pending" if not terminal else "complete"
|
| 670 |
return "warning"
|
| 671 |
if terminal:
|
| 672 |
+
return "complete" if bundle.get("eval_record") else "pending"
|
| 673 |
return "pending"
|
| 674 |
|
| 675 |
if phase == "deploy" and _build_error_observation(bundle):
|
| 676 |
return "failed"
|
| 677 |
|
| 678 |
+
# Pi model changes are surfaced as run notes, not phase warnings.
|
|
|
|
| 679 |
if phase == "hardware" and _hardware_warning(bundle):
|
| 680 |
return "warning"
|
| 681 |
|