Problem
Deployment.state is defined in the model (app/core/models.py:88, default "pending") and is reset to "pending" at create / new-attempt / teardown, but it never advances to deploying, ready, failed, or unknown. There is no transition logic anywhere.
app/core/events_watcher.py:25-26 documents the intended design:
# state_transition: emitted by the state-machine transitions in
# app/core/state_machine.py on every DB-backed state write.
…but app/core/state_machine.py does not exist. app/core/orphans.py:123 calls mark_attempt_unknown() inside a try/except that only warns on import failure.
Impact
- Deployment lifecycle is invisible: a deployment shows
pending even after it has succeeded or failed.
- Teardown's
unknown-state guard (app/routes/v1/deployments/teardown.py:51) can never fire, because nothing sets unknown.
- Blocks the v1.1 multi-attempt work, which needs valid state guards.
Proposed work
- Add
app/core/state_machine.py with the documented transitions (pending → deploying → ready/failed/unknown) and DB-backed writes.
- Emit
state_transition events from each write (per events_watcher.py contract).
- Wire transitions into the attempt lifecycle (start → deploying; attempt_end ok/fail → ready/failed; orphan/abandoned → unknown).
Evidence
app/core/models.py:88 — state field, only ever "pending"
app/routes/v1/deployments/crud.py:89, attempts.py:61, teardown.py:87 — all set "pending"
app/core/events_watcher.py:25-26 — references missing state_machine.py
Surfaced by a code audit; Deployment.state confirmed static in the dev branch.
Problem
Deployment.stateis defined in the model (app/core/models.py:88, default"pending") and is reset to"pending"at create / new-attempt / teardown, but it never advances todeploying,ready,failed, orunknown. There is no transition logic anywhere.app/core/events_watcher.py:25-26documents the intended design:…but
app/core/state_machine.pydoes not exist.app/core/orphans.py:123callsmark_attempt_unknown()inside a try/except that only warns on import failure.Impact
pendingeven after it has succeeded or failed.unknown-state guard (app/routes/v1/deployments/teardown.py:51) can never fire, because nothing setsunknown.Proposed work
app/core/state_machine.pywith the documented transitions (pending → deploying → ready/failed/unknown) and DB-backed writes.state_transitionevents from each write (perevents_watcher.pycontract).Evidence
app/core/models.py:88— state field, only ever "pending"app/routes/v1/deployments/crud.py:89,attempts.py:61,teardown.py:87— all set "pending"app/core/events_watcher.py:25-26— references missingstate_machine.pySurfaced by a code audit;
Deployment.stateconfirmed static in thedevbranch.