Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5f4687e
docs(plan): Plan v1 milestones, decisions D11-D18, scope and open que…
Oct 30, 2026
77d344c
docs(design): central server, review_by, 13-tool surface, hooks and CLI
Oct 30, 2026
5ca5df6
docs(contract): note the Plan v1 surface changes planned for M1
Oct 30, 2026
489ef7d
docs(contributing): add the Plan v1 engineering rules
Oct 30, 2026
b18efa9
docs(plan): correct the milestone-to-phase mapping
Oct 30, 2026
ff5a734
docs: correct built-state claims and Plan v1 review warnings
Oct 30, 2026
a5051ff
docs: milestone marker and status lines name M1 as current
Oct 30, 2026
1460f8e
docs(plan): milestones replace phases in §3 to §7
Oct 30, 2026
53d54b1
docs(design): central server, milestones and cut surface
Oct 30, 2026
bfa2ef4
docs(contract): milestone references replace phases
Oct 30, 2026
7127de4
docs(readme): operating record category, server required, rename planned
Oct 30, 2026
84f5a21
docs(wiki): milestones, decisions D11 to D18, one-server architecture
Oct 30, 2026
3e0e97b
github: milestone labels m1 to m8 and later; phase labels are history
Oct 30, 2026
c3fb79f
github: roadmap milestones M1 to M8 and Later, with issue mapping
Oct 30, 2026
b74e5e8
github: bootstrap sets a Milestone board field and reads phases from …
Oct 30, 2026
829c1ae
ci: comment names Later for release builds, not phase 10
Oct 30, 2026
27b8e9a
CHANGELOG: link the Plan v1 entry to PR #65
Oct 30, 2026
884f5ef
github: milestone is the built-in board field, not a custom one
Oct 30, 2026
cdc7e50
issue forms: milestone dropdown, decisions D11 to D18, bug environment
Oct 30, 2026
b51f599
ci: docs job named for what it checks
Oct 30, 2026
8ff21ce
docs(wiki): area:server description matches labels.json
Oct 30, 2026
59ba89d
docs: category line is an operating record for coding agents
Oct 30, 2026
af0ab09
docs(readme): serve, mcp and the CLI marked as planned with milestones
Oct 30, 2026
ba67e7d
docs(design): §5 intro points at §5.3 "The server"
Oct 30, 2026
677e12d
docs(wiki): M4, M7 and M8 have no epic yet
Oct 30, 2026
6803709
github: roadmap decision on placing cairn export project
Oct 30, 2026
53d9d6a
Roadmap: M1 children, stale comments for step 9
Oct 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
docs: correct built-state claims and Plan v1 review warnings
Fix round 1 of the step-3 review. DESIGN.md called the local MCP backend,
the session-start hook and the .cairn.toml server switch built. None is:
the local backend was designed (D2) and cut by D11 before it was built,
and session-start is designed with no milestone work row yet. Each site
now says so.

- CONTRACT: split the status note: tool removals and section=events in
  M1; directive cap and review_by in M2.
- PLAN §8: mark D10 superseded by the M1-M8 order; adoption line for
  D11-D18.
- CONTRIBUTING rule 2: CI test names --force, rm, reset, and any init
  other than cairn init, so it agrees with rule 7.
- One count phrasing everywhere: 13 tools plus the read tools recall and
  search (15 names). Open count question removed.
- PLAN: neutral wording for the local bishop-memory checkout; open
  question on M1's exit check against cairn serve.
- DESIGN §4 re-wrapped; §6.2 registrations via cairn enable in M4;
  §8 scopes marked unbuilt and admin dropped.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
  • Loading branch information
Donovan Maidens and claude committed Oct 30, 2026
commit ff5a73421dfbe0c9272c1106f6b0a206335e713a
8 changes: 5 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ Ten rules from Plan v1 (2026-10-30), added to the rules above.
before it is mentioned in docs. A migration never renames or removes its
source before import succeeds, and always has `--dry-run`.
2. **No destructive advice in error text.** A refusal names only a safe fix. A
CI test fails on `--force`, `rm`, `reset` or `init` in any error string.
CI test, not yet written, fails on `--force`, `rm`, `reset`, or any `init`
other than `cairn init`, in an error string.
3. **One source of truth.** Exports are exports; nothing reads an export back
except `import` on an explicit command.
4. **Hooks remind, tools record.** Every task-loop step the skill asks for has a
Expand All @@ -91,8 +92,9 @@ Ten rules from Plan v1 (2026-10-30), added to the rules above.
daily and the "waiting on you" count stays under 15.
7. **No silent identity.** Missing `project` or `server` is an error that names
`cairn init`.
8. **Small tool surface.** 13 tools, descriptions under 200 characters, every
non-obvious affordance shown by example in the skill text.
8. **Small tool surface.** 13 tools plus the read tools `recall` and `search`
(15 names), descriptions under 200 characters, every non-obvious affordance
shown by example in the skill text.
9. **Confirm plugin facts live.** Tool names and `CLAUDE_PROJECT_DIR` behaviour
are checked in a live session at M5 and on every Claude Code minor release.
10. **Rules live in core.** No rule in a handler, hook or skill that the
Expand Down
19 changes: 10 additions & 9 deletions docs/CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ approved.
request and result types, errors). The conformance suite checks the behaviour
described here.

> **Plan v1 (2026-10-30): planned for M1, not yet made.** The agent tool
> surface narrows as Plan v1 sets it out (the count is open; see
> [DESIGN.md](DESIGN.md) §4). `note_put`, `note_get`, `review_record` and
> `event_list` are to be removed, and `event_list` folds into `task_get` with
> `section=events`. The directive cap (12 per call, ranked, decision D16) is to
> be documented on `task_current` and `recall`. CLI equivalents per tool come
> with `internal/cli` in M4. These changes land in M1 with the code, because
> this contract, `internal/core` and `internal/conformance` change together.
> The sections below still describe the surface as it stands.
> **Plan v1 (2026-10-30): planned, not yet made.** The agent tool surface
> narrows as Plan v1 sets it out: 13 tools plus the read tools `recall` and
> `search` (15 names; see [DESIGN.md](DESIGN.md) §4). In M1, `note_put`,
> `note_get`, `review_record` and `event_list` are removed, and `event_list`
> folds into `task_get` with `section=events`. CLI equivalents per tool come
> with `internal/cli` in M4. The M1 changes land with the code, because this
> contract, `internal/core` and `internal/conformance` change together. In M2,
> the directive cap (12 per call, ranked, decision D16) and `review_by` arrive,
> and are then documented on `task_current` and `recall`. The sections below
> still describe the surface as it stands.

This document covers every tool in [DESIGN.md](DESIGN.md) §4, plus the
operator calls behind the web UI and the CLI. Field names are the JSON names
Expand Down
72 changes: 39 additions & 33 deletions docs/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ Cairn has four jobs:
- **One server.** Every client calls one `cairn serve` over HTTP, so a single
team or several machines share one place to look and back up *(decision
D11)*. `cairn mcp` and the CLI require `server` in `.cairn.toml` or
`CAIRN_SERVER`. Built today, the MCP adapter also opens a local database when
no server is set *(decision D2, superseded by D11)*; that path is removed in
M1.
`CAIRN_SERVER`. The local database path that D2 designed (the MCP adapter
opening a database when no server is set) was cut by D11 before it was built.
M1 builds the server-only adapter *(decision D2, superseded by D11)*.
- **The operator decides.** Agents propose findings and directives. Only the
operator accepts them. No tool lets an agent change a finding's status or
ratify a rule.
Expand Down Expand Up @@ -111,7 +111,7 @@ under the same name. Its full contents:

```toml
project = "acme-api" # required; lowercase letters, digits, hyphens
server = "https://cairn.lan:8787" # required from M1 (decision D11); today, absent means the local database
server = "https://cairn.lan:8787" # required from M1 (decision D11); D2's local database was never built
```

The API key never goes in this file. It comes from the plugin's secure option,
Expand Down Expand Up @@ -299,13 +299,13 @@ Tool names are short and unprefixed; the client adds the server prefix
(Claude Code: `mcp__plugin_cairn_cairn__task_start`). Each write tool takes
`agent`. Output is compact JSON or short text, designed to be read by a model.

Plan v1 (decision D14, D11) sets the agent surface for M1. The plan gives it as
13 tools; the table below names 15, the 13 plus `recall` and `search`, which
the plan lists as read tools. The count is open (PLAN.md §10). Until M1,
`event_list`, `review_record`, `note_put` and `note_get` still exist; M1
removes them, and `event_list` folds into `task_get` (`section: events`). Each tool also has a CLI command over the same HTTP API
(`internal/cli`, M4), which is how every harness other than Claude Code reaches
Cairn.
Plan v1 (decisions D11 and D14) sets the agent surface for M1: 13 tools plus
the read tools `recall` and `search` (15 names). The table below lists all 15.
Until M1, the contract and `internal/core` still carry `event_list`,
`review_record`, `note_put` and `note_get`, and no MCP tool wraps them yet. M1
removes them, and `event_list` folds into `task_get` (`section: events`). Each
tool also has a CLI command over the same HTTP API (`internal/cli`, M4), which
is how every harness other than Claude Code reaches Cairn.

| Tool | Purpose |
|---|---|
Expand Down Expand Up @@ -335,9 +335,10 @@ context: the active task (title, next action, current step), the count of
directives that apply, and one line telling the agent to call `task_current`.
When no task is active it says so in one line. It writes nothing.

Plan v1 (decision D15) sets three hooks: `session-start`, which is built, and
`pre-compact` and `stop`, which are planned for M4. `cairn enable --agent`
installs all three.
Plan v1 (decision D15) sets three hooks: `session-start`, `pre-compact` and
`stop`. `session-start` is designed and not yet built; PLAN.md §3 does not yet
place it in a milestone's work row. `pre-compact` and `stop` are planned for M4.
`cairn enable --agent` installs all three.

- `pre-compact` (planned, M4) prints the active task, the current step, the
next action and the directive count, so a task loop survives compaction.
Expand All @@ -346,8 +347,9 @@ installs all three.

## 5. Architecture

The target after M1: one server, no local backend. Built today, `cairn mcp`
also has the local backend (§5.3).
The target after M1: one server, no local backend. The local backend in §5.3
was designed under D2 and cut by D11 before it was built. M1 builds the
server-only adapter.

```
┌──────────── project ─────────────┐
Expand Down Expand Up @@ -411,19 +413,21 @@ any other backend. A behaviour exists when the conformance suite says so.

### 5.3 Local and remote backends

- **Local (built today; removed in M1, decision D11):** `cairn mcp` opens
`~/.local/share/cairn/cairn.db` (or `CAIRN_DB`) in WAL mode with a busy
timeout. Several MCP processes on one machine share it safely. Task-id
allocation is one transaction. No daemon is needed. `cairn serve` on the same
database shows the web UI. From M1, `cairn mcp` refuses to start without a
`server`, and this backend is no longer a client option. The store stays
inside `cairn serve`.
- **Local (designed under D2; cut by D11 before it was built):** the design had
`cairn mcp` open `~/.local/share/cairn/cairn.db` (or `CAIRN_DB`) in WAL mode
with a busy timeout, so several MCP processes on one machine would share it.
Task-id allocation is one transaction in the store, which is built. No daemon
would be needed, and `cairn serve` on the same database would show the web UI.
D11 removes this path before it exists: `cairn mcp` refuses to start without a
`server` (M1), and this backend is not a client option. The store stays inside
`cairn serve`.
- **Remote:** `cairn mcp` sends each call to `cairn serve` with the API key.
Used for a home server, a team, or several machines, and the only client
backend from M1.

Today, switching is one line in `.cairn.toml` or one environment variable. A
project's data does not move automatically; `cairn serve` can be pointed at
Under D2 (designed, never built), switching would have been one line in
`.cairn.toml` or one environment variable. D11 removes the choice. A project's
data does not move automatically; `cairn serve` can be pointed at
the local database file to make it the server's.

## 6. Clients
Expand All @@ -441,7 +445,8 @@ plugins/claude-code/
bin/cairn-launch finds the cairn binary; if missing, exits
with the one-line install command
hooks/hooks.json SessionStart → cairn hook session-start
(built); PreCompact and Stop → cairn hook
(designed, not yet built; milestone not set in
PLAN §3); PreCompact and Stop → cairn hook
pre-compact and stop (planned, M4, D15)
skills/cairn/SKILL.md how to work with Cairn: the task loop below
commands/init.md /cairn:init → cairn init
Expand Down Expand Up @@ -471,7 +476,8 @@ rules, written in terms of the same tools.
Plan v1 (decision D14) gives every client other than Claude Code the CLI over
the same HTTP API (`internal/cli`, planned for M4). Bash is enough for that, so
no per-harness plugin is needed in v1. The rows below are the per-client
registrations; they are deferred to Later, with per-harness plugins.
registrations. They come through `cairn enable` in M4 (OpenCode and Pi
experimental, as PLAN.md §3 sets out). Per-harness plugins are Later.

| Client | Registration | Instructions | Notes |
|---|---|---|---|
Expand Down Expand Up @@ -509,14 +515,14 @@ status; they only recommend.

## 8. Security

- Local mode listens on nothing, and the database file is the user's. Built
today; removed in M1 with local mode (D11).
- Local mode (D2) was designed and cut by D11 before it was built. Its design
listened on nothing and kept the database file under the user's control.
- `cairn serve` binds loopback by default and refuses to bind anything else
without at least one API key. TLS by certificate files or behind a proxy.
- API keys are stored hashed. Scopes: `agent` (the MCP tools), `operator`
(decisions and ratification), and `viewer` (read-only on every route; planned
for M2 with a test that a viewer key gets 403 on every write). Plan v1
(decision D13) replaces the earlier agent and operator scopes plus admin.
- API keys are stored hashed. Three scopes, none built yet: `agent` (the MCP
tools), `operator` (decisions and ratification), and `viewer` (read-only on
every route; planned for M2 with a test that a viewer key gets 403 on every
write). Plan v1 (decision D13) drops the `admin` scope from the design.
- An agent key cannot reach operator routes. The web UI asks for an operator
key. A viewer key sees every page and gets 403 on every action (planned, M3).
- Request bodies are capped on every route.
23 changes: 13 additions & 10 deletions docs/PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ What Cairn is and how it works is in [DESIGN.md](DESIGN.md).

## 1. Where this comes from

Cairn replaces [bishop-memory](https://github.com/djm56/bishop-memory) (local
checkout `/Users/djm56/bishop-memory`). bishop-memory works, and it holds the
Cairn replaces [bishop-memory](https://github.com/djm56/bishop-memory) (a local
bishop-memory checkout). bishop-memory works, and it holds the
operator's history: missions, findings, directives and grades. It was built
around one harness, Bishop, and around one idea: the harness writes Markdown
files and the service imports them.
Expand Down Expand Up @@ -173,9 +173,8 @@ Tool surface after the cuts: `task_current`, `task_start`, `task_get`,
`task_list`, `task_update`, `task_close`, `step_plan`, `step_add`,
`step_update`, `event_log`, `learning_add`, `learning_list`, `directive_list`,
plus `recall` and `search` as read tools. `event_list` folds into `task_get`
with `section: events`. The plan gives this surface as 13 tools, but the list
names 15: the 13 above, and `recall` and `search`. Whether the count is 13 or
15 is open (§10).
with `section: events`. That is 13 tools plus the read tools `recall` and
`search` (15 names).

### After v1

Expand Down Expand Up @@ -340,11 +339,14 @@ v1's decisions table.
hook text and install guide. *Recommended.*
- **D10. Build from the outside in**, in the order in §2: contract, core,
MCP, plugin, server, UI, migration, review loop. *Recommended; confirmed
by the operator 2026-10-27.*
by the operator 2026-10-27.* **Superseded by the M1–M8 order in §2**
(Plan v1, 2026-10-30); kept as the record.

Plan v1 (2026-10-30) adds D11–D18. Each row names what it replaces and why.
D2 and D8 are marked superseded above; the other rows replace something that
is not a numbered decision here, and the table says what.
D2, D8 and D10 are marked superseded above; the other rows replace something
that is not a numbered decision here, and the table says what.

**Adopted 2026-10-30 by the operator (Plan v1): D11–D18.**

- **D11. Central server only.** `cairn mcp` and the CLI require a `server` in
`.cairn.toml` or `CAIRN_SERVER`; no local database path for clients.
Expand Down Expand Up @@ -407,5 +409,6 @@ is not a numbered decision here, and the table says what.
- [ ] Do viewers see proposed learnings, or only ratified directives?
- [ ] Keep "Cairn" as the only name, or give the tool a separate internal name?
- [ ] Rename to `cairn` now (one PR, before M1) or after M8?
- [ ] Is the agent tool surface 13 tools or 15? Plan v1 gives 13 and lists 15
(see Scope of v1).
- [ ] M1's exit check runs against `cairn serve`, which M2 builds. Does M1 move
`internal/client` and a serve skeleton into M1, or does it test against an
in-process test server?