---
name: project-skill-protocol
version: 1.0.0
description: '[Utilities] Use when a project needs to add, change, list, or remove its OWN protocol rules layered on top of a framework skill — a named overlay of extra project rules that applies whenever the targeted skill runs, stored with the project rather than in the portable framework. `/project-skill-protocol list` prints every overlay with its target and description; `add` drafts a new overlay and confirms it before writing; `update` applies a surgical change; `delete` removes it. Overlays are ADDITIVE ONLY — they never replace, override, or waive anything the skill already does. Triggers: skill protocol, project protocol, custom protocol for skill, extend a skill, overlay rules, add rules to a skill, project rules for skills, skill protocol overlay.'
---

## Quick Summary

**Goal:** Give a project a registry of named **protocol overlays** — extra project rules layered onto framework skills — with create / read / update / delete over that registry, so a skill picks up this project's conventions on every run **without the portable framework being edited**.

**Summary:** read-this-if-nothing-else digest —

- **Two files, two jobs.** The INDEX (`docs/project-reference/skill-protocols-reference.md`) holds target + scope + name + description and is what resolution reads. The BODY (`docs/project-protocols/<slug>.md`) holds the actual rules and is read only for a MATCHED target. Never bulk-read bodies.
- **ADDITIVE ONLY — the rule that governs every other rule.** An overlay ADDS rules on top of a skill's protocol; it never replaces, overrides, disables, or reinterprets one. Invariant: removing every overlay returns each skill to exactly its documented behavior.
- **Resolution is specificity-based, not order-based.** `exact` > `glob` > `*`, winner tier takes all — and that ordering ranks overlays against EACH OTHER, never against the skill.
- **Project payload, not framework.** Overlays live under `docs/`, never `.claude/`. A rule that stabilizes and generalizes gets PROMOTED to a real skill via `/skill-creator`.
- **ADD authors the best version, then confirms it.** The user's raw wording is raw material, NEVER the artifact. Infer intent, generalize past the incident, draft the body, then run the rules through **`/prompt-enhance`** and the prompt-engineering rubric (imperative · observable · decidable · one rule per line · carries its WHY) — an overlay is an AI instruction that fires unattended, so a vague rule is a nondeterministic one. Show what changed and why, and always offer "save my wording verbatim".
- **Three writes, one turn — then the mirror.** Body + index row + the `CLAUDE.md` `CK:PROJECT-PROTOCOLS` block, then AUTO-RUN the Codex mirror sync (`node .claude/skills/sync-codex/scripts/run-codex-sync.mjs`) so `AGENTS.md` never lags behind the block. Report the sync's real outcome. Never commit.

**Workflow:**

1. **Resolve mode** — parse the invocation into `list` | `add` | `update` | `delete` (Phase 0)
2. **Load contract + index** — read `references/registry.md`, then the index; empty registry branches early
3. **Execute mode** — LIST (Phase 1) · ADD (Phase 2) · UPDATE (Phase 3) · DELETE (Phase 4)
4. **Three writes** — body, index row, and the `CLAUDE.md` block, all in the same turn
5. **Sync the mirror** — auto-run `node .claude/skills/sync-codex/scripts/run-codex-sync.mjs` so Codex sees the overlay
6. **Report** — state every path touched AND the sync outcome (pass, or the failing stage); never commit

**Key Rules:**

**MUST ATTENTION** resolve the mode FIRST — a leading `list`/`add`/`update`/`delete` token is a MODE; ambiguous → ask, never guess
**MUST ATTENTION** an overlay is ADDITIVE ONLY and is a brief, not an authority escalation — it can never waive the WORKFLOW-GATE, git discipline, a review gate, or a user-confirmation gate
**MUST ATTENTION** ADD/UPDATE run the drafted rules through `/prompt-enhance` + the prompt-engineering rubric BEFORE the additive-only screen — the deliverable is a precise AI instruction, never a transcription of the request
**MUST ATTENTION** ADD ends at a PROPOSAL GATE — NEVER write a draft the user has not seen, and always offer "save my wording verbatim"
**MUST ATTENTION** every write touches the body AND the index row AND the `CLAUDE.md` block in the SAME turn — a stale block leaves Codex blind to the overlay
**MUST ATTENTION** every write mode ENDS by auto-running the mirror sync, then reports its ACTUAL result — a failed pipeline is reported as a failure with the stage named, never as a completed sync
**MUST ATTENTION** never overwrite on a `Target`+`Scope` collision — ask update-vs-create

**Be skeptical. Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence percentages (Idea should be more than 80%).**

---

# Project Skill Protocol (project overlay registry)

## Storage Contract

| Artifact             | Path                                                                                     | Written by      | Read when                                       |
| -------------------- | ---------------------------------------------------------------------------------------- | --------------- | ----------------------------------------------- |
| **Index**            | `docs/project-reference/skill-protocols-reference.md`                                    | this skill only | every invocation, and whenever overlays resolve |
| **Bodies**           | `docs/project-protocols/<slug>.md`                                                       | this skill only | only for a MATCHED target                       |
| **Cross-host block** | `CLAUDE.md` between `<!-- CK:PROJECT-PROTOCOLS -->` and `<!-- /CK:PROJECT-PROTOCOLS -->` | this skill only | by both hosts, every session                    |

Path resolution order (stop at first hit):

1. `docs/project-config.json` → `referenceDocs[]` entry whose `filename` is `skill-protocols-reference.md` (portability override)
2. The `**Protocols directory:**` line in the index doc header (the index is self-describing about where bodies live)
3. The defaults in the table above

The index doc is auto-created on SessionStart by `session-init-docs.cjs` (registered in `.claude/hooks/lib/session-init-helpers.cjs` → `DEFAULT_REFERENCE_DOCS`). Because that entry declares a `templatePath`, the hook copies `.claude/templates/reference-docs/skill-protocols-reference.md` **verbatim** — it does NOT emit the generic `PLACEHOLDER_MARKER`. So a fresh install has exactly one table row: the sentinel `_(none yet)_`. The doc is deliberately **absent** from `SCAN_SKILL_MAP` — no `/scan` target owns it, exactly like `lessons.md` is owned by `/learn` and `custom-prompts-reference.md` by `/custom-prompt`.

**Empty-registry test (use this everywhere).** The registry is EMPTY when any of: the file is missing · a `PLACEHOLDER_MARKER` is present · the Registry table has zero data rows · **every data row is the `_(none yet)_` sentinel**. Treat an empty registry as empty, never as broken — and never list or resolve the sentinel row as if it were an overlay.

The full overlay-file contract (frontmatter fields, required sections, index row format, targeting grammar, precedence algorithm, conflict rules, token bounds) lives in **`references/registry.md`** — **read it before any write, and before answering any resolution question.**

---

## Phase 0: Resolve Mode (BLOCKING — before any file read)

Parse the invocation text. An explicit flag always wins; otherwise the **leading token** decides.

| Invocation                                   | Mode                                                                         |
| -------------------------------------------- | ---------------------------------------------------------------------------- |
| `--mode={list\|add\|update\|delete}`         | that mode, verbatim — no inference                                           |
| empty, `list`, `ls`, `show`, `all`           | **LIST**                                                                     |
| leading `add`, `create`, `new`, `save`       | **ADD**                                                                      |
| leading `update`, `edit`, `change`, `revise` | **UPDATE**                                                                   |
| leading `delete`, `remove`, `drop`           | **DELETE**                                                                   |
| anything else                                | **ADD**, but only after the ambiguity gate confirms it is not a list request |

**Ambiguity gate (BLOCKING).** A leading write-verb that is plausibly part of the rule text (`/project-skill-protocol add a context tag to every review finding` — where "add a context tag …" is itself the rule) → do NOT pick silently. `AskUserQuestion`: _"Create a new overlay whose rule is '…'"_ vs _"Show the overlays already defined"_. — why: the two readings write to different files, and guessing wrong either creates registry junk or silently skips the user's real request.

There is deliberately **no MATCH mode.** Matching happens at skill-invocation time via the `CLAUDE.md` block, the `SYNC:project-protocol-overlay` reminder, and the Plane-3 hook — all three implementing `references/registry.md` §3. A fourth resolution path here could disagree with them. — why: two resolvers that can disagree is the exact drift class this registry exists to avoid.

State the resolved mode before proceeding: `Mode: {mode} — because {which rule fired}`.

---

## Phase 1: LIST

1. Read the index. Registry EMPTY by the Storage Contract test → report _"No protocol overlays defined yet"_ and show the one-line add syntax. STOP — do not invent examples.
2. Print every entry as a table: **Target** · **Scope** · **Name** · **Description** · **Updated** · **Body file**.
3. Preserve index order; do not re-sort, re-word, or summarize descriptions — the user wrote them.
4. Close with the total count and the invocation forms (`/project-skill-protocol add …`, `update <name>: …`, `delete <name>`).
5. Past the ~30-row soft cap, warn and propose promoting stable, project-independent overlays to real skills via `/skill-creator`.

LIST reads the index ONLY. Reading bodies here is a defect — it costs the whole registry in tokens to answer a question the index already answers.

---

## Phase 2: ADD

**Never store the user's raw wording as-is.** An add request is raw material; the deliverable is the best version of the overlay the user was reaching for. Author it, then get it confirmed.

1. **Infer the rule intent.** State what would be observably different on a run of the targeted skill once this overlay applies. Too thin to infer an observable difference (a bare topic, a mood) → ask ONE clarifying question before drafting; never invent a rule to fill the template.
2. **Resolve the target and scope.** Which skills should this apply to — one named skill (`exact`), a family (`glob`, e.g. `*-review`), or everything (`all`, target `*`)? Not stated → ask; do not default to `*`. — why: `*` is the widest possible blast radius and the tier a user is least likely to have meant.
3. **Generalize.** Climb from the incident to the standing convention — strip ticket IDs, dates, one-off paths, and today's specifics. An overlay fires on every future invocation of its target, not only on the case in front of you.
4. **Draft the body** into the template in `references/registry.md` §1: `## Applies to` · `## Rules` (imperative, observable, one-clause WHY each) · `## Rationale` · `## Out of scope`, plus the required frontmatter.
5. **Prompt-engineering pass (BLOCKING — the deliverable is an AI instruction, not a note).** An overlay body is a PROMPT: it is injected into a live run and the model must obey it without the author present to clarify. Run the drafted `## Rules` through **`/prompt-enhance`** and apply its result.

    Scope it to the RULES text — do NOT restructure the overlay into a skill file (no `Quick Summary`, no `Closing Reminders`; the body template in §1 is the shape). Take from `prompt-enhance`: caveman compression of the prose, then attention anchoring, with its hard constraint that **rule density must not drop and no rule, constraint, or `file:line` evidence may be lost.**

    Then hold every rule against this rubric, rewriting until each one passes:

    | Test                                                                                              | Reject                                                     | Prefer                                                      |
    | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ----------------------------------------------------------- |
    | **Imperative**                                                                                    | "it would be good if findings had context"                 | "Tag every finding with its bounded context"                |
    | **Observable** — a reader can tell from the output whether it was followed                        | "be thorough"                                              | "Cite `file:line` for every claim"                          |
    | **Decidable** — no vague qualifier the model must guess at                                        | "reasonably", "appropriate", "as needed", "where possible" | a named threshold, list, or condition                       |
    | **Positive form** — say what to DO, not only what to avoid                                        | "don't skip the schema"                                    | "Read the schema first, then …"                             |
    | **Self-contained** — no pronoun pointing outside the body, no "as discussed", no ticket reference | "apply the rule from the standup"                          | the rule, stated                                            |
    | **One rule per line** — a compound rule half-fires                                                | "Validate input and log it and alert"                      | three numbered rules                                        |
    | **Carries its WHY in one clause**                                                                 | bare directive                                             | "… — why: a silent failure here is invisible until release" |
    | **Triggerable** — states WHEN it applies if not always                                            | "use the strict parser"                                    | "When the payload is user-supplied, use the strict parser"  |

    — why: an overlay fires unattended on every future run of its target. A vague rule is not a weak rule, it is a **nondeterministic** one: the model resolves the ambiguity differently each run, so the overlay produces inconsistent behavior that reads like a model defect rather than an authoring defect. Precision at authoring time is the only point where that is cheap to fix.

    **This pass never adds authority.** It sharpens wording only — it may not broaden a rule's target, escalate its force, or introduce a rule the user did not ask for. Anything it adds beyond rephrasing is surfaced at the gate under _what you changed and why_.

6. **Additive-only screen (BLOCKING).** Read every drafted rule against the targeted skill's own protocol. Any rule that would ignore, skip, replace, relax, disable, or reinterpret a framework rule — or that would waive the WORKFLOW-GATE, git discipline, a review gate, or a user-confirmation gate — is **REFUSED**: drop that line from the draft and name it at the gate as refused, with the reason. The remaining rules proceed. — why: a stored overlay is a persistent instruction; an override rule turns the registry into a standing bypass of every safety control in the harness.
7. **Target-collision check (BLOCKING).** An existing index row with the same `Target` **and** `Scope` → `AskUserQuestion`: _update the existing `<name>`_ vs _create a second overlay for the same target_. NEVER overwrite silently. — why: silent overwrite destroys a body the user cannot recover from the index.
8. **Contradiction pre-check (BLOCKING).** Resolve the draft's target per `references/registry.md` §3 and compare its rules against every overlay that would land in the SAME tier. A direct contradiction → surface BOTH rules to the user and let them choose; never resolve it yourself, and never write an overlay you know contradicts a live one without saying so.
9. **PROPOSAL GATE (BLOCKING).** Present the draft before writing anything to disk:
    - the proposed **name**, **target**, **scope**, and **description**, each on its own line
    - the drafted **rules** in full — the user is approving content, not a summary
    - **which skills this will actually match**, resolved and listed by name, so the blast radius is visible rather than inferred
    - **what you changed and why** — one line per substantive edit, plus anything you ADDED that the user never said
    - **the prompt-engineering rewrite**, where step 5 changed the user's phrasing: show the user's wording and yours side by side for any rule whose MEANING could be read differently, so an over-eager rewrite is caught here rather than at the next run
    - **any rule you REFUSED** under step 6, quoted, with the reason
    - **open assumptions** you had to make

    Then `AskUserQuestion` with: _Save the improved version (Recommended)_ · _Let me correct the name/target/scope first_ · _Save my wording verbatim instead_ · _Cancel_.

    **NEVER write a draft the user has not seen.** — why: an overlay changes how a skill behaves on every future run; an unreviewed rewrite silently substitutes your inference for the user's intent, and the divergence only surfaces later when the skill does the wrong thing.

10. **Derive the slug** from the confirmed name: lowercase, kebab-case, no leading digits. Collision after step 7 → suffix `-2`, `-3`.
11. **Perform the three writes, in the same turn** (see [Three Writes](#three-writes-one-turn)).
12. Report every path written. **Do not commit** — report and stop.

---

## Phase 3: UPDATE

1. Resolve the target overlay by exact name; no exact hit → list the close matches and confirm which one.
2. **Read the existing body first.** Never regenerate from the index row.
3. Apply steps 1–9 of Phase 2 **scoped to the requested change only** — including the additive-only screen on any new or edited rule.
4. **Surgical diff, not a rewrite.** Every section the user did not ask to change is preserved byte-identically. — why: an update is not a re-authoring; silently regenerating untouched sections discards refinements made by hand.
5. Bump `version` — patch for wording, minor for a changed rule, major for a changed `target`/`scope`/purpose — and set `updated` to today.
6. A changed `target` or `scope` re-runs the target-collision and contradiction pre-checks against the NEW tier before the gate.
7. Perform the three writes. Report the paths. Do not commit.

---

## Phase 4: DELETE

1. Resolve the target by exact name; no exact hit → list the close matches and confirm which one.
2. `AskUserQuestion` to confirm, showing the **description, target, and body path** being removed.
3. Delete the body file, remove the index row, and refresh the `CLAUDE.md` block — same turn.
4. When the removal empties the registry, restore BOTH empty states — they use different literals and are not interchangeable: the index table gets its `_(none yet)_` sentinel row back, and the block's last line becomes exactly `Active overlays: _(none)_`. Never leave a table header with no rows.
5. Auto-run the mirror sync (§ _After the three writes_), then report all three removals plus the sync outcome. Do not commit.

---

## Three Writes, One Turn

Every write mode (ADD, UPDATE, DELETE) touches exactly these three carriers, together:

| #   | Carrier                                     