polyc-controller 2026.8.3

Conversation CRD + kube reconciler for the polychrome control plane.
//! Emit polychrome's `CustomResourceDefinition`s as a multi-document YAML
//! stream on stdout, one CRD per document separated by `---`.
//!
//! This is a code generator, not a deploy step: its output is committed to
//! `manifests/crds/crds.yaml` (regenerate with `just crdgen`) so the CRDs are
//! version-controlled and installed before their instances — the
//! GitOps-friendly pattern kube recommends ("provide a generated YAML file so
//! consumers can install a CRD out of band"). The committed file is applied via
//! its own kustomization (`kubectl apply -k manifests/crds`) ahead of the
//! workloads, since a CRD must exist before any CR of that kind.
//!
//! Each CRD is serialized as genuine YAML (`serde_yaml_ng` — the maintained
//! fork `polyc-control-plane`/`polyc-harness`/`polyc-runtime` already pin;
//! `serde_yaml` is deprecated upstream). Earlier this printed pretty JSON
//! joined by `---`: JSON is a valid YAML 1.2 subset for a single document,
//! but `kubectl` sniffs the leading `{` of the whole stream, decides the
//! entire input is one JSON document, and errors on the first `---`
//! separator ("invalid character '-' in numeric literal") — the committed
//! file's entire purpose, being applied as a stream, was unreachable (#1233).
//! Every document, including the first, opens with its own `---` so the
//! stream unambiguously sniffs as YAML from the first byte.

use kube::CustomResourceExt;
use polyc_controller::{Agent, Conversation, Routine, ServiceDefinition, ToolService, Workflow};

fn main() {
    // Ordered (alphabetical by kind) for stable diffs in the committed file.
    let crds = [
        Agent::crd(),
        Conversation::crd(),
        Routine::crd(),
        ServiceDefinition::crd(),
        ToolService::crd(),
        Workflow::crd(),
    ];
    for crd in &crds {
        println!("---");
        print!("{}", serde_yaml_ng::to_string(crd).expect("CRD serializes"));
    }
}