@cairnkeep/cli 2.15.0 → 2.15.1

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 CHANGED
@@ -5,6 +5,16 @@ All notable user-facing changes are documented here. This project follows
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [2.15.1] - 2026-08-17
9
+
10
+ ### Fixed
11
+
12
+ - Make concurrent playbook policy updates tolerate lock handoff races,
13
+ including transient Windows directory-removal errors, while retaining
14
+ fail-closed validation for unsafe lock objects.
15
+ - Strengthen the playbook concurrency regression with repeated mixed profile
16
+ and reset operations across the supported Node and Windows CI matrix.
17
+
8
18
  ## [2.15.0] - 2026-08-17
9
19
 
10
20
  ### Added
@@ -398,7 +408,8 @@ stored memories.
398
408
  - Preserve executable permissions and Bash 3.2 portability on macOS.
399
409
  - Add backup-first uninstall and SQLite-safe memory export/import guidance.
400
410
 
401
- [Unreleased]: https://github.com/cairnkeep/cairnkeep/compare/v2.15.0...HEAD
411
+ [Unreleased]: https://github.com/cairnkeep/cairnkeep/compare/v2.15.1...HEAD
412
+ [2.15.1]: https://github.com/cairnkeep/cairnkeep/compare/v2.15.0...v2.15.1
402
413
  [2.15.0]: https://github.com/cairnkeep/cairnkeep/compare/v2.14.0...v2.15.0
403
414
  [2.14.0]: https://github.com/cairnkeep/cairnkeep/compare/v2.13.1...v2.14.0
404
415
  [2.13.1]: https://github.com/cairnkeep/cairnkeep/compare/v2.13.0...v2.13.1
@@ -1,6 +1,6 @@
1
1
  # Curriculum Coverage Map
2
2
 
3
- **Baseline:** Cairnkeep 2.15.0
3
+ **Baseline:** Cairnkeep 2.15.1
4
4
  **Last reviewed:** 2026-08-17
5
5
 
6
6
  This map prevents the course from drifting behind the product. It assigns each
@@ -1,6 +1,6 @@
1
1
  # Cairnkeep feature guide
2
2
 
3
- **Baseline:** Cairnkeep 2.15.0
3
+ **Baseline:** Cairnkeep 2.15.1
4
4
 
5
5
  This is the step-back map for choosing and operating Cairnkeep features. The
6
6
  [course labs](https://github.com/cairnkeep/cairnkeep-course-labs) provide one
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Quickstart
5
5
  **Time:** 10 minutes
6
- **Tested with:** Cairnkeep 2.15.0
6
+ **Tested with:** Cairnkeep 2.15.1
7
7
 
8
8
  ## Outcome
9
9
 
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Quickstart
5
5
  **Time:** 15 minutes
6
- **Tested with:** Cairnkeep 2.15.0
6
+ **Tested with:** Cairnkeep 2.15.1
7
7
 
8
8
  ## Outcome
9
9
 
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Quickstart
5
5
  **Time:** 25 minutes
6
- **Tested with:** Cairnkeep 2.15.0 and Node.js 22 or newer
6
+ **Tested with:** Cairnkeep 2.15.1 and Node.js 22 or newer
7
7
 
8
8
  ## Outcome
9
9
 
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Quickstart
5
5
  **Time:** 25 minutes
6
- **Tested with:** Cairnkeep 2.15.0
6
+ **Tested with:** Cairnkeep 2.15.1
7
7
 
8
8
  ## Outcome
9
9
 
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Evidence and Evaluation
5
5
  **Time:** 50 minutes
6
- **Tested with:** Cairnkeep 2.15.0
6
+ **Tested with:** Cairnkeep 2.15.1
7
7
 
8
8
  ## Outcome
9
9
 
@@ -1,7 +1,7 @@
1
1
  # L20 - Least-authority MCP tool profiles
2
2
 
3
3
  **Status:** Ready
4
- **Tested with:** Cairnkeep 2.15.0 and Node.js 22 or newer
4
+ **Tested with:** Cairnkeep 2.15.1 and Node.js 22 or newer
5
5
  **Time:** 25 minutes
6
6
 
7
7
  ## Outcome
@@ -1,7 +1,7 @@
1
1
  # L21 - Immutable context packs and skill approval
2
2
 
3
3
  **Status:** Ready
4
- **Tested with:** Cairnkeep 2.15.0 and Node.js 22 or newer
4
+ **Tested with:** Cairnkeep 2.15.1 and Node.js 22 or newer
5
5
  **Time:** 40 minutes
6
6
 
7
7
  ## Outcome
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Operator
5
5
  **Time:** 30 minutes
6
- **Tested with:** Cairnkeep 2.15.0, Windows x64, and Node.js 22 or newer
6
+ **Tested with:** Cairnkeep 2.15.1, Windows x64, and Node.js 22 or newer
7
7
 
8
8
  ## Outcome
9
9
 
@@ -3,7 +3,7 @@
3
3
  **Status:** Ready
4
4
  **Track:** Quickstart and Operator
5
5
  **Time:** 35 minutes
6
- **Tested with:** Cairnkeep 2.15.0; Pi 0.84.1; Node.js 22, 24, and 26
6
+ **Tested with:** Cairnkeep 2.15.1; Pi 0.84.1; Node.js 22, 24, and 26
7
7
 
8
8
  ## Outcome
9
9
 
@@ -1,7 +1,7 @@
1
1
  # L24 - Reviewed knowledge exchange
2
2
 
3
3
  **Status:** Ready
4
- **Tested with:** Cairnkeep 2.15.0 and Node.js 22 or newer
4
+ **Tested with:** Cairnkeep 2.15.1 and Node.js 22 or newer
5
5
  **Time:** 35 minutes
6
6
 
7
7
  ## Outcome
@@ -1,7 +1,7 @@
1
1
  # L25 - Bounded workflow playbooks
2
2
 
3
3
  **Status:** Ready
4
- **Tested with:** Cairnkeep 2.15.0 and Node.js 22 or newer
4
+ **Tested with:** Cairnkeep 2.15.1 and Node.js 22 or newer
5
5
  **Time:** 35 minutes
6
6
 
7
7
  ## Outcome
@@ -1 +1 @@
1
- {"identifier":"cairn-offline-fake-v1","package_version":"2.15.0","schema_version":1,"task_set_digest":"13e95379f35839593047ec34521a65a8fa3ab92bd3993bca9dc8bf5c4a9ff36f"}
1
+ {"identifier":"cairn-offline-fake-v1","package_version":"2.15.1","schema_version":1,"task_set_digest":"13e95379f35839593047ec34521a65a8fa3ab92bd3993bca9dc8bf5c4a9ff36f"}
@@ -187,11 +187,24 @@ async function acquireLock(lock) {
187
187
  return () => rm(lock, { recursive: true, force: true });
188
188
  }
189
189
  catch (error) {
190
- if (error.code !== "EEXIST")
190
+ const code = error.code;
191
+ if (code !== "EEXIST" && !(process.platform === "win32" && code === "EPERM"))
191
192
  throw error;
192
- const info = await lstat(lock);
193
- if (!info.isDirectory() || info.isSymbolicLink())
194
- throw new Error("Playbook configuration lock is unsafe.");
193
+ try {
194
+ const info = await lstat(lock);
195
+ if (!info.isDirectory() || info.isSymbolicLink())
196
+ throw new Error("Playbook configuration lock is unsafe.");
197
+ }
198
+ catch (inspectionError) {
199
+ const inspectionCode = inspectionError.code;
200
+ if (inspectionCode === "ENOENT")
201
+ continue;
202
+ if (process.platform === "win32" && (inspectionCode === "EPERM" || inspectionCode === "EBUSY")) {
203
+ await delay(LOCK_WAIT_MS);
204
+ continue;
205
+ }
206
+ throw inspectionError;
207
+ }
195
208
  await delay(LOCK_WAIT_MS);
196
209
  }
197
210
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cairnkeep/cli",
3
- "version": "2.15.0",
3
+ "version": "2.15.1",
4
4
  "description": "A durable, harness-agnostic memory + context layer for coding agents and MCP clients.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",