Skip to content

feat(drivers): execution deadline for legacy Lua entrypoints - #843

Closed
Sanjin-Maker wants to merge 1 commit into
srcfl:masterfrom
Sanjin-Maker:agent/lua-v1-exec-timeout
Closed

feat(drivers): execution deadline for legacy Lua entrypoints#843
Sanjin-Maker wants to merge 1 commit into
srcfl:masterfrom
Sanjin-Maker:agent/lua-v1-exec-timeout

Conversation

@Sanjin-Maker

Copy link
Copy Markdown
Contributor

Summary

  • Only signed control-v2 drivers had lifecycle deadlines (setLifecycleContext no-ops otherwise), so a legacy driver spinning in driver_poll/driver_command wedged its goroutine forever — and all 38 bundled drivers are v1.
  • New setExecContext bounds driver_poll, driver_command, driver_default_mode and driver_cleanup for legacy drivers at LuaDriver.ExecTimeout, set from a new per-driver config knob command_timeout_s (unset → 10 s default; explicit 0 restores unbounded for slow-but-working devices). Control-v2 drivers keep their existing host-policy deadlines unchanged.
  • driver_init is deliberately exempt for legacy drivers — slow discovery at startup is legitimate.
  • driver_command previously had no lifecycle context even for v2-adjacent paths; it now gets one.
  • A deadline abort surfaces as a normal Lua error from the protected call → existing failure/restart/default-mode handling. Docs updated in docs/writing-a-driver.md.

Risk & rollout

Behavior change for all legacy drivers, gated generously: 10 s default is far above any sane poll, and command_timeout_s: 0 is a per-driver escape hatch. Recommend a beta-channel soak. Test TestLegacyDriverRecoversAfterTimeout proves the LState stays usable after an abort (next poll succeeds).

Verification

  • go test ./internal/drivers/ ./internal/config/ -count=1 — new lua_exec_timeout_test.go: spinning poll/command/default all return at the deadline; recovery after abort; 0 installs no context.
  • go build ./..., go vet. Patch changeset included.

🤖 Generated with Claude Code

@Sanjin-Maker
Sanjin-Maker requested a review from frahlg as a code owner August 6, 2026 19:06
Only signed control-v2 drivers had lifecycle deadlines; a legacy driver
spinning in driver_poll or driver_command wedged its goroutine forever
(all 38 bundled drivers are v1). Bound poll/command/default/cleanup at a
configurable command_timeout_s (default 10 s, 0 = legacy unbounded);
driver_init stays unbounded for legacy drivers. A deadline abort is a
normal driver failure — restart and autonomous default mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Sanjin Naidu <sanjin@sanrowconsulting.com>
@Sanjin-Maker
Sanjin-Maker force-pushed the agent/lua-v1-exec-timeout branch from 4981652 to 401ac52 Compare August 6, 2026 20:09

@miravoss26 miravoss26 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.

Extends the existing control-v2 lifecycle-deadline mechanism to legacy (v1) Lua drivers: driver_poll/driver_command/driver_default_mode/driver_cleanup now run under a configurable execution deadline (default 10s, command_timeout_s: 0 opts back out), where previously only signed control-v2 drivers were bounded — all 38 bundled drivers are v1, so this was a real gap.

  • Correctness: setExecContext cleanly branches control-v2 (host-policy deadline, unchanged) vs legacy (operator-configurable ExecTimeout, 0 = unbounded). driver_init stays deliberately unbounded — reasonable, slow discovery at startup isn't a wedge.
  • Test coverage is thorough: spinning poll/command/default-mode all verified to abort at the deadline, and TestLegacyDriverRecoversAfterTimeout proves the LState stays usable for the next call after an abort — the sharpest way this kind of change breaks silently.
  • Reasonable rollout risk note in the PR body (behavior change for all legacy drivers, generously gated default, recommends a beta-channel soak) — worth a human call on whether that soak happens before merge.
  • No secrets, no new deps, no authz/network surface.
  • ⚠️ Same as #841/#842: GitHub reports CONFLICTING against master, no CI check runs shown yet.

Safe to merge from my read once rebased and green; the beta-soak decision is a human call given it changes behavior for every legacy driver in the fleet.

@frahlg

frahlg commented Aug 7, 2026

Copy link
Copy Markdown
Member

Blocking findings from a fresh review of the #841-#843 stack:

  • The 2 s caller deadline in fix(control): bound control-loop driver sends with a per-command deadline #841 can return while the legacy Lua run loop remains occupied until this PR's longer deadline. A watchdog/default command uses the same queue, so it cannot preempt that call. The stack therefore does not yet prove the stated recovery to an autonomous default after a partial write.
  • command_timeout_s < 0 is accepted as unbounded, although the config contract says only 0 disables the deadline. Reject negative values.
  • SendDefault still returns on its caller deadline while the queued default call can remain active under the longer background deadline.

Please treat #841-#843 as one safety change and add a test that covers a blocking or partial legacy write, the default transition, and the final hardware command order. The narrow legacy-driver and config tests pass, but they do not prove that recovery path.

frahlg commented Aug 8, 2026

Copy link
Copy Markdown
Member

Thank you @Sanjin-Maker for finding the legacy Lua liveness gap and testing a spinning VM.

Current master now bounds the production command path and bounds default/cleanup calls. The clear remaining candidate is the legacy poll path. This branch also carries the superseded #841 base, accepts negative timeout values as unbounded and does not prove the final hardware-command order when a timed-out command overlaps the autonomous default.

We are closing this version. Please start any follow-up as a written issue that scopes the remaining legacy-poll behavior on current master, rejects invalid timeout values and states the safety test before code is written. We would be glad to review that smaller proposal.

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.

3 participants