@cairnkeep/cli 2.8.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/README.md +82 -27
  3. package/bin/cairn +6 -153
  4. package/bin/cairn-container +8 -0
  5. package/docs/building-an-overlay.md +41 -4
  6. package/docs/containers.md +10 -0
  7. package/docs/context-packs.md +94 -0
  8. package/docs/harness-compatibility.md +37 -3
  9. package/docs/learning/CURRICULUM-MAP.md +16 -5
  10. package/docs/learning/FEATURE-GUIDE.md +15 -4
  11. package/docs/learning/README.md +8 -2
  12. package/docs/learning/lessons/L00-why-cairnkeep.md +1 -1
  13. package/docs/learning/lessons/L01-safe-trial.md +3 -3
  14. package/docs/learning/lessons/L02-installation.md +11 -2
  15. package/docs/learning/lessons/L03-first-project.md +1 -1
  16. package/docs/learning/lessons/L19-validated-skill-improvement.md +52 -21
  17. package/docs/learning/lessons/L20-mcp-tool-profiles.md +67 -0
  18. package/docs/learning/lessons/L21-context-packs.md +79 -0
  19. package/docs/learning/lessons/L22-native-windows.md +83 -0
  20. package/docs/learning/lessons/L23-guided-setup.md +138 -0
  21. package/docs/learning/tracks/operator.md +10 -3
  22. package/docs/learning/tracks/quickstart.md +7 -3
  23. package/docs/mcp-tool-profiles.md +43 -0
  24. package/docs/native-windows.md +122 -0
  25. package/docs/operating.md +157 -18
  26. package/docs/privacy-and-data-flow.md +51 -1
  27. package/docs/storage.md +29 -0
  28. package/examples/eval/bundled-fake.json +1 -1
  29. package/mcp-memory-server/dist/artifact-store-windows-worker.js +74 -0
  30. package/mcp-memory-server/dist/artifact-store.js +196 -55
  31. package/mcp-memory-server/dist/capability-cli.js +2 -1
  32. package/mcp-memory-server/dist/capability-config.js +4 -3
  33. package/mcp-memory-server/dist/capability-harness.js +34 -7
  34. package/mcp-memory-server/dist/context-pack-cli.js +185 -0
  35. package/mcp-memory-server/dist/context-pack.js +889 -0
  36. package/mcp-memory-server/dist/eval-cli.js +6 -5
  37. package/mcp-memory-server/dist/eval-plan.js +35 -13
  38. package/mcp-memory-server/dist/eval-process.js +11 -4
  39. package/mcp-memory-server/dist/eval-report.js +8 -5
  40. package/mcp-memory-server/dist/eval-runner.js +2 -0
  41. package/mcp-memory-server/dist/eval-schema.js +1 -0
  42. package/mcp-memory-server/dist/graph-cli.js +7 -1
  43. package/mcp-memory-server/dist/index.js +87 -37
  44. package/mcp-memory-server/dist/mcp-tool-catalog.js +47 -0
  45. package/mcp-memory-server/dist/mcp-tool-cli.js +85 -0
  46. package/mcp-memory-server/dist/mcp-tool-profile.js +164 -0
  47. package/mcp-memory-server/dist/note-store.js +12 -3
  48. package/mcp-memory-server/dist/pi-mcp-bridge.js +185 -0
  49. package/mcp-memory-server/dist/platform-security.js +102 -0
  50. package/mcp-memory-server/dist/skill-store.js +27 -12
  51. package/mcp-memory-server/package.json +4 -1
  52. package/package.json +5 -4
  53. package/pi/extensions/cairnkeep-memory.ts +61 -0
  54. package/schemas/cairnkeep-setup-policy.schema.json +55 -0
  55. package/schemas/cairnkeep-setup.schema.json +36 -0
  56. package/schemas/context-pack.schema.json +33 -0
  57. package/schemas/eval-report.schema.json +1 -0
  58. package/scripts/cairn-cli.mjs +119 -0
  59. package/scripts/cairn-container-cli.mjs +121 -0
  60. package/scripts/cairn-hook.mjs +199 -0
  61. package/scripts/completion.sh +33 -5
  62. package/scripts/doctor.sh +96 -0
  63. package/scripts/fix-permissions.mjs +12 -0
  64. package/scripts/memory-wiki-audit.mjs +95 -0
  65. package/scripts/phase26-test-manifest.mjs +26 -0
  66. package/scripts/run-repository-tests.mjs +76 -0
  67. package/scripts/setup-core.mjs +310 -0
  68. package/scripts/setup-reconcile.mjs +331 -0
  69. package/scripts/setup.mjs +306 -0
  70. package/scripts/sync-pi-assets.sh +19 -4
  71. package/scripts/test-cli-dispatch.sh +6 -0
  72. package/scripts/test-completion.sh +44 -0
  73. package/scripts/test-doctor.sh +66 -0
  74. package/scripts/test-learning-docs.sh +53 -3
  75. package/scripts/test-package-install.sh +81 -0
  76. package/scripts/test-phase17-artifact-lifecycle.sh +1 -1
  77. package/scripts/test-phase18-capability-lifecycle.sh +1 -1
  78. package/scripts/test-pi-lifecycle.mjs +190 -0
  79. package/scripts/test-setup-compatibility.mjs +186 -0
  80. package/scripts/test-setup-output.sh +131 -0
  81. package/scripts/test-setup-overlay.sh +113 -0
  82. package/scripts/test-setup-preflight.mjs +281 -0
  83. package/scripts/test-setup-reconcile.mjs +257 -0
  84. package/scripts/test-uninstall.sh +71 -0
  85. package/scripts/test-windows-native.mjs +136 -0
  86. package/scripts/uninstall.sh +95 -7
  87. package/scripts/verify-pi-mcp-bridge.mjs +588 -0
  88. package/scripts/windows-platform.mjs +725 -0
  89. package/templates/env.example.template +11 -0
@@ -0,0 +1,138 @@
1
+ # L23 - Guided setup and Pi memory
2
+
3
+ **Status:** Ready
4
+ **Track:** Quickstart and Operator
5
+ **Time:** 35 minutes
6
+ **Tested with:** Cairnkeep 2.11.0; Pi 0.84.1; Node.js 22, 24, and 26
7
+
8
+ ## Outcome
9
+
10
+ You can classify a missing or empty target, replay setup without a TTY, explain
11
+ the limitations of Git-less mode, verify Pi's local stdio memory bridge, and
12
+ recover or uninstall every managed asset without hidden machine changes.
13
+
14
+ ## Prerequisites
15
+
16
+ - Node.js 22 or newer, npm, and Git for the main exercise.
17
+ - Pi 0.84.1 or newer.
18
+ - A disposable parent directory containing no credentials, secrets, private
19
+ state, or identifying project data.
20
+
21
+ ## Exercise
22
+
23
+ Start with a missing target. The explicit flags make this deterministic and
24
+ safe to replay from a non-interactive or non-TTY process:
25
+
26
+ ```bash
27
+ lab=/tmp/cairnkeep-guided-setup-lab
28
+ cairn setup "$lab" --git init --harness pi --memory local --yes
29
+ cd "$lab"
30
+ cairn doctor
31
+ ```
32
+
33
+ Setup performs its classification before it creates `.ai`, `.planning`, or
34
+ `.agentfs`. It initializes Git only because `--git init` authorizes that action,
35
+ records the selected Pi harness in private `.ai/cairnkeep.json`, and reports
36
+ created, updated, unchanged, and skipped assets. Repeating the same `cairn
37
+ setup` command should report the managed files as unchanged.
38
+
39
+ Project setup never changes the Pi installation. Apply and check machine assets
40
+ explicitly, then diagnose the project again:
41
+
42
+ ```bash
43
+ cairn sync-pi --apply
44
+ cairn sync-pi --check
45
+ cairn doctor
46
+ ./.ai/start-pi.sh
47
+ ```
48
+
49
+ In the disposable Pi session, list the registered Cairnkeep tools and make one
50
+ harmless read-only memory call. The extension starts `cairn memory-server` as a
51
+ local stdio child in this project; it does not select HTTP or a remote server.
52
+ Cancel one in-flight call and confirm a later read still works. Exit Pi normally
53
+ and confirm shutdown completes rather than leaving a memory-server child
54
+ running. Cancellation is per call and an awaited session shutdown owns child
55
+ termination.
56
+
57
+ The bridge discovers the effective server catalog. Full, read-only, and custom
58
+ MCP profiles therefore expose only the tools allowed by the server. It preserves
59
+ tool names, stable order, input and output schemas, original content,
60
+ `structuredContent`, `_meta`, and the exact Phase 21 annotations in trusted
61
+ bridge metadata and result `details`. Pi 0.84.1 has no native annotations field
62
+ in its public tool API: do not interpret this preservation as native
63
+ model-facing annotation propagation and do not invent such a field.
64
+
65
+ To see the intentional Git-less boundary in another empty disposable target:
66
+
67
+ ```bash
68
+ limited=/tmp/cairnkeep-guided-setup-limited
69
+ cairn setup "$limited" --git none --harness pi --memory local --yes
70
+ cd "$limited"
71
+ cairn doctor
72
+ ```
73
+
74
+ The result is `limited`, not `complete`. Launchers and local stdio memory remain
75
+ available, but repository-identity and Git-dependent features do not. An
76
+ existing non-Git tree is never initialized without explicit `--git init`.
77
+
78
+ ## Recovery exercise
79
+
80
+ Delete one setup-owned launcher only in the disposable project, diagnose it,
81
+ then replay the exact recovery command:
82
+
83
+ ```bash
84
+ cd /tmp/cairnkeep-guided-setup-lab
85
+ rm .ai/start-pi.sh
86
+ cairn doctor
87
+ cairn setup . --git init --harness pi --memory local --yes
88
+ cairn sync-pi --apply
89
+ cairn sync-pi --check
90
+ cairn doctor
91
+ ```
92
+
93
+ Doctor reports project-state drift separately from missing or drifted Pi
94
+ machine assets. Setup repairs only recorded project assets; `cairn sync-pi
95
+ --apply` repairs only the package-owned Pi extension and prompt paths.
96
+
97
+ Preview backup-first removal before confirming it:
98
+
99
+ ```bash
100
+ cairn uninstall --dry-run /tmp/cairnkeep-guided-setup-lab
101
+ cairn uninstall --yes /tmp/cairnkeep-guided-setup-lab
102
+ ```
103
+
104
+ Inspect the printed backup bundle and generated revert script. Durable memory
105
+ and context packs remain unless their separate purge flags are supplied.
106
+
107
+ ## Common failures
108
+
109
+ | Symptom | Cause | Recovery |
110
+ |---|---|---|
111
+ | Setup refuses a missing target | The non-interactive command omitted an explicit choice or `--yes` | Supply the target, `--git`, `--harness`, `--memory`, and `--yes` together |
112
+ | Setup refuses `--git existing` | The target is not inside a Git work tree | Choose an existing repository, or explicitly authorize `--git init`; use `--git none` only when limited mode is intended |
113
+ | Doctor reports missing or drifted Pi assets | Project setup selected Pi but machine sync is incomplete | Run `cairn sync-pi --apply`, then `cairn sync-pi --check` and `cairn doctor` |
114
+ | A cancelled call ends the session | The Pi/bridge version does not satisfy the per-call cancellation contract | Preserve sanitized diagnostics, close the session, and do not claim release readiness |
115
+ | Pi exits but a child process remains | Shutdown did not complete or the tested extension drifted | Preserve process-state evidence, run the sync check, and treat the release gate as failed |
116
+ | A client expects native annotation hints | Pi's public tool API has no annotations field | Inspect trusted bridge metadata/result `details`; never claim native propagation |
117
+
118
+ ## Privacy and trust boundary
119
+
120
+ `.ai/cairnkeep.json` is private setup state. It records selected modes,
121
+ harnesses, and setup-owned asset digests—not credentials, secrets, endpoints, or
122
+ absolute paths. The Pi bridge is a local child-process boundary: it inherits the
123
+ operator environment needed by the local server, retains only bounded stderr
124
+ for failure diagnostics, and does not log tool arguments or results.
125
+
126
+ Use only synthetic values in exercises and evidence. Do not publish executable
127
+ paths, usernames, hostnames, repository names, environment values, child output,
128
+ memory content, or private state. The bridge adds tools only; it does not run
129
+ prompts, approve skills, create an autonomous loop, or add remote access.
130
+
131
+ ## Release boundary
132
+
133
+ Ready means this lesson and its deterministic contracts pass against v2.11.0.
134
+ Release readiness requires a non-skipping acceptance run
135
+ against separate Pi 0.84.1 minimum and explicitly versioned registry-current
136
+ installations, plus the documented Node.js, Bash 3.2, and native Windows matrix.
137
+ Those executable paths must differ, but both may report 0.84.1 while that is the
138
+ current release; a future registry advance requires its new exact version.
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Audience:** advanced users and platform maintainers
4
4
  **Prerequisite:** Practitioner track; L13 before operating captured evidence
5
- **Total time:** about 4 hours
5
+ **Total time:** about 5 hours 35 minutes
6
6
 
7
7
  1. [L09 - Domain knowledge with RAG](../lessons/L09-domain-knowledge.md)
8
8
  2. [L10 - Faster context exploration](../lessons/L10-context-exploration.md)
@@ -10,11 +10,18 @@
10
10
  4. [L12 - Managed overlays](../lessons/L12-managed-overlays.md)
11
11
  5. [L15 - Capability governance](../lessons/L15-capability-governance.md)
12
12
  6. [L16 - Evaluation and ablation](../lessons/L16-evaluation.md)
13
+ 7. [L20 - Least-authority MCP tool profiles](../lessons/L20-mcp-tool-profiles.md)
14
+ 8. [L21 - Immutable context packs and skill approval](../lessons/L21-context-packs.md)
15
+ 9. [L22 - Operate Cairnkeep on native Windows](../lessons/L22-native-windows.md)
16
+ 10. [L23 - Guided setup and Pi memory](../lessons/L23-guided-setup.md)
13
17
 
14
18
  All modules are optional. The track is complete when the operator can add and
15
19
  remove each integration without breaking the standalone local workflow and can
16
- explain its storage, network, credential, and rollback boundaries.
20
+ explain its storage, network, credential, and rollback boundaries. L23 adds the
21
+ v2.11 setup/Pi lifecycle only after the earlier storage, governance, trust, and
22
+ native-platform boundaries.
17
23
 
18
24
  Hands-on spine: `course-04-operation`, `course-06-governance`, and
19
- `course-07-evaluation` in the public
25
+ `course-07-evaluation`, `course-10-trust-context`, and
26
+ `course-12-guided-setup` in the public
20
27
  [course labs](https://github.com/cairnkeep/cairnkeep-course-labs).
@@ -1,17 +1,21 @@
1
1
  # Quickstart Track
2
2
 
3
3
  **Audience:** developers evaluating Cairnkeep
4
- **Total time:** about 75 minutes
4
+ **Total time:** about 110 minutes
5
5
  **Infrastructure:** local machine; Podman is optional
6
6
 
7
7
  1. [L00 - Why Cairnkeep?](../lessons/L00-why-cairnkeep.md)
8
8
  2. [L01 - Try it safely](../lessons/L01-safe-trial.md)
9
9
  3. [L02 - Install the local workflow](../lessons/L02-installation.md)
10
10
  4. [L03 - Bootstrap the first project](../lessons/L03-first-project.md)
11
+ 5. [L23 - Guided setup and Pi memory](../lessons/L23-guided-setup.md)
11
12
 
12
13
  The track is complete when a learner can start a new harness session, retrieve
13
14
  a previously accepted fact, and explain that default stdio memory is stored on
14
- the local machine rather than a discovered remote service.
15
+ the local machine rather than a discovered remote service. L23 then shows how
16
+ the recommended guided entry point preserves deterministic automation and keeps
17
+ Pi machine sync explicit. This guided surface ships in v2.11.
15
18
 
16
- Hands-on spine: `course-00-app` through `course-01-bootstrap` in the public
19
+ Hands-on spine: `course-00-app` through `course-01-bootstrap`, followed by
20
+ `course-12-guided-setup`, in the public
17
21
  [course labs](https://github.com/cairnkeep/cairnkeep-course-labs).
@@ -0,0 +1,43 @@
1
+ # MCP tool annotations and least-authority profiles
2
+
3
+ Cairnkeep publishes a complete annotation contract for every MCP tool. Each
4
+ tool has a stable title and explicit `readOnlyHint`, `destructiveHint`,
5
+ `idempotentHint`, and `openWorldHint` values. Local observations are closed
6
+ world. Tools that query configured services or delegated processes are open
7
+ world. Any mutation that may replace or remove state is destructive; immutable
8
+ artifact creation is additive.
9
+
10
+ Use the profile CLI to reduce the tools visible to an MCP client:
11
+
12
+ ```bash
13
+ cairn mcp-tools list
14
+ cairn mcp-tools status --json
15
+ cairn mcp-tools set read-only
16
+ cairn mcp-tools set custom --tool memory_read --tool memory_search
17
+ cairn mcp-tools reset
18
+ ```
19
+
20
+ Project configuration is strict versioned JSON in `.ai/mcp-tools.json`, created
21
+ only by `set` and written with mode `0600`. Do not hand-edit it. A process may
22
+ override the project with `CAIRN_MCP_TOOL_PROFILE=full|read-only|custom`; custom
23
+ process profiles also require a comma-separated `CAIRN_MCP_ALLOWED_TOOLS`.
24
+ Precedence is process environment, project configuration, then `full`.
25
+
26
+ `read-only` is derived from the central annotation catalog. `custom` is an
27
+ exact allowlist. Unknown names fail server startup and `cairn doctor`. Profiles
28
+ only remove authority: they cannot activate typed nodes, artifacts, context
29
+ packs, HTTP exposure, or a disabled capability. Effective discovery is:
30
+
31
+ ```text
32
+ available feature gates ∩ capability contract ∩ MCP tool profile
33
+ ```
34
+
35
+ `status` includes a canonical profile digest. Evaluation reports record that
36
+ same digest in their evidence provenance without changing the independent
37
+ capability-configuration digest. Restart the memory server after changing an
38
+ MCP profile.
39
+
40
+ The default `full` profile preserves the same tool names, schemas, responses,
41
+ feature gates, and ordering as an unconfigured server. The annotations help
42
+ conservative clients distinguish observations from actions; they do not grant
43
+ permission or replace the client's approval policy.
@@ -0,0 +1,122 @@
1
+ # Native Windows operation
2
+
3
+ Cairnkeep supports Windows x64 directly from PowerShell and Command Prompt.
4
+ The supported path does not invoke WSL, Git Bash, or a POSIX shell. Windows
5
+ ARM64 may use Windows x64 emulation, but it is not a native ARM64 support claim
6
+ until the database dependency publishes and passes an ARM64 Windows binding.
7
+
8
+ ## Install and guided setup
9
+
10
+ Prerequisites are Node.js 22 or newer, npm, and the harness you intend to use.
11
+ Git is required for `--git init`, `--git existing`, Git-backed context packs,
12
+ and `--untracked` bootstrap. Explicit `--git none` provides the same documented
13
+ limited mode as POSIX setup.
14
+ The optional `sqlite3.exe` command enables WAL-safe `cairn memory export`.
15
+
16
+ ```powershell
17
+ npm install --global @cairnkeep/cli
18
+ cairn version
19
+ $Project = 'C:\src\my-project'
20
+ cairn setup $Project --git init --harness claude,pi --memory local --yes
21
+ cairn sync --apply
22
+ cairn sync-pi --apply
23
+ cairn sync-pi --check
24
+ Set-Location $Project
25
+ cairn doctor
26
+ .\.ai\start-claude.cmd
27
+ ```
28
+
29
+ Guided setup exposes the same target classification, confirmation, Git,
30
+ harness, memory, reconciliation, counts, JSON result, diagnostics, launch, and
31
+ recovery contract as POSIX. It writes a restricted `.ai/cairnkeep.json` setup
32
+ record and never syncs machine assets automatically. `cairn bootstrap` remains
33
+ the deterministic compatibility primitive for existing scripts.
34
+
35
+ Setup and bootstrap write both the established Unix launchers and native Windows
36
+ launchers. Each `.cmd` file enters `start-harness.ps1`, loads `.ai/.env`, changes
37
+ to the project root, and forwards arguments without shell interpolation.
38
+ Optional `.ai/pre-launch.ps1` and `.ai/post-exit.ps1` seams run in the same
39
+ PowerShell process, so exported environment changes reach the harness. The post
40
+ hook receives `$env:CAIRN_EXIT_STATUS`.
41
+
42
+ ## MCP and operating assets
43
+
44
+ Register the stdio server exactly as on other platforms:
45
+
46
+ ```powershell
47
+ claude mcp add cairn-memory -s user -- cairn memory-server
48
+ cairn sync --check
49
+ ```
50
+
51
+ `cairn sync --apply` installs native `.cmd` hook transports and registers them
52
+ in the harness settings. The hook logic itself is Node and remains fail-open
53
+ except for capability admission, which preserves its fail-closed contract.
54
+ `cairn sync-pi` and `cairn sync-kimi` use native filesystem operations. Pi sync
55
+ installs the maintained local stdio memory extension explicitly; setup does not
56
+ start it or add remote access. Pi 0.84.1 is the validated minimum; the v2.11
57
+ release matrix also exercised a separate installation of the exact
58
+ registry-current Pi release. The two executable paths were distinct, while
59
+ both reported 0.84.1 because that was also the current release.
60
+
61
+ ## PowerShell completion
62
+
63
+ Load completion for the current session:
64
+
65
+ ```powershell
66
+ Invoke-Expression (& cairn completion powershell | Out-String)
67
+ ```
68
+
69
+ Place the same expression in `$PROFILE` to load it in future sessions.
70
+
71
+ ## Storage and permissions
72
+
73
+ Cairnkeep retains the same storage paths and formats. `~` resolves to the
74
+ Windows user profile. Sensitive managed JSON files do not rely on meaningless
75
+ Unix mode bits: Cairnkeep removes inherited ACLs and grants access only to the
76
+ current SID, Local System, and built-in Administrators. Context-pack content is
77
+ digest-verified before receiving restricted ACLs and a read-only attribute.
78
+ The guided setup state uses this same private ACL and contains no credentials,
79
+ endpoints, or absolute paths.
80
+
81
+ The embedded AgentFS database driver retains Windows file handles until its
82
+ Node process exits. Cairnkeep therefore runs artifact-store operations in
83
+ short-lived local Node helpers on Windows. Hard deletion and pruning build a
84
+ compacted replacement, release all handles when the helper exits, and only then
85
+ atomically replace the live database. This does not add a daemon, network
86
+ access, or background synchronization.
87
+
88
+ `cairn memory import` uses an internal path-validating tar/gzip reader. Export
89
+ uses `sqlite3.exe` `.backup` for a consistent snapshot of each live WAL database
90
+ and then writes the same portable `.tgz` format used on Unix.
91
+
92
+ ## Scheduling and process cleanup
93
+
94
+ `cairn audit-timer` registers the opt-in `Cairnkeep Memory Audit` task through
95
+ Windows Task Scheduler. `--render-only DIR` writes the command without changing
96
+ the scheduler. Evaluation cancellation targets the exact child PID and its
97
+ descendant tree through `taskkill.exe /T`, then escalates through `/F` after the
98
+ configured grace period.
99
+
100
+ ## Uninstall and recovery
101
+
102
+ Preview first, then confirm explicitly:
103
+
104
+ ```powershell
105
+ cairn uninstall --dry-run C:\src\my-project
106
+ cairn uninstall --yes C:\src\my-project
107
+ ```
108
+
109
+ Uninstall removes only managed assets and their hook registrations. Before
110
+ mutation it creates a timestamped bundle under
111
+ `~/cairnkeep-uninstall-backups/` containing exact files, a strict manifest, and
112
+ `revert.ps1`. Durable memory and context packs remain unless their separate
113
+ purge flags are supplied.
114
+
115
+ ## Verification boundary
116
+
117
+ The release gate runs from `windows-latest` using PowerShell for Node 22, 24,
118
+ and 26. It builds the TypeScript server, runs its Node tests, exercises guided
119
+ setup and bootstrap, sync/check (including Pi), native hooks, safe archive
120
+ import, backup-first uninstall, spaces and Unicode paths, packs the npm artifact,
121
+ installs it globally, invokes `cairn.cmd`, and runs `cairn doctor`. Git Bash is
122
+ never selected as the job shell.
package/docs/operating.md CHANGED
@@ -7,20 +7,23 @@ Cairnkeep has three moving parts:
7
7
 
8
8
  1. **The memory server** (`cairn-memory`) — an MCP server your harness talks to.
9
9
  2. **The project scaffold** — `.ai/` launchers and the `.planning/` knowledge
10
- layer, written by `cairn bootstrap`.
10
+ layer, written by `cairn setup` or the compatibility-oriented
11
+ `cairn bootstrap` primitive.
11
12
  3. **The operating layer** — the commands, agents, and hooks that live in your
12
13
  harness config and drive the workflow.
13
14
 
14
- `cairn bootstrap` only does step 2. Steps 1 and 3 are one-time-per-machine
15
- installs. This guide covers all three in order.
15
+ `cairn setup` is the recommended project entry point. `cairn bootstrap`
16
+ retains its established deterministic behavior for existing automation. Steps
17
+ 1 and 3 are one-time-per-machine installs; project setup reports the explicit
18
+ sync command but never runs it automatically. This guide covers all three.
16
19
 
17
20
  ## Prerequisites
18
21
 
19
22
  - Node.js 22 or newer (for the memory server) and a supported harness. Claude
20
23
  Code and OpenCode receive the full operating layer. Kimi Code receives the
21
24
  memory MCP, launcher, and opt-in graph Skill; Qwen Code receives the memory
22
- MCP and launcher. Pi receives its native trajectory adapter, graph prompt,
23
- and launcher.
25
+ MCP and launcher. Pi receives a maintained local stdio MCP extension, native
26
+ trajectory adapter, graph prompt, and launcher after explicit machine sync.
24
27
  - Optional: the `sqlite3` CLI for `cairn memory export`. Runtime memory and
25
28
  `cairn memory import` do not require it.
26
29
  - Optional: an OpenAI-compatible LLM endpoint for memory extraction and
@@ -29,6 +32,12 @@ installs. This guide covers all three in order.
29
32
  - Optional: rootless Podman for the containerized memory server and isolated
30
33
  workspace base described in [Containers](containers.md).
31
34
 
35
+ Native Windows x64 is supported directly from PowerShell or Command Prompt;
36
+ WSL and Git Bash are not required. The npm package installs a Node entry point,
37
+ and bootstrap emits `.cmd` plus PowerShell launchers. See
38
+ [Native Windows operation](native-windows.md) for the exact setup and recovery
39
+ contract. Windows ARM64 currently uses x64 emulation.
40
+
32
41
  ## Shell completion
33
42
 
34
43
  Generate completion definitions directly from the CLI:
@@ -37,12 +46,65 @@ Generate completion definitions directly from the CLI:
37
46
  cairn completion bash
38
47
  cairn completion zsh
39
48
  cairn completion fish
49
+ cairn completion powershell
40
50
  ```
41
51
 
42
52
  Distributions can install these outputs into the platform's normal completion
43
53
  directories. They can also be loaded for the current shell, for example with
44
54
  `source <(cairn completion bash)`.
45
55
 
56
+ In PowerShell, load completion for the current session with:
57
+
58
+ ```powershell
59
+ Invoke-Expression (& cairn completion powershell | Out-String)
60
+ ```
61
+
62
+ ## Guided project setup
63
+
64
+ Interactive terminals may run `cairn setup` and answer the target, Git,
65
+ harness, memory, and confirmation questions. Automation must make every choice
66
+ explicit:
67
+
68
+ ```bash
69
+ cairn setup /path/to/project --git init --harness claude,pi --memory local --yes
70
+ ```
71
+
72
+ The deterministic form accepts `--git init|existing|none`, a comma-separated
73
+ subset of `claude,opencode,pi,kimi,qwen`, and `--memory local|none`. `--git
74
+ existing` requires the target to be in an existing work tree. `--git init`
75
+ requires Git and is the only non-interactive authorization to initialize a
76
+ repository. `--git none` is an explicit limited mode: repository-aware features
77
+ remain unavailable, and both setup output and `cairn doctor` say so. A missing
78
+ or empty interactive target recommends initialization and asks before writing;
79
+ an existing non-Git tree is never initialized silently.
80
+
81
+ Setup first classifies the target and Git state without writing, then creates or
82
+ reconciles only the selected project launchers and common scaffold assets.
83
+ Identical managed files remain unchanged, changed managed files are updated,
84
+ and unrelated files are preserved. The result reports created, updated,
85
+ unchanged, and skipped counts; `cairn doctor`; an exact launcher per selected
86
+ harness; and the deterministic setup command to use for recovery. `--json`
87
+ returns the same schema-v1 result. The private mode-`0600`
88
+ `.ai/cairnkeep.json` record stores the package version, Git and memory modes,
89
+ selected harnesses, and digests/modes/template identifiers for setup-owned
90
+ assets. It contains no credentials, endpoints, or absolute paths.
91
+
92
+ Setup never installs or refreshes machine-level harness assets. Its
93
+ `machine_sync.automatic` field is always false, and the human output labels the
94
+ reported command as not run automatically. Apply the relevant machine command
95
+ explicitly, check it, then diagnose and launch:
96
+
97
+ ```bash
98
+ cairn sync --apply # Claude Code operating assets
99
+ cairn sync-pi --apply # Pi extension and prompt
100
+ cairn sync-pi --check
101
+ cd /path/to/project && cairn doctor
102
+ ./.ai/start-pi.sh
103
+ ```
104
+
105
+ `cairn bootstrap [--untracked] PATH` remains available for scripts that depend
106
+ on its original scaffold and Git-exclusion contract.
107
+
46
108
  ## Setup order (Claude Code)
47
109
 
48
110
  The commands below install the default local topology: `cairn-memory` runs as a
@@ -206,8 +268,9 @@ cairn graph diff
206
268
  ```
207
269
 
208
270
  The same direct CLI works with Qwen Code, Codex, and other shell-capable
209
- clients. This does not add a Pi MCP bridge or imply that those harnesses receive
210
- the rest of Cairnkeep's operating layer.
271
+ clients. Pi sync separately installs Cairnkeep's maintained local stdio MCP
272
+ extension; the graph prompt remains a thin adapter and does not expand the rest
273
+ of Pi's operating surface.
211
274
 
212
275
  All six modes delegate to `cairn graph`. Managed builds run Graphify's local
213
276
  code-only `update` path with provider credentials removed from the subprocess
@@ -217,6 +280,9 @@ so Graphify cannot re-index its own generated HTML/report/JSON. Managed builds
217
280
  do not perform Graphify's optional semantic document extraction. Prefer exact
218
281
  function, class, or file names; broad natural-language graph queries are less
219
282
  precise. Cairnkeep does not install or update Graphify automatically.
283
+ Set `CAIRN_GRAPHIFY_BINARY` to override the `graphify` command when Graphify is
284
+ installed at a specific path. Native executables run directly; `.js`, `.mjs`,
285
+ and `.cjs` helpers run through the active Node runtime on every platform.
220
286
 
221
287
  Graphify also maintains an incremental `graphify-out/` work directory at the
222
288
  repository root. It is separate from Cairnkeep's published
@@ -299,26 +365,52 @@ configuration, approval behavior, and overlay guidance.
299
365
 
300
366
  ## Setup order (Pi)
301
367
 
302
- Pi trajectory capture uses the same project scaffold and store. Its sync also
303
- installs a thin `/graphify` prompt into Pi's agent root:
368
+ Pi uses the same project scaffold and local memory store. Its explicit sync
369
+ installs the maintained memory extension, native trajectory extension, and thin
370
+ `/graphify` prompt into Pi's agent root:
304
371
 
305
372
  ```bash
306
373
  npm install -g @cairnkeep/cli
307
374
  cairn sync-pi --apply # default: ~/.pi/agent
308
- cairn bootstrap /path/to/project
375
+ cairn setup /path/to/project --git init --harness pi --memory local --yes
309
376
  cp /path/to/project/.ai/env.example /path/to/project/.ai/.env
310
377
  cd /path/to/project && cairn doctor && ./.ai/start-pi.sh
311
378
  ```
312
379
 
313
- This command does not install an MCP bridge. Cairnkeep does not own or select a
314
- Pi bridge; if you want `cairn memory-server` tools inside Pi as well, configure
315
- a user-chosen Pi extension/bridge separately.
380
+ The memory extension starts `cairn memory-server` as a local stdio child from
381
+ the project root. It dynamically discovers the effective server catalog, so
382
+ feature gates, capability state, and the current MCP tool profile remain
383
+ authoritative. It does not contain a second hard-coded catalog. Startup is
384
+ bounded to 10 seconds, calls to 30 seconds, results to 4 MiB, and retained child
385
+ stderr to the newest 16 KiB. Cancellation is propagated, child or protocol
386
+ failure is surfaced, and session shutdown closes the child.
387
+
388
+ Tool names, descriptions, input and output schemas, content,
389
+ `structuredContent`, `_meta`, and failure behavior cross the bridge without
390
+ semantic rewriting. The exact MCP annotations are preserved in the trusted Pi
391
+ result `details`, together with the discovered tool metadata and original
392
+ content. Pi 0.84.1 has no native annotations field in its public tool API, so
393
+ Cairnkeep does not claim native model-facing annotation propagation or invent a
394
+ substitute field.
395
+
396
+ The bridge is tools-only: it does not run prompts, activate context-pack skills,
397
+ create an autonomous loop, add remote access, or bypass server-side tool
398
+ restrictions. Removing `MCP_HTTP_PORT` from the child environment deliberately
399
+ keeps this integration on local stdio.
316
400
 
317
401
  Use `cairn sync-pi --check` to report drift without writing, or
318
402
  `--live-root DIR` to target an isolated Pi agent root. The command owns exactly
319
- `extensions/cairnkeep-trajectory.ts` and `prompts/graphify.md`; `cairn
320
- uninstall --pi-live-root DIR` removes those files backup-first and leaves every
321
- other Pi asset untouched.
403
+ `extensions/cairnkeep-memory.ts`, `extensions/cairnkeep-trajectory.ts`, and
404
+ `prompts/graphify.md`; `cairn doctor` reports a selected Pi extension that is
405
+ missing or drifted and points to `cairn sync-pi --apply`. `cairn uninstall
406
+ --pi-live-root DIR` removes those files backup-first and leaves every other Pi
407
+ asset untouched.
408
+
409
+ Pi 0.84.1 is the validated minimum supported version for this extension. The
410
+ v2.11 release passed the complete setup and bridge matrix on separate Pi 0.84.1
411
+ minimum and registry-current installations, Node.js 22, 24, and 26, Bash 3.2,
412
+ and native Windows. The two Pi executable paths differed, while both reported
413
+ 0.84.1 because that was also the registry-current release.
322
414
 
323
415
  The extension listens for Pi's native `session_shutdown` event and reads only
324
416
  the active branch from the read-only session manager. It returns before doing
@@ -381,6 +473,7 @@ vendor or host.
381
473
  | `CAIRN_HARNESS_STATE_DIR` | Optional absolute local root for recoverable native capability leases (default `${XDG_STATE_HOME:-~/.local/state}/cairn/harness`) |
382
474
  | `CAIRN_GIT_PROVIDER` | Git host for collaboration commands: `github`\|`gitlab`\|`codeberg`\|`forgejo`\|`none`. See [git-providers.md](git-providers.md) |
383
475
  | `CAIRN_ROUTE_ENDPOINT` | Base URL of an already-running token-miser routing/tiering proxy (unset → the `route_check` tool is inert) |
476
+ | `CAIRN_GRAPHIFY_BINARY` | Optional Graphify command/path override; JavaScript helpers run through the active Node runtime (default `graphify` from `PATH`) |
384
477
  | `CAIRN_EXPLORE_BINARY` | Absolute path to the `token_miser` binary used by `context_explore` (unset → the tool throws at call time) |
385
478
  | `CAIRN_EXPLORE_REPO_ROOT` | Default repo root for `context_explore` when no per-call `repo_root` is given (unset + no param → the tool throws) |
386
479
  | `CAIRN_EXPLORE_CACHE` | Caches `context_explore` results keyed on query + repo HEAD + dirty-state; default ON, set to `0` to disable |
@@ -809,6 +902,13 @@ rebuild only derived indexes/dedupe/pointers from valid authoritative records.
809
902
  Unsupported schema, SQLite failure, invalid full records, or digest corruption
810
903
  fails untouched with guidance to preserve the database before manual recovery.
811
904
 
905
+ When `.ai/cairnkeep.json` exists, doctor also validates its private state,
906
+ selected assets, digests, and modes. It reports `limited` for explicit
907
+ `--git none`, fails an incomplete or drifted setup with the recorded
908
+ deterministic `cairn setup` recovery command, and checks the Pi machine
909
+ extension when Pi was selected. `cairn sync-pi --apply` repairs that
910
+ machine-level drift; setup itself never performs the sync.
911
+
812
912
  ### Evaluation harness (opt-in)
813
913
 
814
914
  `cairn eval` is a local, serial experiment coordinator. It is disabled unless
@@ -897,8 +997,9 @@ claims.
897
997
  SIGINT or SIGTERM stops schedule admission, terminates the active adapter,
898
998
  checkpoints a `cancelled` observation, waits for bounded cleanup, and retains
899
999
  an inspectable partial report. On POSIX systems the runner targets the child
900
- process group with TERM then bounded KILL escalation. Windows descendant-tree
901
- termination is not guaranteed and is not a supported evaluation claim.
1000
+ process group with TERM then bounded KILL escalation. Native Windows targets
1001
+ the adapter and its descendant tree with `taskkill.exe /T`, escalating to `/F`
1002
+ after the bounded grace period.
902
1003
 
903
1004
  See [storage](storage.md#evaluation-report-and-note-snapshot-storage) for local
904
1005
  retention/removal and [privacy](privacy-and-data-flow.md#evaluation-adapter-and-report-flow)
@@ -1099,3 +1200,41 @@ truthy it launches exactly one separate `cairn notes distill --all-projects`
1099
1200
  process after the wiki scan and reports its bounded status. With the flag unset
1100
1201
  it performs no note work. Note failure does not replace wiki findings or change
1101
1202
  their actionable exit status; no credentials are embedded in rendered units.
1203
+
1204
+ ## Least-authority MCP profiles
1205
+
1206
+ Inspect the annotation-derived catalog and then choose the smallest profile the
1207
+ client needs:
1208
+
1209
+ ```bash
1210
+ cairn mcp-tools list
1211
+ cairn mcp-tools set read-only --project .
1212
+ cairn mcp-tools set custom --tool memory_read --tool memory_search --project .
1213
+ cairn mcp-tools status --project . --json
1214
+ ```
1215
+
1216
+ Restart the memory server after `set` or `reset`. Environment overrides win over
1217
+ the mode-`0600` project file. A profile can only remove tools; feature and
1218
+ capability gates still apply. Invalid names make both startup and doctor fail.
1219
+ See [MCP tool profiles](mcp-tool-profiles.md).
1220
+
1221
+ ## Context packs (opt-in)
1222
+
1223
+ Build and validate a local pack before installing it, then enable the immutable
1224
+ digest for exactly one project:
1225
+
1226
+ ```bash
1227
+ cairn pack init ./reference --id reference --version 1.0.0 \
1228
+ --title Reference --description "Reviewed project context" --license Apache-2.0
1229
+ cairn pack lock ./reference
1230
+ cairn pack validate ./reference
1231
+ cairn pack install ./reference
1232
+ cairn pack enable PACK-DIGEST --project .
1233
+ CAIRN_CONTEXT_PACKS=1 cairn memory-server
1234
+ ```
1235
+
1236
+ Git sources additionally require `--ref`. Updates are a manual `--check`, then
1237
+ an `--apply --confirm CANDIDATE-DIGEST`. Use `cairn pack skills` and exact-digest
1238
+ approval before a bundled skill can be read through MCP. HTTP needs the separate
1239
+ `CAIRN_CONTEXT_PACK_HTTP=1` flag and all existing authentication/Host/CORS
1240
+ controls. See [Immutable context packs](context-packs.md).