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>
26 KiB
Handover Contracts (ultra-suite local pipeline)
This document is the single source of truth for the file formats that pass between the four commands of the ultraplan-local pipeline. When you fork the plugin or extend a stage, the contracts below tell you what every producer must write and what every consumer is allowed to assume.
For each handover, the same headings appear in the same order: Producer, Consumer, Path conventions, Frontmatter schema, Body invariants, Validation strategy, Versioning, Failure modes.
Versioning policy
Each artifact carries an explicit version field. Schema bumps are coordinated:
| Artifact | Field | Current |
|---|---|---|
brief.md |
brief_version (frontmatter) |
2.0 |
research/*.md |
(implicit; tracked via type: ultraresearch-brief) |
unversioned |
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
- Bump the artifact's version field.
- Update the matching validator in
lib/validators/. - Add a fixture under
tests/fixtures/covering both old and new shapes. - Document the change in
MIGRATION.mdwith at least an N-1 compatibility window in the validator (read both shapes; warn on old, fail only after one minor version of warning). - Bump the plugin version in
package.jsonand.claude-plugin/plugin.json.
Validator → handover map
| Handover | Validator |
|---|---|
| 1. brief → research | lib/validators/brief-validator.mjs |
| 2. research → plan | lib/validators/research-validator.mjs |
| 3. architecture → plan | lib/validators/architecture-discovery.mjs |
| 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.
Handover 1 — brief.md → research/
Producer: /ultrabrief-local Phase 4g (after brief-reviewer stop-gate passes or iteration cap is hit).
Consumer: /ultraresearch-local Phase 1 (mode parse + brief validation).
Path conventions:
- Project-dir mode (recommended):
.claude/projects/{YYYY-MM-DD}-{slug}/brief.md. - Legacy / loose mode: any path passed via
--brief <file>.
Frontmatter schema:
| Field | Type | Required | Allowed values | Notes |
|---|---|---|---|---|
type |
string | yes | ultrabrief |
Hard-coded discriminator |
brief_version |
string | yes | "2.0" (current) |
Bump on schema change |
created |
date | yes | YYYY-MM-DD | |
task |
string | yes | one-line description | |
slug |
string | yes | URL-safe slug | Used in project_dir |
project_dir |
string | yes | .claude/projects/{date}-{slug}/ |
|
research_topics |
number | yes | ≥ 0 | |
research_status |
string | yes | pending | in_progress | complete | skipped |
State machine — see below |
auto_research |
bool | optional | true | false |
|
interview_turns |
number | optional | ≥ 0 | |
source |
string | optional | interview | manual |
|
brief_quality |
string | optional | complete | partial |
Set when iteration cap is hit |
Body invariants: required sections (validator runs in strict mode at write-time, soft mode at read-time):
## Intent## Goal## Success Criteria
Optional but standard sections: ## Non-Goals, ## Constraints, ## Preferences, ## Non-Functional Requirements, ## Research Plan.
Validation strategy:
| Layer | When | What |
|---|---|---|
| Frontmatter parse | every read | YAML subset; reject nested dicts |
| Required fields | every read | All BRIEF_REQUIRED_FRONTMATTER present |
| Type discriminator | every read | type === "ultrabrief" |
| Status enum | every read | research_status ∈ allowed values |
| State machine | every read | research_topics > 0 && research_status === "skipped" requires brief_quality === "partial" |
| Body sections | strict only | All BRIEF_BODY_SECTIONS present |
State machine detail: a brief that says it has research topics but skipped them must explicitly admit it (via brief_quality: partial). This is the most common failure mode the validator catches.
Versioning: current is 2.0. There are no live 1.x briefs; remove legacy paths in next major.
Failure modes:
BRIEF_NOT_FOUND→ consumer halts with a usage messageFM_MISSING→ file has no frontmatter; haltBRIEF_WRONG_TYPE→ file is not a brief; haltBRIEF_MISSING_FIELD→ strict halt; soft-mode warningBRIEF_STATE_INCOHERENT→ strict halt; soft-mode warning (incoherence will haunt downstream agents)BRIEF_MISSING_SECTION→ strict halt; soft-mode warning
Handover 2 — research/*.md → plan
Producer: /ultraresearch-local Phase 7 (synthesis + brief writer).
Consumer: /ultraplan-local Phase 1 (project-dir auto-discovery) + planning-orchestrator (consumes findings as context).
Path conventions:
- Project-dir mode:
.claude/projects/{YYYY-MM-DD}-{slug}/research/{NN}-{topic-slug}.md(sorted by filename). - Legacy:
.claude/research/ultraresearch-{date}-{slug}.md.
Frontmatter schema:
| Field | Type | Required | Allowed values |
|---|---|---|---|
type |
string | yes | ultraresearch-brief |
created |
date | yes | YYYY-MM-DD |
question |
string | yes | the research question |
confidence |
number | optional | [0.0, 1.0] — strongly recommended |
dimensions |
number | optional | ≥ 1 |
mcp_servers_used |
list | optional | server names |
local_agents_used |
list | optional | agent names |
external_agents_used |
list | optional | agent names |
Missing confidence is a warning, not an error — but downstream planning has no signal to weight findings.
Body invariants: required sections (strict mode):
## Executive Summary## Dimensions
Optional: ## Local Context, ## External Knowledge, ## Triangulation, ## Sources, ## Recommendations.
Validation strategy: schema parse + body-section check. Per-file by validateResearch; whole-directory by validateResearchDir. Anchoring back to brief topics is currently best-effort, not enforced (planned for a future minor).
Versioning: unversioned — research briefs are write-once read-once; no migration concern. If schema changes, change type discriminator or add research_brief_version.
Failure modes: all same shape as brief (RESEARCH_* codes). Default soft mode in plan Phase 1 — research drift does not block planning, but warnings surface in the user-visible summary.
Handover 3 — architecture/ → plan (EXTERNAL CONTRACT)
This is the only handover where the producer is in a different plugin. The architecture/overview.md (and optional gaps.md) are produced by /ultra-cc-architect-local from the separate ultra-cc-architect plugin (v0.1.0+). When that plugin is not installed, this handover is absent — and that is fine.
Producer: /ultra-cc-architect-local (external plugin).
Consumer: /ultraplan-local Phase 1 (architecture-discovery) + planning-orchestrator Phase 7 (cross-reference architecture-note as priors during synthesis).
Path conventions:
- Canonical:
{project_dir}/architecture/overview.md - Optional:
{project_dir}/architecture/gaps.md - Tolerated alternatives (with warning):
architecture-overview.md,overview.markdown,README.md
Frontmatter schema: unenforced. This is the external contract — ultraplan-local does not validate the format. We sniff only the first H1 heading.
Body invariants: unenforced. We never read body content beyond the first heading.
Validation strategy: drift-WARN, never drift-FAIL.
| Detection | Result |
|---|---|
| File at canonical path | found: true, no warnings |
| File at known alternative path | found: true, warning ARCH_NON_CANONICAL_OVERVIEW |
Loose *.md files in architecture/ not in known set |
warning ARCH_LOOSE_FILES |
No architecture/ dir |
found: false, no warnings |
The validator (lib/validators/architecture-discovery.mjs) is intentionally minimal. It is unit-tested to assert it does NOT read body content beyond the first heading — guarding against scope creep into the sister plugin's territory.
Versioning: the producer (ultra-cc-architect) owns its schema. We do not version this handover from our side.
Failure modes: none. Discovery always succeeds (returns found: false if absent). The handover is additive.
Handover 4 — plan.md → execute
Producer: planning-orchestrator Phase 5 (plan synthesis) + Phase 5.5 (schema self-check via plan-validator --strict).
Consumer: /ultraexecute-local Phase 2 (plan parsing) + --validate mode.
Path conventions:
- Project-dir:
{project_dir}/plan.md - Legacy:
.claude/plans/ultraplan-{date}-{slug}.md
Frontmatter schema:
| Field | Type | Required | Allowed |
|---|---|---|---|
plan_version |
string | yes | "1.7" (current) |
Body invariants (strict, v1.7):
- Top-level structure:
## Implementation Planheading present- One or more
### Step N: <title>headings, numbered 1..N contiguously ### Step N:is the literal canonical form — colon + space
- Forbidden narrative-drift heading forms (Opus 4.7 regression guard):
## Fase N(Norwegian)### Phase N### Stage N### Steg N(Norwegian variant)
- Per-step Manifest block — required for every step:
- Indented fenced YAML:
```yaml\n manifest:\n ...\n ``` - Required keys:
expected_paths(list),min_file_count(number),commit_message_pattern(string compilable to RegExp),bash_syntax_check(list),forbidden_paths(list),must_contain(list of{path, pattern}dicts or empty list)
- Indented fenced YAML:
- Step count == manifest count
Validation strategy:
The strongest validation in the entire pipeline. Phase 5.5 (planning-orchestrator) must run plan-validator --strict before handing the plan to plan-critic. --validate mode of /ultraexecute-local runs the same check + progress-validator.
| Code | Meaning | Recovery |
|---|---|---|
PLAN_FORBIDDEN_HEADING |
Narrative drift detected | Rewrite using literal Phase 5 template |
PLAN_NO_STEPS |
No ### Step N: headings |
Plan is empty; restart |
PLAN_STEP_NUMBERING |
Steps skip a number | Renumber sequentially |
PLAN_MANIFEST_COUNT_MISMATCH |
Some step lost its manifest | Add missing manifest |
MANIFEST_MISSING |
Specific step has no manifest YAML | Add Manifest block |
MANIFEST_MISSING_KEY |
Manifest is missing a required key | Add the key |
MANIFEST_PATTERN_INVALID |
commit_message_pattern does not compile |
Check escaping (\\( not \( in YAML double-quoted strings) |
PLAN_VERSION_MISMATCH |
Older plan_version |
Warning only; planner should bump |
Versioning: v1.7 has been stable since v1.8.0 of the plugin (when literal-template + Phase 5.5 self-check were added to fix Opus 4.7 schema drift). v1.6 → v1.7 added the Manifest block (mandatory). Before bumping to v1.8, write the new validator branch + fixtures first.
Failure modes: strict mode is the default for both producer and consumer. There is no soft mode here — a malformed plan is a hard failure for execute.
Handover 5 — progress.json (resume contract)
Producer: /ultraexecute-local per-step (after Verify + Manifest audit + Checkpoint).
Consumer: /ultraexecute-local --resume (re-entry) + pre-compact-flush hook (drift detection before context compaction).
Path conventions:
- Project-dir:
{project_dir}/progress.json - Legacy:
{plan-dir}/.ultraexecute-progress-{slug}.json
Schema (top-level):
| Field | Type | Required | Notes |
|---|---|---|---|
schema_version |
string | yes | "1" (current) |
plan |
string | yes | Path to the plan being executed |
plan_type |
string | optional | plan | session-spec |
plan_version |
string | yes | Mirrors plan's frontmatter |
started_at |
ISO string | yes | |
updated_at |
ISO string | yes | Bumped on every write |
completed_at |
ISO string | optional | Set when status flips to completed |
mode |
string | yes | execute | dry-run | validate |
total_steps |
number | yes | |
current_step |
number | yes | 0..total_steps |
status |
string | yes | pending | in_progress | completed | failed | partial |
session_start_sha |
string | optional | git sha at execute start |
session_end_sha |
string | optional | git sha at execute end |
steps |
object | yes | Map of step number → step record |
Per-step record:
| Field | Type | Notes |
|---|---|---|
status |
completed | in_progress | failed | pending | deferred | skipped |
|
attempts |
number | 1..N |
error |
string | null | |
completed_at |
ISO string | null | |
commit |
string | null | git sha after Checkpoint |
manifest_audit |
string | pass | fail | pass-with-note | n/a |
note |
string | optional human-readable annotation |
Validation strategy: progress-validator.mjs runs at:
/ultraexecute-local --validate(alongside plan-validator)/ultraexecute-local --resumeentry (must passcheckResumeReadiness)pre-compact-flushhook (drift check before compaction; never blocks)
Drift detection: the pre-compact-flush hook compares progress.steps[N].commit against git log --oneline {session_start_sha}..HEAD. If git reality has progressed past the recorded current_step, the hook updates progress.json atomically (tmp + rename, monotonic only) before allowing compaction. This guards against the documented P0 drift in docs/ultraexecute-v2-observations-from-config-audit-v4.md.
Versioning: schema_version: "1" is current. Future bump (e.g. "2") should add a backward-compat read path that downgrades unknown fields to warnings.
Failure modes:
PROGRESS_PARSE_ERROR→ JSON corruption; resume haltsPROGRESS_SCHEMA_MISMATCH→ unknown schema version; resume haltsPROGRESS_MISSING_FIELD→ required top-level field absent; resume haltsPROGRESS_STEP_RANGE→current_stepoutside[0, total_steps]; resume haltsPROGRESS_ALREADY_DONE→status === completed; nothing to resumePROGRESS_STEP_COUNT_MISMATCH→ warning; not a blocker
Handover 6 — review.md → plan
Handover 6 closes the iteration loop. Where Handovers 1–4 flow forward (brief → research → plan → execute) and Handover 5 makes execute resumable, Handover 6 routes review findings back into planning so a remediation plan can be produced with full traceability via source_findings.
Producer: /ultrareview-local Phase 7 (write review.md after coordinator dedup + verdict).
Consumer: /ultraplan-local Phase 1 when --brief review.md is supplied and the consumer detects type: ultrareview in frontmatter. The plan command branches into a remediation-plan path: BLOCKER + MAJOR findings become plan goals, the produced plan.md carries a source_findings: [<id>, ...] frontmatter list as the audit trail back to the consumed findings. MINOR + SUGGESTION are skipped for v1.0 plan-input.
Path conventions:
- Project-dir mode (recommended):
{project_dir}/review.md(one per review iteration; subsequent runs overwrite atomically). - Multiple review iterations are allowed in the same project; each overwrites the canonical path. Audit trail lives in git history.
Frontmatter schema:
| Field | Type | Required | Allowed values | Notes |
|---|---|---|---|---|
type |
string | yes | ultrareview |
Hard-coded discriminator |
review_version |
string | yes | "1.0" (current) |
Bump on schema change |
task |
string | yes | one-line description | Mirrors brief task |
slug |
string | yes | URL-safe slug | Used in project_dir |
project_dir |
string | yes | .claude/projects/{date}-{slug}/ |
|
brief_path |
string | yes | path to consumed brief.md |
Audit trail back to brief |
scope_sha_end |
string | yes | git sha of HEAD at review time | Defines "after" boundary |
reviewed_files_count |
number | yes | ≥ 0 | From triage gate Coverage |
findings |
list | yes | block-style YAML list of 40-char hex IDs | Flat array; full objects in body |
created |
date | optional | YYYY-MM-DD | |
scope_sha_start |
string | optional | git sha at review start | null if mtime fallback used |
verdict |
string | optional | BLOCK | WARN | ALLOW |
Coordinator output |
findings: is a flat array of finding-IDs (40-char hex from lib/parsers/finding-id.mjs). The full finding objects (severity, location, message, evidence, fix) live in the body as ### <id> subsections under per-severity ## Findings (...) headings — same pattern as brief-reviewer to avoid frontmatter-parser fragility on lists of dicts.
Body invariants: required sections (validator runs in strict mode at write-time, soft mode at read-time):
## Executive Summary## Coverage## Remediation Summary
Optional but standard sections: ## Findings (BLOCKER), ## Findings (MAJOR), ## Findings (MINOR), ## Findings (SUGGESTION). The ## Coverage section enumerates which files were deep-reviewed, summary-only, or skipped (with reason) — this is how the triage gate stays honest and avoids Copilot-style silent skips.
Validation strategy:
| Layer | When | What |
|---|---|---|
| Frontmatter parse | every read | YAML subset; reject nested dicts |
| Required fields | every read | All REVIEW_REQUIRED_FRONTMATTER present |
| Type discriminator | every read | type === "ultrareview" |
| Findings shape | every read | Array of strings, each matching ^[0-9a-f]{40}$ |
| Body sections | strict only | Executive Summary, Coverage, Remediation Summary |
| Version format | every read | review_version matches N.M; warning otherwise |
The validator (lib/validators/review-validator.mjs) exposes the same CLI as the others: node lib/validators/review-validator.mjs --json <review.md>. Strict mode is the default; --soft downgrades section-missing errors to warnings. /ultrareview-local Phase 8 runs --strict. /ultraplan-local Phase 1 (when consuming --brief review.md) runs --soft so a partially-valid review can still seed a plan.
Versioning: current is 1.0. There are no live 0.x reviews. Future schema changes follow the breaking-change protocol above.
Failure modes:
REVIEW_NOT_FOUND→ consumer halts with usage messageREVIEW_READ_ERROR→ I/O failure; haltFM_MISSING→ file has no frontmatter; haltREVIEW_WRONG_TYPE→type !== "ultrareview"; haltREVIEW_MISSING_FIELD→ strict halt; soft-mode warningREVIEW_BAD_FINDINGS_TYPE→findingsis not an array; halt (covers the YAML flow-style trap)REVIEW_BAD_FINDING_ID→ an ID is not 40-char hex; haltREVIEW_MISSING_SECTION→ strict halt; soft-mode warningREVIEW_VERSION_FORMAT→ warning only; review_version not inN.Mform
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-localPhase 8 (canonical convergence — every completed/failed/stopped/partial run that reaches the final report)/ultraexecute-localPhase 2.55 (Check 1 — dirty-tree pre-flight stop)/ultraexecute-localPhase 4 (entry-condition stop)/ultraplan-end-session-local(informal multi-session helper — Step 9 of v3.3.0)- Future:
graceful-handoffv2.2 may dual-write here as part of its session-rescue artifact (additive — extra fields tolerated, see Body invariants). hooks/scripts/pre-compact-flush.mjsrefreshesupdated_aton existing state files (statusin_progressorpartialonly). 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 Nparallel 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→/ultracontinueexits with cold-start message ("no active multi-session project here; start with/ultrabrief-localor/ultraplan-local")SESSION_STATE_PARSE_ERROR→ halt with structured error; user fixes JSONSESSION_STATE_MISSING_FIELD→ halt; suggests running validator directlySESSION_STATE_SCHEMA_MISMATCH→ halt; future1→2migration path will warn insteadSESSION_STATE_INVALID_STATUS→ halt; protects against typo'd writersSESSION_STATE_NOT_RESUMABLE→ warning;/ultracontinueexits 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.jsonremains the authoritative record of what was attempted.
Stability summary
| Handover | Validation strength | Owner | Risk |
|---|---|---|---|
| 1. brief → research | strict at write, soft at read | this plugin | low |
| 2. research → plan | soft, drift-warn | this plugin | low |
| 3. architecture → plan | discovery-only, drift-WARN | external (ultra-cc-architect) | low — by design we tolerate drift |
| 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.