@cairnkeep/cli 2.16.0 → 2.17.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 (59) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +1 -0
  3. package/docs/README.md +8 -0
  4. package/docs/agents.md +20 -0
  5. package/docs/context-intelligence.md +143 -0
  6. package/docs/context-packs.md +33 -0
  7. package/docs/domain-knowledge.md +29 -0
  8. package/docs/learning/CURRICULUM-MAP.md +3 -1
  9. package/docs/learning/FEATURE-GUIDE.md +22 -3
  10. package/docs/learning/README.md +1 -0
  11. package/docs/learning/lessons/L00-why-cairnkeep.md +1 -1
  12. package/docs/learning/lessons/L01-safe-trial.md +3 -3
  13. package/docs/learning/lessons/L02-installation.md +2 -2
  14. package/docs/learning/lessons/L03-first-project.md +1 -1
  15. package/docs/learning/lessons/L19-validated-skill-improvement.md +1 -1
  16. package/docs/learning/lessons/L20-mcp-tool-profiles.md +1 -1
  17. package/docs/learning/lessons/L21-context-packs.md +1 -1
  18. package/docs/learning/lessons/L22-native-windows.md +2 -2
  19. package/docs/learning/lessons/L23-guided-setup.md +1 -1
  20. package/docs/learning/lessons/L24-okf-exchange.md +1 -1
  21. package/docs/learning/lessons/L25-playbooks.md +1 -1
  22. package/docs/learning/lessons/L26-context-intelligence.md +180 -0
  23. package/docs/learning/tracks/evidence-and-evaluation.md +1 -0
  24. package/docs/learning/tracks/operator.md +1 -0
  25. package/docs/learning/tracks/practitioner.md +1 -0
  26. package/docs/learning/video-scripts/V26-context-intelligence.md +144 -0
  27. package/docs/operating.md +44 -0
  28. package/docs/privacy-and-data-flow.md +22 -0
  29. package/docs/storage.md +21 -0
  30. package/docs/work-evidence.md +14 -0
  31. package/examples/eval/bundled-fake.json +1 -1
  32. package/mcp-memory-server/dist/context-pack-cli.js +3 -1
  33. package/mcp-memory-server/dist/context-pack-retrieval.js +413 -0
  34. package/mcp-memory-server/dist/context-pack.js +171 -3
  35. package/mcp-memory-server/dist/domain-retrieval-provider.js +257 -0
  36. package/mcp-memory-server/dist/index.js +73 -387
  37. package/mcp-memory-server/dist/mcp-tool-catalog.js +2 -0
  38. package/mcp-memory-server/dist/memory-extraction.js +87 -0
  39. package/mcp-memory-server/dist/memory-proposal-cli.js +110 -0
  40. package/mcp-memory-server/dist/memory-proposal-schema.js +78 -0
  41. package/mcp-memory-server/dist/memory-proposal-store.js +273 -0
  42. package/mcp-memory-server/dist/platform-security.js +32 -26
  43. package/mcp-memory-server/dist/retrieval-benchmark.js +199 -0
  44. package/mcp-memory-server/dist/reviewed-memory-store.js +281 -0
  45. package/mcp-memory-server/dist/work-evidence-schema.js +17 -0
  46. package/mcp-memory-server/dist/work-evidence-store.js +57 -1
  47. package/mcp-memory-server/package.json +8 -1
  48. package/package.json +1 -1
  49. package/schemas/context-usage-receipt.schema.json +41 -0
  50. package/schemas/memory-proposal.schema.json +65 -0
  51. package/schemas/retrieval-benchmark.schema.json +64 -0
  52. package/scripts/cairn-cli.mjs +2 -0
  53. package/scripts/completion.sh +17 -6
  54. package/scripts/doctor.sh +4 -2
  55. package/scripts/test-completion.sh +8 -1
  56. package/scripts/test-doctor.sh +21 -0
  57. package/scripts/test-release-sbom.sh +3 -0
  58. package/scripts/test-windows-native.mjs +30 -0
  59. package/scripts/windows-platform.mjs +8 -5
@@ -0,0 +1,180 @@
1
+ # L26 - Context intelligence with explicit authority
2
+
3
+ ## Outcome
4
+
5
+ You will measure retrieval before changing it, retrieve an enabled context pack
6
+ progressively, link a privacy-preserving usage receipt to work evidence, and
7
+ review a trajectory-derived memory proposal before any durable write. You will
8
+ also understand when the optional OpenViking adapter is useful and what it does
9
+ not replace.
10
+
11
+ ## Prerequisites
12
+
13
+ - Complete [L21 - Immutable context packs](L21-context-packs.md) and
14
+ [L25 - Bounded workflow playbooks](L25-playbooks.md).
15
+ - Work in a project already bootstrapped with Cairnkeep.
16
+ - Enable at least one document-bearing context pack. Skill entries stay hidden
17
+ unless separately approved for this project.
18
+ - For the proposal exercise, capture a trajectory and configure the existing
19
+ Cairnkeep extraction endpoint. The retrieval and benchmark exercises are
20
+ local and offline.
21
+
22
+ ## 1. Freeze the retrieval baseline
23
+
24
+ From a Cairnkeep source checkout, run the checked-in synthetic suite:
25
+
26
+ ```sh
27
+ npm --prefix mcp-memory-server run build
28
+ npm --prefix mcp-memory-server run check:retrieval-benchmark
29
+ ```
30
+
31
+ The suite contains hierarchical documents, multiple versions, and a hidden
32
+ skill. It checks frozen substring and deterministic mock-embedding results, then
33
+ reports Hit@1, Recall@5, MRR, relevant and irrelevant bytes, estimated tokens,
34
+ latency, mutation counts, and forbidden leakage. A quality improvement is not
35
+ accepted if it leaks the skill, mutates storage, or quietly uses the network.
36
+
37
+ For a non-golden current report:
38
+
39
+ ```sh
40
+ npm --prefix mcp-memory-server run benchmark:retrieval
41
+ ```
42
+
43
+ Record the mode with the score. Comparing one mode's score with another mode's
44
+ label omitted is not meaningful evidence.
45
+
46
+ ## 2. Retrieve progressively
47
+
48
+ Start the memory server with `CAIRN_CONTEXT_PACKS=1`. In an MCP-capable harness,
49
+ inspect the visible hierarchy first:
50
+
51
+ ```json
52
+ context_pack_tree { "detail": "abstract" }
53
+ ```
54
+
55
+ Now ask a broad question without loading every file:
56
+
57
+ ```json
58
+ context_pack_search {
59
+ "query": "release validation",
60
+ "strategy": "hierarchical",
61
+ "detail": "overview",
62
+ "explain": true,
63
+ "include_refs": true
64
+ }
65
+ ```
66
+
67
+ Check four things in the result:
68
+
69
+ 1. The selected pack, directory, and file fit the question.
70
+ 2. The bounded trace explains selection without exposing hidden content.
71
+ 3. Each result includes a `chunk_digest` and the response includes a
72
+ `result_digest`.
73
+ 4. No unapproved skill appears in the tree, summaries, results, or trace.
74
+
75
+ Ask for `detail: "content"` only after summaries narrow the candidate set. For a
76
+ known path, use `context_pack_read`; exact path/title searches can bypass the
77
+ hierarchy. Omitting all new fields exercises the compatible flat search.
78
+
79
+ ## 3. Record use without recording content
80
+
81
+ Create or activate a work-evidence record for the task, then enable the local
82
+ receipt mutation with both `CAIRN_WORK_EVIDENCE=1` and
83
+ `CAIRN_CONTEXT_USAGE=1`. After deciding whether you used a
84
+ search result, call:
85
+
86
+ ```json
87
+ context_usage_record {
88
+ "task_digest": "<64-lowercase-hex-task-digest>",
89
+ "result_digest": "<result_digest-from-search>",
90
+ "outcome": "used"
91
+ }
92
+ ```
93
+
94
+ Use `unused` or `unknown` when that is the honest outcome. Supply `evidence_id`
95
+ only when linking a non-active record deliberately. Inspect the evidence and
96
+ verify that the receipt contains identifiers and outcome—not query text,
97
+ retrieved content, prompts, or responses.
98
+
99
+ This is a mutation. A read-only MCP profile correctly hides it even though the
100
+ pack retrieval tools remain visible.
101
+
102
+ ## 4. Promote a trajectory through review
103
+
104
+ List or capture a trajectory you want to distill, then create a proposal:
105
+
106
+ ```sh
107
+ cairn proposals create --session SESSION_ID --scope project --json
108
+ cairn proposals list --json
109
+ cairn proposals show PROPOSAL_DIGEST --json
110
+ ```
111
+
112
+ Review every candidate for accuracy, scope, sensitivity, and durability. The
113
+ proposal is not reviewed memory. If it is acceptable, apply the exact digest:
114
+
115
+ ```sh
116
+ cairn proposals apply PROPOSAL_DIGEST --json
117
+ cairn proposals doctor --json
118
+ ```
119
+
120
+ Creation redacts the stored trajectory again before configured model extraction.
121
+ Application rechecks the source digest and base reviewed-memory hashes. If it
122
+ reports stale state, create and review a new proposal; do not edit the digest-
123
+ addressed file or bypass the check.
124
+
125
+ ## 5. Decide whether an external provider helps
126
+
127
+ AnythingLLM remains Cairnkeep's default domain provider. Use OpenViking only when
128
+ you deliberately operate an OpenViking index and want its search results through
129
+ the existing `domain_knowledge_query` surface:
130
+
131
+ ```sh
132
+ CAIRN_DOMAIN_RETRIEVAL_PROVIDER=openviking
133
+ CAIRN_OPENVIKING=1
134
+ CAIRN_OPENVIKING_BASE_URL=http://127.0.0.1:1933
135
+ ```
136
+
137
+ The adapter is read-only and calls search only. It does not synchronize data,
138
+ manage OpenViking, or replace Cairnkeep's reviewed memory, context-pack pins,
139
+ approvals, evidence, or tool profiles. Leave the variables unset when you do not
140
+ need the external index.
141
+
142
+ ## Common failures
143
+
144
+ - **A hidden skill appears:** revoke exposure, run `cairn doctor`, and treat it as
145
+ a visibility regression. Approval is bound to pack/path/file digests.
146
+ - **Hierarchical search looks worse:** compare it with the frozen benchmark and
147
+ inspect a bounded trace. Do not change default flat behavior to hide a miss.
148
+ - **A receipt conflicts:** the same task/result identity was recorded with a
149
+ different outcome. Resolve the evidence rather than overwriting history.
150
+ - **Proposal apply is stale:** source or reviewed memory changed after creation.
151
+ Generate a new proposal and review it.
152
+ - **OpenViking is unreachable:** verify the explicit gates, HTTPS requirement for
153
+ non-loopback hosts, endpoint, timeout, and service separately. Cairnkeep's
154
+ default operation does not depend on it.
155
+
156
+ ## Privacy and trust boundary
157
+
158
+ Context-pack and proposal digests prove content integrity and bind decisions to
159
+ specific state; they do not authenticate a publisher or prove that extracted
160
+ claims are true. Derived summaries can contain visible pack content, so protect
161
+ the cache like the pack store. Proposal extraction can cross a model-provider
162
+ boundary only through the operator's existing extraction configuration and only
163
+ after redaction. Context-usage receipts deliberately avoid raw content.
164
+
165
+ ## Recovery and acceptance
166
+
167
+ You are done when:
168
+
169
+ - the frozen benchmark passes without network or filesystem mutation;
170
+ - tree and hierarchical search expose enabled documents and only approved skills;
171
+ - flat search still works when optional fields are omitted;
172
+ - a receipt links to work evidence without copying content;
173
+ - a proposal is inspected before exact-digest apply, or intentionally rejected;
174
+ - you can explain why OpenViking is optional retrieval rather than a replacement
175
+ for Cairnkeep.
176
+
177
+ Continue with the operational references in
178
+ [Context intelligence](../../context-intelligence.md),
179
+ [Immutable context packs](../../context-packs.md), and
180
+ [Git-linked work evidence](../../work-evidence.md).
@@ -11,6 +11,7 @@
11
11
  4. [L16 - Evaluation and ablation](../lessons/L16-evaluation.md)
12
12
  5. [L17 - The agent boundary](../lessons/L17-agent-boundary.md)
13
13
  6. [L19 - Validated skill improvement](../lessons/L19-validated-skill-improvement.md)
14
+ 7. [L26 - Context intelligence with explicit authority](../lessons/L26-context-intelligence.md)
14
15
 
15
16
  The track is complete when the learner can explain each consent boundary,
16
17
  inspect and manage every local evidence store, including Git-linked work
@@ -16,6 +16,7 @@
16
16
  10. [L23 - Guided setup and Pi memory](../lessons/L23-guided-setup.md)
17
17
  11. [L24 - Reviewed knowledge exchange](../lessons/L24-okf-exchange.md)
18
18
  12. [L25 - Bounded workflow playbooks](../lessons/L25-playbooks.md)
19
+ 13. [L26 - Context intelligence with explicit authority](../lessons/L26-context-intelligence.md)
19
20
 
20
21
  All modules are optional. The track is complete when the operator can add and
21
22
  remove each integration without breaking the standalone local workflow and can
@@ -12,6 +12,7 @@
12
12
  6. [L08 - Multiple machines](../lessons/L08-multiple-machines.md)
13
13
  7. [L13 - Session evidence and hindsight](../lessons/L13-session-evidence.md)
14
14
  8. [L25 - Bounded workflow playbooks](../lessons/L25-playbooks.md)
15
+ 9. [L26 - Context intelligence with explicit authority](../lessons/L26-context-intelligence.md)
15
16
 
16
17
  The track is complete when the learner can decide what should become memory,
17
18
  review derived knowledge, run governed repository checks, locate the store, and
@@ -0,0 +1,144 @@
1
+ # V26 - Context intelligence with explicit authority
2
+
3
+ Target length: 12–15 minutes. Audience: experienced developers who understand
4
+ MCP and have completed the context-pack lesson.
5
+
6
+ ## Recording outline
7
+
8
+ ### 0:00–0:45 — The contract
9
+
10
+ Show a simple four-step card: **measure → retrieve → attest → review**.
11
+
12
+ Narration:
13
+
14
+ > Cairnkeep now makes context retrieval more selective without making memory
15
+ > promotion automatic. We measure retrieval first, inspect context progressively,
16
+ > record only a digest-level usage receipt, and review every durable-memory
17
+ > proposal before applying it.
18
+
19
+ Pause. State that OpenViking is optional external retrieval and does not replace
20
+ Cairnkeep.
21
+
22
+ ### 0:45–2:15 — Run the frozen benchmark
23
+
24
+ Use a real terminal at readable zoom and human typing speed:
25
+
26
+ ```sh
27
+ npm --prefix mcp-memory-server run build
28
+ npm --prefix mcp-memory-server run check:retrieval-benchmark
29
+ ```
30
+
31
+ Highlight Hit@1, Recall@5, MRR, byte/token estimates, latency, mutations, and
32
+ forbidden leakage. Explain that the corpus includes versions, hierarchy, and a
33
+ hidden skill. Do not claim that synthetic scores predict every project.
34
+
35
+ ### 2:15–5:15 — Tree, overview, then content
36
+
37
+ Start from an already installed and enabled demo pack. Show:
38
+
39
+ ```json
40
+ context_pack_tree { "detail": "abstract" }
41
+ ```
42
+
43
+ Expand one directory visually. Then run:
44
+
45
+ ```json
46
+ context_pack_search {
47
+ "query": "release validation",
48
+ "strategy": "hierarchical",
49
+ "detail": "overview",
50
+ "explain": true,
51
+ "include_refs": true
52
+ }
53
+ ```
54
+
55
+ Zoom briefly into the bounded trace, `chunk_digest`, and `result_digest`. Follow
56
+ with one content-level read of the selected file. Cut between overview and
57
+ content so the terminal remains dynamic without rushing.
58
+
59
+ Call out that omitting the new options keeps the existing flat content response,
60
+ and that an unapproved skill is absent from every visible surface.
61
+
62
+ ### 5:15–7:00 — Privacy-preserving receipt
63
+
64
+ With work evidence active and `CAIRN_CONTEXT_USAGE=1`, record the result:
65
+
66
+ ```json
67
+ context_usage_record {
68
+ "task_digest": "<demo-task-digest>",
69
+ "result_digest": "<search-result-digest>",
70
+ "outcome": "used"
71
+ }
72
+ ```
73
+
74
+ Show the stored receipt fields. Add an on-screen comparison:
75
+
76
+ - stored: evidence ID, task digest, result digest, outcome;
77
+ - not stored: query, prompt, content, response.
78
+
79
+ Pause after the comparison. Mention that this is a mutation and is unavailable
80
+ in the read-only MCP profile.
81
+
82
+ ### 7:00–10:15 — Review-gated proposal
83
+
84
+ Use a real captured demo trajectory and type:
85
+
86
+ ```sh
87
+ cairn proposals create --session SESSION_ID --scope project --json
88
+ cairn proposals show PROPOSAL_DIGEST --json
89
+ ```
90
+
91
+ Scroll through a small proposal. Inspect one candidate aloud for correctness,
92
+ scope, sensitivity, and durability. Then apply the exact digest:
93
+
94
+ ```sh
95
+ cairn proposals apply PROPOSAL_DIGEST --json
96
+ cairn proposals doctor --json
97
+ ```
98
+
99
+ Use a diagram or terminal split to show that creation redacts again, extraction
100
+ creates immutable candidates, and apply rechecks source and base-memory state.
101
+ Do not imply that the model writes reviewed memory directly.
102
+
103
+ ### 10:15–12:00 — Optional provider boundary
104
+
105
+ Show the minimal settings, without exposing a real key:
106
+
107
+ ```sh
108
+ CAIRN_DOMAIN_RETRIEVAL_PROVIDER=openviking
109
+ CAIRN_OPENVIKING=1
110
+ CAIRN_OPENVIKING_BASE_URL=http://127.0.0.1:1933
111
+ ```
112
+
113
+ Run one `domain_knowledge_query`, then return to a boundary diagram:
114
+
115
+ - OpenViking: optional read-only search index;
116
+ - Cairnkeep: identity, reviewed memory, pack pins, approvals, evidence, profiles.
117
+
118
+ Mention loopback-only HTTP, HTTPS elsewhere, no redirects, and the separate
119
+ remote-MCP consent gate. Do not show installation as required.
120
+
121
+ ### 12:00–13:00 — Recap and acceptance
122
+
123
+ Return to **measure → retrieve → attest → review**. Recap:
124
+
125
+ 1. Frozen evidence before retrieval changes.
126
+ 2. Summaries before content, with compatible flat fallback.
127
+ 3. Digest-level receipts instead of prompt logging.
128
+ 4. Explicit proposal review and exact-digest apply.
129
+ 5. Optional providers do not replace Cairnkeep's authority model.
130
+
131
+ Point viewers to L26 and `docs/context-intelligence.md`.
132
+
133
+ ## Recording cautions
134
+
135
+ - Use a synthetic pack, trajectory, digests, endpoint, and API key placeholder.
136
+ - Ensure the skill shown in the manifest is unapproved and absent from tree,
137
+ search, trace, and summaries.
138
+ - Keep command pauses long enough to read output; cut dead time rather than
139
+ accelerating narration.
140
+ - Use terminal autocomplete and real command execution, but prewarm builds so the
141
+ lesson focuses on behavior rather than compilation.
142
+ - Never label OpenViking as a dependency, synchronization target, memory store,
143
+ or Cairnkeep replacement.
144
+ - Do not call a proposal “memory” until exact-digest application succeeds.
package/docs/operating.md CHANGED
@@ -1409,3 +1409,47 @@ read-only related-document traversal. Privacy-reviewed export is an explicit
1409
1409
  `export-okf --check` followed by `--apply --confirm PREVIEW-DIGEST`; only named
1410
1410
  Markdown files and promoted shared notes are eligible. See
1411
1411
  [Open Knowledge Format exchange](open-knowledge-format.md).
1412
+
1413
+ ## Context-intelligence operations
1414
+
1415
+ The v2.17 context-intelligence surfaces are opt-in and independently bounded:
1416
+
1417
+ ```sh
1418
+ # Existing context-pack gate; default search stays flat and compatible.
1419
+ CAIRN_CONTEXT_PACKS=1
1420
+
1421
+ # Optional local usage-receipt mutation.
1422
+ CAIRN_CONTEXT_USAGE=1
1423
+
1424
+ # Optional external retrieval provider (AnythingLLM remains the default).
1425
+ CAIRN_DOMAIN_RETRIEVAL_PROVIDER=openviking
1426
+ CAIRN_OPENVIKING=1
1427
+ CAIRN_OPENVIKING_BASE_URL=http://127.0.0.1:1933
1428
+ ```
1429
+
1430
+ For authenticated remote MCP, context packs still require
1431
+ `CAIRN_CONTEXT_PACK_HTTP=1`; OpenViking retrieval separately requires
1432
+ `CAIRN_OPENVIKING_MCP_HTTP=1`. Neither setting weakens authentication, Host, or
1433
+ CORS checks.
1434
+
1435
+ Use these source-checkout checks during upgrades and incident diagnosis:
1436
+
1437
+ ```sh
1438
+ npm --prefix mcp-memory-server run check:context-pack-retrieval
1439
+ npm --prefix mcp-memory-server run check:context-usage
1440
+ npm --prefix mcp-memory-server run check:domain-retrieval
1441
+ npm --prefix mcp-memory-server run check:retrieval-benchmark
1442
+ cairn proposals doctor --project /path/to/project --json
1443
+ (cd /path/to/project && cairn doctor)
1444
+ ```
1445
+
1446
+ Proposal extraction is manual. Create, inspect, and apply the exact digest:
1447
+
1448
+ ```sh
1449
+ cairn proposals create --session SESSION_ID --scope project --project /path/to/project --json
1450
+ cairn proposals show PROPOSAL_DIGEST --project /path/to/project --json
1451
+ cairn proposals apply PROPOSAL_DIGEST --project /path/to/project --json
1452
+ ```
1453
+
1454
+ No background process synchronizes OpenViking, creates proposals, applies
1455
+ memory, enables packs, or approves skills.
@@ -630,3 +630,25 @@ All enabled documents carry pack and file provenance in MCP results. Skill files
630
630
  are excluded until the current project approves the exact pack digest, path, and
631
631
  file digest. Updating the pack invalidates that approval. Approval only makes a
632
632
  skill readable; Cairnkeep never copies it into a harness or executes it.
633
+
634
+ ## Context-intelligence privacy boundaries
635
+
636
+ - Progressive pack summaries are deterministic local derivatives of currently
637
+ visible files. Unapproved skills are excluded from trees, summaries, search,
638
+ and explanation traces.
639
+ - `include_refs: true` produces content-derived digests. A usage receipt stores
640
+ only evidence/task/result identifiers and `used`, `unused`, or `unknown`; it
641
+ does not store the query, prompt, retrieved content, or model response.
642
+ - Proposal creation starts from a locally stored trajectory and runs redaction
643
+ again before configured model extraction. Extraction remains a proposal until
644
+ an operator or authorized agent reviews and applies its exact digest.
645
+ - AnythingLLM is still the default external domain provider. Selecting
646
+ OpenViking requires `CAIRN_DOMAIN_RETRIEVAL_PROVIDER=openviking` and
647
+ `CAIRN_OPENVIKING=1`; remote MCP requires an additional
648
+ `CAIRN_OPENVIKING_MCP_HTTP=1` consent flag.
649
+ - The OpenViking adapter is query-only. It sends the requested workspace target
650
+ and query to the configured endpoint, but performs no synchronization, watch,
651
+ commit, update, or deletion. Non-loopback endpoints must use HTTPS.
652
+
653
+ Pack digests and proposal digests protect integrity and stale-state detection;
654
+ they do not authenticate a publisher or make extracted statements true.
package/docs/storage.md CHANGED
@@ -576,3 +576,24 @@ link index is derived data under `cache/graphs/<pack-digest>.json`; corruption
576
576
  or deletion does not affect identity and causes a rebuild from the object. OKF
577
577
  exports are not stored automatically: `export-okf --apply` creates a new
578
578
  operator-selected directory only after its preview digest is confirmed.
579
+
580
+ ## Context-intelligence derived and review state
581
+
582
+ Progressive context-pack abstracts and overviews live below
583
+ `${CAIRN_PACK_BASE_DIR:-~/.cairnkeep/packs}/cache/context/<pack-digest>/` as
584
+ digest-named JSON. This cache is derived, permission-restricted, outside
585
+ immutable pack objects, and safe to discard or deterministically rebuild.
586
+ Validation rejects symlinks, invalid names, oversized records, digest mismatches,
587
+ and temporary remnants. Repair removes invalid derived entries only; it never
588
+ changes a project pointer or skill approval.
589
+
590
+ Review-gated memory proposals live under
591
+ `<project>/.agentfs/memory-proposals/<proposal-digest>.json`. The directory is mode
592
+ `0700` and files are mode `0600` on POSIX. Proposals are immutable and include
593
+ the source trajectory digest and base reviewed-memory hashes used to reject stale
594
+ application. Applying a proposal writes through the existing reviewed-memory
595
+ store; it does not turn the proposal directory into a second memory authority.
596
+
597
+ Context-usage receipts are strict links in the existing work-evidence store.
598
+ They inherit work-evidence inspection, retention, and doctor behavior; there is
599
+ no separate prompt or retrieved-content log.
@@ -52,6 +52,20 @@ bodies are not included. The patch is redacted, bounded by the lower of the
52
52
  work-evidence and artifact limits, and stored in the existing artifact store.
53
53
  Cairnkeep provides no patch apply, restore or replay command.
54
54
 
55
+ ## Context-usage receipts
56
+
57
+ With context packs enabled, `context_pack_search` can return stable references
58
+ when called with `include_refs: true`. With `CAIRN_WORK_EVIDENCE=1` active, set
59
+ `CAIRN_CONTEXT_USAGE=1` as the second gate to expose the
60
+ local-only `context_usage_record` mutation. It links `task_digest`,
61
+ `result_digest`, and an outcome (`used`, `unused`, or `unknown`) to the active
62
+ work-evidence record, or to an explicit `evidence_id`.
63
+
64
+ Receipts intentionally exclude the query, prompt, retrieved text, and model
65
+ response. Their ID is deterministic, repeat recording is idempotent, conflicting
66
+ outcomes fail, and the normal work-evidence doctor and retention rules apply.
67
+ Because recording changes evidence, the read-only MCP profile excludes the tool.
68
+
55
69
  ## Inspect and maintain
56
70
 
57
71
  ```sh
@@ -1 +1 @@
1
- {"identifier":"cairn-offline-fake-v1","package_version":"2.16.0","schema_version":1,"task_set_digest":"13e95379f35839593047ec34521a65a8fa3ab92bd3993bca9dc8bf5c4a9ff36f"}
1
+ {"identifier":"cairn-offline-fake-v1","package_version":"2.17.0","schema_version":1,"task_set_digest":"13e95379f35839593047ec34521a65a8fa3ab92bd3993bca9dc8bf5c4a9ff36f"}
@@ -21,6 +21,7 @@ function usage() {
21
21
  cairn pack skills [--project PATH | --project-id ID] [--json]
22
22
  cairn pack approve-skill SELECTOR PATH --confirm FILE_DIGEST [--project PATH | --project-id ID]
23
23
  cairn pack revoke-skill SELECTOR PATH [--project PATH | --project-id ID]
24
+ cairn pack doctor [--repair] [--json]
24
25
  `);
25
26
  process.exit(2);
26
27
  }
@@ -205,9 +206,10 @@ async function main() {
205
206
  return;
206
207
  }
207
208
  if (command === "doctor") {
209
+ const repair = flag(args, "--repair");
208
210
  if (args.length)
209
211
  usage();
210
- const result = await doctorContextPacks();
212
+ const result = await doctorContextPacks({ repair });
211
213
  output(result, json, result.ok ? `Context packs healthy (${result.objects} objects, ${result.projects} projects).` : `Context pack problems: ${[...result.issues, ...result.temporary_remnants].join("; ")}`);
212
214
  if (!result.ok)
213
215
  process.exitCode = 1;