pointbreak 0.10.0

Durable terminal code review for changes humans and coding agents collaborate on together
Documentation
use std::collections::BTreeMap;

use serde::Serialize;

use super::DiagnosticDocument;

pub const VERSION_SCHEMA: &str = "pointbreak.version";
pub const VERSION_DISPLAY: &str = concat!(
    env!("CARGO_PKG_VERSION"),
    " (",
    env!("POINTBREAK_BUILD_DESCRIBE"),
    ")"
);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum BuildSourceV1 {
    Git,
    Package,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BuildIdentityV1 {
    pub source: BuildSourceV1,
    pub commit: Option<String>,
    pub describe: String,
    pub dirty: bool,
}

impl BuildIdentityV1 {
    pub fn current() -> Self {
        let source = match env!("POINTBREAK_BUILD_SOURCE") {
            "git" => BuildSourceV1::Git,
            "package" => BuildSourceV1::Package,
            value => unreachable!("build.rs emitted unsupported build source {value:?}"),
        };
        let commit = match source {
            BuildSourceV1::Git => Some(env!("POINTBREAK_BUILD_COMMIT").to_owned()),
            BuildSourceV1::Package => None,
        };
        let dirty = match env!("POINTBREAK_BUILD_DIRTY") {
            "true" => true,
            "false" => false,
            value => unreachable!("build.rs emitted unsupported dirty state {value:?}"),
        };
        Self {
            source,
            commit,
            describe: env!("POINTBREAK_BUILD_DESCRIBE").to_owned(),
            dirty,
        }
    }
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct VersionBody {
    pub cli_version: String,
    pub build: BuildIdentityV1,
    pub documents: BTreeMap<&'static str, u32>,
}

impl VersionBody {
    pub fn current() -> Self {
        Self {
            cli_version: env!("CARGO_PKG_VERSION").to_owned(),
            build: BuildIdentityV1::current(),
            documents: super::document_registry().iter().copied().collect(),
        }
    }

    pub fn display_version(&self) -> String {
        format!("{} ({})", self.cli_version, self.build.describe)
    }
}

pub fn version_document() -> DiagnosticDocument<VersionBody> {
    DiagnosticDocument::new(VERSION_SCHEMA, VersionBody::current(), Vec::new())
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeSet;
    use std::fs;
    use std::path::Path;

    use super::*;

    #[test]
    fn registry_covers_the_extension_required_documents() {
        let registry = crate::documents::document_registry();
        for (schema, version) in [
            ("pointbreak.version", 1),
            ("pointbreak.attention-list", 1),
            ("pointbreak.identity-whoami", 1),
            ("pointbreak.review-revision-list", 1),
            ("pointbreak.change-capture-receipt.v1", 1),
            ("pointbreak.review-capture", 1),
            ("pointbreak.review-observation-add", 1),
            ("pointbreak.store-status", 1),
            ("pointbreak.review-revision", 2),
            ("pointbreak.review-snapshot", 1),
            ("pointbreak.inspect-freshness", 1),
            ("pointbreak.inspect-startup", 1),
        ] {
            assert_eq!(
                registry
                    .iter()
                    .find(|(candidate, _)| *candidate == schema)
                    .map(|(_, version)| *version),
                Some(version),
                "registry missing or mis-versioned: {schema}"
            );
        }
    }

    #[test]
    fn version_body_serializes_camel_case_with_sorted_documents() {
        let body = VersionBody::current();
        let value = serde_json::to_value(&body).unwrap();
        assert_eq!(value["cliVersion"], env!("CARGO_PKG_VERSION"));
        assert_eq!(value["build"]["source"], env!("POINTBREAK_BUILD_SOURCE"));
        match env!("POINTBREAK_BUILD_SOURCE") {
            "git" => assert_eq!(value["build"]["commit"].as_str().unwrap().len(), 40),
            "package" => assert!(value["build"]["commit"].is_null()),
            source => panic!("unexpected build source {source:?}"),
        }
        assert!(value["build"]["describe"].is_string());
        assert!(value["build"]["dirty"].is_boolean());
        let documents = value["documents"].as_object().unwrap();
        assert!(documents.len() >= 5);
        let keys: Vec<_> = documents.keys().cloned().collect();
        let mut sorted = keys.clone();
        sorted.sort();
        assert_eq!(
            keys, sorted,
            "documents map must be deterministically ordered"
        );
    }

    #[test]
    fn naming_cutover_version_v1_bytes_are_frozen() {
        let mut actual = serde_json::to_value(version_document()).unwrap();
        actual["cliVersion"] = serde_json::Value::String("0.6.0".to_owned());
        assert!(
            actual.as_object_mut().unwrap().remove("build").is_some(),
            "current v1 adds build without rewriting the historical v1 fixture"
        );
        for approved_addition in [
            "pointbreak.change-capture-receipt.v1",
            "pointbreak.store-paths",
            "pointbreak.store-derived-build",
            "pointbreak.store-derived-rebuild",
            "pointbreak.store-derived-status",
        ] {
            if let Some(version) = actual["documents"]
                .as_object_mut()
                .unwrap()
                .remove(approved_addition)
            {
                assert_eq!(version, 1, "the approved registry addition stays v1");
            }
        }
        let expected: serde_json::Value = serde_json::from_slice(
            &crate::test_fixtures::naming_cutover_contract_bytes("protocol/version-v1.json"),
        )
        .unwrap();
        assert_eq!(actual, expected);
    }

    #[test]
    fn registry_is_cli_documents_plus_the_exact_promoted_inspect_set() {
        let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
        let mut emitted = BTreeSet::from([VERSION_SCHEMA.to_owned()]);
        collect_schema_literals(&manifest_dir.join("src/cli"), &mut emitted);
        collect_schema_literals(&manifest_dir.join("src/documents"), &mut emitted);

        let cli_registered = crate::documents::cli_document_registry()
            .iter()
            .map(|(schema, _)| (*schema).to_owned())
            .collect::<BTreeSet<_>>();
        let headless_noninspect = crate::documents::change_revision_document_registry()
            .iter()
            .map(|(schema, _)| (*schema).to_owned())
            .filter(|schema| !schema.starts_with("pointbreak.inspect-"))
            .collect::<BTreeSet<_>>();
        assert_eq!(
            emitted,
            cli_registered
                .union(&headless_noninspect)
                .cloned()
                .collect()
        );

        let promoted = crate::documents::promoted_inspect_document_registry()
            .iter()
            .map(|(schema, _)| (*schema).to_owned())
            .collect::<BTreeSet<_>>();
        assert_eq!(
            promoted,
            BTreeSet::from([
                "pointbreak.review-snapshot".to_owned(),
                "pointbreak.inspect-freshness".to_owned(),
                "pointbreak.inspect-startup".to_owned(),
            ])
        );

        let registered = crate::documents::document_registry()
            .iter()
            .map(|(schema, _)| (*schema).to_owned())
            .collect::<BTreeSet<_>>();
        assert_eq!(
            registered,
            cli_registered.union(&promoted).cloned().collect()
        );
        assert!(!registered.contains("pointbreak.inspect-attention"));
        assert!(!registered.contains("pointbreak.inspect-identity"));
    }

    fn collect_schema_literals(path: &Path, schemas: &mut BTreeSet<String>) {
        for entry in fs::read_dir(path).unwrap() {
            let entry = entry.unwrap();
            let path = entry.path();
            if path.is_dir() {
                if path.file_name().is_some_and(|name| name == "inspect") {
                    continue;
                }
                collect_schema_literals(&path, schemas);
            } else if path.extension().is_some_and(|extension| extension == "rs")
                && !path.ends_with("src/documents/mod.rs")
                && !path.ends_with("src/documents/version.rs")
                && !path.ends_with("src/documents/inspect.rs")
            {
                let source = fs::read_to_string(path).unwrap();
                for schema in schema_literals(&source) {
                    schemas.insert(schema);
                }
            }
        }
    }

    fn schema_literals(source: &str) -> Vec<String> {
        source
            .match_indices("\"pointbreak.")
            .filter_map(|(start, _)| {
                let schema = &source[start + 1..];
                let end = schema
                    .find(|character: char| {
                        !(character.is_ascii_lowercase()
                            || character.is_ascii_digit()
                            || matches!(character, '.' | '-'))
                    })
                    .unwrap_or(schema.len());
                (schema.as_bytes().get(end) == Some(&b'\"')).then(|| schema[..end].to_owned())
            })
            .collect()
    }
}