# Changelog

All notable changes to `ccd-cli` are documented in this file.

This changelog was introduced after `v0.4.1`. Earlier tags exist, but they were
published before a repo-local changelog was maintained here.

## [1.0.0-beta.4] - 2026-04-26

### Breaking

- The session close-out surface is now `ccd handover`; the lightweight
  mid-session pulse is `ccd checkpoint`. The old radar-state vocabulary has
  been decomposed so checkpoint carries the shared continuity foundation while
  handover remains the full wrap-up and evaluation path. Skills, docs, and the
  implementation matrix now describe the checkpoint/handover split.

### Added

- `ccd doctor --output json` and the matching MCP `ccd_health doctor` surface
  now include `agent_diagnostics` with package version, binary metadata, and
  state.db schema compatibility details, and `likely_host_process_drift` hints so
  long-lived agents can distinguish a stale MCP/CLI process from repository
  corruption.
- `ccd marker repair` now previews or applies a local-only repair for legacy
  `.ccd.toml` markers that still use `repo_id` with `version = 1`, preserving
  the existing project identity and metadata while rewriting to
  `project_id`/`version = 2`; `ccd doctor` now points affected workspaces at
  the exact repair command.
- `ccd thread export` and `ccd thread import --preview` now ship the
  experimental thread-transfer capsule rail. The kernel owns the portable
  envelope, continuity payload, attachment budget, content digest validation,
  duplicate tuple detection, unknown-extension rejection, and hidden
  fail-closed `--write` guard.
- The default binary includes the first first-party, batteries-included
  extension provider: `ccd-fixity`. Thread export may include a bounded,
  read-only `handoff_scoped_fixity` attachment derived from pending memory
  evidence. Import remains preview-only and validates schema version, caps,
  summary length, summary digest, candidate id, source-to-Fixity type mapping,
  and unknown fields before accepting the payload. Fixity remains
  extension-owned; durable memory promotion is still governed separately.
- `ccd checkpoint` is available as a strict subset of handover output for
  context-pressure checks, repeated-retry triage, and auto-lifecycle hooks. It
  keeps session boundary, context health, behavioral drift, Git state, handoff
  summary, projection telemetry, work-stream decay, and handoff refresh
  candidates while omitting handover-only evaluation buckets, approval steps,
  repo-native checks, and memory candidates.

### Fixed

- `ccd session-state start --recover-stale` now provides an explicit same-actor
  stale lease recovery path. It verifies the requested actor matches the stale
  owner, preserves the prior owner kind, supervisor id, lease TTL, and mode unless
  those flags are deliberately overridden, and keeps different-actor recovery on
  the existing explicit takeover path.
- `ccd session-state heartbeat --output json` now emits a structured failed or
  stale heartbeat payload when the CCD lease renewal is rejected, including the
  CCD payload status, represented command exit status, last heartbeat timestamp,
  lease expiry, owner metadata, and error summary so wrappers cannot mask CCD
  heartbeat failure by reporting their own execution success.
- Thread-transfer import preview now rejects malformed attachment metadata,
  invalid content digests, oversize payload declarations, unknown extension
  attachments, duplicate attachment tuples, and incompatible extension schema
  versions without mutating kernel continuity.
- `ccd describe` now reflects the new thread command behavior consistently.
- The Hermes reference guidance was clarified around work-window lifecycle
  handling, and the temporary Codex auto-lifecycle advisory was reverted after
  the hook behavior was fixed and recall adapters were externalized.

## [1.0.0-beta.3] - 2026-04-23

### Breaking

- **RFC 0006 pod-layer collapse.** The `pod` layer is being retired as an
  operator-facing concept. This release lands the external-surface
  retirements that define the RFC 0006 breaking boundary; the remaining
  internal pod-scoped runtime paths (`~/.ccd/pods/{pod}/pod.toml`,
  `machine.toml`, `presence/`, `policy.md`) stay live behind the compat
  window until the final cutover. Tracked under ccd#593.
  - `ccd pod <subcommand>` is retired as a user-facing CLI. Every
    subcommand (`ccd pod init`, `ccd pod list`, `ccd pod status`,
    `ccd pod migrate-defaults`) ships as a fail-closed deprecation shim
    that exits non-zero and prints migration guidance without delegating.
    Use `ccd machine list` for the post-collapse inventory; there is no
    direct replacement for `ccd pod status` (`ccd status` and
    `ccd doctor` cover the reachable surface).
  - `ccd remember --scope pod` and `ccd memory promote --destination
    pod-memory` are retired. Pod-scoped memory writes, the pod-memory
    read path, and the `memory_evidence.scope = 'pod'` CHECK constraint
    are all gone. The schema migration gate fails closed against
    residual pod-scoped state until `ccd migrate from-pod-layout` has
    run.
  - `ccd session open --pod <name>` is retired. The flag and the matching
    MCP tool argument fail closed; callers that depended on pod-scoped
    session dispatch should move to the default profile/locality routing.
  - The `pod_name` field is retired from every agent-facing machine JSON
    surface (`MachineIdentityView`, `MachinePresenceView`,
    `MachineExecutionContextView`, `MachineListEntry`,
    `LoadedMachineIdentity`), the `Pod` column is removed from
    `ccd machine list` text output, and the pod-scoped tail is dropped
    from the `machine_identity` doctor advisory. `pod_name` is preserved
    only on internal on-disk surfaces for forward-compat during the
    compat window: `MachinePresenceRecord` still carries it on disk,
    `ccd migrate from-pod-layout --output json` still emits
    `pods[*].pod_name` as the migration tool's pod-dir identifier.
  - The `pod_identity` runtime/JSON surface is retired from `ccd start
    --output json` and `ccd status --output json`; `ccd describe
    --output json` no longer lists any pod subcommand. MCP tools that
    carried pod-shaped schemas are removed without a compat-alias window
    (per RFC 0006 §5, MCP clients discover tools by schema rather than
    name, so a removed tool surfaces as a clean "unknown tool" error on
    the client side).
  - The `pod_identity` and `pod_migration` doctor advisories are
    retired; the advisory category is gone, not replaced.

### Fixed

- `ccd session-state takeover` now uses `BEGIN IMMEDIATE` with a CAS
  guard so concurrent takeover attempts are serialized by SQLite's
  reserved lock instead of racing on a pre-lock snapshot. The
  transaction body re-reads the session row and re-validates staleness
  and authorization against the fresh view, writing through
  `write_if_revision_matches` so a stale snapshot surfaces as
  `RevisionConflict` instead of a silent lost update. Closes ccd#568
  (PR #604).
- `ccd radar-state` context-health scoring now applies a raw-token
  degradation risk estimate when no context-window size is known
  (e.g., when `CCD_CONTEXT_WINDOW_TOKENS` is unset). Previously
  `degradation_risk_pct` was null in this case; it now falls back to
  a coarse heuristic based on cumulative `host_total_tokens` so
  runtimes without native telemetry still get a directional signal.
  The `host` vocabulary was swept to `runtime` across 33 files for
  consistency. Closes ccd#529, ccd#527 (PR #605).
- Shipped skills and the `radar-state-schema.json` reference no longer
  declare extension-owned fields (`backlog`, `workflow_signal`,
  `workflow_hints`) that were removed from the CLI when backlog moved
  to `ccd-extensions`. The `ccd-attach` skill no longer mentions
  `backlog.md` as kernel project truth. `ccd skills install` now warns
  about stale `ccd-*` skill directories from previous versions, and
  `ccd doctor` detects both stale and missing installed skills. Closes
  ccd#606 (PR #607).
- Handoff drift detectors (`handoff_references_resolved` and
  `referential_integrity`) no longer fire `Missing` drift for
  forward-references — paths the session is explicitly chartered to
  create via a create-action verb (`author`, `write`, `publish`,
  `create`, `produce`, `draft`, `generate`, `emit`, `compose`, `land`,
  `open`, plus common tense forms). The classifier is token-local: a
  later input verb in the same clause (`Generate X after reviewing Y`)
  or an explicit dependency preposition (` from `, ` using `,
  ` based on `, ` against `, ` via `, ` out of `) correctly identifies
  `Y` as an input and keeps the audit firing for missing prerequisites.
  Absolute paths and parent-dir traversal still fail audit on
  create-verb lines; `key_files` entries remain treated as inputs and
  audited normally; substring matches of a token inside another path
  token are rejected via word-boundary search; the clause walker is
  UTF-8 safe. Scope note: the classifier relies on explicit verbs and
  dependency prepositions; ambiguous English prepositions (`in`,
  `with`, `for`) inherit the enclosing verb, and parent-directory
  existence of a forward-reference is not independently validated. A
  missing-parent-dir drift signal and a richer schema split between
  `inputs` and `outputs` are tracked as follow-ups. Before this fix, a
  handoff that named a not-yet-authored deliverable flipped
  `session_boundary.action` to `stop` and surfaced `recalibrate_session`
  on every clean resume of an in-progress multi-session deliverable.
  Closes ccd#597.

### Added

- `ccd doctor` now fails closed with `severity: error` when a workspace
  declares a Tier-2 host integration (`[hosts.<name>].mode =
  "native_hook"` for Claude or `"reference_adapter"` for OpenClaw /
  Hermes) but neither the CCD-managed scaffold under `.ccd-hosts/` nor
  the installed runtime artifacts at the host's canonical destination
  paths exist (ccd#595). The new `host_integration_readiness` check
  names the combined remediation (`ccd init --host <name> --path . &&
  ccd host install <name> --path .`) and suppresses the two previously
  redundant per-asset warnings for the same workspace. When only one of
  the two asset sets is missing, the existing per-asset warnings still
  fire individually.
- `ccd` hooks can now emit a `handoff_refresh` candidate patch on
  `on-agent-end` (ccd#596). When `[handoff.candidate_refresh] enabled =
  true` is set in the profile config or repo overlay, every radar
  evaluation — including the lightweight checkpoint that Claude's
  on-agent-end hook produces — scans commits in `session_start..HEAD`
  for completion signals against the workspace handoff: commit subjects
  matching distinctive tokens in `immediate_actions`, and session-touched
  paths intersecting `key_files`. Matches surface as
  `candidate_updates.handoff[]` entries that `/ccd-radar` can review. The
  hook never mutates the persisted handoff — canonical writes still flow
  through `ccd handoff write`. The flag defaults to `false`, so existing
  deployments see byte-identical output until they opt in. Signal
  sources are local-deterministic (commit subjects/footers, touched
  paths, handoff text) — no GitHub API. Overhead measured at ~20ms at
  100 commits in the session window, well under the 200ms budget.
- `ccd radar-state` gains a new `handoff_milestone_progression_fresh`
  behavioral-drift signal (ccd#598). The detector parses the workspace
  handoff's `title` and active `immediate_actions` for milestone-shaped
  tokens (`M<digits>`, `Phase <uppercase-letter>`) and walks commit
  subjects in `session_start..HEAD`; when a subject references a
  milestone beyond the handoff's stated ceiling, the signal fires
  `drift` and the ccd-radar fast path forces a handoff rewrite before
  wrap-up. The matcher is intentionally conservative — exact-phrase,
  case-sensitive on `M` and `Phase`, word-boundary safe — and fails
  closed when `git log` cannot be read, mirroring the
  `handoff_issue_references_fresh` signal from ccd#570.
- `ccd machine list` is the post-collapse machine inventory surface. It
  reads both the flat `~/.ccd/machines/{machine_id}/machine.toml` layout
  and the legacy `~/.ccd/pods/{pod}/machine.toml` manifest during the
  compat window, and reports which source each record came from. Text
  and `--output json` modes are supported.
- `ccd migrate from-pod-layout [--dry-run] [--output json]` relocates
  machine identity and presence records from `~/.ccd/pods/{pod}/` to the
  flat `~/.ccd/machines/` layout without deleting any pod-authored
  state. `pod.toml`, `policy.md`, `memory.md`, and every other authored
  file stay in place under `~/.ccd/pods/{pod}/` and are inventoried in a
  `MIGRATED.md` marker. Discarding the residual directory is an
  explicit operator action — CCD does not delete pod-authored state on
  the operator's behalf. The migration is idempotent: re-running after a
  completed migration exits 0 without further mutation.

### Security

- Updated `rustls-webpki` 0.103.12 → 0.103.13 (RUSTSEC-2026-0104).

### Migration

- **Operators on installs with existing `~/.ccd/pods/{pod}/` state:** run
  `ccd migrate from-pod-layout` once before the next `ccd` invocation
  that would touch `memory_evidence`. The schema gate refuses to run
  against residual pod-scoped state and names this command as the
  remediation; no data has been rewritten at the point of refusal, so
  pinning back to v1.0.0-beta.2 is safe. After the migration completes,
  any subsequent `ccd` invocation proceeds. Review the `MIGRATED.md`
  inventory before removing the residual pod directory — the migration
  tool never deletes pod-authored files.
- **Tooling or scripts that called `ccd pod <subcommand>`:** the shims
  print migration guidance and exit non-zero. Move to `ccd machine list`
  where an inventory is needed, or to `ccd status` / `ccd doctor` for
  status and advisory output. The compat-alias window lasts one release;
  the shims are removed in the next beta (or 1.0.0 stable if that is the
  next release).
- **Tooling that consumed `pod_name` from `ccd start`, `ccd status`,
  `ccd runtime-state export`, or `ccd machine list` JSON:** the field is
  gone from those surfaces. Machine identity is keyed on `machine_id`
  alone; where pod-grouping context is still needed, read the on-disk
  `MachinePresenceRecord` during the compat window or call
  `ccd migrate from-pod-layout --output json` which still reports the
  pod-dir identifier as `pods[*].pod_name`.

## [1.0.0-beta.2] - 2026-04-19

### Added

- Host-agnostic `CCD_CONTEXT_WINDOW_TOKENS` env var lets any adapter
  declare its model context window without per-host plumbing. Effective
  precedence (uniform across `claude`, `codex`, `gemini`, `opencode`):
  `CCD_<HOST>_CONTEXT_WINDOW_TOKENS` → legacy `<HOST>_CONTEXT_WINDOW_TOKENS`
  → native runtime source (Codex payload, OpenCode config, Gemini session)
  → `CCD_CONTEXT_WINDOW_TOKENS` → none. For Claude, which has no native
  source, the effective order collapses to host-specific env → general env
  → none. Implementation lives behind a new
  `host_telemetry::general_context_window()` helper. When `host_total_tokens`
  is observed but no window can be resolved, `radar` now downgrades
  `confidence` to `"low"` and switches `recommendation` to
  `"capture_session_state"` instead of falsely reporting `continue` on a
  null band. `ccd doctor` warns when neither a host-specific nor the
  general fallback is set, so the misconfiguration surfaces before a
  session starts. Closes ccd#529 (PR #590, redesign of the window-agnostic
  approach withdrawn in #589).
- `cargo-deny` runs on CI as its own workflow against a checked-in
  `deny.toml`, so license, advisory, and source-allowlist regressions
  fail PRs without overlapping the lint workflow. Closes ccd#497
  (PR #504).
- CI now runs `cargo fmt --all -- --check` on every PR and tightens the
  local clippy configuration so unformatted or lint-flagged code fails
  before review. Closes ccd#496 (PR #503).

### Fixed

- The `radar-state` behavioral-drift prose detector was emitting
  high-volume false positives at session start — the post-#582 handoff
  alone surfaced 16 "missing" path references and 2 "non-local"
  references, flipping `session_boundary.action` to `stop` /
  `recalibrate_session` on otherwise-correct handoffs. The detector in
  `src/state/reference_paths.rs` now routes by quoting: backtick-quoted
  prose tokens stay on the permissive `looks_like_surfaced_reference`
  path (quoting is an explicit authoring signal), while unquoted tokens
  go through a new strict `looks_like_unquoted_prose_path` that requires
  slashed unquoted tokens to start with a known repo prefix (`src/`,
  `.claude/`, …) or an absolute/relative anchor (`/`, `./`, `../`).
  Bare extensioned filenames and unprefixed slashed paths are rejected
  unless explicitly backticked. Five additional guards land alongside:
  a stem-length guard rejects bare `.rs`/`.md` with no filename stem;
  `CHANGELOG` is removed from `SURFACED_EXTENSIONLESS_FILENAMES` (prose
  references to "the changelog" almost always mean `CHANGELOG.md`);
  `contains_unresolved_placeholder` now catches `NNN-short-slug.md`
  alongside existing `YYYY` / `MM-DD` / `XXXX` / `XX` patterns; Rust
  module notation `radar/context_check.rs::build_X` is recognized as a
  code locator and skipped; and `/namespace:command` slash-commands
  (`/codex:review`, `/codex:rescue`) no longer trip the absolute-path
  branch. 19 regression tests cover every false-positive class named in
  the issue plus positive-case regressions for real paths. Closes
  ccd#585 (PR #588, supersedes the withdrawn #540).
- `ccd handoff write` audited path references at **read** time only via
  `ccd radar-state`, so bad references already persisted — often
  inherited across several sessions before anyone noticed. Validation is
  now symmetric: a new `consistency::audit_handoff_for_write` helper
  reuses the read-time audit logic and runs against the payload after
  `authorize_owner_surface_write` and before persistence. Missing
  references (or references that resolve outside the repo root) fail the
  write with a clear error naming each bad path. `HandoffWriteInput` /
  `run_with_input` take a new `WriteOptions` struct, and a new
  `--allow-missing-refs` CLI flag covers deliberate forward-reference
  cases. Radar's `--commit` auto-commit path leaves the default audit
  on, so radar-drafted handoffs also fail closed on stale references.
  Closes ccd#531 (PR #541).
- The MCP JSON-RPC serializer no longer unwraps inside hot paths.
  Failure modes that previously panicked the daemon now propagate as
  ordinary errors so the host can recover without restarting the
  process. Part of PR #503 (closes ccd#496 alongside the CI lint work
  above).

### Tests

- New focused unit coverage for the memory lifecycle modules — `promote`,
  `compact`, and the candidate selection logic — closing a coverage gap
  that previously let lifecycle regressions land without test
  observability. Closes ccd#498 (PR #505).

## [1.0.0-beta.1] - 2026-04-18

### Fixed

- `session::start` and `session::clear` previously derived successor
  state (for `start`) or authorization (for `clear`) from a pre-lock
  snapshot. Two overlapping `start` calls on the same active session
  could both derive the same `start_count` / `revision` and the later
  commit would silently overwrite the earlier bump; a `clear` racing
  with a `takeover` could enter `BEGIN IMMEDIATE` on stale auth and
  delete the newer session's state. Both entrypoints now port the
  ccd#568 pattern: the transaction body re-reads the session row,
  re-computes the successor (for `start`) or re-runs `authorize_clear`
  (for `clear`) against the fresh view, and writes via
  `db::session::write_if_revision_matches` so a stale snapshot surfaces
  as `RevisionConflict` (retry-safe) instead of a silent lost update.
  Pre-tx best-effort telemetry (cost recording, legacy-JSON escalation
  migration with its filesystem-rename side effects) stays pre-tx and
  is idempotent on re-entry. `write_if_revision_matches` itself was
  taught that a zero expected-revision is not the same as a missing
  row: a legacy-JSON migration can seed a row at revision 0, and the
  helper now branches on row existence rather than on `expected == 0`
  so the subsequent lifecycle write CAS-updates that row instead of
  silently conflicting with an INSERT OR IGNORE. Closes ccd#580
  (follow-up to the Codex adversarial review on PR #579 / ccd#568).

### Security

- User-controlled identifier fields (`actor_id`, `owner_id`,
  `supervisor_id`, `session_id`) accepted as unrestricted `String`
  upstream previously flowed verbatim into `bail!` / `format!` /
  `eprintln!` text. A caller supplying newlines or terminal control
  bytes (C0/C1 controls, ANSI escapes like `\x1b[2J`, Unicode line
  separators U+2028 / U+2029 / NEL U+0085) could therefore inject
  fake log lines, clear an operator's terminal mid-session, or split
  CI captures. A new `display_safe(&str) -> impl Display` helper
  escapes those code points (without adding surrounding quotes so the
  existing backtick-wrapped convention in error prose stays intact)
  and is now applied at every refusal / error / alert site under
  `src/state/session.rs`, `src/state/protected_write.rs`, and
  `src/commands/start.rs` that interpolates an actor-like field.
  Type signatures are unchanged: `String` remains `String` at every
  API boundary. Regression tests per touched module assert that a
  newline-bearing id produces no literal `\n` or ESC byte in the
  rendered message. Closes ccd#576 (follow-up to the Codex
  adversarial review on PR #575 / ccd#574).

### Changed

- `build_evaluation` in `src/state/radar/evaluation.rs` was split into
  three bucket builders (`build_next_step_bucket`, `build_memory_bucket`,
  `build_wrap_up_bucket`) so the orchestrator is a three-field
  `RadarEvaluation` construction. The stringly-typed `status: &'static
  str` on `EvaluationBucket` became one typed enum per bucket
  (`NextStepStatus`, `MemoryStatus`, `WrapUpStatus`, in a new
  `src/state/radar/status.rs` submodule) with
  `#[serde(rename_all = "snake_case")]` preserving every existing JSON
  tag bit-for-bit. `EvaluationBucket` is now generic over its status
  type. Cross-submodule consumers in `src/state/radar/context_check.rs`
  and `src/state/radar/session_boundary.rs` match on enum variants
  instead of `&str` literals, so a typo at any site is caught at compile
  time instead of only by the radar-state regression anchor in
  `tests/cli.rs`. `RadarStateReport`'s public JSON is unchanged;
  unit-level serde tests in `status.rs` pin the rename contract.
  Addresses complexity major #3 from the 2026-04-17 kernel review
  (follow-up to the ccd#581 decomposition).
- `src/state/radar.rs` was decomposed into submodules under
  `src/state/radar/` (`behavioral_drift`, `candidates`, `context_check`,
  `context_health`, `evaluation`, `session_boundary`). The entry file now
  carries only shared types, the public API (`run`, `run_with_digests`,
  `run_context_check`, `apply_delta_filter`, `commit_writes`), the
  orchestration glue (`build_radar_snapshot`), and the test module.
  Move-only refactor with no behavior change: `RadarStateReport` and
  `ContextCheckReport` JSON shapes are byte-for-byte stable and the
  existing radar-state regression tests in `tests/cli.rs` are the
  correctness anchor. Closes ccd#581 (complexity major #1 from the
  2026-04-17 kernel review). Follow-up work to enum-ify the
  stringly-typed priority cascades inside `build_evaluation`,
  `build_context_check_decision`, `build_context_health`, and
  `build_session_boundary` (complexity findings #3/#4/#5/#9) is left for
  separate PRs so each can target one submodule.
- `ccd session-state clear` now emits a distinct error when a different
  actor attempts to clear a *stale* autonomous session: the message
  names `ccd session-state takeover --actor-id <actor-id> --reason
  <reason>` as the canonical recovery path for a different actor
  rather than the generic "active autonomous session" text that
  previously confused operators into retrying `clear` with the wrong
  flags. Both required takeover flags appear as placeholders (not
  raw interpolations of the caller's `actor_id`) so a malformed or
  metacharacter-bearing actor id cannot turn the recovery hint into
  a copy-paste that re-tokenizes under shell. The authorization rule
  itself is unchanged — owner and supervisor still bypass the refusal
  regardless of staleness; only the refusal message for non-owner
  actors on a stale session is more specific. The takeover hint is
  gated on `takeover`'s own hard preconditions (`session_id` AND
  `lease_ttl_secs` both present on the stale row) — when either is
  missing the refusal falls back to the generic text so a corrupt or
  partially migrated row does not send the operator down a recovery
  path that `takeover` itself would reject. Closes ccd#574
  (correctness minor #4 from the 2026-04-17 kernel review).

### Added

- `ccd radar-state` emits a new `behavioral_drift.signals` entry
  `handoff_issue_references_fresh` that fires `drift` when commits
  whose committer timestamp is at or after
  `session_state.started_at_epoch_s` on `HEAD` close or reference a
  GitHub issue whose `#N` or `ccd#N` token also appears in the current
  handoff's `title` or active `immediate_actions`. Keying off
  committer date rather than author date means cherry-picks and
  rebases that preserved an older author date are still caught. The
  detector parses autoclose keywords (`close[sd]?`, `fix(e[sd])?`,
  `resolve[sd]?`), `Refs #N`, and the GitHub squash-merge trailer
  `(#N)` out of each commit subject and body; the `ccd` prefix is
  accepted on both commit and handoff sides. The new signal is gated
  by the existing fast-path rule, so any `drift` outcome forces a full
  handoff rewrite even on a clean working tree, matching the
  `handoff_references_resolved` discipline. Fails closed when the
  handoff references GitHub issues but `git log` cannot be read —
  returns `drift` with the unverified tokens as evidence so the
  fast-path rule cannot declare the handoff clean without the check
  ever running. Degrades to `no_signal` only when no active CCD
  session boundary is available. Schema version bumped from 21 to 22.
  Closes ccd#570.

### Performance

- `ccd radar-state` computes the projection-telemetry source fingerprint once
  per invocation instead of three times. Formerly each of
  `preview_for_target_with_cache`, `preview_symbolic_for_target_with_cache`, and
  `preview_bundle_for_target_with_cache` invoked `fingerprint_for_inputs`
  (serialize seven runtime surfaces to JSON + SHA-256) independently; all three
  now share a single precomputed fingerprint. No observable output change.
  Closes ccd#554.
- `ccd radar-state` loads runtime state once per invocation instead of twice.
  The behavioral-drift audit now receives the already-loaded
  `LoadedRuntimeState` through `BehavioralDriftInputs` rather than reloading it
  inside `projection_observations_for_session`. Saves five file reads + JSON
  parse + DB open per non-lightweight invocation. No observable output change.
  Refs ccd#557 (Phase A.1).
- `ccd radar-state` opens `state.db` once per invocation instead of five times
  on the top-level read path. `session_state`, `escalation_state`, and
  `work_stream_decay` readers gained `*_from_db` siblings that accept a
  shared `StateDb` handle; `build_radar_snapshot` opens once via
  `StateDb::try_open_for_layout` and threads the handle through. On trees
  with no `state.db` yet (fresh or legacy-JSON-only), readers fall back to
  their per-module probe-and-migrate paths so legacy migration behavior is
  preserved. Refs ccd#557 (Phase A.2).
- `ccd radar-state` projection-telemetry pipeline also reuses the shared
  `StateDb` handle across `build_projection_telemetry`'s deeper call paths.
  `resolve_cached_projection` and the three `preview_*_with_precomputed_fingerprint`
  helpers accept an optional `&StateDb`; `projection_metadata` and
  `session_state` gained `_from_shared_db(&StateDb, &StateLayout, …)` siblings
  that run the per-module idempotent legacy-JSON migration against the shared
  handle before reading. This eliminates 3–4 additional `state.db` opens per
  non-lightweight `ccd radar-state` invocation (cache lookup/write for
  narrative + symbolic + bundle, plus the baseline-for-session probe, plus
  the nested `load_session_id` lookup inside each cache-event record).
  Public preview APIs (`preview_for_target_with_cache` and siblings) pass
  `None` so single-shot callers are unchanged. Same null-safe fallback:
  trees with no `state.db` still migrate through the per-module paths.
  Source fingerprint stays bit-identical across narrative/symbolic/bundle
  surfaces. Regression tests in `src/db/mod.rs` pin the
  migrate-through-shared-handle behavior so future performance refactors
  cannot silently reintroduce the "DB exists but legacy JSON present"
  correctness gap. Refs ccd#557 (Phase A.3).

### Fixed

- `ccd session-state heartbeat` is now concurrency-safe against two
  same-actor calls racing on the same workspace. Previously both
  heartbeats would read revision N outside the transaction, both
  compute `next.revision = N+1`, and both commit via `INSERT OR
  REPLACE` — the later commit silently overwrote the earlier one
  and the monotonic-revision invariant broke. Two defenses now
  apply: `run_session_lifecycle_transaction` uses `BEGIN IMMEDIATE`
  so the second writer blocks on SQLite's reserved lock until the
  first commits, and `heartbeat` re-reads the session row inside
  the transaction, derives `next.revision` from the fresh snapshot,
  and writes with a new `db::session::write_if_revision_matches`
  (mirroring `session_gates` / `handoff`) so any CAS mismatch
  surfaces as `ExclusiveWriteResult::RevisionConflict` instead of a
  silent clobber. The helper also validates that the caller's
  `state.revision` equals `expected_revision + 1` so a future call
  site cannot accidentally break the monotonic-revision invariant
  by passing a mismatched successor state. The CLI reports the
  conflict as a structured error with both the expected and current
  revisions. `StateDb` connections now set a 5-second `busy_timeout`
  so concurrent writers wait on the lock rather than failing fast
  with `SQLITE_BUSY`. Wall-clock reads happen inside the transaction
  (after the lock is acquired) so a heartbeat that blocks past the
  lease TTL cannot renew against a stale staleness check. The
  persisted `last_heartbeat_at_epoch_s` uses raw `now_in_tx` (not
  a monotonic clamp) so a future-dated prior heartbeat from a
  skewed clock cannot pin lease validity into the future and block
  takeover of a dead worker. Regression coverage: two concurrent
  CLI heartbeats from the same actor join with a barrier and
  assert a revision bump of exactly 2 (no silent lost update);
  a future-dated seed verifies the next heartbeat converges back to
  real time. `start` and `clear` inherit the stronger lock policy
  but their pre-transaction TOCTOU windows are not closed here —
  that hardening is filed as a separate follow-up. Closes ccd#568.
- `ccd session-state start` and `ccd session-state clear` now mutate session
  state, escalation state, and execution-gate state atomically inside a
  single SQLite transaction on one shared `StateDb` handle. Previously each
  subsystem opened its own handle and a process death between steps could
  leave the subsystems out of sync — for `clear`, the session row deleted
  but dead-session escalations still blocking successor sessions; for
  `start`, a disk-full on the session write leaving the still-live old
  session without its escalation protection. Both scenarios are now
  protected by `BEGIN`/`COMMIT` with `ROLLBACK` on error. New helpers
  `escalation_state::clear_all_on_shared_db`,
  `escalation_state::clear_non_blocking_on_shared_db`, and
  `session_gates::clear_on_shared_db` perform the mutations against the
  shared handle. Legacy-JSON migration
  (`escalation_state::migrate_legacy_on_shared_db`) runs BEFORE `BEGIN`, so
  the `escalation.json` → `.migrated` rename stays outside SQLite's
  rollback domain — a transaction failure can no longer orphan legacy
  escalation data. The underlying `LifecycleTransactionGuard` issues
  `ROLLBACK` via `Drop`, so both explicit `Err` propagation AND panics
  inside the closure body trigger unwind; a failing `ROLLBACK` is
  surfaced through `tracing::error!` rather than silently swallowed.
  Regression tests in `src/state/session.rs::tests` pin the rollback
  behavior on error, the panic path, and the pre-migration-survives-rollback
  invariant, so future refactors cannot silently reintroduce the gap.
  Closes correctness majors #1 and #2 from the 2026-04-17 kernel review.
  Refs ccd#557 (Phase B).

### Internal

- `scripts/check-kernel-surface-sync.sh` now accepts `CHANGELOG.md` as a valid
  surface-docs target. Pure internal refactors of files in `public_surface_regex`
  (e.g., `src/state/radar.rs`) can now document themselves in the changelog
  rather than forcing unjustified updates to `README.md` or
  `docs/reference/cheatsheet.md`. Closes ccd#559.
- `state::session::STALE_AFTER_SECS` is now exposed at `pub(crate)`
  visibility so `db::session::tests::load_session_id_returns_none_for_stale`
  can import the canonical constant instead of re-encoding the
  `8 * 60 * 60` literal. Importing the constant keeps the test
  aligned with whatever the production threshold currently is, so
  the test never silently drifts to compare against a frozen
  8-hour value — any future adjustment to the threshold flows
  through the import and the test keeps exercising the real
  stale-session boundary. `DEFAULT_READY_LEASE_SECS` in
  `machine_presence.rs` is intentionally not consolidated: it
  happens to equal 8 hours today but means "default
  autonomous-machine lease TTL", not "idle-stale threshold for
  interactive sessions" — coupling them would make a future policy
  adjustment to one silently move the other. Closes ccd#577
  (maintainability major #3 from the 2026-04-17 kernel review).
- Consolidated the five divergent `try_open_*_db` helpers in
  `state/{escalation,session,projection_metadata,runtime,session_gates}.rs`
  onto a single `StateDb::try_open_with_migration(layout, legacy_present,
  migrate)` primitive. Module helpers keep their legacy-JSON probe responsibility
  via a `legacy_present: FnOnce() -> bool` closure (so the common case where
  `state.db` already exists short-circuits before any legacy `stat` syscalls
  run, matching the per-module helpers' pre-consolidation behavior) and their
  per-module migration closure; the shared open+probe logic lives in one
  place. `session_gates::try_open_state_db` collapses to the existing
  `StateDb::try_open_for_layout` since it has no legacy predecessor. No
  observable behavior change — legacy JSON migration still runs on the same
  probe predicates as before. Refs ccd#557 (maintainability major #2).

## [1.0.0-alpha.9] - 2026-04-15

### Changed

- **Breaking: default kernel surfaces are now continuity-only.** `ccd start`,
  `ccd status`, `ccd radar-state`, runtime export, and the default JSON
  contracts no longer surface workflow/backlog/dispatch state unless callers
  explicitly request extension-owned fields.
- **Breaking: kernel persistence no longer carries workflow identity.**
  Telemetry focus targeting now derives from continuity targets, and the
  clone-local `state.db` schema moves to `user_version = 15` to drop legacy
  workflow identity columns. Older CCD builds fail closed against state
  upgraded by this release until the CLI is updated.
- **Extension-private workflow state now lives behind extension-owned paths
  and migrations.** Backlog/dispatch/work-queue storage and the legacy
  backlog overlay migration moved out of kernel layout ownership, while the
  shipped skills/contracts/docs were realigned to the purified boundary.
- **Kernel boundary proofs are now executable release gates.** The repo now
  ships `tests/kernel_purity.rs` to keep workflow tokens and workflow-shaped
  fields from leaking back into production kernel code or default contracts.

## [1.0.0-alpha.8] - 2026-04-14

### Changed

- **Breaking: `ccd handoff export` no longer writes `handoff.md` to the
  profile root.** The rendered Markdown body is emitted to stdout in text
  mode (with the status header on stderr so stdout stays a clean Markdown
  body) and embedded in the JSON report as a new `body` field. The
  previous `export_path` field is removed from the JSON report. Tooling
  that read `handoff.md` from disk or consumed `export_path` must switch
  to capturing stdout or reading the new `body` field.
- **Breaking: `ccd start` now reaps any stale `handoff.md` left under the
  profile root.** Pre-A2 profiles can carry a legacy export on disk; the
  next `ccd start` (and `ccd start --compiled-only`) removes it.
  `ccd start --check` remains read-only and is intentionally not
  affected. As a result, `runtime_state_export_json.sources.handoff_export.status`
  now reports `"absent"` for any profile that has run `ccd start` since
  this release. The substrate-abstraction spec's Storage table no longer
  lists handoff export as a substrate-backed location, and the canonical
  `ccd-radar` skill text was updated to reflect stdout-only emission.
- **The `operational_state` benchmark and its fixtures have been retired.**
  The bench compared five projections of `handoff.md` and informed the
  state.db-native substrate decision that has since landed. It was not in
  CI, had been dormant since 2025-03-18, and its subject matter is the
  exact substrate Phase A is removing. The `memory_transfer` and
  `doctor_bench` benches are unaffected.
- **`ccd radar-state` now validates that handoff file references still
  resolve under the repo root.** A new `handoff_references_resolved`
  behavioral-drift signal checks active `key_files` entries plus path-like
  references in immediate actions, guardrails, and definition-of-done
  prose. Missing paths, absolute paths, `..` traversal, and symlink escapes
  now force `behavioral_drift.status = "needs_recalibration"` and keep the
  `ccd-radar` close-out path from fast-pathing until the handoff is
  rewritten to repo-local existing files.

## [1.0.0-alpha.7] - 2026-04-13

### Fixed

- **Checkpoint payloads now keep behavioral drift visible across host handoff.**
  The lightweight checkpoint path once again surfaces `behavioral_drift` so
  recalibration-worthy drift remains available to downstream continuity
  checks.

## [1.0.0-alpha.6] - 2026-04-13

### Added

- **Projection-startup KPI evaluation is now part of the shipped repo.**
  CCD now carries the startup-bundle evaluation schema and regression harness
  needed to score startup projection behavior deterministically.
- **Session lifecycle and host-integration reference docs are now first-class.**
  The repo now ships explicit reference material for the session liveness
  contract, host startup wrappers, and the canonical cross-host continuity
  walkthrough.
- **The KPI reference set now covers memory governance and closeout continuity.**
  Operators now have documented release surfaces for those families alongside
  the existing projection-startup metrics.

### Changed

- **`extension-backlog` is now opt-in.** The default `ccd` binary now stays
  kernel-only unless you build or install with `--features extension-backlog`.
  Backlog commands remain available behind the explicit feature-gated build.
- **`ccd start` refreshes its surfaced report after activation.** Startup now
  keeps the returned report aligned with the post-activation runtime state
  instead of leaving the caller with pre-activation session metadata.
- **CLI dispatch and startup resolution are split into focused internal phases.**
  Top-level command routing now lives in dedicated `src/commands/dispatch/*`
  modules and `resolve_core()` is decomposed into named startup phases without
  changing the public CLI contract.

### Fixed

- **Legacy projection metadata digests no longer break newer kernels.** CCD now
  tolerates older projection metadata digests instead of failing compatibility
  checks during projection compilation.

## [1.0.0-alpha.5] - 2026-04-12

### Added

- **CCD now ships a built-in GitLab backlog provider.** Backlog adapter
  resolution and validation can now activate a first-party `gitlab-issues`
  path, fetch GitLab work items through `glab`, normalize them into the
  hosted backlog cache, and feed provider-aware continuity and dispatch
  flows during `ccd start --refresh`.
- **Radar and telemetry now expose projection-cache cadence, skip stats,
  and work-stream decay.** CCD now persists projection observations keyed
  by target, format, and source fingerprints, reports per-surface and
  per-format token telemetry in `checkpoint`, `radar-state`, and
  `ccd telemetry report`, and folds `on-agent-end --attempt-outcome`
  work-stream decay into checkpoint and radar recommendations.

### Fixed

- **Radar helper signature matching in CI is less brittle.** The release
  gate now tolerates the widened helper signatures introduced by the new
  radar telemetry path, keeping the CI contract aligned with the shipped
  behavior.

## [1.0.0-alpha.4] - 2026-04-10

### Added

- **Explicit repo-local host integration management is now part of the
  shipped kernel loop.** CCD can now scaffold reviewable host assets with
  `ccd init --host <host>` and apply them deliberately with
  `ccd host install <host>`, instead of leaving host posture to
  undocumented local setup. The landed path covers Codex (manual baseline
  plus optional launcher), Claude Code native hooks, and OpenClaw/Hermes
  reference-adapter configs, with `ccd doctor` verifying both the
  scaffolded source assets and the applied host paths.
- **Host-loop diagnostics and telemetry reporting are now first-class.**
  `ccd host-hook` gained explicit diagnostics/reporting support and CCD now
  ships `ccd telemetry report --output json --path .` plus persisted
  host-loop telemetry storage. This makes payload sizing, churn, bounded
  startup injection, and prompt-overhead analysis inspectable through a
  stable machine-readable surface instead of ad hoc debugging.

### Changed

- **Startup and resume memory selection is narrower and more relevant.**
  `ccd start` now ranks bounded memory recall more conservatively, records
  explicit remember-selection reasoning in the startup flow, and ships
  regression coverage for the intended selection behavior. The goal is to
  reduce broad noisy recall during startup/resume while keeping the chosen
  memory slices explainable.
- **Pituitary is now framed as a consistency governance engine, not a
  spec checker.** The GitHub Actions workflow (`pituitary-spec-hygiene.yml`)
  has been relabeled *Pituitary Consistency Governance*, step names have
  been rewritten to talk about declared consistency relations rather than
  spec compliance, and a load-bearing file header documents the gate
  semantics: the CI gate fails only on `conflicts` (drifted relations).
  It deliberately does not fail on `unspecified`,
  `missing_governance_edge`, or `explicit_but_underexercised` — those
  categories surface files that are not yet claimed by a declared
  consistency relation, which is a discovery signal, not a release
  blocker. This reframe preserves the existing gate behaviour (already
  `conflicts`-only) while preventing a future well-intentioned "also
  fail on unspecified" tightening from silently re-encoding a
  spec-coverage-as-health model. Filename and job id are unchanged so
  existing branch-protection rules keep working.

### Fixed

- **`ccd-radar` now treats no-active-session close-out as a first-class
  outcome.** Wrap-up no longer fails awkwardly when the active session has
  already been cleared or was never present. Radar can emit a clean
  `no_active_session` delta, keep the close-out path narrow, and still
  evaluate the current handoff and continuity state deterministically.
- **Host integration config validation now fails closed more reliably.**
  Invalid install modes are rejected earlier, `ccd doctor` reports
  unsupported host-mode combinations more clearly, and the configured host
  aliases/modes are handled more defensively so repo-local host
  integrations are harder to misapply silently.
- **Reference-adapter doc governance edges now activate as
  `explicit_applies_to`.** The `doc://` `applies_to` URIs on the Hermes
  and OpenClaw reference-adapter specs were corrected from the
  workspace-relative `doc://docs/reference/<name>.md` form to the
  source-root-relative `doc://reference/<name>` form that the indexer
  actually emits. Combined with dusk-network/pituitary#298, which taught
  `governedRefsForPath` to synthesise `doc://` candidates, the two
  reference docs now resolve against their specs via explicit
  applies_to rather than weak semantic retrieval. Verification: per-path
  `check-compliance` reports `basis: ["applies_to"]` and
  `traceability: "explicit_applies_to"` for both docs.

## [1.0.0-alpha.3] - 2026-04-09

### Added

- **Project- and profile-scope memory evidence automation landed on `main`.**
  CCD now ships the project-memory evidence pipeline plus profile-scope
  autonomous apply gating with a profile-local confirmation ledger, so staged
  rule and constraint candidates can move upward through deterministic review
  paths instead of ad hoc copy-forward.
- **First-class host-hook and ingest reporting surfaces.** `ccd host-hook`
  is now a real host lifecycle entrypoint with bounded context injection,
  checkpoint, session-clear, and heartbeat behavior, and the memory runtime
  exposes live advisory ingest `sync-status` and `source-map` operations
  through the CLI, MCP dispatch, and runtime manifest.

### Changed

- **Daemon/runtime event discovery now reports truthful event families.**
  The runtime manifest and emitted event-family surfaces are aligned so host
  integrations can trust the advertised daemon event contract.
- **Text-mode host-hook output now matches the shipped lifecycle contract.**
  The default CLI path renders the new lifecycle payloads directly instead of
  hiding them behind `--output json`, keeping the host-hook surface usable in
  both human and machine flows.

### Fixed

- **Host-hook compaction capture preserves host correlation metadata.**
  Captured evidence rows can now carry session, run, and task identifiers from
  the documented host-hook entrypoint.
- **Advisory ingest provider reporting is no longer view-only.** The provider
  follow-through landed as actual kernel operations rather than placeholder
  summaries, so runtime consumers can query live sync/source-map state.

## [1.0.0-alpha] - 2026-04-03

### Added

- **OpenClaw reference adapter path and conformance coverage (ccd#360,
  ccd#361).** The repo now ships a concrete OpenClaw execution-host reference
  path in `docs/reference/openclaw-reference-adapter.md`, plus adapter-level
  conformance coverage in `tests/cli.rs` for bounded startup injection,
  pre-compaction refresh, checkpoint versus session close-out, stale takeover,
  and approval routing.

### Changed

- **The OpenClaw adapter spec snapshot now reflects the shipped reference
  path.** The canonical implementation snapshot now treats
  `reference-adapter-openclaw` as mostly implemented: the runtime proof,
  reference mapping, and conformance harness are landed, while a native
  OpenClaw plugin/gateway package remains follow-on work.

## [0.9.0] - 2026-03-31

### Added

- **Directory-substrate session support (ccd#283, ccd#284).** CCD can now
  attach, persist session state, and export handoff continuity for directory
  projects that are not backed by a Git worktree, while keeping the same
  fail-closed session loop semantics.
- **First-class pod identity rollout (ccd#300).** Pod identity is now part of
  the landed operator model, with the corresponding policy/memory separation
  and coordination-scope migration surfaces available through the CLI.
- **Structured session-boundary guidance from `ccd start` (ccd#270).** Startup
  reports now tell host integrations whether the current continuity should
  continue, refresh, or stop before execution.
- **Read-only memory recall provider seam plus shipped reference adapters
  (ccd#309, ccd#310, ccd#311, ccd#312, ccd#266, ccd#313).** CCD now ships a
  conformance-tested recall-provider contract with Mem0/OpenMemory and
  Graphiti adapters, bounded startup recall, normalized provenance/temporal
  hints, and the accepted recall-first provider boundary documented in the
  repo.
- **External adapter trust labeling and reusable field filters (ccd#257,
  ccd#260).** Machine-facing status and doctor surfaces can now return
  filtered top-level JSON fields, and adapter-backed queue content is labeled
  explicitly so host tooling can keep project truth and external context
  separate.

### Changed

- **Git workflow coaching is split from the CCD kernel skills (ccd#285).**
  `ccd-start` and `ccd-radar` stay focused on CCD state, while the shipped
  `ccd-git-workflow` skill owns branch/worktree/commit/push/merge follow-through.
- **Public vocabulary now reflects the substrate-aware model more directly
  (ccd#286, ccd#288, ccd#289).** The operator-facing docs and compatibility
  surfaces now use project/workspace/substrate terminology more consistently
  while preserving compatibility paths during the migration window.
- **Agent safety guidance is more explicit (ccd#258, ccd#271).** The canonical
  safety contract, startup guidance, and failure remediation text now align
  more tightly around fail-closed behavior and operator-visible next steps.

### Fixed

- **Directory-substrate handoff export and linked-session edge cases are more
  robust.** This includes the handoff export fix from `ccd#284` plus clearer
  remediation guidance when startup or session-state bootstrap fails in
  non-trivial checkouts.
- **Machine-facing validation and doctor surfaces are less error-prone.**
  `ccd doctor` now honors requested field filters correctly, and the expanded
  validation coverage catches fail-closed input-path regressions earlier.

## [0.8.1] - 2026-03-28

### Added

- **Read-only `ccd status` session summary (ccd#252).** CCD now exposes a
  no-write status surface that reports the current continuity phase,
  recommended next command, git state, review state, and available telemetry
  without mutating clone-local state.
- **Memory promotion and admission guidance in `ccd radar-state` (ccd#263,
  ccd#264, ccd#265, ccd#267, ccd#274).** Radar now surfaces deterministic
  memory candidates, self-contained promotion preview/apply actions, apply
  requirements, and the new candidate-admission flow for escalating reviewed
  learnings into durable memory.
- **Bulk GitHub priority scoping for backlog queues (ccd#251).** The GitHub
  backlog adapter can now scope priority updates across multiple matching
  items, making queue triage less single-item and less error-prone.

### Changed

- **Agent-facing backlog mutations are preview-first (ccd#254, ccd#255,
  ccd#256).** `ccd backlog claim`, `ccd backlog set-status`, and
  `ccd backlog complete` now require explicit `--write`, `ccd describe`
  surfaces behavior metadata for machine consumers, and backlog status input
  is constrained instead of accepting arbitrary strings.
- **Telemetry and codemap guidance are more explicit.** Session/focus cost
  estimation now persists with clearer fail-closed behavior for ambiguous host
  data, and the shipped start guidance more clearly explains codemap-aware
  context narrowing.

### Fixed

- **Linked-worktree session bootstrap failures now explain themselves
  (ccd#253).** `ccd session-state start` reports why first-run `state.db`
  creation can fail under `.git/worktrees` instead of leaving the operator
  with an opaque SQLite error.
- **`ccd radar-state` now points at the right handoff remediation (ccd#273).**
  When the canonical clone-local handoff row is missing, radar reports the
  real uninitialized state and suggests `ccd handoff write`, including the
  active profile when it is non-default.
- **Memory and backlog edge cases are less confusing.** This includes the
  memory scope write-target and recovery-doc fixes from `ccd#249` plus clearer
  backlog queue activation and metadata errors from `ccd#250`.

## [0.8.0] - 2026-03-26

### Added

- **Codemap extension for structural summaries (ccd#233 / ccd#96).** CCD can
  now ingest, store, and serve per-file codemap summaries through
  `ccd codemap import`, `ccd codemap status`, `ccd codemap query`, and the
  `ccd_codemap` MCP tool when built with the opt-in `extension-codemap`
  feature.
- **Session intent signals and radar workflow hints (ccd#234 / ccd#100).**
  Clone-local session state now tracks `general`, `research`, and `implement`
  modes, and `ccd radar-state` can emit structured `workflow_hints` so host
  skills can suggest a fresh implementation session without making CCD itself
  a workflow engine.

### Changed

- **Dispatch continuity is now SQLite-only (ccd#232 / ccd#230).** The legacy
  `focus.md`, `manifest.md`, and JSON fallback paths for dispatch state were
  removed; the canonical dispatch DB is now the only read/write surface.
- **Canonical file-write tracing is broader.** `CCD_LOG=debug` now records the
  destination path and write intent for dispatch, remember, and memory-promotion
  writes, making file-surface mutations easier to audit during agent sessions.
- **Breaking: clone-local `state.db` user_version bumped from 3 to 4.** The
  session table now persists `mode` (`general` / `research` / `implement`),
  and `RADAR_STATE_SCHEMA_VERSION` is now `14`. Older `ccd 0.7.0` binaries
  will fail closed against state upgraded by this release until the CLI is
  reinstalled or upgraded.

## [0.7.0] - 2026-03-26

### Added

- **Structured memory scopes across clone, branch, and pod layers (ccd#225, ccd#111).**
  The memory overlay chain now supports clone-local, branch-shared, and
  pod-shared structured memory in addition to the existing profile and repo
  layers. `ccd remember`, `ccd memory compact`, and `ccd memory promote`
  gained the matching scope and promotion paths.
- **First-class multi-host pod scope (ccd#112).** Pod identity is now a native
  kernel primitive rather than ad hoc workflow guidance, allowing one actor to
  resume the same CCD profile across multiple hosts while keeping shared pod
  state explicit.
- **Execution gates for session focus (ccd#227).** Clone-local execution gates
  now live in `state.db`, with `ccd session-state gates ...` commands plus
  `start`, `radar-state`, and `runtime-state export` surfacing the first
  unfinished gate as the current attention anchor.

### Changed

- **Memory resolution and promotion now form a fuller kernel overlay ladder.**
  Effective memory now composes profile -> repo -> pod -> branch -> clone for
  the scopes available to a checkout, while reviewed promotion paths can move
  learned state upward across those same boundaries.
- Runtime, compiled-state, and radar projections now include the new pod and
  execution-gate surfaces, so continuity and operator-facing summaries track
  the same canonical state that mutation commands write.

## [0.6.5] - 2026-03-24

### Added

- **Opt-in structured logging (ccd#217).** `CCD_LOG` env var enables structured
  `tracing` output to stderr. Instrumented boundaries: command dispatch, DB
  open/migration, git subprocesses, external adapter execution, `start`, and
  `radar-state`. Default: off (zero overhead). stdout is never touched.
- Regression tests for stdout isolation with `CCD_LOG=debug` for both
  `--output json` and `mcp-serve` JSON-RPC.
- `Debugging with Logs` section in the cheatsheet.

### Changed

- **Locality-neutral Ring 0 contracts (ccd#207).** Public JSON keys renamed from
  `repo_focus` / `repo_memory` / `repo_focus_active` / `repo_focus_assignment`
  to `locality_focus` / `locality_memory` / `locality_focus_active` /
  `locality_focus_assignment`. Internal implementation names stay repo-shaped.
  `KERNEL_CONTRACT.md` updated. **Breaking:** machine consumers of `ccd start`,
  `ccd radar-state`, and `ccd runtime-state export` JSON must use the new keys.
- `CompiledStateStore` schema version bumped 3 to 4; `RADAR_STATE_SCHEMA_VERSION`
  bumped 10 to 11 (was already 11 in 0.6.4 changelog, now effectively 12 after
  the backlog dispatch migration).
- `ProjectionDigests` carries a serde alias for backward-compatible
  deserialization of old `state.db` rows containing `repo_focus`.
- **Backlog dispatch state moved to SQLite (ccd#214).** Local dispatch
  assignments now live in `state.db` instead of `focus.md`, completing the
  extension-private storage migration.
- GitHub backlog bindings activated on `ccd backlog pull`.
- Local-markdown backlog adapter: tightened reference handling and normalized
  continuity messages.

### Fixed

- GitHub Actions workflows bumped to Node 24 runtimes.
- Pituitary spec hygiene workflow added and hardened.

## [0.6.4] - 2026-03-23

### Added

- **SQLite clone-state kernel (ccd#172 / ccd#178).** Clone-local CCD runtime
  state now lives in `state.db`, giving `start`, `doctor`, `radar-state`, and
  session lifecycle commands a single native store for handoff, recovery, and
  projection data.
- `ccd handoff write`, `ccd handoff write-recovery`, and related native state
  export surfaces for explicitly authoring clone-local handoff and recovery
  payloads without editing derived markdown by hand.

### Changed

- **Workflow ownership moved behind extensions.** Repo-scoped focus, dispatch,
  backlog policy, and radar workflow coaching are now extension-owned rather
  than kernel-owned, continuing the boundary split introduced in `0.6.3`.
- `ccd radar-state` now reports extension-owned workflow guidance and no longer
  exposes the kernel-owned `backlog_cache` JSON surface. The radar schema is
  now version `11`.
- The profile and repo overlay configuration surfaces were consolidated around
  `config.toml`, reducing duplicate kernel/runtime config paths during startup
  and migration flows.

### Fixed

- **Wrap-up safety around closed work (#180).** `ccd radar-state` once again
  forces recalibration when the active branch, session assignment, or handoff
  still points at closed backlog work, even after the workflow guidance moved
  behind extension boundaries.
- `ccd doctor` now respects extension health severity instead of flattening
  extension-owned workflow problems into generic kernel warnings.
- `--no-default-features` and release CI now validate the extension boundary
  more strictly, preventing feature-gated regressions from shipping in the
  standalone binary.

## [0.6.3] - 2026-03-18

### Changed

- **Backlog implementation extraction (ccd#108).** The shipped backlog command,
  cache, and continuity implementation now lives under `src/extensions/`
  instead of kernel-owned module paths.
- Core backlog consumers now import the extension-owned state and command
  modules directly; the temporary `src/commands/backlog.rs` and
  `src/state/backlog.rs` compatibility shims were removed in the same slice.
- The `ccd backlog ...-github` compatibility aliases remain available during
  the adapter migration window, but the Rust source ownership now matches the
  backlog extension boundary.

## [0.6.2] - 2026-03-18

### Changed

- **Native-canonical handoff runtime state (ccd#150).** Clone-local handoff
  runtime truth now lives in `runtime_state/state.json`, while `handoff.md`
  is treated as a derived human-readable export instead of a peer source of
  runtime truth.
- `ccd handoff refresh` now regenerates the handoff export from canonical
  native state and no longer imports edited markdown back into runtime state
  except through the explicit legacy bootstrap path in `ccd start`.
- `ccd runtime-state export`, `ccd start`, `ccd doctor`, and `ccd radar-state`
  now report handoff export staleness separately from canonical runtime state
  instead of failing closed on drifted markdown exports.

## [0.6.1] - 2026-03-17

### Added

- **Backlog provider mismatch detection (ccd#142).** When the backlog adapter is
  `local-markdown` with no active items and the origin remote points to GitHub,
  `ccd start` emits a `backlog_provider_mismatch` warning with the
  `pull-github` command hint.
- `github_remote_owner_repo()` helper to parse SSH and HTTPS GitHub URLs from
  `git remote get-url origin`.

### Fixed

- `session-state start` now emits a "legacy session state detected" message
  when encountering v2 session state files instead of being silent.

## [0.6.0] - 2026-03-17

### Added

- **Session-based dispatch identity (ccd#136).** Focus assignments are now keyed
  by a CLI-minted session ID (`ses_<ulid>`) instead of the git branch name.
  Sessions survive branch switches and detached HEAD. Pre-session branch-keyed
  entries are adopted automatically by `session-state start`.
- **Explicit startup disposition (ccd#135).** `ccd start` emits a machine-readable
  `disposition` field (`ResumeActiveContinuity`, `NeedsContinuityInput`,
  `NoActiveContinuity`, `WorkflowAttentionRequired`) so skills can react to
  startup state without parsing alerts.
- **Session continuity on checkout changes (ccd#137).** Detached HEAD and
  landed-branch checkout states preserve session continuity instead of resetting
  the handoff. Checkout snapshot drift is advisory only.
- **Continuity / workflow-signal separation (ccd#134).** Handoff freshness and
  issue-reference drift are classified as continuity signals or workflow signals,
  allowing the start and radar layers to prioritize them independently.
- `Session:` line in handoff Current System State, refreshed alongside Branch
  and HEAD.
- `session_branch_drift` informational drift signal in radar when the session
  assignment's recorded branch differs from the current git branch.
- `session-state start` and `session-state clear` perform focus-entry cleanup
  (adoption, stale-session pruning) as lifecycle side effects.

### Changed

- `ccd init` renamed to `ccd attach` (`init` kept as a hidden alias).
- `ccd start` auto-offers `ccd attach` when the repo is not linked.
- `ccd attach` detects already-attached repos and short-circuits.
- Native profile and repo runtime mirrors for structured state access.
- `session_state.json` schema bumped to v3 (backward-compatible; v2 files
  trigger a fresh session on next `session-state start`).
- Landed-branch dispatch skipping only applies in the pre-session branch-based
  fallback; session-based dispatch takes priority.
- Focus-update errors in `session-state start` and `session-state clear` now
  fail closed instead of being swallowed.

### Fixed

- Radar and doctor handoff freshness checks now use the staleness-gated session
  ID, preventing stale sessions from influencing freshness comparisons.
- Doctor and drift propagate `session_state.json` parse errors instead of
  silently falling back to no-session mode.
- Native runtime lifecycle values accept lowercase variants.
- Radar aligns with runtime handoff state for authored-first fixtures.

## [0.5.0] - 2026-03-15

### Added

- Unified backlog adapter execution boundaries, including built-in
  `local-markdown` support and external-adapter fixtures.
- Actor-local intent, attempt-memory tracking, and `ccd start --check`
  readiness surfaces.
- `ccd checkpoint` as an alias for `ccd radar-state`.

### Changed

- Start, radar, and handoff/runtime refresh flows are faster through the new
  compiled-state and git-read fast paths.
- Repo focus now separates dispatch assignments from actor-local intent, and
  missing backlog cache state is treated as optional instead of blocking start
  and radar flows.

### Fixed

- Backlog adapter refresh and mutation paths fail closed more consistently
  across provider switches and capability boundaries.
- `ccd start` and `ccd radar-state` now treat repo-focus assignments as the
  primary issue-reference mapping and warn before stale closed issue numbers are
  reused in handoffs or branches.

## [0.4.1] - 2026-03-15

### Added

- Provider-neutral backlog CLI entrypoints under `ccd backlog`.
- Backlog adapter capability discovery and normalized `claimed_by` handling.
- `ccd backlog promote-next`.
- `ccd remember` and the memory-transfer evaluation harness.
- Repository identity inspection surfaces with `ccd repo status` and
  `ccd repo list`.

### Changed

- Reviewed memory compaction surfaces and deterministic lifecycle metadata.
- Runtime projections now exclude expired memory entries.
- Session startup and radar flows are faster and more explicit about recovery.
- Clone-local recovery surfaces and bundle preview support landed in the
  runtime/session loop.

### Fixed

- Merged-branch handoff reset logic is more robust.
- Backlog cache refresh and focus cleanup paths are less error-prone.
- Skill binary resolution no longer falls back to stale worktree-local binaries.

## [0.4.0] - 2026-03-11

### Notes

- Baseline `0.4.x` release before the `0.4.1` backlog, memory, runtime, and
  repo-administration follow-ons.

[1.0.0-beta.4]: https://github.com/dusk-network/ccd/compare/v1.0.0-beta.3...v1.0.0-beta.4
[1.0.0-beta.3]: https://github.com/dusk-network/ccd/compare/v1.0.0-beta.2...v1.0.0-beta.3
[1.0.0-beta.2]: https://github.com/dusk-network/ccd/compare/v1.0.0-beta.1...v1.0.0-beta.2
[1.0.0-beta.1]: https://github.com/dusk-network/ccd/compare/v1.0.0-alpha.9...v1.0.0-beta.1
[1.0.0-alpha.9]: https://github.com/dusk-network/ccd/compare/v1.0.0-alpha.8...v1.0.0-alpha.9
[1.0.0-alpha.8]: https://github.com/dusk-network/ccd/compare/v1.0.0-alpha.7...v1.0.0-alpha.8
[1.0.0-alpha.6]: https://github.com/dusk-network/ccd/compare/v1.0.0-alpha.5...v1.0.0-alpha.6
[1.0.0-alpha.7]: https://github.com/dusk-network/ccd/compare/v1.0.0-alpha.6...v1.0.0-alpha.7
[1.0.0-alpha.5]: https://github.com/dusk-network/ccd/compare/v1.0.0-alpha.4...v1.0.0-alpha.5
[1.0.0-alpha.4]: https://github.com/dusk-network/ccd/compare/v1.0.0-alpha.3...v1.0.0-alpha.4
[1.0.0-alpha.3]: https://github.com/dusk-network/ccd/compare/v1.0.0-alpha.2...v1.0.0-alpha.3
[1.0.0-alpha]: https://github.com/dusk-network/ccd/compare/v0.9.0...v1.0.0-alpha
[0.9.0]: https://github.com/dusk-network/ccd/compare/v0.8.1...v0.9.0
[0.8.1]: https://github.com/dusk-network/ccd/compare/v0.8.0...v0.8.1
[0.8.0]: https://github.com/dusk-network/ccd/compare/v0.7.0...v0.8.0
[0.7.0]: https://github.com/dusk-network/ccd/compare/v0.6.5...v0.7.0
[0.6.5]: https://github.com/dusk-network/ccd/compare/v0.6.4...v0.6.5
[0.6.4]: https://github.com/dusk-network/ccd/compare/v0.6.3...v0.6.4
[0.6.3]: https://github.com/dusk-network/ccd/compare/v0.6.2...v0.6.3
[0.6.2]: https://github.com/dusk-network/ccd/compare/v0.6.1...v0.6.2
[0.6.1]: https://github.com/dusk-network/ccd/compare/v0.6.0...v0.6.1
[0.6.0]: https://github.com/dusk-network/ccd/compare/v0.5.0...v0.6.0
[0.5.0]: https://github.com/dusk-network/ccd/compare/v0.4.1...v0.5.0
[0.4.1]: https://github.com/dusk-network/ccd/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/dusk-network/ccd/releases/tag/v0.4.0
