# Protocols

A **protocol** in this repo is a reusable consent + invocation + error-handling contract for an external CLI tool consumed by two or more skills. Protocols centralize the "how do we talk to this tool?" surface so each consuming skill only has to handle the tool-specific call site, not the cross-cutting concerns of detection, consent, error handling, and version compatibility.

## Required Sections

Every protocol file MUST include the following sections:

- **Detection** — how a skill checks whether the tool is available (subshell command, exit code).
- **Consent** — the user-visible consent surface, including the `.forge/local.yaml` keys this protocol owns, the prompt copy, and the first-use setup behavior.
- **Invocation** — the command(s) used to call the tool, prompt/template structure, file-vs-inline rules, and timeouts.
- **Presentation / Error Handling** — how results are surfaced back to the user, and what happens when the tool fails, returns empty output, times out, or has corrupted config.
- **Constraints** — what the protocol does NOT do (lifecycle management, auto-suggestion, etc.).
- **Version Compatibility** — minimum tool version, pinned install source (commit SHA / release tag), and any breaking-change notes.

## Current Protocols

- **[codex.md](codex.md)** — Codex CLI integration (Verify / Takeover / Delegate modes) for review and build skills.
- **[graphify.md](graphify.md)** — Knowledge graph enrichment via the `/graphify` skill and `graphify` CLI for skills that benefit from architectural context.

## Intake Criteria

A new protocol file is justified only when ALL of the following hold:

1. The tool is **external** — invoked via subshell, not a forge-internal skill.
2. The tool is consumed by **two or more skills** — a single-skill caller belongs inline in that skill.
3. The tool has a **user-visible consent surface** — installation prompts, mode selection, or preference storage.

If any criterion fails, the integration belongs inline in the consuming skill, not as a shared protocol.

## `.forge/local.yaml` Merge Contract

Each protocol owns its own top-level namespace in `.forge/local.yaml`:

- `codex.md` owns the `codex:` namespace.
- `graphify.md` owns the `graphify:` namespace.

Writers MUST preserve other namespaces when writing to their own. Read-modify-write the whole file; do not truncate.

When a single namespace is corrupted (malformed YAML, unexpected types), the owning protocol resets only that namespace to its defaults and warns the user. Other namespaces are left untouched. If the whole file is unparseable, the protocol that detects it first resets the file to a minimal default with all known namespaces and warns the user.
