Skip to content

Lightflow v0.5.0

Choose a tag to compare

@cedricbellet cedricbellet released this 19 Oct 10:15
· 21 commits to main since this release

Lightflow v0.5.0

Fixes for issues #11, #14, #15, #16, #17 and #18. Two behaviour changes are called out first because existing workflows will see them.

Behaviour changes

A paused gate no longer halts the whole run (#15). An operator_action that pauses now parks only its own dependents, the same way a polling yield does; independent branches keep running before the process suspends. Several gates can be open at once, and the briefing (and status) lists each with its resume command. If a stage also failed in the same run, the run exits 1 with the failure footer naming the open gates; gates-only still exits 2. status, list and the footer now agree on precedence: failed > rejected > paused > waiting. A parked gate no longer prevents resume from re-arming a failed sibling.

Timed-out attempts are never overlapped (#11). Threads cannot be cancelled, so timeout_seconds bounds how long the engine waits; the action keeps running. Previously a retry started while the timed-out attempt was still running, and rollback_action could run (and report success) while both were live. Now: a retry is started only if the timed-out attempt finishes during the backoff — otherwise the stage fails with an explicit "not retried" note; rollback_action waits up to one more timeout_seconds for a live attempt and otherwise skips with an explicit "rollback skipped … verify by hand" note. The same guard applies to polling ticks. Net effect: retry_policy on timeouts is weaker than before, in exchange for the passport never claiming a rollback that raced a live side effect. README updated accordingly.

Fixes

  • #14 Stamp.reason (REJECTED / UPSTREAM_FAILED / POLL_YIELD) is now recorded, and run status is derived from it instead of from message text. A stage whose exception text happens to contain the yield marker is reported as FAILED, not WAITING. Old passport.json files round-trip unchanged; the legacy text fallback is anchored on the engine's own message prefix so it cannot misfire.
  • #15 A stage failure is printed when it happens (❌ [stage] …), like skipped and blocked stages already were, so it is visible even when the run later pauses at a gate.
  • #16 hn_digest, usgs_seismic_alert and pypi_upgrade_guard no longer substitute bundled sample data when the live source is unreachable: the fetch raises (so retry_policy applies) with a message naming the fix and the explicit opt-in (--payload='{"offline": true}'). When fixture data is used, the gate instructions are prefixed [OFFLINE FIXTURE].
  • #17 resume --operator=<who> keeps the session that made the call in the audit trail: stamps read approved by <who> (via <session>); payload.operator stays the supplied identity.
  • #18 Errors raised while importing an action module (SyntaxError, ImportError, anything at import time) fail the stage immediately instead of being retried. A missing third-party dependency is reported as such rather than as a misplaced manifest. visualizer.html timeline dots regain their colours (the inline CSS subset lacked the status classes).

Wording

The gate briefing footer, the status/start hints, AGENTS.md, CLAUDE.md and skills/run_lightflows/SKILL.md now say only what to do — follow the Instructions, then resume with a payload matching the Payload Schema — rather than asserting who must decide. Gates pace a run and record who decided (#17); they are not a containment boundary, and the previous "do not self-approve" wording implied an enforcement the engine does not provide. (Issue #8 had asked for neutral wording in v0.2.0; that change had not actually shipped.)

Unchanged

  • Python API (lightflow.engine, lightflow.lib, lightflow.schema, lightflow.visualizer); StampReason is added to lightflow.schema.
  • CLI commands, flags, exit codes, and the passport.json format (one new optional reason key on stamps).
  • 130 standalone tests pass (PYTHONPATH=. python3 -B -m unittest discover -s tests).