Skip to content

Add latent PR worker hibernation lifecycle - #1862

Open
ivannovak wants to merge 3 commits into
kunchenguid:mainfrom
ivannovak:fm/fm-latent-hibernation-build
Open

Add latent PR worker hibernation lifecycle#1862
ivannovak wants to merge 3 commits into
kunchenguid:mainfrom
ivannovak:fm/fm-latent-hibernation-build

Conversation

@ivannovak

Copy link
Copy Markdown

Summary

  • add crash-safe latent worker hibernation for exact authenticated GitHub PR heads
  • preserve recoverable commits under protected local refs while releasing worker processes and temporary Treehouse slots
  • add resume, attention, startup recovery, merge finalization, visibility, and project-removal safeguards
  • use durable pr_ready_head/pr_head identity rather than status-log pause tails for eligibility
  • keep GitLab and tasks with dirty/divergent work, open decisions, validation, or pending obligations active

Local evidence

  • failing baseline: bash tests/fm-latent.test.sh failed with not ok - fm-latent.sh is missing
  • passing implementation: bash tests/fm-latent.test.sh passed every latent lifecycle case
  • bin/fm-lint.sh passed with ShellCheck 0.11.0
  • bin/fm-doc-audience-check.sh passed
  • targeted PR, watcher, teardown, backend, spawn, snapshot, documentation, bootstrap, and test-run suites passed locally

CI

CI did not run. This is a fork pull request, so workflow runs require maintainer approval. An empty check set is not being reported as passing checks.

@kunchenguid

Copy link
Copy Markdown
Owner

Automated reminder: thanks for the PR! This branch currently has a merge conflict with the base branch.

When you get a chance, please rebase onto (or merge) the latest base branch, resolve the conflict, and push. After that, checks will re-run and the PR will get looked at again.

Noted for firstmate#1862 at c1500766.

Compose the hibernation lifecycle with main's deferred session-start
network stage (kunchenguid#1860).

Both sides restructured how session start sequences its work, so the
resolution is a composition, not a side pick:

- main split bin/fm-bootstrap.sh into a local pass and a network-only
  pass (FM_BOOTSTRAP_NETWORK_PHASE), moving four network sweeps into the
  detached bounded worker owned by bin/fm-startup-network.sh and
  reporting them in the digest's NETWORK CHECKS section.
- the hibernation commit added an eighth mutating sweep, latent
  transaction recovery, written against the pre-deferral ordering.

Latent transaction recovery stays on the LOCAL pass, inside main's
`local_phase` guard, because fm-latent.sh recover-all reconciles an
interrupted hibernation against local refs and the local manifest only
and makes no external-network call. Deferring it would buy no startup
latency while leaving a half-applied transaction unreconciled beneath
the fleet-state digest that reports that task's endpoint.

The hibernation ENTER path is the network half of the lifecycle and
stays off the session-start path entirely: bin/fm-pr-check.sh drives it
when a PR is registered and bin/fm-watch.sh drives it from the
supervision poll. Session start therefore still makes no blocking
external-network call.

Sweep count reconciled from six to seven across AGENTS.md,
bin/fm-bootstrap.sh, and bin/fm-session-start.sh so one owner describes
the composed ordering, and the bootstrap-diagnostics trigger list is the
union of both sides (NETWORK_CHECKS and LATENT_RECOVERY).
The hibernation lifecycle is otherwise network-driven, which makes this
one sweep's placement easy to get wrong in exactly two silent ways: wire
it to the deferred network half and it is installed but invisible to the
fleet-state digest that reports the task's endpoint, or drop it and the
whole lifecycle goes inert while still looking present in the tree.

recover-all is purely local - it reconciles an interrupted hibernation
against local refs and the local manifest - so it belongs on the local
half. The test asserts it runs there, that the network half does not
repeat it, and that a lock-refused detect-only session does not run it at
all.

Each assertion was watched failing before this landed: removing the sweep
fails the local-half assertion, moving it outside both guards fails the
network-repeat assertion, and dropping only the detect-only guard fails
the read-only assertion.
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.

2 participants