# Self-Check Baseline

`manifest.json` is the **single source of truth** for how a ClaudeTools machine
should be wired. Every machine's `/self-check` grades itself against this file.
It is checked into the repo and syncs to all workstations via Gitea, so updating
it here updates the standard for the whole fleet.

## Why a checked-in manifest (the "how do we set a baseline" answer)

The fleet has architectural differences — Windows/macOS/Linux, amd64/arm64, boxes
with and without a local GPU for Ollama. We still want every machine to *behave*
the same. A checked-in manifest gives us that:

- **Required everywhere** lives in `required_*` keys. Missing = a real failure on
  any machine, regardless of OS.
- **Allowed-to-differ** lives in `capability_tools` + `capability_rules`. A capability
  being absent is never a failure — it selects a *fallback ruleset* so the machine
  knows how to behave without it (the canonical example: no local Ollama → use the
  remote endpoint; if that is down too, route Tier-0 work to haiku instead of
  blocking on it).

`identity.json` (per-machine, gitignored) carries the machine's actual coordinates
and capabilities. The manifest says what's required; identity says where things are
and what this box can do; the probe reconciles the two.

## How the baseline gets built (V1 census → ratified baseline)

The current `manifest.json` is **provisional** — generated from one known-good
machine (GURU-5070, 2026-06-02). It has not been confirmed against the fleet.
The build sequence:

1. `self-check.sh fanout` — ask every active instance to report.
2. Each machine runs `self-check.sh --publish` — publishes its census to coord as
   component `selfcheck_<host>`.
3. `self-check.sh aggregate` — reads them all back and proposes:
   - items present on **all** reporting machines → **required everywhere** candidates,
   - items present on **some** machines → **capability-gated** candidates.
4. Mike reviews the proposal and edits this `manifest.json` to ratify it, then
   flips `"status": "provisional"` to `"ratified"` and commits.

Until ratified, treat "extra"/"missing" skill and command findings as **candidates**,
not gospel.

## Manifest structure

| Key | Meaning |
|-----|---------|
| `schema_version`, `status` | manifest version; `provisional` or `ratified`. |
| `required_tools[]` | tools every machine must have on PATH (`name`, `why`). Missing = FAIL. |
| `required_python.any_of[]` | acceptable python launchers (`py`/`python3`/`python`). |
| `capability_tools[]` | optional tools; presence is INFO and toggles a `capability`. |
| `required_identity_fields[]` | dotted identity.json paths that must be set. |
| `required_scripts[]`, `required_hook_files[]` | repo files that must exist (+ executable). |
| `required_settings_hooks[]` | hooks that must be wired in settings.json (`event`, `command_contains`, `why`). |
| `git` | expected remote host, internal IP, post-commit-hook expectation. |
| `skills[]`, `commands[]` | the canonical skill dirs / command files. |
| `connectivity[]` | endpoints to probe (`required` ones FAIL if unreachable). |
| `capability_rules{}` | per-capability fallback behavior (the "different rules" for different hardware). |

## Editing rules

- Add a **required** item only when it should hold on *every* machine, every OS.
  If a Windows box legitimately can't have it, it's a capability, not a requirement.
- Every `capability_tools` entry needs a story for what to do without it — encode
  it in `capability_rules` (or reference an existing tier) so the probe can print
  the effective ruleset.
- Keep paths repo-relative and forward-slashed.
- After editing: commit + `/sync`. The fleet picks it up on next pull.
