relay-knowledge 1.1.16

Graph-database-based knowledge graph project.
Documentation
use super::{accept_topic_item_indent, content_digest, facts, stable_id, top_level_yaml_section};
use crate::project::KNOWLEDGE_MAP_RELATIVE_PATH;

fn valid_root(relative: &str, digest: &str) -> String {
    format!(
        "schema_version: 2\nmap_version: 1\nupdated_at: now\ntopics:\n  - id: build\n    title: Build\n    description: Build knowledge\n    source_ids: []\n    ref: {relative}\n    digest: {digest}\nhistory:\n  archived_through: 0\n  recent:\n    - version: 1\n      action: init\n      actor: test\n      summary: Initialize map\n"
    )
}

#[test]
fn extracts_only_topics_from_the_authoritative_knowledge_map() {
    let mut definitions = Vec::new();
    let content = "schema_version: 1\ntopics:\n  - id: parsing\n  - id: indexing\nignored:\n  - id: storage\n";

    facts(
        KNOWLEDGE_MAP_RELATIVE_PATH,
        "yaml",
        content,
        &mut definitions,
    );

    let names = definitions
        .iter()
        .map(|definition| definition.name.as_str())
        .collect::<Vec<_>>();
    assert_eq!(names, ["parsing", "indexing"]);
}

#[test]
fn fixes_the_topic_list_indent_after_the_first_item() {
    let mut indent = None;

    assert!(accept_topic_item_indent(&mut indent, 2));
    assert!(accept_topic_item_indent(&mut indent, 2));
    assert!(!accept_topic_item_indent(&mut indent, 4));
    assert_eq!(top_level_yaml_section("topics:"), Some("topics"));
    assert_eq!(top_level_yaml_section("  nested:"), None);
}

#[test]
fn emits_manifest_authorization_and_digest_verified_shard_facts() {
    let shard = "schema_version: 2\ntopic:\n  id: build\n  title: Build\n  description: Build knowledge\nsources: []\nroute: null\n";
    let digest = content_digest(shard.as_bytes());
    let relative = format!("topics/topic-{}-{digest}.yaml", stable_id("build"));
    let root = valid_root(&relative, &digest);
    let mut root_facts = Vec::new();
    facts(KNOWLEDGE_MAP_RELATIVE_PATH, "yaml", &root, &mut root_facts);
    let shard_path = format!("knowledge/{relative}");
    assert!(
        root_facts.iter().any(|fact| {
            fact.kind == "knowledge_map_topic_shard_ref" && fact.name == shard_path
        })
    );
    assert!(
        root_facts
            .iter()
            .any(|fact| { fact.kind == "knowledge_map_topic_shard_topic" && fact.name == "build" })
    );
    let root_identity = root_facts
        .iter()
        .find(|fact| fact.kind == "knowledge_map_topic_shard_identity")
        .expect("root identity should exist");

    let mut shard_facts = Vec::new();
    facts(&shard_path, "yaml", shard, &mut shard_facts);
    assert!(
        shard_facts
            .iter()
            .any(|fact| { fact.kind == "knowledge_map_topic_shard" && fact.name == "build" })
    );
    assert!(shard_facts.iter().any(|fact| {
        fact.kind == "knowledge_map_topic_shard_identity" && fact.name == root_identity.name
    }));

    let mut tampered_facts = Vec::new();
    facts(
        &shard_path,
        "yaml",
        &shard.replace("Build", "Tampered"),
        &mut tampered_facts,
    );
    assert!(tampered_facts.is_empty());
}

#[test]
fn accepts_valid_noncanonical_topic_indentation() {
    let shard = "schema_version: 2\ntopic:\n    id: build\n    title: Build\n    description: Build knowledge\nsources: []\nroute: null\n";
    let digest = content_digest(shard.as_bytes());
    let path = format!(
        ".knowledge/topics/topic-{}-{digest}.yaml",
        stable_id("build")
    );
    let mut definitions = Vec::new();

    facts(&path, "yaml", shard, &mut definitions);

    assert!(
        definitions
            .iter()
            .any(|fact| { fact.kind == "knowledge_map_topic_shard" && fact.name == "build" })
    );
}

#[test]
fn accepts_a_flow_mapping_on_the_line_after_the_topic_key() {
    let shard = "schema_version: 2\ntopic:\n  {id: build, title: Build, description: Build knowledge}\nsources: []\nroute: null\n";
    let digest = content_digest(shard.as_bytes());
    let path = format!(
        ".knowledge/topics/topic-{}-{digest}.yaml",
        stable_id("build")
    );
    let mut definitions = Vec::new();

    facts(&path, "yaml", shard, &mut definitions);

    assert!(
        definitions
            .iter()
            .any(|fact| { fact.kind == "knowledge_map_topic_shard" && fact.name == "build" })
    );
}

#[test]
fn rejects_shards_that_violate_source_and_route_invariants() {
    let invalid_shards = [
        "schema_version: 2\ntopic: {id: build, title: Build}\nsources: []\nroute: null\n",
        "schema_version: 2\ntopic: {id: build, title: Build, description: Build knowledge}\nsources:\n  - id: cargo\n    topic: other\n    kind: config\n    uri: Cargo.toml\n    read_policy: direct\n    write_policy: manual-review\n    status: active\n    version: 1\nroute: {topic: build, source_order: [cargo]}\n",
        "schema_version: 2\ntopic: {id: build, title: Build, description: Build knowledge}\nsources:\n  - id: cargo\n    topic: build\n    kind: config\n    uri: Cargo.toml\n    read_policy: direct\n    write_policy: manual-review\n    status: active\n    version: 1\nroute: null\n",
        "schema_version: 2\ntopic: {id: build, title: Build, description: Build knowledge}\nsources:\n  - id: cargo\n    topic: build\n    kind: config\n    uri: Cargo.toml\n    read_policy: direct\n    write_policy: manual-review\n    status: active\n    version: 1\nroute: {topic: build, source_order: [foreign]}\n",
    ];

    for shard in invalid_shards {
        let digest = content_digest(shard.as_bytes());
        let path = format!(
            ".knowledge/topics/topic-{}-{digest}.yaml",
            stable_id("build")
        );
        let mut definitions = Vec::new();
        facts(&path, "yaml", shard, &mut definitions);
        assert!(
            !definitions
                .iter()
                .any(|fact| fact.kind == "knowledge_map_topic_shard"),
            "invalid shard emitted an authorization fact: {shard}"
        );
    }
}

#[test]
fn root_and_shard_identity_facts_detect_metadata_disagreement() {
    let inconsistent_shards = [
        "schema_version: 2\ntopic: {id: build, title: Different, description: Build knowledge}\nsources: []\nroute: null\n",
        "schema_version: 2\ntopic: {id: build, title: Build, description: Build knowledge}\nsources:\n  - id: cargo\n    topic: build\n    kind: config\n    uri: Cargo.toml\n    read_policy: direct\n    write_policy: manual-review\n    status: active\n    version: 1\nroute: {topic: build, source_order: [cargo]}\n",
    ];

    for shard in inconsistent_shards {
        let digest = content_digest(shard.as_bytes());
        let relative = format!("topics/topic-{}-{digest}.yaml", stable_id("build"));
        let root = valid_root(&relative, &digest);
        let mut root_facts = Vec::new();
        let mut shard_facts = Vec::new();
        facts(KNOWLEDGE_MAP_RELATIVE_PATH, "yaml", &root, &mut root_facts);
        facts(
            &format!(".knowledge/{relative}"),
            "yaml",
            shard,
            &mut shard_facts,
        );

        let root_identity = root_facts
            .iter()
            .find(|fact| fact.kind == "knowledge_map_topic_shard_identity")
            .expect("root identity should exist");
        let shard_identity = shard_facts
            .iter()
            .find(|fact| fact.kind == "knowledge_map_topic_shard_identity")
            .expect("locally valid shard identity should exist");
        assert_ne!(root_identity.name, shard_identity.name);
    }
}

#[test]
fn malformed_v2_refs_do_not_fall_back_to_legacy_root_topics() {
    let content = "schema_version: 2\ntopics:\n  - id: unauthorized\n    ref: ../escape.yaml\n    digest: invalid\n";
    let mut definitions = Vec::new();

    facts(
        KNOWLEDGE_MAP_RELATIVE_PATH,
        "yaml",
        content,
        &mut definitions,
    );

    assert!(
        !definitions
            .iter()
            .any(|fact| { fact.kind == "knowledge_map_topic" && fact.name == "unauthorized" })
    );
}

#[test]
fn incomplete_or_globally_inconsistent_v2_manifests_authorize_no_shards() {
    let digest = "a".repeat(64);
    let relative = format!("topics/topic-{}-{digest}.yaml", stable_id("build"));
    let valid = valid_root(&relative, &digest);
    let conflicting_id = valid.replace(
        "history:\n",
        &format!(
            "  - id: Build\n    title: Other build\n    description: Conflicts by folded id\n    source_ids: []\n    ref: topics/topic-{}-{digest}.yaml\n    digest: {digest}\nhistory:\n",
            stable_id("Build")
        ),
    );
    let invalid = [
        valid.replacen("map_version: 1\n", "", 1),
        valid.replacen("history:\n", "ignored_history:\n", 1),
        valid.replace("version: 1", "version: 2"),
        conflicting_id,
    ];

    for manifest in invalid {
        let mut definitions = Vec::new();
        facts(
            KNOWLEDGE_MAP_RELATIVE_PATH,
            "yaml",
            &manifest,
            &mut definitions,
        );
        assert!(
            definitions.is_empty(),
            "invalid v2 manifest authorized shard facts: {manifest}"
        );
    }
}

#[test]
fn flow_style_v2_topics_emit_authorization_facts() {
    let shard = "schema_version: 2\ntopic: {id: build, title: Build, description: Build knowledge}\nsources: []\nroute: null\n";
    let digest = content_digest(shard.as_bytes());
    let relative = format!("topics/topic-{}-{digest}.yaml", stable_id("build"));
    let root = format!(
        "schema_version: 2\nmap_version: 1\nupdated_at: now\ntopics: [{{id: build, title: Build, description: Build knowledge, source_ids: [], ref: {relative}, digest: {digest}}}]\nhistory: {{archived_through: 0, recent: [{{version: 1, action: init, actor: test, summary: Initialize map}}]}}\n"
    );
    let mut definitions = Vec::new();

    facts(KNOWLEDGE_MAP_RELATIVE_PATH, "yaml", &root, &mut definitions);

    assert!(definitions.iter().any(|fact| {
        fact.kind == "knowledge_map_topic_shard_ref" && fact.name == format!("knowledge/{relative}")
    }));
}

#[test]
fn quoted_ref_keys_emit_manifest_authorization_facts() {
    let shard = "schema_version: 2\ntopic: {id: build, title: Build, description: Build knowledge}\nsources: []\nroute: null\n";
    let digest = content_digest(shard.as_bytes());
    let relative = format!("topics/topic-{}-{digest}.yaml", stable_id("build"));
    let root = format!(
        "schema_version: 2\nmap_version: 1\nupdated_at: now\ntopics:\n  - id: build\n    title: Build\n    description: Build knowledge\n    source_ids: []\n    \"ref\": {relative}\n    digest: {digest}\nhistory: {{archived_through: 0, recent: [{{version: 1, action: init, actor: test, summary: Initialize map}}]}}\n"
    );
    let mut definitions = Vec::new();

    facts(KNOWLEDGE_MAP_RELATIVE_PATH, "yaml", &root, &mut definitions);

    assert!(definitions.iter().any(|fact| {
        fact.kind == "knowledge_map_topic_shard_ref" && fact.name == format!("knowledge/{relative}")
    }));
}