@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.
- package/CHANGELOG.md +44 -1
- package/README.md +51 -2
- package/bin/cairn +19 -1
- package/docs/context-packs.md +94 -0
- package/docs/design/meta-agent.md +39 -35
- package/docs/harness-compatibility.md +7 -1
- package/docs/learning/CURRICULUM-MAP.md +14 -4
- package/docs/learning/FEATURE-GUIDE.md +11 -4
- package/docs/learning/README.md +8 -2
- package/docs/learning/lessons/L00-why-cairnkeep.md +1 -1
- package/docs/learning/lessons/L01-safe-trial.md +3 -3
- package/docs/learning/lessons/L02-installation.md +2 -2
- package/docs/learning/lessons/L03-first-project.md +1 -1
- package/docs/learning/lessons/L17-agent-boundary.md +12 -8
- package/docs/learning/lessons/L18-local-code-graph.md +97 -0
- package/docs/learning/lessons/L19-validated-skill-improvement.md +118 -0
- package/docs/learning/lessons/L20-mcp-tool-profiles.md +67 -0
- package/docs/learning/lessons/L21-context-packs.md +79 -0
- package/docs/learning/tracks/evidence-and-evaluation.md +5 -3
- package/docs/learning/tracks/operator.md +4 -2
- package/docs/learning/tracks/practitioner.md +5 -4
- package/docs/mcp-tool-profiles.md +43 -0
- package/docs/operating.md +61 -0
- package/docs/privacy-and-data-flow.md +59 -1
- package/docs/skill-improvement.md +124 -0
- package/docs/storage.md +42 -0
- package/examples/eval/bundled-fake.json +1 -1
- package/mcp-memory-server/dist/context-pack-cli.js +185 -0
- package/mcp-memory-server/dist/context-pack.js +830 -0
- package/mcp-memory-server/dist/eval-plan.js +22 -5
- package/mcp-memory-server/dist/eval-process.js +31 -0
- package/mcp-memory-server/dist/eval-report.js +1 -0
- package/mcp-memory-server/dist/eval-runner.js +12 -4
- package/mcp-memory-server/dist/eval-schema.js +2 -1
- package/mcp-memory-server/dist/eval-workspace.js +50 -1
- package/mcp-memory-server/dist/index.js +68 -17
- package/mcp-memory-server/dist/mcp-tool-catalog.js +47 -0
- package/mcp-memory-server/dist/mcp-tool-cli.js +85 -0
- package/mcp-memory-server/dist/mcp-tool-profile.js +162 -0
- package/mcp-memory-server/dist/skill-cli.js +236 -0
- package/mcp-memory-server/dist/skill-evaluation.js +244 -0
- package/mcp-memory-server/dist/skill-schema.js +164 -0
- package/mcp-memory-server/dist/skill-store.js +583 -0
- package/mcp-memory-server/package.json +4 -1
- package/package.json +1 -1
- package/schemas/context-pack.schema.json +33 -0
- package/schemas/eval-report.schema.json +2 -1
- package/schemas/skill-adapter.schema.json +39 -0
- package/schemas/skill-proposal-protocol.schema.json +97 -0
- package/scripts/completion.sh +62 -5
- package/scripts/doctor.sh +39 -0
- package/scripts/test-cli-dispatch.sh +6 -0
- package/scripts/test-completion.sh +16 -0
- package/scripts/test-learning-docs.sh +13 -3
- package/scripts/test-package-install.sh +35 -0
- package/scripts/test-skill-cli.sh +30 -0
- package/scripts/test-uninstall.sh +21 -0
- package/scripts/uninstall.sh +26 -1
- package/templates/env.example.template +11 -0
- 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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
44
|
+
npm install --global @cairnkeep/cli@2.9.0
|
|
45
45
|
cairn --version
|
|
46
46
|
```
|
|
47
47
|
|
|
@@ -6,23 +6,25 @@
|
|
|
6
6
|
|
|
7
7
|
## Outcome
|
|
8
8
|
|
|
9
|
-
Separate Cairnkeep's shipped evidence
|
|
10
|
-
design-only
|
|
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
|
-
-
|
|
18
|
-
candidate
|
|
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
|
|
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
|
|
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,
|
|
17
|
-
|
|
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
|
|
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. [
|
|
10
|
-
4. [
|
|
11
|
-
5. [
|
|
12
|
-
6. [
|
|
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).
|