@cairnkeep/cli 2.7.0 → 2.9.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 (60) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/README.md +51 -2
  3. package/bin/cairn +19 -1
  4. package/docs/context-packs.md +94 -0
  5. package/docs/design/meta-agent.md +39 -35
  6. package/docs/harness-compatibility.md +7 -1
  7. package/docs/learning/CURRICULUM-MAP.md +14 -4
  8. package/docs/learning/FEATURE-GUIDE.md +11 -4
  9. package/docs/learning/README.md +8 -2
  10. package/docs/learning/lessons/L00-why-cairnkeep.md +1 -1
  11. package/docs/learning/lessons/L01-safe-trial.md +3 -3
  12. package/docs/learning/lessons/L02-installation.md +2 -2
  13. package/docs/learning/lessons/L03-first-project.md +1 -1
  14. package/docs/learning/lessons/L17-agent-boundary.md +12 -8
  15. package/docs/learning/lessons/L18-local-code-graph.md +97 -0
  16. package/docs/learning/lessons/L19-validated-skill-improvement.md +118 -0
  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/tracks/evidence-and-evaluation.md +5 -3
  20. package/docs/learning/tracks/operator.md +4 -2
  21. package/docs/learning/tracks/practitioner.md +5 -4
  22. package/docs/mcp-tool-profiles.md +43 -0
  23. package/docs/operating.md +61 -0
  24. package/docs/privacy-and-data-flow.md +59 -1
  25. package/docs/skill-improvement.md +124 -0
  26. package/docs/storage.md +42 -0
  27. package/examples/eval/bundled-fake.json +1 -1
  28. package/mcp-memory-server/dist/context-pack-cli.js +185 -0
  29. package/mcp-memory-server/dist/context-pack.js +830 -0
  30. package/mcp-memory-server/dist/eval-plan.js +22 -5
  31. package/mcp-memory-server/dist/eval-process.js +31 -0
  32. package/mcp-memory-server/dist/eval-report.js +1 -0
  33. package/mcp-memory-server/dist/eval-runner.js +12 -4
  34. package/mcp-memory-server/dist/eval-schema.js +2 -1
  35. package/mcp-memory-server/dist/eval-workspace.js +50 -1
  36. package/mcp-memory-server/dist/index.js +68 -17
  37. package/mcp-memory-server/dist/mcp-tool-catalog.js +47 -0
  38. package/mcp-memory-server/dist/mcp-tool-cli.js +85 -0
  39. package/mcp-memory-server/dist/mcp-tool-profile.js +162 -0
  40. package/mcp-memory-server/dist/skill-cli.js +236 -0
  41. package/mcp-memory-server/dist/skill-evaluation.js +244 -0
  42. package/mcp-memory-server/dist/skill-schema.js +164 -0
  43. package/mcp-memory-server/dist/skill-store.js +583 -0
  44. package/mcp-memory-server/package.json +4 -1
  45. package/package.json +1 -1
  46. package/schemas/context-pack.schema.json +33 -0
  47. package/schemas/eval-report.schema.json +2 -1
  48. package/schemas/skill-adapter.schema.json +39 -0
  49. package/schemas/skill-proposal-protocol.schema.json +97 -0
  50. package/scripts/completion.sh +62 -5
  51. package/scripts/doctor.sh +39 -0
  52. package/scripts/test-cli-dispatch.sh +6 -0
  53. package/scripts/test-completion.sh +16 -0
  54. package/scripts/test-learning-docs.sh +13 -3
  55. package/scripts/test-package-install.sh +35 -0
  56. package/scripts/test-skill-cli.sh +30 -0
  57. package/scripts/test-uninstall.sh +21 -0
  58. package/scripts/uninstall.sh +26 -1
  59. package/templates/env.example.template +11 -0
  60. package/templates/graph-policy.md.template +3 -1
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Quickstart
5
5
  **Time:** 15 minutes
6
- **Tested with:** Cairnkeep 2.7.0
6
+ **Tested with:** Cairnkeep 2.9.0
7
7
 
8
8
  ## Outcome
9
9
 
@@ -26,7 +26,7 @@ ephemeral; the named course volume is persistent.
26
26
  1. Pull the public image:
27
27
 
28
28
  ```bash
29
- podman pull ghcr.io/cairnkeep/cairnkeep:2.7.0
29
+ podman pull ghcr.io/cairnkeep/cairnkeep:2.9.0
30
30
  ```
31
31
 
32
32
  2. Start the stdio server with a read-only root filesystem and no Linux
@@ -38,7 +38,7 @@ ephemeral; the named course volume is persistent.
38
38
  --read-only --cap-drop=all --security-opt=no-new-privileges \
39
39
  --tmpfs=/tmp:rw,noexec,nosuid,size=64m,mode=1777 \
40
40
  --volume cairnkeep-course-data:/data:Z,U \
41
- ghcr.io/cairnkeep/cairnkeep:2.7.0 stdio
41
+ ghcr.io/cairnkeep/cairnkeep:2.9.0 stdio
42
42
  ```
43
43
 
44
44
  3. The process waits quietly for MCP input. Press `Ctrl-C` after confirming it
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Quickstart
5
5
  **Time:** 25 minutes
6
- **Tested with:** Cairnkeep 2.7.0 and Node.js 22 or newer
6
+ **Tested with:** Cairnkeep 2.9.0 and Node.js 22 or newer
7
7
 
8
8
  ## Outcome
9
9
 
@@ -41,7 +41,7 @@ machine-level steps.
41
41
  2. Install Cairnkeep:
42
42
 
43
43
  ```bash
44
- npm install --global @cairnkeep/cli@2.7.0
44
+ npm install --global @cairnkeep/cli@2.9.0
45
45
  cairn --version
46
46
  ```
47
47
 
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Quickstart
5
5
  **Time:** 25 minutes
6
- **Tested with:** Cairnkeep 2.7.0
6
+ **Tested with:** Cairnkeep 2.9.0
7
7
 
8
8
  ## Outcome
9
9
 
@@ -6,23 +6,25 @@
6
6
 
7
7
  ## Outcome
8
8
 
9
- Separate Cairnkeep's shipped evidence and evaluation substrates from the
10
- design-only bounded meta-agent proposal, and identify which authority always
11
- remains with the operator and external harness.
9
+ Separate Cairnkeep's shipped evidence, evaluation, and narrow skill-file
10
+ lifecycle from the design-only general meta-agent proposal, and identify which
11
+ authority always remains with the operator and external harness.
12
12
 
13
13
  ## Planned lesson
14
14
 
15
15
  - Current facts: typed capability state, local evidence, immutable evaluation
16
16
  inputs, isolated schedules, independent verification, and canonical reports.
17
- - Design only: natural-language form compilation, candidate generation,
18
- candidate injection, comparison, proposal bundles, patch application, and
19
- rollback ledgers.
17
+ - Shipped in 2.8.0: reviewed hindsight candidates, bounded edits to one existing
18
+ `SKILL.md`, isolated baseline/candidate comparison, held-out confirmation,
19
+ exact-digest application, and rollback ledgers.
20
+ - Design only: general natural-language configuration compilation, arbitrary
21
+ target types, autonomous scheduling, and an owner inference loop.
20
22
  - Cairnkeep coordinates evidence; it does not own a harness inference loop.
21
23
  - Natural language is untrusted proposal data, not executable authorization.
22
24
  - Separate human gates for form, evaluation, application, confirmation, and
23
25
  rollback.
24
- - Why no CLI command, schema, runtime default, or quality claim ships for the
25
- proposed meta-agent loop.
26
+ - Why the shipped `cairn skill` command does not authorize or imply the broader
27
+ proposed meta-agent loop or a product quality claim.
26
28
 
27
29
  ## Hands-on lab
28
30
 
@@ -36,6 +38,8 @@ be required before any future implementation could act.
36
38
 
37
39
  - No learner attempts to invoke a meta-agent command or treats an illustrative
38
40
  block as a supported schema.
41
+ - The learner can distinguish supported `cairn skill` operations from the
42
+ broader design-only proposal.
39
43
  - Every inference execution remains owned by an operator-configured adapter.
40
44
  - A capability digest is not treated as approval, identity proof, or evidence
41
45
  of improvement.
@@ -0,0 +1,97 @@
1
+ # L18 - Local code graph
2
+
3
+ **Status:** Brief
4
+ **Track:** Practitioner
5
+ **Planned time:** 35 minutes
6
+ **Introduced in:** Cairnkeep 2.7.0
7
+
8
+ ## Outcome
9
+
10
+ Build and inspect an optional local structural graph without confusing derived
11
+ graph data with canonical source code or granting an external tool ownership of
12
+ the Cairnkeep operating layer.
13
+
14
+ ## Planned lesson
15
+
16
+ - When a structural graph answers a code-navigation question better than
17
+ durable memory, the wiki, or broad text search.
18
+ - Why the graph capability is disabled unless the managed capability contract
19
+ enables `graph` or the compatibility setting `graphify.enabled` is true.
20
+ - How to install only the isolated `graphify` executable with `uv tool install
21
+ graphifyy` or `pipx install graphifyy`. Do not run `graphify install` because
22
+ Cairnkeep owns the harness commands, policies, and lifecycle.
23
+ - How `cairn graph build`, `cairn graph status`, `cairn graph query`,
24
+ `cairn graph explain`, `cairn graph path`, and `cairn graph diff` share one
25
+ portable owner across harnesses and the shell.
26
+ - Why builds index local code only, use a reduced subprocess environment, avoid
27
+ provider credentials and semantic document extraction, and publish validated
28
+ artifacts atomically under `.planning/graphs/` while Graphify maintains its
29
+ separate incremental work directory under `graphify-out/`.
30
+ - How the previous successful graph snapshot supports `diff`, and why `--force`
31
+ is appropriate only when an intentional code deletion reduces the graph.
32
+ - Why exact symbols and narrow terms are more reliable than broad prose, and
33
+ why every graph result must be checked against canonical source files.
34
+ - How Claude Code and OpenCode receive managed `/graphify` wrappers while
35
+ `cairn sync-kimi --apply` and `cairn sync-pi --apply` install thin delegates
36
+ that call only `cairn graph`.
37
+
38
+ ## Hands-on lab
39
+
40
+ Use the synthetic course repository at checkpoint `course-08-graph` in a
41
+ disposable clone. Confirm that a disabled graph fails before Graphify or graph
42
+ artifacts are accessed. Install only the isolated executable, enable the graph
43
+ through one documented capability path, and then run:
44
+
45
+ ```bash
46
+ cairn graph build
47
+ cairn graph status
48
+ cairn graph query addItem
49
+ cairn graph explain addItem
50
+ cairn graph path addItem writeLedger
51
+ ```
52
+
53
+ Make one reversible change to the synthetic ledger, rebuild, and inspect
54
+ `cairn graph diff`. Revert the source change, rebuild again, and verify the
55
+ status. Inspect `.planning/graphs/` and `graphify-out/` without adding either
56
+ derived location to Git.
57
+
58
+ ## Acceptance criteria
59
+
60
+ - The disabled-path check creates or changes no graph artifact.
61
+ - `status` identifies whether the published graph is present and current.
62
+ - `query`, `explain`, and `path` return structural discovery evidence that the
63
+ learner verifies against `src/trail-ledger.mjs`.
64
+ - A second successful build produces a snapshot-backed diff.
65
+ - The learner can explain why `--force` is not a generic retry flag.
66
+ - The repository contains no Graphify-owned harness assets and neither
67
+ `graphify-out/` nor a published graph artifact is staged for commit.
68
+ - The learner can distinguish graph storage and subprocess data flow from
69
+ Cairnkeep memory storage and optional embedding traffic.
70
+
71
+ ## Common failures
72
+
73
+ - If `graphify` is missing, install the isolated CLI and verify it is on
74
+ `PATH`; do not run its harness installer.
75
+ - If the capability is disabled, enable it through the managed contract or the
76
+ compatibility setting rather than bypassing the owner.
77
+ - If no previous snapshot exists, make a successful build after a real code
78
+ change before requesting `diff`.
79
+ - If a path or explanation is empty, retry with exact symbol names and verify
80
+ the source directly instead of treating a broad query as proof.
81
+
82
+ ## Privacy and trust boundary
83
+
84
+ The managed build passes the repository path to a local Graphify subprocess and
85
+ publishes a validated view locally. Its reduced environment excludes provider
86
+ credentials, and the managed workflow does not perform semantic document
87
+ extraction. Graphify's incremental `graphify-out/` workspace and Cairnkeep's
88
+ published `.planning/graphs/` view can both contain sensitive structural data.
89
+ Keep both local by default, review ignore rules, and never present the graph as
90
+ canonical evidence.
91
+
92
+ ## Source material
93
+
94
+ - [Operating guide](../../operating.md#optional-graphify-workflow)
95
+ - [Harness compatibility](../../harness-compatibility.md)
96
+ - [Privacy and data flow](../../privacy-and-data-flow.md)
97
+ - [L15 - Capability governance](L15-capability-governance.md)
@@ -0,0 +1,118 @@
1
+ # L19 - Validated skill improvement
2
+
3
+ **Status:** Ready
4
+ **Track:** Evidence and Evaluation
5
+ **Time:** 50 minutes
6
+ **Tested with:** Cairnkeep 2.9.0
7
+
8
+ ## Outcome
9
+
10
+ Turn repeated failure and demonstrated resolution evidence into one reviewed
11
+ skill proposal, measure it on separate exploration and confirmation tasks,
12
+ apply only the exact eligible digest, and prove rollback without risking a real
13
+ project.
14
+
15
+ ## Lesson
16
+
17
+ - Why harvest requires failures from at least two sessions and at least one
18
+ recorded resolution.
19
+ - How `harvest`, `show`, and `review --approve` keep evidence local until the
20
+ learner consents to proposal-adapter egress.
21
+ - How the strict proposal adapter receives a bounded request, a private process
22
+ environment, and an edit budget for one existing `SKILL.md`.
23
+ - Why proposal generation and evaluation never modify the live target.
24
+ - How separate committed sets with at least two disjoint task IDs and
25
+ definitions each, one immutable source revision, fresh Git worktrees, exact
26
+ adapter digests, and an independent verifier protect the gate.
27
+ - Why improvements count distinct tasks, any regressed task rejects the
28
+ candidate, and small passing fixtures are not universal quality proof.
29
+ - How full proposal-digest confirmation, backup-first atomic replacement, and
30
+ concurrent-edit-safe rollback limit application authority.
31
+
32
+ ## Hands-on lab
33
+
34
+ Use the disposable `course-09-skill` checkpoint from the synthetic course
35
+ repository. It contains bounded hindsight evidence, one existing `SKILL.md`,
36
+ deterministic proposal and evaluation adapters, and separate committed task
37
+ sets. Keep every generated artifact under `.course-state/`:
38
+
39
+ ```bash
40
+ git switch --detach course-09-skill
41
+ scripts/reset-course-state.sh --yes
42
+ node scripts/setup-skill-lab.mjs
43
+ core=$(node scripts/locate-cairnkeep-core.mjs)
44
+ lab="$PWD/.course-state/skill-project"
45
+ export CAIRN_AGENTFS_BASE_DIR="$PWD/.course-state/agentfs"
46
+
47
+ "$core/bin/cairn" skill harvest --project "$lab" --json
48
+ "$core/bin/cairn" skill show --project "$lab" \
49
+ --kind candidate --id CANDIDATE_ID
50
+ "$core/bin/cairn" skill review --project "$lab" \
51
+ --candidate CANDIDATE_ID --approve --json
52
+ "$core/bin/cairn" skill propose --project "$lab" \
53
+ --candidate CANDIDATE_ID --target skills/course-review/SKILL.md \
54
+ --adapter "$lab/fixtures/proposal-adapter.json" --json
55
+
56
+ export CAIRN_EVAL=1
57
+ "$core/bin/cairn" skill evaluate --project "$lab" \
58
+ --proposal PROPOSAL_ID \
59
+ --exploration-task-set "$lab/eval/exploration.json" \
60
+ --confirmation-task-set "$lab/eval/confirmation.json" \
61
+ --adapter "$lab/eval/eval-adapter.json" \
62
+ --repetitions 1 --minimum-improvement 1 --yes --json
63
+
64
+ "$core/bin/cairn" skill apply --project "$lab" \
65
+ --proposal PROPOSAL_ID --evaluation EVALUATION_ID \
66
+ --confirm FULL_PROPOSAL_DIGEST --json
67
+ "$core/bin/cairn" skill rollback --project "$lab" \
68
+ --application APPLICATION_ID --confirm --json
69
+ ```
70
+
71
+ Before applying, deliberately try an incorrect digest and verify it is rejected.
72
+ After rollback, compare the target with `fixtures/skill/SKILL.md` byte for byte.
73
+
74
+ ## Acceptance criteria
75
+
76
+ - No candidate exists for repeated failure without resolution evidence.
77
+ - Proposal execution cannot inherit unapproved credentials or isolation-owned
78
+ environment variables.
79
+ - The live `SKILL.md` is byte-identical before and after propose/evaluate.
80
+ - Overlapping task IDs, changed adapters, unknown verifier results, and any
81
+ regression fail closed.
82
+ - Apply rejects a wrong digest or changed target.
83
+ - Rollback restores the original bytes and refuses to overwrite a later edit.
84
+ - The learner can explain why an eligible small task set supports one local
85
+ decision but not a universal performance claim.
86
+
87
+ ## Common failures
88
+
89
+ - If harvest returns no candidate, confirm the evidence contains the same
90
+ failure family in at least two distinct sessions and a recorded resolution.
91
+ - If proposal validation rejects the adapter program, regenerate the lab and
92
+ verify its configuration resolves to the reviewed executable by absolute
93
+ path.
94
+ - If evaluation is disabled, set `CAIRN_EVAL=1` only for this disposable lab
95
+ and retain the explicit `--yes` confirmation.
96
+ - If task validation reports overlap or a mutable revision, use the committed
97
+ exploration and confirmation fixtures from `course-09-skill` unchanged.
98
+ - If apply rejects the confirmation, copy the full `proposal_digest` from the
99
+ reviewed proposal rather than an ID, prefix, or candidate-content digest.
100
+ - If rollback reports a concurrent target change, stop and inspect that edit;
101
+ do not overwrite it by copying the backup manually.
102
+
103
+ ## Privacy and trust boundary
104
+
105
+ Hindsight excerpts and skill content remain local until candidate approval.
106
+ Approval permits those exact fields to enter the explicitly configured proposal
107
+ adapter. Evaluation adapters receive isolated worktrees with baseline or
108
+ candidate skill bytes, not the hindsight evidence. Candidate, proposal,
109
+ evaluation, application, backup, and report artifacts remain sensitive local
110
+ project state under `.agentfs/`.
111
+
112
+ ## Source material
113
+
114
+ - [Validated skill improvement](../../skill-improvement.md)
115
+ - [Evaluation and ablation](L16-evaluation.md)
116
+ - [The agent boundary](L17-agent-boundary.md)
117
+ - [Storage](../../storage.md#validated-skill-storage)
118
+ - [Privacy and data flow](../../privacy-and-data-flow.md#validated-skill-improvement-flow)
@@ -0,0 +1,67 @@
1
+ # L20 - Least-authority MCP tool profiles
2
+
3
+ **Status:** Ready
4
+ **Tested with:** Cairnkeep 2.9.0 and Node.js 22 or newer
5
+ **Time:** 25 minutes
6
+
7
+ ## Outcome
8
+
9
+ Classify every MCP tool as an observation or mutation, apply a read-only project
10
+ profile, replace it with an exact allowlist, and prove that invalid authority is
11
+ rejected before server startup.
12
+
13
+ ## Exercise
14
+
15
+ Use a disposable directory so no real project policy changes:
16
+
17
+ ```bash
18
+ lab=$(mktemp -d)
19
+ cairn mcp-tools list --json >"$lab/catalog.json"
20
+ cairn mcp-tools status --project "$lab" --json
21
+ cairn mcp-tools set read-only --project "$lab"
22
+ cairn mcp-tools status --project "$lab" --json >"$lab/read-only.json"
23
+ test "$(stat -c '%a' "$lab/.ai/mcp-tools.json" 2>/dev/null || stat -f '%Lp' "$lab/.ai/mcp-tools.json")" = 600
24
+ cairn mcp-tools set custom --tool memory_read --tool memory_search --project "$lab"
25
+ cairn mcp-tools status --project "$lab" --json >"$lab/custom.json"
26
+ ```
27
+
28
+ Inspect the catalog. Every entry must contain a title and four Boolean hints.
29
+ The read-only profile must contain only tools whose `readOnlyHint` is true. The
30
+ custom profile contains exactly the two named tools in canonical discovery
31
+ order.
32
+
33
+ Confirm environment precedence without changing the project file:
34
+
35
+ ```bash
36
+ CAIRN_MCP_TOOL_PROFILE=full cairn mcp-tools status --project "$lab" --json
37
+ ```
38
+
39
+ The source is `environment`; the project remains custom when the override is
40
+ removed. A profile cannot enable a feature-gated tool, and a disabled capability
41
+ still removes its tool. Restart the memory server after profile changes.
42
+
43
+ ## Common failures
44
+
45
+ - `custom` without `--tool` is invalid because an empty accidental server is
46
+ more likely to be a configuration mistake than useful least authority.
47
+ - Unknown names and a group/world-readable project config fail closed.
48
+ - A running MCP session keeps its discovery snapshot until restarted.
49
+
50
+ ## Privacy and trust boundary
51
+
52
+ Profiles do not read tool payloads or add telemetry. The digest identifies the
53
+ allowlist, not the user's identity or the independent capability state. Client
54
+ approval remains necessary for mutations even when a profile exposes them.
55
+
56
+ ## Recovery and acceptance
57
+
58
+ ```bash
59
+ cairn mcp-tools reset --project "$lab"
60
+ test ! -e "$lab/.ai/mcp-tools.json"
61
+ rm -rf "$lab"
62
+ ```
63
+
64
+ - Unknown custom tool names fail `set`, server startup, and `cairn doctor`.
65
+ - Profile and capability digests are independent.
66
+ - Conservative clients may execute read-only observations; mutations still
67
+ require their approval policy.
@@ -0,0 +1,79 @@
1
+ # L21 - Immutable context packs and skill approval
2
+
3
+ **Status:** Ready
4
+ **Tested with:** Cairnkeep 2.9.0 and Node.js 22 or newer
5
+ **Time:** 40 minutes
6
+
7
+ ## Outcome
8
+
9
+ Build a local offline context pack, verify its immutable identity, pin it to a
10
+ disposable project, and explain why document enablement and skill approval are
11
+ different trust decisions.
12
+
13
+ ## Exercise
14
+
15
+ ```bash
16
+ lab=$(mktemp -d)
17
+ mkdir -p "$lab/pack" "$lab/project"
18
+ printf '# Local guide\n\nSynthetic offline guidance.\n' >"$lab/pack/guide.md"
19
+ export CAIRN_PACK_BASE_DIR="$lab/store"
20
+ cairn pack init "$lab/pack" --id course-guide --version 1.0.0 \
21
+ --title "Course guide" --description "Synthetic local reference" \
22
+ --license Apache-2.0
23
+ cairn pack lock "$lab/pack"
24
+ cairn pack validate "$lab/pack"
25
+ cairn pack install "$lab/pack" --json >"$lab/install.json"
26
+ digest=$(node -e 'process.stdout.write(require(process.argv[1]).digest)' "$lab/install.json")
27
+ cairn pack enable "$digest" --project "$lab/project"
28
+ cairn pack show "$digest" --json
29
+ cairn pack skills --project "$lab/project" --json
30
+ ```
31
+
32
+ The local lifecycle makes no network request. The pack digest covers exact
33
+ manifest and content bytes; `version` is a label, not identity. Objects remain
34
+ under `$CAIRN_PACK_BASE_DIR` after disablement and ordinary uninstall.
35
+
36
+ Add a file with `kind: skill`, refresh it with `cairn pack lock`, install the new
37
+ digest, and enable it. `cairn pack skills` shows the skill but the MCP list/read
38
+ surface does not expose it until:
39
+
40
+ ```bash
41
+ cairn pack approve-skill NEW-PACK-DIGEST path/to/SKILL.md \
42
+ --confirm FILE-DIGEST --project "$lab/project"
43
+ ```
44
+
45
+ Approval binds the project, pack, path, and file bytes. A later pack update
46
+ invalidates it. Approval makes instructions readable only; it never executes or
47
+ copies them into a harness.
48
+
49
+ ## Common failures
50
+
51
+ - Adding a file after `init` requires declaring it in the manifest before
52
+ `lock`; undeclared content is rejected.
53
+ - Git installation without `--ref`, a stale update confirmation, and removal of
54
+ an enabled digest all fail closed.
55
+ - Enabling the pack does not expose a skill until its current file digest is
56
+ approved.
57
+
58
+ ## Privacy and trust boundary
59
+
60
+ Local pack operations are offline. Configured semantic search can send enabled
61
+ chunks and a query to the explicit embedding endpoint; failure falls back to
62
+ substring search. A digest detects changed bytes but does not authenticate the
63
+ publisher. Approved instructions remain untrusted readable context, not code.
64
+
65
+ ## Recovery and acceptance
66
+
67
+ ```bash
68
+ cairn pack disable course-guide --project "$lab/project"
69
+ cairn pack remove "$digest"
70
+ unset CAIRN_PACK_BASE_DIR
71
+ rm -rf "$lab"
72
+ ```
73
+
74
+ - Traversal, symlinks, undeclared files, invalid UTF-8, and digest tampering fail
75
+ validation.
76
+ - `update --check` never switches a project; apply requires the inspected digest.
77
+ - `CAIRN_CONTEXT_PACKS=1` enables local read-only tools only after restart.
78
+ - HTTP additionally requires `CAIRN_CONTEXT_PACK_HTTP=1` and existing auth.
79
+ - A digest proves integrity, not publisher authenticity.
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Audience:** maintainers and advanced practitioners evaluating optional layers
4
4
  **Prerequisite:** Practitioner track
5
- **Total time:** about 3.25 hours
5
+ **Total time:** about 4 hours
6
6
  **Infrastructure:** local fixtures first; a live harness is operator-provided
7
7
 
8
8
  1. [L13 - Session evidence and hindsight](../lessons/L13-session-evidence.md)
@@ -10,11 +10,13 @@
10
10
  3. [L15 - Capability governance](../lessons/L15-capability-governance.md)
11
11
  4. [L16 - Evaluation and ablation](../lessons/L16-evaluation.md)
12
12
  5. [L17 - The agent boundary](../lessons/L17-agent-boundary.md)
13
+ 6. [L19 - Validated skill improvement](../lessons/L19-validated-skill-improvement.md)
13
14
 
14
15
  The track is complete when the learner can explain each consent boundary,
15
16
  inspect and manage every local evidence store, compare baseline and ablation
16
- reports without making unsupported claims, and distinguish current runtime
17
- features from the design-only meta-agent contract.
17
+ reports without making unsupported claims, apply or roll back an exact eligible
18
+ skill proposal, and distinguish that narrow runtime from the design-only
19
+ general meta-agent contract.
18
20
 
19
21
  Hands-on spine: `course-05-evidence` through `course-07-evaluation` in the
20
22
  public [course labs](https://github.com/cairnkeep/cairnkeep-course-labs).
@@ -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
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,13 @@
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)
13
15
 
14
16
  All modules are optional. The track is complete when the operator can add and
15
17
  remove each integration without breaking the standalone local workflow and can
16
18
  explain its storage, network, credential, and rollback boundaries.
17
19
 
18
20
  Hands-on spine: `course-04-operation`, `course-06-governance`, and
19
- `course-07-evaluation` in the public
21
+ `course-07-evaluation`, and `course-10-trust-context` in the public
20
22
  [course labs](https://github.com/cairnkeep/cairnkeep-course-labs).
@@ -6,10 +6,11 @@
6
6
 
7
7
  1. [L04 - Memory fundamentals](../lessons/L04-memory-fundamentals.md)
8
8
  2. [L05 - The daily workflow](../lessons/L05-daily-workflow.md)
9
- 3. [L06 - Repository review and security](../lessons/L06-repository-quality.md)
10
- 4. [L07 - Privacy and storage](../lessons/L07-privacy-and-storage.md)
11
- 5. [L08 - Multiple machines](../lessons/L08-multiple-machines.md)
12
- 6. [L13 - Session evidence and hindsight](../lessons/L13-session-evidence.md)
9
+ 3. [L18 - Local code graph](../lessons/L18-local-code-graph.md)
10
+ 4. [L06 - Repository review and security](../lessons/L06-repository-quality.md)
11
+ 5. [L07 - Privacy and storage](../lessons/L07-privacy-and-storage.md)
12
+ 6. [L08 - Multiple machines](../lessons/L08-multiple-machines.md)
13
+ 7. [L13 - Session evidence and hindsight](../lessons/L13-session-evidence.md)
13
14
 
14
15
  The track is complete when the learner can decide what should become memory,
15
16
  review derived knowledge, run governed repository checks, locate the store, and
@@ -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.
package/docs/operating.md CHANGED
@@ -218,6 +218,13 @@ do not perform Graphify's optional semantic document extraction. Prefer exact
218
218
  function, class, or file names; broad natural-language graph queries are less
219
219
  precise. Cairnkeep does not install or update Graphify automatically.
220
220
 
221
+ Graphify also maintains an incremental `graphify-out/` work directory at the
222
+ repository root. It is separate from Cairnkeep's published
223
+ `.planning/graphs/` view and can contain the same sensitive structural data.
224
+ Keep both locations local. Before the first build in a Git repository, add
225
+ `/graphify-out/` to the clone-local exclude file or the repository's ignore
226
+ policy, and verify with `git status --short` after every build.
227
+
221
228
  ## Setup order (Kimi Code)
222
229
 
223
230
  Kimi Code can use the Cairnkeep memory MCP, generated project launcher, and one
@@ -897,6 +904,22 @@ See [storage](storage.md#evaluation-report-and-note-snapshot-storage) for local
897
904
  retention/removal and [privacy](privacy-and-data-flow.md#evaluation-adapter-and-report-flow)
898
905
  for the exact request, observation, environment, and persistence boundaries.
899
906
 
907
+ ### Validated skill improvement (opt-in)
908
+
909
+ After hindsight-note distillation has recorded the same failure family in at
910
+ least two sessions, `cairn skill harvest` creates a local candidate under
911
+ `.agentfs/skills/`. Review its exact evidence with `show`, approve it explicitly,
912
+ then use a private proposal adapter to generate a bounded edit list for one
913
+ existing skill file. Proposal and evaluation do not modify the live target.
914
+
915
+ Evaluation reuses the default-off evaluation coordinator and therefore requires
916
+ `CAIRN_EVAL=1`, `--yes`, an explicit harness adapter, and two disjoint committed
917
+ task sets. Only a complete, no-regression improvement in exploration opens the
918
+ confirmation set. Only the same result on confirmation makes the proposal
919
+ eligible for exact-digest application. See
920
+ [Validated skill improvement](skill-improvement.md) for the command sequence,
921
+ adapter contract, task constraints, and rollback procedure.
922
+
900
923
  ### Structured session trajectories (opt-in)
901
924
 
902
925
  Trajectory capture is disabled by default. To enable it for a launched Claude
@@ -1076,3 +1099,41 @@ truthy it launches exactly one separate `cairn notes distill --all-projects`
1076
1099
  process after the wiki scan and reports its bounded status. With the flag unset
1077
1100
  it performs no note work. Note failure does not replace wiki findings or change
1078
1101
  their actionable exit status; no credentials are embedded in rendered units.
1102
+
1103
+ ## Least-authority MCP profiles
1104
+
1105
+ Inspect the annotation-derived catalog and then choose the smallest profile the
1106
+ client needs:
1107
+
1108
+ ```bash
1109
+ cairn mcp-tools list
1110
+ cairn mcp-tools set read-only --project .
1111
+ cairn mcp-tools set custom --tool memory_read --tool memory_search --project .
1112
+ cairn mcp-tools status --project . --json
1113
+ ```
1114
+
1115
+ Restart the memory server after `set` or `reset`. Environment overrides win over
1116
+ the mode-`0600` project file. A profile can only remove tools; feature and
1117
+ capability gates still apply. Invalid names make both startup and doctor fail.
1118
+ See [MCP tool profiles](mcp-tool-profiles.md).
1119
+
1120
+ ## Context packs (opt-in)
1121
+
1122
+ Build and validate a local pack before installing it, then enable the immutable
1123
+ digest for exactly one project:
1124
+
1125
+ ```bash
1126
+ cairn pack init ./reference --id reference --version 1.0.0 \
1127
+ --title Reference --description "Reviewed project context" --license Apache-2.0
1128
+ cairn pack lock ./reference
1129
+ cairn pack validate ./reference
1130
+ cairn pack install ./reference
1131
+ cairn pack enable PACK-DIGEST --project .
1132
+ CAIRN_CONTEXT_PACKS=1 cairn memory-server
1133
+ ```
1134
+
1135
+ Git sources additionally require `--ref`. Updates are a manual `--check`, then
1136
+ an `--apply --confirm CANDIDATE-DIGEST`. Use `cairn pack skills` and exact-digest
1137
+ approval before a bundled skill can be read through MCP. HTTP needs the separate
1138
+ `CAIRN_CONTEXT_PACK_HTTP=1` flag and all existing authentication/Host/CORS
1139
+ controls. See [Immutable context packs](context-packs.md).