Skip to content

Stage-A A1: an open-loop run can save its recording, and a survey survives losing the lease - #10

Open
muthmann wants to merge 1 commit into
worktree-fix+windows-serial-port-discoveryfrom
fix/a1-open-loop-sidecar-and-lease-recovery
Open

Stage-A A1: an open-loop run can save its recording, and a survey survives losing the lease#10
muthmann wants to merge 1 commit into
worktree-fix+windows-serial-port-discoveryfrom
fix/a1-open-loop-sidecar-and-lease-recovery

Conversation

@muthmann

Copy link
Copy Markdown
Owner

A forty-point protocol reported 3/40 recorded — 37 skipped (… metadata save failed: cannot write a quantitative A1 sidecar without a fresh photodiode optical summary from a confirmed I_tot anchor; the modulation owner requires an active automation lease) after an hour on the bench. Two independent faults, both of which only became visible once the recordings had already been spent.

Stacked on worktree-fix+windows-serial-port-discovery (#9) so the diff is just this fix.

1. The open-loop source could not save anything

write_sidecar refused any run without a fresh photodiode optical summary "from a confirmed I_tot anchor" — regardless of Depth a source.

ADR 020 created DepthSource::Commanded for exactly the bench that cannot produce one: no phase-0 markers, so no anchor to confirm, depth read back from the applied Pockels transfer curve instead. The ADR is explicit that such a run "simply carries no measured_a, rather than carrying a commanded value under that name". The implementation had drifted from that decision, so the documented way past a missing anchor could drive a whole survey and then save none of it.

  • the [optical] block is written only for a photodiode-sourced run; an open-loop one records depth_a_source = "modulation_commanded" and claims nothing the detector did not measure;
  • whether a run can be described at all is now asked in begin_recording (before the camera and the PDQ start) and in begin_protocol (before the drive is taken), phrased as the photodiode owner's own reason plus the way past it.

begin_sweep, begin_a0_lock and begin_freq_sweep already gated up front through depth_a_blocker. The protocol was the one path that did not — which is why it was the one that could burn forty rows.

2. One lost lease cost the whole rest of the survey

The ADR 029 heartbeat can only renew a lease the owner still advertises, so a lease that ends behind its back (an expiry the owner decided during a long point, an owner that restarted) left every remaining retarget rejected with LeaseRequired. Skipping the point does not give the lease back, so the run skipped every row after the first failure.

A protocol now re-acquires the same lease id — that lease continuing, not a second one — announces it on the status line, and repeats the point from the top, restating all three axes. One retry per point, so a lease that is genuinely gone still ends as a named skip rather than a spin; LeaseBusy is never retried, because that one means somebody else holds the drive.

Tests

Five new cases, each verified to fail without its fix:

  • an_open_loop_run_saves_its_sidecar_without_a_photodiode_anchor
  • a_run_that_could_not_be_described_is_refused_before_the_camera_starts
  • a_protocol_is_refused_when_no_row_of_it_could_be_described
  • a_lost_modulation_lease_is_taken_again_and_the_point_repeated
  • a_lease_the_owner_will_not_give_back_costs_one_retry_then_skips

The ready_photodiode() fixture now publishes the optical summary the default depth source is recorded against — a fixture without one was not a bench that could record at all.

cargo test --workspace green (144 in stage-a-a1); cargo clippy -p augur-plugin-stage-a-a1 --all-targets clean.

Docs

  • ADR 020 — records where the implementation had drifted from the decision.
  • ADR 029 — amendment: why "report the loss per point" was the wrong end state for an unattended run, and the bounded retry that replaces it.
  • docs/features/stage-a-a1.md — the sidecar's [optical] block is source-dependent, preconditions are checked before the camera rolls, and a lost lease is taken again.

… nothing

A forty-point protocol reported `3/40 recorded — 37 skipped` after an hour on
the bench, for two reasons that both surfaced only once the recordings had
already been spent.

`write_sidecar` demanded a fresh photodiode optical summary "from a confirmed
I_tot anchor" on every run, whatever the depth source. ADR 020's open-loop
source exists for exactly the bench that cannot produce one — no phase-0
markers, so no anchor to confirm — and that ADR is explicit that such a run
carries no `measured_a` rather than a commanded value under that name. So the
documented way past a missing anchor could drive a whole survey and then save
none of it. The `[optical]` block is now written only for a photodiode-sourced
run, and whether a run can be described at all is asked in `begin_recording`
(before the camera and the PDQ start) and in `begin_protocol` (before the drive
is taken), where the answer still costs nothing. The sweep, the a0 lock and the
frequency ladder already gated up front through `depth_a_blocker`; the protocol
was the one path that did not.

The second reason was the modulation lease. The heartbeat from ADR 029 can only
renew what the owner still advertises, so a lease that ended behind its back
left every remaining retarget rejected with `LeaseRequired` — and skipping the
point does not give the lease back, so one expiry cost the entire rest of the
survey. A protocol now re-acquires the same lease id, says so on the status
line, and repeats the point from the top. One retry per point, so a lease that
is genuinely gone still ends as a named skip rather than a spin, and a lease
somebody else holds is never taken from them.
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.

1 participant