# 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.
## [Unreleased]
## [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.
[Unreleased]: https://github.com/dusk-network/ccd/compare/v1.0.0-beta.1...HEAD
[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