name: engagement-state description: Updates the engagement's rolling state from the approved ledger — decided, still open, named gaps, constraints, and open commitments on both sides. One file per engagement, updated in place, never a dated copy. Use in Phase B on every session without exception.
Engagement state
One file per engagement. The answer to "where does this stand" without reading a session's worth of history.
Never skipped
This runs on every session including thin ones. On a thin session it moves the last-touch date and whatever changed, and that is enough. Skipping it is how state gets reconstructed from memory three sessions later.
Updated in place
engagements/, overwritten. Never -v2, never dated. Git holds the history; the file holds the present. A dated state file is two sources of truth by the second session.
Shape
# [Engagement] — state
**Last updated:** [date] from `ledger.json` [ledgerId]
**Latest session incorporated:** [YYYY-MM-DD] <!-- state-through: YYYY-MM-DD -->
**Engagement:** [type] · [cadence] · [what "done" is]
## Where this stands
## Decided (running, newest first)
## Still being shaped
## Still open
## Named gaps
## Open commitments — Kathryn
## Open commitments — client
## Closed since last session
## Scope events
Never rolled backwards
state.md holds the present. A session older than the one already incorporated may not overwrite it — that turns a current state file into a historical one silently, and nothing downstream can tell.
Read the marker before writing.
- This session is newer: update as normal and move the marker.
- This session is older (a backfill): do not touch the present-state sections. Append what it contributes under
## Earlier sessions — backfilled, dated, and leave the marker where it is. - No marker: first run. Write both.
verify_run.py fails the run if the marker ends up older than it started.
Rules
Commitments keep their modality and date state. A hedged commitment stays hedged for as long as it stays open. This is the file that turns "I'll see if I can put something together" into a dated promise if nobody guards it.
Close what closed. Before adding, check every open commitment against this session's ledger — if it was completed, move it to Closed with the date and what happened. Recorded failure: a job description was delivered and sent while the open-actions file still listed it open, because the list only ever grew.
Scope events accumulate. Each time an engagement's fence gets tested, log it — what crossed, who raised it, what was said. A fence tested three times is a re-scope conversation, and nobody sees that from a single session.
No conversion or upsell read. This is a paid engagement's state, not a pipeline card. Whether scope should change is a question for a person, and it appears as a flag, never as a recommendation.
Output
engagements/, stamped with ledgerId.