Skip to content

templates: restore per-iter frames via pinned IpoptOptions.intermediate_callback (#177) - #184

Merged
kateebonner merged 1 commit into
mainfrom
amico/issue-177-frames
Jul 20, 2026
Merged

templates: restore per-iter frames via pinned IpoptOptions.intermediate_callback (#177)#184
kateebonner merged 1 commit into
mainfrom
amico/issue-177-frames

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Summary

Closes #177. Restores the per-iteration frame emitter (pulse_emit) in all four solve templates via the intermediate-callback hook that the pinned DirectTrajOpt 0.9.7 exposes (julia/Manifest.toml git-tree-sha1 c722d301a8d0… == v0.9.7^{tree} — verified against the package source, not docs).

  • IpoptOptions(intermediate_callback = pulse_emit)iter_<N>.png + AMICODE_PULSE per IPM iteration + STOP poll, composed with the existing cb_log stats callback.
  • hasfield-guarded (the templates: fix cloud-solve blockers (Ipopt callback + bare using Piccolissimo) #157 lesson): a cloud bundle still baked with DTO ≤ 0.9.6 degrades to stats-only (AMICODE_ITER still flows, frames dark, one @warn) instead of dying on a kwarg MethodError before the solve.
  • Templates touched: skeleton_free.jl, solve_rydberg_cz.jl, solve_template.jl, solve_template_hp.jl.

Verification (live bounded mini-solve, pinned julia env)

  • iter_00000.png / iter_00006.png / iter_00012.png produced; AMICODE_PULSE + AMICODE_ITER emitted every iteration; pulse.jld2 + result.toml written; run completed DONE fidelity=0.744 with no MethodError.

🤖 Generated with Claude Code

…te_callback (#177)

Re-wires pulse_emit (LivePulsePlotCallback delegate -> iter_*.png + AMICODE_PULSE
+ STOP poll) in all four templates through the intermediate-callback API that the
pinned DirectTrajOpt actually exposes — undoing the #157 removal now that the
bundle pin has the hook.

API verification (AC3), against the pin rather than docs:
- julia/Manifest.toml (repo copy == provisioned ~/.amico/julia copy) pins
  DirectTrajOpt 0.9.7, git-tree-sha1 c722d301a8d064de5d9ab67e5bc8a1dff893683a,
  identical to `git rev-parse v0.9.7^{tree}` in DirectTrajOpt.jl.
- At that tree, src/solvers/ipopt_solver/options.jl declares
  `intermediate_callback::Any = nothing` on IpoptOptions; solver.jl's
  `_ipopt_callback_function` wraps it via Callbacks.callback_intermediate_factory
  into `(primal, iter) -> Bool` (full NLP primal, restoration phase skipped) and
  composes it with the raw `callback` — all fire per IPM iteration, solve
  continues iff all return true.
- Runtime check in the provisioned project: pkgversion(DirectTrajOpt) == 0.9.7,
  hasfield(IpoptOptions, :intermediate_callback) == true.

The hasfield guard is the #157 lesson: a cloud bundle still baked with DTO
<= 0.9.6 lacks the field (the kwarg MethodError that killed cloud solves), so
the template degrades to stats-only (AMICODE_ITER flows, frames dark, @warn)
instead of crashing before the solve. Zero run-dir contract drift: PulseEmitCallback,
cb_log, PLOT_EVERY, frame names (LivePulsePlotCallback's iter_NNNNN.png) untouched;
the HP template's bare `using Piccolissimo` cloud-wrapper marker preserved.

Verified locally: bounded mini-solve (max_iter=12) of solve_template.jl under
julia --project=$HOME/.amico/julia — iter_00000/00006/00012.png written,
13 AMICODE_PULSE + 13 AMICODE_ITER lines, result.toml + pulse.jld2 + DONE,
no MethodError. All four templates parse clean. Staging cloud solve (AC2)
deferred to a live run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit b06e254 into main Jul 20, 2026
5 checks passed
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.

Restore per-iteration frames (iter_*.png) via the bundle's real intermediate-callback API

1 participant