# Session-Close Standard

> **Canonical source.** This document ships as `mgf.fedres` package data and is therefore
> byte-identical in both foundation families. Each family references it as a **MUST** from its
> own standard (in that family's native rule format); the enforcement is the same command in
> both — `fedres session-close --check`. Print this text anywhere with `fedres session-close --doc`.
>
> **Applies to** every AI agent (and human) on every project in the Magogi Foundation, at the
> end of every working session or before any handoff.

## Why this exists

Session **start** is standardized — a memory-load order and, where the harness supports it, a
hook that injects durable memory into context. Session **close** has not been. Closing quality
has depended entirely on discipline: a careful agent commits memory and lists open work; a
rushed one leaves uncommitted knowledge, orphaned branches, forgotten PRs, undocumented running
daemons, or an unflagged leaked secret. **Resumability should not depend on luck.** This
standard makes a clean close a **MUST**, so any agent or human can resume — in a fresh session,
on another machine, months later — with **zero knowledge loss**.

## The MUSTs

At session close, the agent **MUST**:

1. **Persist durable state, git-tracked.** Append to the decision log (*what changed and why*,
   newest-first); write or append a session log; **commit** all memory and docs touched. No
   uncommitted durable knowledge survives the session — a crash after close must cost nothing.

2. **Record the full state-at-exit** using the [template](#the-record) below — every: **open
   PR** (number · title · branch → base · CI state · held/ready), **local branch with unmerged
   commits** (+ its intent), **uncommitted working-tree change** (+ why it's uncommitted),
   **process or daemon this session started** (+ how to stop it), and **pending decision** (what's
   blocked, and on whom). These five fields are MUST; the rest of the template is SHOULD.

3. **Close or explicitly flag every loose end.** No orphaned branches — delete the abandoned,
   name the in-flight. Any **leaked or exposed secret is rotated and flagged**, never left live.
   No half-applied edit, migration, or refactor left silent. Every deviation from an agreed plan
   is logged with its reason.

4. **Make the handoff unambiguous.** A **Next steps** section: what to do next, what's blocked
   and on whom, and — wherever PRs or releases interact — the explicit **merge/release order**.

5. **Verify, then report.** Run a **health check** of the project's key invariants at exit
   (build/tests/services green, no secret-shaped strings in tracked files, no unexpected running
   daemons) and record each with its verified state. Close with a human-facing summary of the
   review pile and the decisions made.

### SHOULD (not MUST)

- A one-line status delta vs. the last session.
- Token/effort notes for the session.
- Links to the specific artifacts touched (PRs, files, dashboards).

## The record

Appended to the session log (each family's memory convention names the file).
`fedres session-close --init` pre-fills what it can detect from git and the live channel, so the
agent **edits** rather than **authors**:

```
# SESSION CLOSE — <date>
## What happened        — 2–5 lines; link the decision log for depth
## State at exit
  - Merged/released:    <what landed live>
  - Open PRs:           #n <title> · <branch>→<base> · CI <state> · held/ready   [MUST]
  - Local branches:     <branch> (n unmerged commits) — intent                   [MUST]
  - Uncommitted:        <paths> — why not committed                              [MUST]
  - Processes started:  <name> (pid / how-to-stop)                               [MUST]
  - Pending decisions:  <question> — blocked on <who>                            [MUST]
## Next steps           — ordered; note merge/release order where PRs interact
## Health at exit       — the key invariants, each with its verified state
## Lessons              — what to carry forward
```

## Enforcement — `fedres session-close --check`

`--check` verifies the mechanically-checkable MUSTs and exits non-zero on any unmet one:

- the git working tree carries no uncommitted durable state (MUST 1);
- the current branch is not silently ahead of its upstream — pushed, or noted (MUST 2/3);
- no `fed-resources` live session was left open — every traced op finished (MUST 3/5).

It is **non-blocking but loud**: agents run it before ending, humans can too, and it names each
unmet invariant — but it does not hard-stop a close (block only if it proves necessary). It is
the *portable* enforcement — it runs anywhere `mgf.fedres` is installed, independent of harness.
A Claude-Code `Stop`/`SessionEnd` hook that surfaces its output is an optional convenience layer,
never the primary mechanism (not every foundation agent runs in Claude Code).

**Escape hatch.** A legitimately-uncommitted draft or intentionally-open branch is declared with
an explicit, recorded line in the close — never a silent skip:

```
# session-close: allow <path-or-branch> <reason>
```

An exception is then visible, attributable, and reviewable — not a hole.
