Skip to content

/cairn-attention

Resolve Cairn's pending-attention queue inline (DEC drafts, baseline findings, drift events).

shell
$ npx -y skills add isaacriehm/cairn --skill cairn-attention --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/cairn-attention
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Resolve Cairn's pending-attention queue inline (DEC drafts, baseline findings, drift events).

SKILL.md

cairn-attention.SKILL.md
name: cairn-attention
description: Resolve Cairn's pending-attention queue inline (DEC drafts, baseline findings, drift events).
when_to_use: |
  Use when SessionStart flagged `attention_count > 0` — pending DEC
  drafts in `_inbox/`, baseline sensor findings, or drift from last
  GC sweep. Also chained from `cairn-adopt` Step 5 to drain fresh
  DEC drafts. Skip when operator in-flight on task or recent turn
  already deferred this surface.

Skill: cairn-attention

Host portability

This skill is shared by Claude Code, Cursor, and Codex. Resolve Cairn MCP tools with the host's native discovery mechanism. `AskUserQuestion` means the host's structured question UI; when that UI is unavailable, ask the identical concise A/B/C question in chat and pause. References to restarting a client mean restarting the active host.

You are surfacing Cairn's pending-attention queue inline so the operator can resolve drafts and findings without leaving the chat. Spec: `docs/PLUGIN_ARCHITECTURE.md` §11.

Step 0 — bootstrap preflight

Before surfacing any DEC choices, verify the clone is bootstrapped. SessionStart auto-runs `cairn join` when `core.hooksPath` is unset, so by the time this skill engages bootstrap should be wired. If `cairn_resolve_attention` still refuses with `BOOTSTRAP_REQUIRED`, SessionStart's auto-bootstrap failed — call `cairn_bootstrap_retry` once to retry inline. On `ok: true`, fall through to Step 0.7. On `ok: false`, surface the `failed_steps` list to the operator and end the turn (the `remediation` field of the error envelope cites this same tool plus an agent-client restart as the recovery paths). Never reference `cli.mjs` or `cairn join` directly in the chat surface — Plugin spec §11 forbids exposing CLI subcommands to the operator.

Step 0.2 — mission attention (phase_ready_to_exit + drift)

Before the regular attention queue, handle mission-specific surfaces. These don't go through `cairn_resolve_attention` — missions have their own resolver tool (`cairn_mission_advance`).

Preload the mission tools alongside the existing attention tools:

ToolSearch(select:mcp__plugin_cairn_cairn__cairn_mission_get,mcp__plugin_cairn_cairn__cairn_mission_advance,AskUserQuestion)

Then call:

cairn_mission_get({})

If `active: false`, skip this step.

0.2a — phase ready to exit

When the active phase's tasks all graduate under `exit_gate=prompt`, Cairn surfaces a phase-exit decision via one of two channels — both arrive as plain context, no red "Stop hook error" frame:

1. **MCP response (primary).** When the model itself calls `cairn_task_complete`, the response carries a structured `phase_ready_to_exit` block (mission_id, mission_title, phase_id, phase_title, exit_criteria). The model decides whether to surface an `AskUserQuestion` in the same turn — do so at a natural stopping point unless the operator is running autonomously. 2. **UPS additionalContext (auto-graduator fallback).** When the Stop-hook auto-graduator completes a task (attestation written without an explicit MCP call), it writes the pending hint to `.cairn/sessions/<id>/phase-ready-pending.json` and emits a `systemMessage` operator notice. The UserPromptSubmit hook reads the file on the next prompt and injects via `additionalContext`.

The hint fires exactly once per phase (the `ready_emitted` flag on `phase_progress` suppresses re-emission until the cursor advances or reopens). Surface a single `AskUserQuestion`:

> Phase `<active_phase_title>` looks done. Move on? > > Exit criteria: `<active_phase_exit_criteria>`. > > - `[a]` Mark phase done, advance to next phase > - `[b]` Keep working on this phase

Dispatch:

cairn_mission_advance({phase_id: "<active_phase>", choice: "exit" | "not_yet"})

When the mission's `exit_gate` is `auto`, the cursor already advanced silently (no prompt fires). When `manual`, the prompt is suppressed entirely — operator must invoke advance directly.

Render a one-line outcome after the call:

✓ Phase advanced (next: <next_phase>) · M/N done.

If `closed: true`, the mission auto-closed on last phase complete:

✓ Mission MIS-… complete. Archived.

0.2a.5 — pending mission resync

If `.cairn/missions/<id>/_resync.json` exists for the active mission, the operator amended the source spec doc. Read the marker file (`Read` tool — it's a small JSON), surface the diff via `AskUserQuestion`:

> Mission `<mission_id>` resync pending — spec at `<spec_path>` > proposes: > > - +<N> phase(s) added: `<id1>`, `<id2>` > - −<M> phase(s) removed: `<id3>` > - ↻<K> phase(s) renamed > - <P> phase(s) with new exit_criteria > > Pick: > > - `[a]` accept — rewrite roadmap.md, refresh spec.md, reconcile > phase_progress (added → pending, removed → dropped) > - `[b]` reject — delete the marker, keep roadmap.md unchanged

Dispatch via:

cairn_mission_resync_accept({outcome: "accept" | "reject"})

After the call, render a one-line outcome:

✓ Resync applied (+N −M ↻K). Cursor: <next_phase>.

If the marker file is missing, skip this sub-step.

0.2b — mission drift

If `mission_get` returned a non-empty `drift_phase_ids`, the operator edited `roadmap.md` mid-mission and removed phases that still have graduated task records in `state.json`. Surface a single block per drift id:

> Mission drift detected — phase `<id>` no longer in roadmap.md but > has graduated tasks linked. > > - `[a]` accept drift — drop phase from `phase_progress` (orphans > the linked task records; the tasks themselves remain in > `tasks/done/`). > - `[b]` restore phase to roadmap.md (operator edits the file by > hand; this option defers the prompt for 24h while they work). > - `[c]` defer 24h

Dispatch via `cairn_mission_advance({phase_id: "<drift_id>", choice: "drop"})` on `[a]` — `drop` removes the drifted entry from `phase_progress` and journals the resolution. The tool refuses `drop` when the phase is still present in roadmap.md (operato

Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withcairn

Persistent ground truth for AI coding agents. First-class support for Claude Code, Cursor, and Codex. Stop agents from drifting.

Get the whole plugin, auto-invoked
Stats
6
Stars
0
Views
1
Forks
Active
Maintenance
TypeScript
Language
MIT
License
4d ago
Last commit
3mo ago
Created

Repo: isaacriehm/cairn