{
  "schema_version": "1.0.0",
  "status": "provisional",
  "derived_from": "GURU-5070",
  "derived_at": "2026-06-02",
  "note": "PROVISIONAL baseline, generated from a single known-good machine. V1 of self-check is a CENSUS tool: every machine probes itself, publishes to the coord API, and we refine this manifest from real fleet data (see baseline/README.md). Do NOT treat 'extra' or 'missing' items as authoritative until the fleet census has confirmed them across machines.",
  "harness": {
    "min_version": "1.4.0",
    "version_file": ".claude/harness/VERSION",
    "registry_desc_budget_chars": 10500,
    "registry_desc_why": "Sum of all skill SKILL.md description: fields. These inject into EVERY session's skill registry, so a bloated description is a fleet-wide context tax. Budget set at the 1.4.0 post-trim size (~8.7k) + headroom; a WARN here means a skill description grew back and should be re-trimmed (move triggers/examples into the SKILL.md body).",
    "syntax_check_scripts": [
      ".claude/scripts/sync.sh",
      ".claude/scripts/harness-guard.sh",
      ".claude/scripts/now-phoenix.sh",
      ".claude/scripts/test-harness-guard.sh"
    ],
    "guard_wired_in": ".claude/scripts/sync.sh"
  },
  "command_standard_links": [
    {
      "topic": "syncro-billing",
      "standard": ".claude/standards/syncro/time-entry-protocol.md",
      "must_reference": "syncro\\.md|single source of truth",
      "why": "the time-entry standard must DEFER to the /syncro command (one SSOT), not restate billing mechanics. A past drift had the standard say 'always timer' while the command said 'outlier only' \u2014 losing the pointer is the early warning of that re-drift."
    }
  ],
  "command_standard_links_note": "Deterministic half of the command-restates-standard lint: each linked standard must contain a defer-to-SSOT pointer (must_reference, a grep -iE regex). A WARN means the standard may have drifted back into restating/contradicting the command. The SEMANTIC contradiction judgement (read both files, decide if they actually conflict) is delegated to the model in SKILL.md, mirroring the memory contradiction pass.",
  "required_tools": [
    {
      "name": "bash",
      "why": "hooks, scripts, sync, vault wrapper"
    },
    {
      "name": "git",
      "why": "repo + submodules + Gitea sync"
    },
    {
      "name": "jq",
      "why": "every hook and coord script parses JSON with jq"
    },
    {
      "name": "curl",
      "why": "coord API, vault, RMM, all HTTP calls"
    },
    {
      "name": "sops",
      "why": "vault decryption (SOPS)"
    },
    {
      "name": "age",
      "why": "SOPS age recipient/decrypt"
    },
    {
      "name": "ssh",
      "why": "infra access; must be system OpenSSH"
    }
  ],
  "required_python": {
    "any_of": [
      "py",
      "python3",
      "python"
    ],
    "why": "JSON sanitizer in check-messages.sh, identity migration, skill scripts. The resolved command is recorded in identity.json (.python.command)."
  },
  "capability_tools": [
    {
      "name": "ollama",
      "capability": "ollama_local",
      "why": "Tier-0 local inference (prose/classification)"
    },
    {
      "name": "cargo",
      "capability": "rust_build",
      "why": "GuruRMM / GuruConnect Rust builds"
    },
    {
      "name": "node",
      "capability": "node_build",
      "why": "dashboard / TS builds"
    },
    {
      "name": "gh",
      "capability": "github_cli",
      "why": "optional GitHub operations"
    },
    {
      "name": "docker",
      "capability": "containers",
      "why": "optional container workflows"
    },
    {
      "name": "op",
      "capability": "onepassword_cli",
      "why": "1Password fallback credential access"
    }
  ],
  "required_identity_fields": [
    "user",
    "full_name",
    "email",
    "role",
    "machine",
    "vault_path",
    "claudetools_root",
    "platform",
    "architecture",
    "python.command",
    "ollama.endpoint",
    "ollama.fallback",
    "ollama.prose_model"
  ],
  "optional_identity_fields": [
    "coord_api",
    "last_updated"
  ],
  "required_scripts": [
    ".claude/scripts/vault.sh",
    ".claude/scripts/sync.sh",
    ".claude/scripts/sync-memory.sh",
    ".claude/scripts/check-messages.sh",
    ".claude/scripts/migrate-identity.sh"
  ],
  "grok_recovery_scripts": [
    ".claude/scripts/recover_grok_session.py"
  ],
  "required_hook_files": [
    ".claude/hooks/block-backslash-winpath.sh",
    ".claude/hooks/block-tmp-path.sh",
    ".claude/hooks/post-commit.template"
  ],
  "grok_hook_files": [
    ".grok/hooks/claudetools.json"
  ],
  "required_settings_hooks": [
    {
      "event": "PreToolUse",
      "matcher": "Bash",
      "command_contains": "block-backslash-winpath.sh",
      "why": "blocks garbled backslash Windows-path redirects in Git Bash"
    },
    {
      "event": "PreToolUse",
      "matcher": "Bash",
      "command_contains": "block-tmp-path.sh",
      "why": "blocks /tmp file writes in Git Bash on Windows (Write/Python resolve /tmp differently - read-back fails)"
    },
    {
      "event": "UserPromptSubmit",
      "matcher": "",
      "command_contains": "check-messages.sh",
      "why": "injects unread coord messages + dev-mode locks each prompt"
    },
    {
      "event": "SessionStart",
      "matcher": "",
      "command_contains": "sync-memory.sh",
      "why": "pulls shared memory at session start"
    }
  ],
  "git": {
    "remote_host_contains": "git.azcomputerguru.com",
    "remote_host_internal_ip": "172.16.3.20",
    "remote_note": "On-network machines should use the internal Gitea IP (172.16.3.20:3000) to bypass NPM SSL-renewal blips; off-network may use the domain. Either is acceptable; a non-ACG remote is a FAIL.",
    "post_commit_hook_expected": true,
    "post_commit_hook_note": "HOOKS.md mandates the dev-alerts post-commit hook in the main repo and each initialized submodule. Missing = AMBER (informational; reinstall from .claude/hooks/post-commit.template)."
  },
  "skills": [
    "1password",
    "b2",
    "bitdefender",
    "frontend-design",
    "gc-audit",
    "impeccable",
    "memory-dream",
    "remediation-tool",
    "rmm-audit",
    "screenconnect",
    "skill-creator",
    "stop-slop",
    "theme-factory",
    "self-check"
  ],
  "commands": [
    "1password",
    "checkpoint",
    "context",
    "create-spec",
    "feature-request",
    "forum-post",
    "gc-feature-request",
    "import",
    "inject-standards",
    "mailbox",
    "mode",
    "recover",
    "remediation-tool",
    "rmm",
    "save",
    "scc",
    "shape-spec",
    "sync",
    "syncro-emergency-billing",
    "syncro",
    "wiki-compile",
    "wiki-lint",
    "self-check"
  ],
  "capability_commands": [
    {
      "name": "autotask",
      "capability": "psa_autotask",
      "why": "Autotask PSA command. Syncro is the fleet-default PSA (feedback_psa_default_syncro.md), so /autotask is intentionally NOT in the shared repo and is absent on Syncro machines. Capability-gated, not required-everywhere; absence is INFO, never a FAIL. Present only on machines whose PSA is Autotask."
    }
  ],
  "capability_commands_note": "Per-machine/per-capability slash commands that must NOT be required fleet-wide. The probe iterates only .commands[] for required conformance; entries here are documentary so a gated command is not silently dropped. Move a command here (and out of .commands[]) when it is intentionally machine-specific.",
  "connectivity": [
    {
      "name": "coord_api",
      "url": "http://172.16.3.30:8001/api/coord/status",
      "required": true,
      "why": "live coordination source of truth"
    },
    {
      "name": "claudetools_api",
      "url": "http://172.16.3.30:8001/health",
      "required": false,
      "why": "main API health"
    },
    {
      "name": "gitea_internal",
      "url": "http://172.16.3.20:3000",
      "required": false,
      "why": "internal Gitea (git/API on-network)"
    }
  ],
  "memory": {
    "note": "Deterministic memory checks: MEMORY.md index exists + no orphaned memory files, plus the contradiction_patterns below. A pattern fires ONLY on machines where identity.<when_field> == when_equals, so it flags a memory only where it is actually a contradiction for THIS box. Kept empty in V1 to avoid false positives; the real semantic contradiction analysis (memories vs identity.json + settings.json + this manifest) is done by the model per SKILL.md, optionally via Ollama Tier-0.",
    "pattern_schema": {
      "when_field": "dotted identity.json path, e.g. python.command",
      "when_equals": "value that makes the grep a contradiction, e.g. python3",
      "grep": "ERE matched case-insensitively against memory files",
      "why": "human explanation shown in the finding"
    },
    "contradiction_patterns": []
  },
  "capability_rules": {
    "ollama_local": {
      "tier0_engine": "local ollama (localhost:11434) for summarize/classify/extract/draft",
      "detect": "curl localhost:11434/api/tags reachable",
      "fallback_if_unavailable": "ollama_remote"
    },
    "ollama_remote": {
      "tier0_engine": "remote ollama via identity.ollama.fallback (Beast over Tailscale)",
      "detect": "localhost unreachable but identity.ollama.fallback reachable",
      "fallback_if_unavailable": "ollama_none"
    },
    "ollama_none": {
      "tier0_engine": "NONE - no Tier-0 path. Route low-stakes prose/classification to Tier-1 (haiku) instead of Ollama. Do NOT block work waiting on Ollama.",
      "detect": "neither localhost nor fallback reachable",
      "fallback_if_unavailable": null
    }
  }
}
