docs(ultraplan-local): add Handover 7 + doc-consistency pins for /ultracontinue

Adds Handover 7 (.session-state.local.json) section to HANDOVER-CONTRACTS.md
documenting the multi-session-resume contract:
- Producers: ultraexecute Phase 8/2.55/4 + helper command + future
  graceful-handoff v2.2 + pre-compact-flush refresh
- Consumer: /ultracontinue (read-only)
- Schema v1: schema_version, project, next_session_brief_path,
  next_session_label, status (5-value enum), updated_at
- Forward-compat: unknown top-level keys silently tolerated (drift-WARN)
- Path: .claude/projects/<project>/.session-state.local.json (gitignored)
- Failure modes mapped to validator error codes

Also updates the validator → handover map and Versioning + Stability
tables to include Handover 7.

Extends tests/lib/doc-consistency.test.mjs with three new pins:
1. HANDOVER-CONTRACTS.md contains Handover 7 section
2. session-state-validator.mjs exposes the standard CLI shim
3. CLAUDE.md mentions /ultracontinue-local

Adds the /ultracontinue-local row to the plugin CLAUDE.md commands table —
minimum viable to keep the existing 'CLAUDE.md commands table mentions
every commands/*.md file' iteration test green. Step 11 (Session 2b) will
expand to full README + CLAUDE.md narrative documentation.

Test suite: 182 → 185 (3 new doc-consistency pins, zero regressions).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-01 20:53:47 +02:00
commit 5688512898
3 changed files with 97 additions and 0 deletions

View file

@ -15,6 +15,7 @@ Each artifact carries an explicit version field. Schema bumps are coordinated:
| `plan.md` | `plan_version` (frontmatter) | `1.7` |
| `progress.json` | `schema_version` (top-level) | `"1"` |
| `review.md` | `review_version` (frontmatter) | `1.0` |
| `.session-state.local.json` | `schema_version` (top-level) | `1` (number) |
## Breaking-change protocol
@ -34,6 +35,7 @@ Each artifact carries an explicit version field. Schema bumps are coordinated:
| 4. plan → execute | `lib/validators/plan-validator.mjs` |
| 5. progress.json (resume) | `lib/validators/progress-validator.mjs` |
| 6. review → plan | `lib/validators/review-validator.mjs` |
| 7. session-state (multi-session resume) | `lib/validators/session-state-validator.mjs` |
Every validator exposes a CLI: `node lib/validators/<name>.mjs --json <path>` returns `{valid, errors[], warnings[], parsed}`. Errors and warnings have stable `code` fields for downstream tooling.
@ -350,6 +352,68 @@ The validator (`lib/validators/review-validator.mjs`) exposes the same CLI as th
---
## Handover 7 — `.session-state.local.json`
**Handover 7 enables zero-friction multi-session resumption.** Where Handover 5 (`progress.json`) makes a single execute run resumable after a crash inside that session, Handover 7 makes a *multi-session* plan resumable across fresh Claude Code chats. The state file is the contract; any session-end mechanism may write it; `/ultracontinue` only reads.
**Producer:**
- `/ultraexecute-local` Phase 8 (canonical convergence — every completed/failed/stopped/partial run that reaches the final report)
- `/ultraexecute-local` Phase 2.55 (Check 1 — dirty-tree pre-flight stop)
- `/ultraexecute-local` Phase 4 (entry-condition stop)
- `/ultraplan-end-session-local` (informal multi-session helper — Step 9 of v3.3.0)
- *Future:* `graceful-handoff` v2.2 may dual-write here as part of its session-rescue artifact (additive — extra fields tolerated, see Body invariants).
- `hooks/scripts/pre-compact-flush.mjs` *refreshes* `updated_at` on existing state files (status `in_progress` or `partial` only). Never creates the file; never changes status or owned fields.
**Consumer:** `/ultracontinue` (read-only). Reads the file, validates it, narrates a 3-line summary, then begins executing the next session by reading `next_session_brief_path`.
**Path conventions:**
- Per-project: `.claude/projects/{YYYY-MM-DD}-{slug}/.session-state.local.json` — one file per project directory.
- Gitignored at the plugin level via `*.local.json` (added in v3.3.0). State files MUST NOT be committed — they may contain absolute project paths and label strings that vary per-machine.
- For `--session N` parallel multi-session runs the parent's Phase 8 aggregate write IS the canonical state. Child session writes (inside their worktrees) are ephemeral; the worktree is cleaned up after merge so child state is intentionally discarded.
**Frontmatter schema:** N/A — file is JSON, not Markdown. Top-level keys:
| Field | Type | Required | Allowed values | Notes |
|---|---|---|---|---|
| `schema_version` | number | yes | `1` (current) | Bump on breaking changes only |
| `project` | string | yes | absolute or repo-relative path | Project directory containing brief/plan |
| `next_session_brief_path` | string | yes | path to a brief or session-spec | Validator soft-checks file existence (warning, not error) |
| `next_session_label` | string | yes | human-readable label | e.g. "Session 2b" or "Continue" |
| `status` | string | yes | `in_progress \| partial \| failed \| stopped \| completed` | Mirrors progress.json status. `completed` triggers SESSION_STATE_NOT_RESUMABLE warning (valid:true) |
| `updated_at` | string | yes | ISO-8601 timestamp | Refreshed by pre-compact-flush on resumable statuses |
**Body invariants:** N/A (JSON).
**Forward-compat — drift-WARN principle:** Unknown top-level keys are **silently tolerated**. The validator does not warn on extras. This is a load-bearing decision: it lets future writers (graceful-handoff v2.2, custom plugin extensions) add metadata fields without breaking `/ultracontinue`. Mirrors Handover 3's discovery-only, drift-WARN posture.
**Validation strategy:**
| Layer | When | What |
|---|---|---|
| JSON parse | every read | `JSON.parse``SESSION_STATE_PARSE_ERROR` on failure |
| Required fields | every read | All six top-level keys present → `SESSION_STATE_MISSING_FIELD` on absence |
| Schema version | every read | Numeric `1``SESSION_STATE_SCHEMA_MISMATCH` otherwise |
| Status enum | every read | Must be one of the five values → `SESSION_STATE_INVALID_STATUS` otherwise |
| Resumability | every read | `completed` emits `SESSION_STATE_NOT_RESUMABLE` warning but valid:true |
| Path shape | every read | `next_session_brief_path` must be non-empty string → `SESSION_STATE_INVALID_PATH` otherwise |
| Timestamp shape | every read | `updated_at` parses via `Date.parse``SESSION_STATE_INVALID_TIMESTAMP` otherwise |
| Unknown keys | every read | Tolerated silently (drift-WARN forward-compat) |
The validator (`lib/validators/session-state-validator.mjs`) exposes the standard CLI: `node lib/validators/session-state-validator.mjs --json <path>`. Returns `{valid, errors[], warnings[], parsed}`. Exit code 0 on valid, 1 on invalid, 2 on usage error.
**Versioning:** Current is `1` (number). Schema is **additive only** — new optional fields land without bumping schema_version (forward-compat tolerates them). A breaking change (renaming a field, narrowing the status enum) requires bumping schema_version to `2`, adding migration support in the validator, and following the breaking-change protocol above.
**Failure modes:**
- `SESSION_STATE_NOT_FOUND``/ultracontinue` exits with cold-start message ("no active multi-session project here; start with `/ultrabrief-local` or `/ultraplan-local`")
- `SESSION_STATE_PARSE_ERROR` → halt with structured error; user fixes JSON
- `SESSION_STATE_MISSING_FIELD` → halt; suggests running validator directly
- `SESSION_STATE_SCHEMA_MISMATCH` → halt; future `1``2` migration path will warn instead
- `SESSION_STATE_INVALID_STATUS` → halt; protects against typo'd writers
- `SESSION_STATE_NOT_RESUMABLE` → warning; `/ultracontinue` exits cleanly with "no further sessions to resume; project complete"
- Validator failures during writer Phase 8 emit a stderr warning but DO NOT block the session-end report. `progress.json` remains the authoritative record of what was attempted.
---
## Stability summary
| Handover | Validation strength | Owner | Risk |
@ -360,5 +424,6 @@ The validator (`lib/validators/review-validator.mjs`) exposes the same CLI as th
| 4. plan → execute | **strict, both ends** | this plugin | medium — Opus 4.7 narrative drift requires constant vigilance |
| 5. progress.json | shape + resume readiness | this plugin | medium — drift during compaction handled by pre-compact-flush hook (CC v2.1.105+) |
| 6. review → plan | strict at write, soft at read | this plugin | low — additive feedback loop; consumer falls back gracefully when source_findings is absent |
| 7. session-state (multi-session resume) | required-fields + status enum + drift-WARN extras | this plugin | low — readers tolerate unknown keys; writers are owned by ultraexecute Phase 8 + helper command |
When extending the plugin or adding a new pipeline stage, follow the same pattern: produce an artifact with a versioned frontmatter (or `schema_version` for JSON), write a validator under `lib/validators/`, add fixtures under `tests/fixtures/`, and add an entry to this document.