{
  "$schema": "./agent-baseline.schema.json",
  "schemaVersion": "1.0",
  "manifestVersion": 2,
  "description": "Baseline capabilities every operator PA agent is expected to carry. Each entry is a mechanical presence-probe: `pa agent audit` diffs an agent estate against this manifest and reports gaps. New capabilities land here at the same time as the platform release that ships them, so drift becomes a generated to-do instead of a memory test. Version-coupling convention: bump `manifestVersion` whenever a new capability entry lands; set the capability's `sinceVersion` to the @stravica-ai/engineering-pa-core release that introduced it. Host-dependent probes MUST carry `hostDependent:true` so a mismatched host is reported as `unverified-here`, not a false fail.",
  "capabilities": [
    {
      "id": "spawn-log",
      "label": "Spawn-log JSON present",
      "sinceVersion": "0.1.0",
      "rationale": "Every dispatch must leave a trail; the spawn-log is the machine-readable record the librarian sweeps.",
      "probe": {
        "type": "file-exists",
        "path": "agents/{paName}/spawn-log.json"
      }
    },
    {
      "id": "journal",
      "label": "Self-improvement journal present",
      "sinceVersion": "0.1.0",
      "rationale": "Every PA keeps a journal — the substrate for the librarian's distillation pass.",
      "probe": {
        "type": "file-exists",
        "path": "agents/{paName}/journal.md"
      }
    },
    {
      "id": "next-session",
      "label": "Next-session handover file present",
      "sinceVersion": "0.1.0",
      "rationale": "Session-boundary continuity — the top of the file is operator-facing.",
      "probe": {
        "type": "file-exists",
        "path": "agents/{paName}/next-session.md"
      }
    },
    {
      "id": "autonomy-envelope",
      "label": "Autonomy-envelope file present",
      "sinceVersion": "0.1.0",
      "rationale": "Per-task-type approval state — the durable record the PA checks when the reflex is unclear.",
      "probe": {
        "type": "file-exists",
        "path": "agents/{paName}/autonomy-envelope.md"
      }
    },
    {
      "id": "staging-dir",
      "label": "Staging directory present",
      "sinceVersion": "0.1.0",
      "rationale": "Real-time observation staging — the librarian's inbox. Absent staging dir means the PA has no place to write in-session observations.",
      "probe": {
        "type": "directory-exists",
        "path": "agents/{paName}/staging"
      }
    },
    {
      "id": "staging-recent-write",
      "label": "Staging directory has a recent write",
      "sinceVersion": "0.1.0",
      "rationale": "Warns (never fails) if the staging dir has been quiet for longer than the tolerated window — a signal that real-time staging discipline has drifted, but tolerant of legitimate quiet weeks.",
      "severity": "warn",
      "probe": {
        "type": "staging-recent-write",
        "path": "agents/{paName}/staging",
        "maxAgeDays": 7
      }
    },
    {
      "id": "session-end-sop-overlay",
      "label": "Session-boot-and-end SOP overlay present",
      "sinceVersion": "0.1.0",
      "rationale": "The estate-side SOP that layers over the core session-end routine — its absence means the PA is running on the core baseline only, with no estate customisation applied.",
      "probe": {
        "type": "knowledge-doc-exists",
        "path": "operator/knowledge/operator-interface/session-boot-and-end.md"
      }
    },
    {
      "id": "boot-slice-job",
      "label": "Boot-slice schedule + output file",
      "sinceVersion": "0.1.7",
      "rationale": "The lightweight boot slice is what the PA loads on every session boot instead of the full profile. Its regeneration is scheduled on a profile-bearing host; the output file must exist somewhere in the estate.",
      "hostDependent": true,
      "probe": {
        "type": "schedule-defined",
        "path": "schedules",
        "commandIncludes": ["slice generate"],
        "outputPathHints": ["operator/profile/slices/"]
      }
    },
    {
      "id": "library-sync-up",
      "label": "Library-sync up-path scheduled",
      "sinceVersion": "0.1.5",
      "rationale": "Fresh estate content must reach canonical on every device that authors it; a missing up-path is the mechanism that produced the 2026-07-14 stale-clobber family.",
      "hostDependent": true,
      "probe": {
        "type": "schedule-defined",
        "path": "schedules",
        "commandIncludes": ["library-sync"],
        "commandIncludesAny": ["--up", "library-sync-cycle"]
      }
    },
    {
      "id": "library-sync-down",
      "label": "Library-sync down-path scheduled",
      "sinceVersion": "0.1.5",
      "rationale": "Every device must materialise the freshest canonical content. On devices that use the cycle orchestrator the down leg is embedded; standalone down-only schedules also satisfy this probe.",
      "hostDependent": true,
      "probe": {
        "type": "schedule-defined",
        "path": "schedules",
        "commandIncludes": ["library-sync"],
        "commandIncludesAny": ["--down", "library-sync-cycle", "library-sync-refresh"]
      }
    },
    {
      "id": "relay-agent-registration",
      "label": "Agent id registered in claude-relay config",
      "sinceVersion": "0.1.0",
      "rationale": "Cross-agent transport requires the agent id to appear in `operator/extensions/tools/claude-relay/config.json:agents`; absence means no cross-machine relay traffic can address this PA.",
      "probe": {
        "type": "json-field-includes",
        "path": "operator/extensions/tools/claude-relay/config.json",
        "field": "agents",
        "expectedValue": "{paName}",
        "requiredTool": "claude-relay"
      }
    },
    {
      "id": "board-session-start-hook",
      "label": "SessionStart hook runs pa board check, compaction included",
      "sinceVersion": "0.1.68",
      "rationale": "The board check is the boot path: at startup, resume, clear and after compaction the session is told the board's age and every open dispatch missing from the board, so a stale board is said out loud instead of read as a quiet day.",
      "probe": {
        "type": "settings-hook-includes",
        "path": ".claude/settings.json",
        "altPaths": ["agents/{paName}/.claude/settings.json"],
        "event": "SessionStart",
        "matcherIncludes": "compact",
        "commandIncludes": ["board check", "--hook-envelope"]
      }
    },
    {
      "id": "board-rule-in-claude-md",
      "label": "Board upkeep rule present in the agent CLAUDE.md",
      "sinceVersion": "0.1.68",
      "rationale": "The rule that the Status board moves with the work, and that pa board check passes before the session-end commit, must sit where the PA reads its operating rules, not only in a knowledge doc.",
      "probe": {
        "type": "file-includes",
        "path": "agents/{paName}/CLAUDE.md",
        "includes": ["pa board check"]
      }
    }
  ]
}
