Skip to content

feat(pipeline): finalize on best iteration, not last#28

Merged
njaltran merged 1 commit into
feature/finetune-finbertfrom
feature/best-iteration-restore
Jul 2, 2026
Merged

feat(pipeline): finalize on best iteration, not last#28
njaltran merged 1 commit into
feature/finetune-finbertfrom
feature/best-iteration-restore

Conversation

@njaltran

@njaltran njaltran commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Problem

Accuracy can regress across retune passes — a real run showed history [0.21, 0.22, 0.24, 0.39, 0.37, 0.37]: iteration 3 hit 0.39, but the loop force-proceeded at 0.37, and each pass overwrites predictions_test.csv / evaluation_report.json / classifier.py. So explain + finalize ran on the regressed artifacts and the best iteration was lost.

Change

  • evaluate node snapshots PREDS/EVAL/CODE to outputs/best/ on each new accuracy best (tracked via best_accuracy / last_accuracy in graph state).
  • New select_best node on the proceed branch: gate ─(proceed)→ select_best → explain. If the last iteration wasn't the best, it restores the snapshot over the canonical paths and redraws sample_for_explanation.csv from the restored predictions.
  • Extracted the Manager's sampling into a shared write_sample() so the sample format keeps a single definition.

Gate semantics unchanged: the Manager still decides from the last iteration's report; the restore happens after the verdict. outputs/best/ is internal to the loop, not a new contract handoff — no data_contracts.md change.

Testing

New test test_best_iteration_restored_when_accuracy_regresses: fake Sabina emits a peak-then-regress accuracy sequence, fake Nadi stamps each pass into the predictions file; asserts the surviving artifacts are the best pass's and final_report.final_accuracy reflects it. Full suite: 34 passed.

Note

Stacked on #27 (feature/finetune-finbert) — merge that first; this PR then contains only f29a14a.

Accuracy can regress across retune passes (e.g. 0.39 at iter 3 but 0.37 at
the forced proceed), yet each pass overwrote predictions/eval/classifier, so
explain + finalize ran on the regressed artifacts.

- evaluate node snapshots PREDS/EVAL/CODE to outputs/best/ on each new best
- new select_best node on the proceed branch restores that snapshot and
  redraws sample_for_explanation.csv when the last iteration wasn't the best
- extract Manager's sampling into shared write_sample() so the sample format
  keeps a single definition

Gate semantics unchanged: the Manager still decides from the last
iteration's report; restore happens after the verdict.
Copilot AI review requested due to automatic review settings July 2, 2026 13:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@njaltran njaltran merged commit 1c23702 into feature/finetune-finbert Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants