ccd-cli 1.0.0-beta.3

Bootstrap and validate Continuous Context Development repositories
// Compat shim for the retired `ccd pod …` CLI surface.
//
// RFC 0006 (pod-layer collapse) retires the `ccd pod` surface. This module
// keeps the subcommand names callable so that existing scripts and docs fail
// with a clear pointer instead of an unknown-command error. Every shim fails
// closed: even `pod list` does not delegate silently to `ccd machine list`,
// because the two commands have different report shapes and a silent swap
// would break JSON consumers without a signal.
//
// Forward paths:
//   `ccd pod list`              → `ccd machine list` (different report shape)
//   `ccd pod status`            → `ccd status` / `ccd doctor`
//   `ccd pod init`              → retired (no equivalent; edit repo overlay
//                                 config, or use `ccd session open --pod`)
//   `ccd pod migrate-defaults`  → retired with no automated replacement
//                                 (manual review of profile defaults)

use std::process::ExitCode;

use serde::Serialize;

use crate::output::CommandReport;

const DEPRECATION_NOTE: &str =
    "`ccd pod` is retired (RFC 0006 pod-layer collapse). See the replacement \
     surface below.";

/// Report emitted by all retired-surface shims. `ok=false` variants exit
/// non-zero; `ok=true` variants (e.g. `pod status` which has no hard failure
/// mode) still print the deprecation notice.
#[derive(Serialize)]
pub struct PodShimReport {
    command: &'static str,
    ok: bool,
    deprecated: bool,
    message: &'static str,
    replacement: &'static str,
}

impl CommandReport for PodShimReport {
    fn exit_code(&self) -> ExitCode {
        if self.ok {
            ExitCode::SUCCESS
        } else {
            ExitCode::FAILURE
        }
    }

    fn render_text(&self) {
        eprintln!("warning: {}", self.message);
        eprintln!("hint: {}", self.replacement);
    }
}

pub fn list_shim() -> PodShimReport {
    PodShimReport {
        command: "pod-list",
        ok: false,
        deprecated: true,
        message: DEPRECATION_NOTE,
        replacement: "`ccd pod list` is retired; run `ccd machine list` for the post-collapse \
             inventory. The two commands have different report shapes, so this shim \
             fails closed rather than silently returning a different schema.",
    }
}

pub fn status_shim() -> PodShimReport {
    // Fails closed even though the old command was a read with no hard
    // failure mode: returning `ok: true` with a shim payload would let
    // exit-status gates silently treat the command as healthy while JSON
    // consumers lose the old membership schema.
    PodShimReport {
        command: "pod-status",
        ok: false,
        deprecated: true,
        message: DEPRECATION_NOTE,
        replacement: "run `ccd status --path .` for coordination-scope visibility, or \
             `ccd doctor --path .` for the full health report.",
    }
}

pub fn init_shim() -> PodShimReport {
    PodShimReport {
        command: "pod-init",
        ok: false,
        deprecated: true,
        message: DEPRECATION_NOTE,
        replacement: "`ccd pod init` is retired; coordination scopes are no longer \
             authored via CLI. Set `[dispatch].coordination_scope` in the \
             repo overlay config directly if you need to wire a profile into \
             a shared scope.",
    }
}

pub fn migrate_defaults_shim() -> PodShimReport {
    // No automated replacement exists. `ccd migrate from-pod-layout` is a
    // separate layout-migration tool (it relocates machine identity and
    // presence records only) and does not migrate profile memory/policy
    // defaults. Presenting it here would strand operators who followed the
    // pointer and assumed defaults were handled.
    PodShimReport {
        command: "pod-migrate-defaults",
        ok: false,
        deprecated: true,
        message: DEPRECATION_NOTE,
        replacement: "`ccd pod migrate-defaults` is retired under RFC 0006 with no automated \
             replacement. Review `~/.ccd/profiles/<p>/memory.md` and \
             `~/.ccd/profiles/<p>/policy.md` by hand and split entries into \
             repo-local overlays where appropriate. Note: `ccd migrate from-pod-layout` \
             is a separate tool (machine-identity/presence layout migration) and does \
             NOT migrate profile defaults.",
    }
}