Retrospective Learning Default-On Policy

Mission ID: 01KS049J4V9CSWBKJHTY2FB69H Slug: retrospective-default-policy-01KS049J Mission Type: software-dev Target Branch: main Created: 2026-05-19

Purpose

Make retrospective learning a default-on, policy-driven feedback loop in Spec Kitty 3.2.0. Every completed mission should produce a useful .kittify/missions/<mission_id>/retrospective.yaml. Policy lives in .kittify/config.yaml and charter frontmatter — not in environment variables. The default behavior is "post-completion, warn-on-failure"; strict projects can opt into pre-completion blocking via durable policy. Real authoring surfaces (spec-kitty retrospect create, backfill) replace the practice of using agent retrospect synthesize (a proposal preview/apply tool) as the de facto author.

Context

Tracking issues:

  • Primary epic: Priivacy-ai/spec-kitty#1138 — Epic: Make retrospective learning default-on and policy-driven for 3.2.0
  • 3.2.0 release context: #822 — Epic: 3.2.0 stabilization and release readiness
  • Pytest collection blocker (closed not-a-bug; documentation-only follow-up in scope): #1137 — diagnosed as local PEP 420 namespace-package corruption from a partial pip uninstall; the published wheel is fine. Fix command: uv sync --reinstall-package spec-kitty-events. A code workaround in validate.py would violate the FR-024 frozen public-surface contract per the closing comment
  • Schema-version bootstrap papercut surfaced during specify: #1158mission create blocked while upgrade reports up-to-date
  • Recent doc PR to revisit: #1136 — Clarify accept, merge, and retrospective workflow (its post-merge guidance currently overstates what summary/synthesize capture)

Historical retrospective tranche (Phase 6 epic #468): #506, #507, #508, #509, #511, #965.

Today's incoherence:

  • SPEC_KITTY_RETROSPECTIVE=1 is the user-facing on/off switch.
  • SPEC_KITTY_MODE=autonomous is the user-facing strict-mode switch.
  • runtime_bridge.py passes facilitator_callback=None into run_terminus, so enabled strict paths fail closed instead of producing useful learning.
  • spec-kitty retrospect summary is read-only aggregation, but PR #1136 docs treat it as the post-merge "capture the retrospective" step.
  • spec-kitty agent retrospect synthesize is a proposal preview/apply tool, but it has a quiet fallback that fabricates an empty completed record when artifacts look sufficient — used in practice as the de facto authoring surface.
  • No retrospect create or retrospect backfill command exists; there is no real, durable authoring path.

The product thesis (from the workspace's start-here.md handoff):

> Retrospective learning should be a core Spec Kitty feedback loop, not an env-gated experimental terminus trap.

Workspace handoff: /Users/robert/spec-kitty-dev/retrospective-default-policy-20260519-131623-oUG5Kq/start-here.md. Local CLI/runtime work only; SaaS sync flag (SPEC_KITTY_ENABLE_SAAS_SYNC=1) is not normally required for this mission.

Hotspot

The following are the highest-leverage code/doc surfaces the implementation will touch. Final task decomposition happens at /spec-kitty.plan and /spec-kitty.tasks time.

ItemLocation
Env-driven policy resolver (today)src/specify_cli/retrospective/config.py
Mode/strictness resolver (today)src/specify_cli/retrospective/mode.py
Runtime callback wiring (facilitator_callback=None)src/specify_cli/next/runtime_bridge.py
Terminus integration pointsrc/specify_cli/next/_internal_runtime/retrospective_terminus.py
Schema definitionssrc/specify_cli/retrospective/schema.py
Writersrc/specify_cli/retrospective/writer.py
Read-only aggregationsrc/specify_cli/retrospective/summary.py
Existing CLI surface (preview/apply)src/specify_cli/cli/commands/agent_retrospect.py
Proposal synthesissrc/specify_cli/doctrine_synthesizer/
Shipped retrospective-facilitator profilesrc/doctrine/agent_profiles/shipped/retrospective-facilitator.agent.yaml
Pytest collection blocker (issue #1137)src/specify_cli/status/validate.py imports normalize_event_id from spec_kitty_events; 5.1.0 lacks the top-level export
Docs likely to updateREADME.md, docs/how-to/accept-and-merge.md, docs/how-to/merge-feature.md, docs/how-to/use-retrospective-learning.md, docs/explanation/retrospective-learning-loop.md, docs/reference/cli-commands.md, docs/reference/slash-commands.md, docs/tutorials/your-first-feature.md
Shipped skills likely to updatesrc/doctrine/skills/spec-kitty-mission-review/SKILL.md, spec-kitty-implement-review/SKILL.md, spec-kitty-program-orchestrate/SKILL.md, spec-kitty-runtime-next/SKILL.md

User Scenarios & Testing

Primary Scenario — Default post-completion success

Actor: A developer who has just merged a mission via spec-kitty merge. Trigger: Mission completion path runs after merge with the default RetrospectivePolicy (enabled: true, timing: post_completion, failure_policy: warn). Happy-path outcome: The runtime invokes the real retrospective generator. It reads spec.md, plan.md, tasks.md, tasks/WP*.md, meta.json, status.events.jsonl, review/rejection cycles, mission-review report (if present), and applicable DRG/doctrine/glossary context. It writes .kittify/missions/<mission_id>/retrospective.yaml (or the canonical analog) with helped, not_helpful, gaps, proposals, provenance, mission metadata, and evidence references. A RetrospectiveCaptured (or equivalent) event lands in the event log. Mission completion proceeds normally. No doctrine/DRG/glossary mutation happens automatically — proposals stay pending human approval.

Strict Scenario — Pre-completion block on missing/failed retrospective

Actor: A governed-project operator running on policy timing: before_completion, failure_policy: block. Trigger: Mission ready to complete; retrospective generation either fails or has not run. Outcome: Completion blocks with a structured reason that cites the policy source (e.g. .kittify/config.yaml#retrospective.timing or charter frontmatter path) and the failure category. Operator fixes the underlying cause (artifacts present, generator error, etc.) and re-runs. Skipping requires explicit permission and records actor/provenance in the event log.

Failure-Warn Scenario — Default policy, generator error

Actor: A developer on the default policy whose generator hits an exception (e.g. malformed status.events.jsonl, missing mission-review-report.md that was expected, a transient I/O error). Outcome: A warning event is emitted with the failure category and remediation hint; mission completion is not blocked. The user can run spec-kitty retrospect create --mission <handle> later to author the record.

Opt-Out Scenario — enabled: false

Actor: A project that has set retrospective.enabled: false in .kittify/config.yaml. Outcome: No generator runs at any mission boundary. No warning. No event noise. spec-kitty retrospect create --mission <handle> continues to work as an explicit manual surface.

Authoring Scenario — retrospect create for one mission

Actor: A maintainer who wants to author or refresh a retrospective for a specific completed mission. Trigger: spec-kitty retrospect create --mission <handle> (where <handle> is mission_id ULID, mid8, or mission_slug). Outcome: A real retrospective.yaml is authored from mission artifacts. If a record already exists, the command does not silently overwrite — the user must pass an explicit flag (e.g. --overwrite or --update) and the action is recorded in the event log with actor/provenance. Missing artifacts produce actionable errors, not empty "completed" records.

Backfill Scenario — historical missions

Actor: A maintainer who wants to seed retrospectives for missions completed before this mission shipped. Trigger: spec-kitty retrospect backfill --since 2026-05-01 (or another time window) with optional --mission <handle> for single-target backfill. Outcome: For each candidate mission, the command attempts authoring. JSON output enumerates created, skipped (with reason: already exists / not completed / not in window), failed (with category), and next_actions. Existing records are never silently overwritten.

Synthesize Scenario — preview/apply unchanged but no longer the author

Actor: A maintainer reviewing proposals in an already-authored retrospective.yaml. Trigger: spec-kitty agent retrospect synthesize --mission <handle> [--preview | --apply <proposal_id>]. Outcome: Preview shows the proposed glossary/DRG/doctrine changes. Apply requires explicit selection and human confirmation. Auto-application is permitted only for explicitly low-risk classes (e.g. flag_not_helpful) and only when policy permits. Structural changes to doctrine/DRG/glossary never auto-apply.

Env-Var Deprecation Scenario

Actor: A developer with SPEC_KITTY_RETROSPECTIVE=1 and SPEC_KITTY_MODE=autonomous in their shell. Outcome: The runtime emits a deprecation warning at first use per session: SPEC_KITTY_RETROSPECTIVE is deprecated; set retrospective.enabled in .kittify/config.yaml or charter. The runtime still honors the env var for test/dev use this release cycle, but it does not override durable policy when both are present (durable policy wins, deprecation warning still emitted). Tests prefer injected policy over ambient env.

Acceptance Rule (must always hold)

For every completed mission under default policy:

  • The retrospective generator MUST be attempted exactly once.
  • On success, retrospective.yaml MUST exist with a schema-valid record and a RetrospectiveCaptured event MUST appear in status.events.jsonl.
  • On failure, a RetrospectiveCaptureFailed (or equivalently named) event MUST be emitted with a structured failure category, and mission completion MUST NOT be blocked.
  • The policy source MUST be recorded on every emitted retrospective event.
  • Generation MUST NOT mutate doctrine/DRG/glossary as a side effect.
  • A synthesize invocation with --fabricate-empty MUST author a record whose findings_status is exactly ran_no_findings and whose provenance.kind is synthesize_fabricate. No fabrication path may produce a has_findings record.

Domain Language

TermMeaning
RetrospectivePolicyThe durable policy model defining whether retrospective generation runs, when (before vs after completion), how to react to failure (block vs warn), and which permission classes are granted. Resolved from .kittify/config.yaml and charter frontmatter with documented precedence.
Retrospective recordA schema-valid YAML artifact (retrospective.yaml) containing helped, not_helpful, gaps, proposals, provenance, mission metadata, and evidence references for a single mission.
GeneratorThe runtime code path that inspects mission artifacts and produces a RetrospectiveRecord. Distinct from "writer" (persistence) and "synthesizer" (proposal application).
SynthesizeThe existing proposal preview/apply surface (spec-kitty agent retrospect synthesize). Operates on proposals inside an already-authored retrospective record. Not a real author.
CreateThe new authoring surface (spec-kitty retrospect create) that runs the generator on demand for one mission.
BackfillThe new historical-authoring surface (spec-kitty retrospect backfill) that authors records for previously completed missions.
SummaryThe read-only aggregation surface (spec-kitty retrospect summary). Reports across existing records. Not an author.
Policy sourceA structured pointer to where a given policy field was resolved from (e.g. .kittify/config.yaml#retrospective.timing, charter frontmatter key, env-var fallback). Recorded on emitted retrospective events.
Failure policyBranch of RetrospectivePolicy controlling block-vs-warn on generation failure. Default warn.
TimingBranch of RetrospectivePolicy controlling before_completion vs post_completion. Default post_completion.
Apply modeBranch of RetrospectivePolicy controlling whether generated proposals can be auto-applied. Default require_human for all proposal classes except an explicitly enumerated low-risk allowlist.
Empty findingsA retrospective record explicitly representing "ran, no findings". MUST be distinct from "missing retrospective" or "failed retrospective" in both event payloads and read-only summaries.
Mission completion (for retrospective policy purposes)The runtime step that emits the MissionCompleted event after all WPs are in terminal lanes (done or canceled) AND the merge has been written to the target branch. The strict gate (timing: before_completion + failure_policy: block) fires between "all WPs terminal AND merge written" and "MissionCompleted emitted" — i.e. it is the last gate the runtime evaluates before declaring the mission complete. This disambiguates the three plausible "completion" moments (last WP→done, merge written, MissionCompleted emitted): for policy purposes the gate hangs off the third, and is bypassable only with --skip-retrospective.
Mission boundaryA point in the mission lifecycle where retrospective policy is evaluated. Today's only mission boundary is "mission completion" as defined above. The term anticipates future boundaries (e.g. per-WP retrospectives) without committing to them in this release.

Functional Requirements

IDDescriptionStatus
FR-001A RetrospectivePolicy model and resolver exist that read policy from .kittify/config.yaml (top-level retrospective: block) and charter frontmatter with documented precedence (config overrides charter only on explicit precedence: config directive; charter wins by default for governed projects). The resolver returns the resolved policy AND a source map naming the origin of every resolved field.Required
FR-002The default RetrospectivePolicy is enabled: true, timing: post_completion, failure_policy: warn, write_record: true, generate_proposals: true, apply_proposals: require_human. Default permissions: write_record: true, inspect_mission_artifacts: true, propose_glossary_changes: true, propose_drg_changes: true, propose_doctrine_changes: true, apply_low_risk_changes: false, apply_structural_changes: false.Required
FR-003Explicit opt-out (retrospective.enabled: false) prevents any generator invocation at any mission boundary, emits no warning, and produces no retrospective events.Required
FR-004Strict policy (timing: before_completion + failure_policy: block) preserves today's gate semantics: missing or failed retrospective blocks completion with a structured reason that cites the resolved policy source.Required
FR-005The runtime no longer passes facilitator_callback=None into run_terminus for enabled paths. A real generator callback is wired such that the strict path produces useful learning rather than failing closed.Required
FR-006A retrospective generator function exists that inspects, at minimum: spec.md, plan.md, tasks.md, tasks/WP*.md, meta.json, status.events.jsonl, review/rejection cycles, mission-review report when present, and policy-relevant DRG/doctrine/glossary context. It produces a schema-valid RetrospectiveRecord with helped, not_helpful, gaps, proposals, provenance, mission metadata, and evidence references.Required
FR-007Empty-findings retrospectives MUST be explicitly represented (e.g. findings_status: ran_no_findings) and MUST NOT be confused with "missing retrospective" or "failed retrospective" anywhere in events, schema, summary, or CLI output.Required
FR-008Under default policy, mission completion path: (a) attempts retrospective generation exactly once; (b) on success writes retrospective.yaml and emits a RetrospectiveCaptured event; (c) on failure emits a RetrospectiveCaptureFailed event with a structured failure category and remediation hint, and does NOT block completion.Required
FR-009Under strict policy (before_completion + block), mission completion path enforces the gate before the completion event lands; the blocking message MUST cite the resolved policy source verbatim. Skips require an explicit --skip-retrospective permission and record actor/provenance in the event log.Required
FR-010Automatic retrospective record generation MUST NOT mutate doctrine, DRG, or glossary. Application of proposals stays human-approved by default; the existing agent retrospect synthesize surface remains the preview/apply path. Narrow low-risk auto-application (e.g. flag_not_helpful) is permitted only when policy explicitly enables it.Required
FR-011A new spec-kitty retrospect create --mission <handle> command authors a real retrospective for one completed mission. <handle> resolves via the canonical resolver (mission_id > mid8 > mission_slug) with structured ambiguity errors. If a record already exists, the command does not silently overwrite; explicit --overwrite or --update flag is required, and the action is logged with actor/provenance.Required
FR-012A new spec-kitty retrospect backfill --since <ISO-date> command (with optional --mission <handle> for single-target backfill) authors records for historical missions. JSON output enumerates created, skipped (with reason), failed (with category), and next_actions. Existing records are never silently overwritten.Required
FR-013spec-kitty retrospect summary remains read-only aggregation. It MUST NOT author, mutate, or write any retrospective record. Its output MUST distinguish "ran, no findings" from "missing" from "failed".Required
FR-014The silent "fabricate an empty completed record when artifacts look sufficient" fallback inside agent retrospect synthesize is removed OR is moved behind an explicit --fabricate-empty flag whose use is logged as actor-attributed provenance. The default path errors with an actionable message pointing at retrospect create.Required
FR-015SPEC_KITTY_RETROSPECTIVE and SPEC_KITTY_MODE are demoted to test/developer overrides. At first use per session, the runtime emits a deprecation warning naming the durable equivalent (retrospective.enabled / retrospective.timing + retrospective.failure_policy). Durable policy takes precedence when both are present; deprecation warning still emits.Required
FR-016Tests prefer injected policy over ambient env. The retrospective unit and integration test suites MUST construct RetrospectivePolicy objects directly rather than mutating os.environ, with at most a single dedicated test module exercising the deprecation-warning path.Required
FR-017A diagnostic note is added to CONTRIBUTING.md (or the project's equivalent local-dev troubleshooting doc) documenting the #1137 namespace-package corruption diagnostic (python -c "import spec_kitty_events; print(spec_kitty_events.__file__, spec_kitty_events.__path__)"None + _NamespacePath(...) is the symptom) and the canonical fix command (uv sync --reinstall-package spec-kitty-events). NO code fallback in validate.py or other import sites is added; per the #1137 closing comment, that would violate the FR-024 frozen public-surface contract.Required
FR-018Docs are updated to reflect the post-mission CLI semantics: summary is read-only aggregation; create authors a record; backfill creates historical records; synthesize previews/applies proposals from an existing record. Affected files at minimum: README.md, docs/how-to/accept-and-merge.md, docs/how-to/merge-feature.md, docs/how-to/use-retrospective-learning.md, docs/explanation/retrospective-learning-loop.md, docs/reference/cli-commands.md, docs/reference/slash-commands.md, docs/tutorials/your-first-feature.md. PR #1136 wording is corrected as part of this update (no separate short-term doc PR is required since this mission ships before that fix would otherwise lapse).Required
FR-019Shipped skills are updated to reflect the same semantics. Affected at minimum: src/doctrine/skills/spec-kitty-mission-review/SKILL.md, spec-kitty-implement-review/SKILL.md, spec-kitty-program-orchestrate/SKILL.md, spec-kitty-runtime-next/SKILL.md. The post-merge guidance reads: mission review first, then create/capture retrospective, then summary or synthesize.Required
FR-020The retrospective-facilitator agent profile (src/doctrine/agent_profiles/shipped/retrospective-facilitator.agent.yaml) is reviewed and, if needed, updated so its declared boundaries and permissions match the FR-001/FR-002 policy model and the FR-010 separation between authoring and applying.Required
FR-021Existing retrospective events still reduce correctly. The reducer in src/specify_cli/status/reducer.py (or the equivalent retrospective-event reducer) is exercised against historical fixtures and produces the same materialized snapshots before and after this mission, with the exception of new event types added by this mission (which MUST be additive).Required
FR-022Bulk-edit guardrails apply where the work performs cross-file string changes. The plan/tasks phase MUST decide whether the env-var deprecation messaging and doc-semantics updates qualify as change_mode: bulk_edit; if yes, an occurrence_map.yaml is produced and the bulk-edit gate must pass. The decision and rationale are recorded in the mission plan.Required
FR-023The legacy src/specify_cli/retrospective/config.py and src/specify_cli/retrospective/mode.py modules either (a) are folded into the new policy.py resolver and deleted with their references updated, or (b) are retained as a documented compatibility shim with an explicit retirement plan (deprecation date, follow-up issue link, and rationale) recorded in the mission plan. The mission MUST NOT leave them in a "half-deleted" state with no documented lifetime.Required
FR-024The RetrospectivePolicy resolver handles malformed input deterministically. Malformed .kittify/config.yaml (e.g. invalid YAML, type errors in retrospective: block, unknown keys when strict mode is enabled) and malformed charter frontmatter produce a structured PolicyResolutionFailed outcome carrying the source path, the offending key, and the underlying parse error. Under default policy the runtime treats this as a generator-side failure (emits RetrospectiveCaptureFailed with failure_category: policy_resolution_error) and proceeds with built-in defaults for completion logic; under strict policy this is a blocking condition with a structured reason.Required
FR-025A regression fixture set under tests/retrospective/fixtures/event_logs/ exercises FR-021's "existing event log reductions remain byte-identical" guarantee. At minimum, fixtures cover: (a) a historical mission's status.events.jsonl with no retrospective events (lane state must materialize identically before/after the mission); (b) the same log with new RetrospectiveCaptured and RetrospectiveCaptureFailed events appended (lane state still materializes identically; retrospective state surfaces as additive top-level keys only). The fixture inventory and expected snapshots are checked in.Required

Non-Functional Requirements

IDDescriptionMeasurable ThresholdStatus
NFR-001Targeted test runtime for retrospective surfacesuv run pytest tests/retrospective tests/integration/retrospective tests/next/test_retrospective_terminus_wiring.py -q completes in under 60 seconds wall-clock on a stock developer machine.Required
NFR-002No regression in the full test suiteuv run pytest tests/ -q exits 0 on main after the mission merges. Collection works today in the project's uv-managed env (verified: 207 tests collected in tests/retrospective/ in 2.4s).Required
NFR-003Lint and type-check gates passuv run ruff check src tests exits 0. Mypy/pyright configuration follows existing repo conventions for the touched modules.Required
NFR-004Coverage gate for new retrospective code pathsCombined line coverage of src/specify_cli/retrospective/, src/specify_cli/next/runtime_bridge.py, src/specify_cli/next/_internal_runtime/retrospective_terminus.py, and the new retrospect create / backfill CLI surface is ≥ 90% measured by coverage after the mission's tests run (matches the charter's 90%+ requirement).Required
NFR-005Default-policy completion latencyDefault-policy mission completion (post-merge path) adds at most 2 seconds wall-clock on a representative mission (≤ 5 WPs, ≤ 50 events) for retrospective generation. Measured by a focused integration test.Required
NFR-006Deprecation-warning noise budgetSetting either deprecated env var emits exactly one warning per process, not per command invocation. The warning text includes both the durable replacement key path AND a link to docs.Required
NFR-007Wire shape additivity for retrospective eventsThis mission MUST NOT remove fields from existing retrospective event payloads. New fields (e.g. policy-source attribution) are additive and documented in the schema.Required
NFR-008Docs render cleanlyuv run markdownlint --config .markdownlint-cli2.jsonc <touched-doc-paths> exits 0; the documented commands in updated how-tos succeed against a fresh project.Required

Constraints

IDDescriptionStatus
C-001Target branch is main; planning/base branch is main; completed changes merge back into main (resolved via spec-kitty agent mission branch-context --json).Required
C-002Local CLI/runtime work only. No SaaS/teamspace-specific retrospective implementation in this mission. SPEC_KITTY_ENABLE_SAAS_SYNC=1 is NOT required in normal operation; if a command path inadvertently exercises hosted auth/tracker/SaaS behavior, the test runs with the flag set.Required
C-003Do not delete existing retrospective schema, event types, or historical records. All changes are additive; deprecated paths are demoted, not removed, this release cycle.Required
C-004Environment variables MUST NOT be the durable user-facing policy model. They remain as test/developer overrides for one release cycle and are documented as such.Required
C-005Auto-application of structural doctrine/DRG/glossary changes is OFF by default. Policy may explicitly enable narrow low-risk classes; structural changes always require human approval.Required
C-006Existing tests under tests/ MUST continue to pass post-merge.Required
C-007Mission identity uses ULID + mid8. Mission slug is retrospective-default-policy-01KS049J; mission_number is display-only and null pre-merge. All cross-mission references use mission_id or mid8, never mission_number.Required
C-008The schema-version bootstrap quirk surfaced in #1158 was worked around in-session by directly invoking _update_schema_version(); this mission MUST NOT depend on that workaround at production sites. If the proper fix lands in #1158 before this mission merges, depend on it; otherwise note the workaround in the mission-review report.Required

Success Criteria

IDStatementMeasurement
SC-001A reader can run spec-kitty merge on a default-policy project and find a non-empty, schema-valid retrospective.yaml afterward, with a RetrospectiveCaptured event in the mission's event log.Manual smoke test on a fresh project + the FR-008 integration test green.
SC-002Setting retrospective.enabled: false in .kittify/config.yaml produces a merge with no retrospective artifacts, no retrospective events, and no warning.Manual smoke + FR-003 integration test green.
SC-003Setting retrospective.timing: before_completion and retrospective.failure_policy: block reproduces today's gate semantics with a clear blocking message citing the policy source.FR-004 + FR-009 integration tests green.
SC-004spec-kitty retrospect create --mission <handle> on an arbitrary completed mission in this repo produces a real, schema-valid record.Manual exercise on at least three already-completed missions in kitty-specs/, e.g. 068-post-merge-reliability-and-release-hardening, 034-feature-status-state-model-remediation, 047-namespace-aware-artifact-body-sync.
SC-005spec-kitty retrospect backfill --since 2026-01-01 on this repo's kitty-specs/ produces a JSON report enumerating created/skipped/failed counts that match a hand-tabulated expected count.One-off verification table in the mission-review report.
SC-006The deprecation warning fires exactly once per process when an env var is set, names the durable replacement key, and the durable policy still wins.FR-015, FR-016, NFR-006 tests green.
SC-007A reader of the updated docs can find — within 30 seconds of opening docs/how-to/use-retrospective-learning.md — the canonical post-merge sequence (mission review → create/capture retrospective → summary/synthesize) and the difference between create, summary, and synthesize.Mission-review doc walkthrough.
SC-008uv run pytest tests/ -q collects without error AND exits 0.CI green. The FR-017 CONTRIBUTING note unblocks local contributor envs that hit the namespace-package corruption signature; CI itself is unaffected (already green on PR #1136).

Assumptions

  • The retrospective schema (src/specify_cli/retrospective/schema.py) is broadly fit for purpose and does not need a structural rewrite this release. Field additions (e.g. policy-source attribution) are additive only.
  • The existing retrospective event types in the canonical event log are not renamed by this mission. New event types (e.g. RetrospectiveCaptured, RetrospectiveCaptureFailed) are added if and only if no existing event type already serves the same purpose; otherwise the existing one is reused.
  • The shipped retrospective-facilitator.agent.yaml profile boundaries are close enough to the FR-010 model that they need at most a configuration-level refinement, not a profile rewrite.
  • The default policy can be implemented and tested without depending on charter being present; missing charter is a no-op for policy resolution, with config-file or built-in defaults filling the resolved policy.
  • The schema-version bootstrap fix (#1158) is independent of this mission's logic and can land separately.

Dependencies & Risks

Dependencies:

  • #1137 (spec_kitty_events 5.1.0 top-level exports) — CLOSED not-a-bug; this mission carries only the FR-017 documentation note, no code change.
  • The canonical event-log infrastructure (src/specify_cli/status/) and the canonical mission-identity model (mission 083+) — both already merged.
  • The spec-kitty merge and mission-completion paths — load-bearing for FR-008 / FR-009.

Risks:

  • R-1 Scope creep into proposal application: The mission is bounded to generation as the default-on behavior. Application semantics could expand. Mitigation: FR-010 hard-bounds the default to require_human for structural changes; auto-apply allowlist is explicitly enumerated, not implicit.
  • R-2 Deprecation warning fatigue: If the warning fires on every command, users will configure environments to suppress it and we will lose the deprecation signal. Mitigation: NFR-006 enforces a per-process budget.
  • R-3 Failure policy ambiguity at completion time: If the generator throws a transient error under default policy, the mission completes with a warning event. If a strict project then surveys completions and finds a warning, they may not know whether the retrospective is missing or just deferred. Mitigation: FR-007 + summary distinguishes "ran, no findings" / "failed" / "missing" / "deferred" in both events and read-only outputs.
  • R-4 Generator quality: An automatic generator that produces low-signal records is worse than no record (training the user to ignore retrospectives). Mitigation: SC-004 sanity-checks the generator against three real completed missions in kitty-specs/ and the mission-review report validates output quality.
  • R-5 Docs/skills drift: The cross-cutting doc and skill updates risk getting partial coverage. Mitigation: FR-018 + FR-019 enumerate the exact files; FR-022 forces bulk-edit classification at plan-time if the work pattern qualifies.
  • R-6 PR #1136 wording remains stale if this mission slips the release window: The post-merge guidance in docs/how-to/accept-and-merge.md currently overstates summary/synthesize. Mitigation: if this mission cannot ship in 3.2.0, a short-term doc-only correction lands separately; otherwise FR-018 catches it as part of this mission.

Non-Goals

  • SaaS/teamspace-specific retrospective implementation.
  • Auto-applying structural doctrine/DRG/glossary changes by default.
  • Deleting existing retrospective schema or event history.
  • Promoting environment variables as the durable user-facing policy model.
  • Restructuring RetrospectiveRecord schema fields beyond additive policy-source attribution.

Suggested Work Package Shape

Decomposition lives at /spec-kitty.tasks time. The brief's suggestion (to validate or revise at planning):

1. WP-PolicyRetrospectivePolicy model + resolver + tests (covers FR-001, FR-002, FR-003, FR-004, NFR-002, NFR-003, NFR-007). 2. WP-Generator — Real retrospective generator + schema additions + tests (FR-005, FR-006, FR-007, FR-010, NFR-004, NFR-007). 3. WP-Runtime — Wire generator into runtime; default post-completion best-effort + strict pre-completion gate + policy-source attribution on events (FR-005, FR-008, FR-009, FR-021, NFR-005). 4. WP-CLIretrospect create and retrospect backfill commands; tighten synthesize fallback (FR-011, FR-012, FR-013, FR-014). 5. WP-Env-Deprecate — Deprecation warnings + test rewrites to prefer injected policy (FR-015, FR-016, NFR-006). 6. WP-Docs-Skills — Docs and shipped-skills updates; PR #1136 wording fix; retrospective-facilitator profile review; CONTRIBUTING.md note for the #1137 namespace-package diagnostic (FR-017, FR-018, FR-019, FR-020, FR-022, NFR-008).

The dependency order is roughly Policy → Generator → Runtime → CLI in parallel with Env-Deprecate, with Docs-Skills landing after the surfaces stabilize.