from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
SKILL_ROOT = ROOT / "hermes-agent" / "leoclean-skills"


def _kb_skill_bundle(surface: str) -> str:
    root = SKILL_ROOT / surface / "teleo-kb-bridge"
    parts = [(root / "SKILL.md").read_text()]
    reference = root / "REFERENCE.md"
    if reference.exists():
        parts.append(reference.read_text())
    return "\n".join(parts)


def test_hermes_installer_uses_visible_handle_identity_only() -> None:
    installer = (ROOT / "hermes-agent" / "install-hermes.sh").read_text()
    squashed = " ".join(installer.split())

    assert "call them m3taversal exactly" in installer
    assert "exact visible sender handle" in installer
    assert "Never infer or use a personal name" in squashed
    assert "Cory" not in installer


def test_gcp_kb_skill_uses_cloudsql_bridge_not_vps_docker() -> None:
    text = (SKILL_ROOT / "gcp" / "teleo-kb-bridge" / "SKILL.md").read_text()
    squashed = " ".join(text.split())

    assert "Cloud SQL" in text
    assert "answer from the Cloud SQL KB after a bounded read" in text
    assert "Do not browse the public web just because the KB has evidence gaps" in text
    assert "/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb" in text
    assert "search-proposals" in text
    assert "decision-matrix-status" in text
    assert "Use `status` for the complete numeric count template" in squashed
    assert "list-proposals --status all" in text
    assert "Do not answer" in text or "do not infer matrix approval" in text
    assert "Next proof-changing follow-up" in text
    assert "Always include the final line label" in text
    assert "Operator Direct-Claim Answer Contract" in text
    assert "Address `@m3taversal` only as `m3taversal`, exactly" in text
    assert "legacy reviewer value `m3ta`" in text
    assert "It is not a form of address" in squashed
    assert "no `body`, generic metadata, or forecast-resolution" in squashed
    assert "it has no author/channel/date fields" in text
    assert "Do not present a proposed v3 field" in text
    assert "Cory" not in text
    assert "not just pointer mismatch" in text
    assert "staging write to `kb_stage.kb_proposals`" in squashed
    assert "demo tier" in text
    assert "Approved is not the same as applied" in squashed
    assert "applied_at: NULL" in text
    assert "not applied" in text
    assert "canonical KB change not safe to demo from chat" in squashed
    assert "not provable from chat" in text
    assert "equivalent GCP execution is not yet proven" in squashed
    assert "false global statement that no apply tooling exists" in squashed
    assert "DB readback:" in text
    assert "full UUID plus observed `status` and `applied_at`" in squashed
    assert "Short eight-character IDs" in text
    assert "PROPOSAL_UUID_36_CHARS" in text
    assert "OBSERVED_STATUS" in text
    assert "OBSERVED_TIMESTAMP_OR_NONE" in text
    assert "claims: `N`; sources: `N`; claim_edges: `N`; claim_evidence: `N`; kb_proposals: `N`" in text
    assert "Never shorten a UUID" in text
    assert "Do not paraphrase a count" in text
    assert "`N/A` and `see public.*` are invalid" in squashed
    assert "canonical identity requires DB rows plus" in squashed
    assert "not canonical Postgres" in text
    assert "not the source of truth" in text
    assert "not a canonical commit" in text
    assert "not collective truth" in text
    assert "Row-level proof would require current readback" in text
    assert "new or updated row IDs" in text
    assert "I cannot claim canonical DB changed" in text
    assert "explicit operator/admin authorization" in text
    assert "docker exec" not in text
    assert "teleo-pg" not in text
    assert "on the VPS" not in text


def test_vps_kb_skill_keeps_vps_scope_explicit() -> None:
    text = _kb_skill_bundle("vps")
    squashed = " ".join(text.split())

    assert "VPS production leoclean" in text
    assert "Cloud SQL" not in text
    assert "/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb" in text
    assert "prefer the bridge over raw database access" in text
    assert "Claim / Body / Concept Map Loop" in text
    assert "Status: applied | pending | missing | partially applied" in text
    assert "search-proposals" in text
    assert "decision-matrix-status" in text
    assert "Use `status` for the complete numeric count template" in squashed
    assert "list-proposals --status all" in text
    assert "do not infer matrix approval" in text
    assert "approved/staged or packet-ready but not canonical" in text
    assert "Next proof-changing follow-up" in text
    assert "Always include the final line label" in text
    assert "Operator Direct-Claim Answer Contract" in text
    assert "Address `@m3taversal` only as `m3taversal`, exactly" in text
    assert "legacy reviewer value `m3ta`" in text
    assert "It is not a form of address" in squashed
    assert "no `body`, generic metadata, or forecast-resolution" in squashed
    assert "it has no author/channel/date fields" in text
    assert "Do not present a proposed v3 field" in text
    assert "Cory" not in text
    assert "not just pointer mismatch" in text
    assert "staging write to `kb_stage.kb_proposals`" in squashed
    assert "demo tier" in text
    assert "Approved is not the same as applied" in squashed
    assert "applied_at: NULL" in text
    assert "not applied" in text
    assert "canonical KB change not safe to demo from chat" in squashed
    assert "not provable from chat" in text
    assert "production permission migration and apply worker remain disabled" in squashed
    assert "false global statement that no apply tooling exists" in squashed
    assert "Approved is not the same as applied." in text
    assert "Fresh readback:" in text
    assert "not a decision-matrix vote" in text
    assert "run both `decision-matrix-status` and `status`" in squashed
    assert "DB readback:" in text
    assert "full UUID plus observed `status` and `applied_at`" in squashed
    assert "Short eight-character IDs" in text
    assert "PROPOSAL_UUID_36_CHARS" in text
    assert "OBSERVED_STATUS" in text
    assert "OBSERVED_TIMESTAMP_OR_NONE" in text
    assert "claims: `N`; sources: `N`; claim_edges: `N`; claim_evidence: `N`; kb_proposals: `N`" in text
    assert "Never shorten a UUID" in text
    assert "Do not paraphrase a count" in text
    assert "`N/A` and `see public.*` are invalid" in squashed
    assert "canonical identity requires DB rows plus" in squashed
    assert "not canonical Postgres" in text
    assert "not the source of truth" in text
    assert "not a canonical commit" in text
    assert "not collective truth" in text
    assert "Row-level proof would require current readback" in text
    assert "new or updated row IDs" in text
    assert "I cannot claim canonical DB changed" in text
    assert "explicit operator/admin authorization" in text
    assert 'Do not call an approved proposal "implemented"' in text
    assert "repository contains a live-proven strict existing-ID `add_edge` path" in squashed
    assert "Never end a normal Telegram answer by offering to run direct `INSERT`, `UPDATE`" in text
    assert "Next admin-panel action" in text
    assert "draft or refresh the admin review packet" in squashed
    assert "/kb/claims/<claim_id>" in text
    assert "wrap claim IDs, proposal IDs" in text
    assert "claim page: https://leo.livingip.xyz/kb/claims/<claim_id>" in text
    assert "search-proposals" in text
    assert "decision-matrix-status" in text


def test_gcp_kb_skill_keeps_claim_links_and_backtick_rendering() -> None:
    text = (SKILL_ROOT / "gcp" / "teleo-kb-bridge" / "SKILL.md").read_text()

    assert "/kb/claims/<claim_id>" in text
    assert "wrap claim IDs, proposal IDs" in text
    assert "claim page: https://leo.livingip.xyz/kb/claims/<claim_id>" in text


def test_leoclean_kb_skills_anchor_external_doctrine_in_target_project_language() -> None:
    for surface in ("vps", "gcp"):
        text = _kb_skill_bundle(surface)

        assert "External Doctrine Contributions" in text
        assert "Use the target project's native language first" in text
        assert "no single voice can own understanding" in text
        assert "purpose precedes" in text
        assert "Prefer issue-before-PR" in text
        assert "Consent is action-specific" in text


def test_leoclean_kb_skills_distinguish_canonical_evidence_from_provenance_quality() -> None:
    for surface in ("vps", "gcp"):
        text = _kb_skill_bundle(surface)
        squashed = " ".join(text.split())

        assert "is canonical evidence even when that source row has no `url` or `storage_path`" in squashed
        assert "weak or citation-only provenance" in squashed
        assert "not traceable to the raw artifact" in squashed
        assert "does not by itself prove canonical evidence from that attachment" in squashed
        assert "`public.sources` row representing the attachment" in squashed
        assert "`public.claim_evidence` link from the claim to that source row" in squashed


def test_leoclean_kb_skills_use_existing_behavioral_rule_storage_and_separate_apply() -> None:
    for surface in ("vps", "gcp"):
        text = _kb_skill_bundle(surface)
        squashed = " ".join(text.split())

        assert "existing `public.behavioral_rules` table" in squashed
        for field in ("`agent_id`", "`category`", "`rank`", "`rule`", "`rationale`"):
            assert field in text
        assert "does not insert `behavioral_rules` or `governance_gates`" in squashed
        assert "separate reviewed apply capability" in squashed
        assert "not a generic schema-table gap" in squashed


def test_leoclean_kb_skills_separate_runtime_session_and_delivery_proof_tiers() -> None:
    for surface in ("vps", "gcp"):
        text = _kb_skill_bundle(surface)
        squashed = " ".join(text.split())

        assert "never exceed 220 words" in squashed or "keep the whole reply under 220 words" in squashed
        assert "Postgres is canonical knowledge, but it is not the only input" in squashed
        assert "Hermes `state.db` and session JSONL provide durable continuity" in squashed
        assert "not Telegram-visible delivery proof" in squashed
        assert "Staging is not canonical apply" in squashed
        assert "Never manufacture a source row from a temporary memory label" in squashed
        assert "claims, sources, and evidence links are shared knowledge objects" in squashed
        assert "no shipped forecast-resolution fields" in squashed
        assert "Do not overwrite historical confidence" in squashed


def test_vps_live_telegram_skill_uses_systemd_for_gateway_liveness() -> None:
    text = (SKILL_ROOT / "vps" / "live-leo-telegram" / "SKILL.md").read_text()

    assert "systemctl is-active leoclean-gateway.service" in text
    assert "systemctl show leoclean-gateway.service" in text
    assert "hermes -p leoclean gateway run" in text
    assert "Do not use `hermes -p leoclean gateway status` as authoritative" in text
    assert "If you are currently replying in Telegram" in text


def test_vps_skills_enforce_compact_default_answers_without_losing_detail_on_request() -> None:
    kb_text = (SKILL_ROOT / "vps" / "teleo-kb-bridge" / "SKILL.md").read_text()
    telegram_text = (SKILL_ROOT / "vps" / "live-leo-telegram" / "SKILL.md").read_text()
    kb_squashed = " ".join(kb_text.split())
    telegram_squashed = " ".join(telegram_text.split())

    assert "final reply must never exceed 220 words" in kb_squashed
    assert "draft to at most 170 words" in kb_squashed
    assert "smaller word or line limit is mandatory" in kb_squashed
    assert "at most three short bullets" in kb_squashed
    assert "Do not mirror this skill" in kb_squashed
    assert "Broad or multi-part questions still receive one compressed answer" in telegram_squashed
    assert "draft to at most 170 words and never exceed 220 words" in telegram_squashed
    assert "explicitly requests a detailed audit or long-form document" in telegram_squashed


def test_vps_kb_skill_encodes_apply_readiness_beliefs_and_current_proof_boundaries() -> None:
    text = (SKILL_ROOT / "vps" / "teleo-kb-bridge" / "SKILL.md").read_text()
    squashed = " ".join(text.split())

    assert "approved_needs_apply_payload" in text
    assert "normalize into a strict payload and review that new packet" in squashed
    assert "never tell the operator to apply the legacy row" in squashed
    assert "`teleo-kb search` and `teleo-kb context` emit the selected claims" in squashed
    assert "An existing claim-evidence link remains canonical evidence" in squashed
    assert "Current agent-owned positions live in `public.beliefs`" in squashed
    for field in ("`agent_id`", "`level`", "`statement`", "`falsifier`", "`rank`"):
        assert field in text
    assert "has no claim-ID foreign key" in squashed
    assert "neither is generic stance storage" in squashed
    assert "`teleo-kb prepare-source` is shipped on the VPS" in squashed
    assert "nearby canonical claims before model extraction" in squashed
    assert "No active general DB-to-`SOUL.md` renderer automation is currently proven" in squashed
    assert "Unchanged table totals also do not prove unchanged rows" in squashed
    assert "current `public.claim_edges` has no rationale field" in squashed
    assert "there is no belief-edge table" in squashed
    assert "`public.claim_edges` connects claims, never belief rows" in squashed
    assert "a chat label or `source_ref` as source identity" in squashed
    assert "cannot insert `behavioral_rules` or `governance_gates`, update beliefs" in squashed
    assert "`applied_at` belongs to the proposal receipt, not each inserted row" in squashed
    assert "`state.db` and session JSONL can preserve continuity across restart" in squashed
    assert "It has no `author`, `title`, `publisher`, or publication-date column" in squashed
    assert "`artifact_verification`" in text
    assert "`semantic_context_sha256`" in text
    assert "stable WAL marker" in text
    assert "Never infer that an artifact is missing from a raw `storage_path`" in squashed
    assert "Never infer `missing` from a raw `storage_path`" in squashed
    assert "accepts only an identical semantic context" in squashed
    assert "Automatic Telegram attachment capture" in squashed
    assert "state/kb-source-inbox/source.md" in text
    assert "--receipt /home/teleo/.hermes/profiles/leoclean/state/kb-source-receipts/source.json" in text
    assert "a reusable framework maps to `reasoning_tools`, not a claim graph" in squashed
    assert "never list them in the supported apply order" in squashed
    assert "Treat the emitted `Current Runtime Contracts` / `operational_contracts` block as binding" in squashed
    assert "It overrides recalled or generic architecture" in squashed
