@@ -440,6 +440,10 @@ Node modifiers:
440440 (``--region ``; default: ``default ``)
441441``launch deferred `` Container starts with ``sleep infinity ``;
442442 use ``exec node pg_autoctl node start ``
443+ ``no-autopilot `` Step mode: the node-active service never
444+ transitions on its own; drive it explicitly
445+ with the ``fsm step <node> `` DSL command
446+ (see `Step mode: no-autopilot nodes `_ below)
443447``coordinator `` / ``worker group <N> `` Citus role
444448``no-monitor `` Standalone node (no monitor)
445449``listen `` Bind all interfaces (``--listen 0.0.0.0 ``)
@@ -478,6 +482,39 @@ See "Deterministic node registration order" in
478482and ``cli_node.c ``).
479483
480484
485+ Step mode: ``no-autopilot `` nodes
486+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
487+
488+ A node declared with the ``no-autopilot `` modifier starts with
489+ ``PG_AUTOCTL_STEP_MODE `` set, which changes what its node-active service does
490+ on each FSM tick: instead of reporting its current state to the monitor and
491+ immediately attempting whatever transition the monitor assigns back —
492+ atomically, on every tick, with no way to observe or freeze the moment in
493+ between — it opens a small Unix-domain-socket server and waits. Nothing
494+ happens to that node's FSM until the spec explicitly drives it with the
495+ ``fsm step <node> `` command, documented under "Commands inside ``setup ``,
496+ ``teardown ``, and ``step `` blocks" below.
497+
498+ This exists so a test can hold a node frozen at a specific reported state on
499+ purpose — e.g. to prove the monitor assigns the right next state before the
500+ node itself races off to reach it, or to reproduce a specific ordering
501+ between two nodes that would otherwise be a race under the normal, freely
502+ ticking FSM. Every other node in the same spec (without the modifier) keeps
503+ autopiloting normally; ``no-autopilot `` only affects the node(s) it's
504+ declared on.
505+
506+ ``fsm step <node> `` is sugar for the combined
507+ ``pg_autoctl manual fsm step `` command (report the current state, then
508+ immediately attempt whatever transition the monitor assigns). The underlying
509+ CLI also exposes the two halves separately as ``manual fsm step report `` and
510+ ``manual fsm step advance `` — see :ref: `pg_autoctl_manual ` — for scenarios
511+ that need to observe the monitor's assigned goal state before deciding
512+ whether, or when, to actually attempt the transition; the DSL does not yet
513+ have separate sugar for the split, so use ``exec <node> pg_autoctl manual
514+ fsm step report --pgdata /var/lib/postgres/pgaf `` / ``... advance ... ``
515+ directly for that.
516+
517+
481518Commands inside ``setup ``, ``teardown ``, and ``step `` blocks
482519~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
483520
@@ -575,6 +612,12 @@ node ...`` which queries the running node/monitor instead of the file.
575612 stop postgres <node>
576613 start postgres <node>
577614
615+ **FSM step ** (``no-autopilot `` nodes only — see `Step mode: no-autopilot nodes `_ above)
616+
617+ .. code-block :: text
618+
619+ fsm step <node>
620+
578621 **Failover **
579622
580623.. code-block :: text
@@ -762,6 +805,12 @@ Schedules under ``tests/tap/schedules/*.sch`` group these into CI jobs.
762805``fast_forward ``
763806 Test fast-forward stuck detection and recovery.
764807
808+ ``fsm_step_report_advance ``
809+ Test the ``pg_autoctl manual fsm step report ``/``... advance `` split
810+ using a ``no-autopilot `` node: report a stale state to the monitor
811+ without transitioning, then advance to the transition the monitor
812+ already assigned, proving the two halves work independently.
813+
765814``guard_data_loss ``
766815 Test ``pgautofailover.guard_data_loss `` /
767816 ``pg_autoctl perform failover --allow-data-loss ``.
0 commit comments