@cairnkeep/cli 2.6.0 → 2.7.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 +14 -1
  2. package/README.md +22 -8
  3. package/bin/cairn +15 -3
  4. package/claude/commands/graphify.md +46 -55
  5. package/docs/harness-compatibility.md +13 -5
  6. package/docs/learning/CURRICULUM-MAP.md +3 -1
  7. package/docs/learning/FEATURE-GUIDE.md +3 -2
  8. package/docs/learning/README.md +12 -12
  9. package/docs/learning/lessons/L00-why-cairnkeep.md +1 -5
  10. package/docs/learning/lessons/L01-safe-trial.md +3 -7
  11. package/docs/learning/lessons/L02-installation.md +6 -8
  12. package/docs/learning/lessons/L03-first-project.md +1 -5
  13. package/docs/learning/lessons/L04-memory-fundamentals.md +0 -6
  14. package/docs/learning/lessons/L05-daily-workflow.md +0 -5
  15. package/docs/learning/lessons/L06-repository-quality.md +0 -6
  16. package/docs/learning/lessons/L07-privacy-and-storage.md +0 -5
  17. package/docs/learning/lessons/L08-multiple-machines.md +0 -5
  18. package/docs/learning/lessons/L09-domain-knowledge.md +0 -5
  19. package/docs/learning/lessons/L10-context-exploration.md +0 -5
  20. package/docs/learning/lessons/L11-containers.md +0 -5
  21. package/docs/learning/lessons/L12-managed-overlays.md +0 -6
  22. package/docs/learning/lessons/L13-session-evidence.md +0 -6
  23. package/docs/learning/lessons/L14-typed-memory.md +0 -6
  24. package/docs/learning/lessons/L15-capability-governance.md +0 -6
  25. package/docs/learning/lessons/L16-evaluation.md +0 -7
  26. package/docs/learning/lessons/L17-agent-boundary.md +0 -6
  27. package/docs/learning/templates/lesson-template.md +0 -4
  28. package/docs/operating.md +79 -9
  29. package/docs/privacy-and-data-flow.md +1 -0
  30. package/examples/eval/bundled-fake.json +1 -1
  31. package/kimi/skills/graphify/SKILL.md +33 -0
  32. package/mcp-memory-server/dist/capability-registry.js +2 -2
  33. package/mcp-memory-server/dist/graph-cli.js +386 -0
  34. package/mcp-memory-server/package.json +2 -1
  35. package/opencode/command/graphify.md +48 -58
  36. package/package.json +2 -1
  37. package/pi/prompts/graphify.md +32 -0
  38. package/scripts/bootstrap.sh +2 -1
  39. package/scripts/completion.sh +17 -6
  40. package/scripts/smoke-bash32.sh +1 -0
  41. package/scripts/sync-kimi-assets.sh +77 -0
  42. package/scripts/sync-pi-assets.sh +52 -31
  43. package/scripts/test-bootstrap-untracked.sh +21 -0
  44. package/scripts/test-cli-dispatch.sh +4 -0
  45. package/scripts/test-completion.sh +5 -0
  46. package/scripts/test-graph-harness-adapters.sh +46 -0
  47. package/scripts/test-launcher-hooks.sh +4 -2
  48. package/scripts/test-learning-docs.sh +2 -9
  49. package/scripts/test-package-install.sh +6 -0
  50. package/scripts/test-trajectory-hooks.sh +5 -1
  51. package/scripts/test-uninstall.sh +12 -2
  52. package/scripts/uninstall.sh +11 -4
  53. package/templates/graph-policy.md.template +23 -4
  54. package/docs/learning/PRODUCTION-PLAN.md +0 -153
  55. package/docs/learning/instructor-guide.md +0 -66
  56. package/docs/learning/templates/video-script-template.md +0 -50
  57. package/docs/learning/video-scripts/L00-why-cairnkeep.md +0 -80
  58. package/docs/learning/video-scripts/L01-safe-trial.md +0 -78
  59. package/docs/learning/video-scripts/L02-installation.md +0 -97
  60. package/docs/learning/video-scripts/L03-first-project.md +0 -99
@@ -11,7 +11,7 @@ _cairn_complete() {
11
11
  COMPREPLY=()
12
12
  current=${COMP_WORDS[COMP_CWORD]}
13
13
  previous=${COMP_WORDS[COMP_CWORD-1]:-}
14
- commands="bootstrap memory-server sync sync-pi doctor trajectory artifact capabilities notes eval memory audit-timer uninstall completion version help"
14
+ commands="bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities notes eval graph memory audit-timer uninstall completion version help"
15
15
  if (( COMP_CWORD == 1 )); then
16
16
  COMPREPLY=( $(compgen -W "$commands" -- "$current") )
17
17
  return
@@ -20,6 +20,7 @@ _cairn_complete() {
20
20
  bootstrap) COMPREPLY=( $(compgen -W "--untracked" -- "$current") ) ;;
21
21
  sync) COMPREPLY=( $(compgen -W "--apply --live-root" -- "$current") ) ;;
22
22
  sync-pi) COMPREPLY=( $(compgen -W "--apply --live-root" -- "$current") ) ;;
23
+ sync-kimi) COMPREPLY=( $(compgen -W "--apply --live-root" -- "$current") ) ;;
23
24
  doctor) COMPREPLY=( $(compgen -W "--repair" -- "$current") ) ;;
24
25
  trajectory) COMPREPLY=( $(compgen -W "list show prune --json --dry-run" -- "$current") ) ;;
25
26
  artifact) COMPREPLY=( $(compgen -W "list show delete prune --kind --session --json --dry-run --include-protected" -- "$current") ) ;;
@@ -62,9 +63,10 @@ _cairn_complete() {
62
63
  *) COMPREPLY=( $(compgen -W "validate run ablate report prune delete" -- "$current") ) ;;
63
64
  esac
64
65
  ;;
66
+ graph) COMPREPLY=( $(compgen -W "build query status diff explain path --force" -- "$current") ) ;;
65
67
  memory) COMPREPLY=( $(compgen -W "path export import" -- "$current") ) ;;
66
68
  audit-timer) COMPREPLY=( $(compgen -W "--on-calendar --para-root --render-only" -- "$current") ) ;;
67
- uninstall) COMPREPLY=( $(compgen -W "--dry-run --yes --purge-memory --live-root --pi-live-root" -- "$current") ) ;;
69
+ uninstall) COMPREPLY=( $(compgen -W "--dry-run --yes --purge-memory --live-root --pi-live-root --kimi-live-root" -- "$current") ) ;;
68
70
  completion) COMPREPLY=( $(compgen -W "bash zsh fish" -- "$current") ) ;;
69
71
  esac
70
72
  }
@@ -80,13 +82,15 @@ _cairn() {
80
82
  'bootstrap:scaffold a project'
81
83
  'memory-server:run the memory MCP server'
82
84
  'sync:install the Claude operating layer'
83
- 'sync-pi:install the Pi trajectory extension'
85
+ 'sync-pi:install the Pi trajectory extension and graph prompt'
86
+ 'sync-kimi:install the Kimi graph Skill'
84
87
  'doctor:check runtime dependencies and endpoints'
85
88
  'trajectory:inspect and prune local session trajectories'
86
89
  'artifact:inspect, delete, and prune local artifacts'
87
90
  'capabilities:inspect and manage project capability state'
88
91
  'notes:distill and search local hindsight notes'
89
92
  'eval:run and inspect default-off local evaluations'
93
+ 'graph:inspect a published Graphify graph'
90
94
  'memory:manage the durable memory store'
91
95
  'audit-timer:install a memory and wiki audit timer'
92
96
  'uninstall:remove installed Cairnkeep components safely'
@@ -102,6 +106,7 @@ _cairn() {
102
106
  bootstrap) _arguments '--untracked[keep scaffold out of Git]' '*:project directory:_files -/' ;;
103
107
  sync) _arguments '--apply[apply changes]' '--live-root[project Claude root]:directory:_files -/' ;;
104
108
  sync-pi) _arguments '--apply[apply changes]' '--live-root[Pi agent root]:directory:_files -/' ;;
109
+ sync-kimi) _arguments '--apply[apply changes]' '--live-root[Kimi Code root]:directory:_files -/' ;;
105
110
  doctor) _arguments '--repair[repair trajectory metadata and indexes]' ;;
106
111
  trajectory) _values 'trajectory command' list show prune ;;
107
112
  artifact)
@@ -134,9 +139,10 @@ _cairn() {
134
139
  *) _values 'eval command' validate run ablate report prune delete ;;
135
140
  esac
136
141
  ;;
142
+ graph) _values 'graph command' build query status diff explain path '--force[allow a smaller graph after code deletion]' ;;
137
143
  memory) _values 'memory command' path export import ;;
138
144
  audit-timer) _arguments '--on-calendar[systemd calendar]:calendar:' '--para-root[PARA root]:directory:_files -/' '--render-only[render directory]:directory:_files -/' ;;
139
- uninstall) _arguments '--dry-run[show changes]' '--yes[skip confirmation]' '--purge-memory[delete memory]' '--live-root[project Claude root]:directory:_files -/' '--pi-live-root[Pi agent root]:directory:_files -/' '*:project directory:_files -/' ;;
145
+ uninstall) _arguments '--dry-run[show changes]' '--yes[skip confirmation]' '--purge-memory[delete memory]' '--live-root[project Claude root]:directory:_files -/' '--pi-live-root[Pi agent root]:directory:_files -/' '--kimi-live-root[Kimi Code root]:directory:_files -/' '*:project directory:_files -/' ;;
140
146
  completion) _values 'shell' bash zsh fish ;;
141
147
  *) _arguments '*:argument:_files' ;;
142
148
  esac
@@ -147,13 +153,15 @@ EOF
147
153
  fish)
148
154
  cat <<'EOF'
149
155
  complete -c cairn -f
150
- for command in bootstrap memory-server sync sync-pi doctor trajectory artifact capabilities notes eval memory audit-timer uninstall completion version help
151
- complete -c cairn -n "not __fish_seen_subcommand_from bootstrap memory-server sync sync-pi doctor trajectory artifact capabilities notes eval memory audit-timer uninstall completion version help" -a $command
156
+ for command in bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities notes eval graph memory audit-timer uninstall completion version help
157
+ complete -c cairn -n "not __fish_seen_subcommand_from bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities notes eval graph memory audit-timer uninstall completion version help" -a $command
152
158
  end
153
159
  complete -c cairn -n "__fish_seen_subcommand_from sync" -l apply
154
160
  complete -c cairn -n "__fish_seen_subcommand_from sync" -l live-root -r
155
161
  complete -c cairn -n "__fish_seen_subcommand_from sync-pi" -l apply
156
162
  complete -c cairn -n "__fish_seen_subcommand_from sync-pi" -l live-root -r
163
+ complete -c cairn -n "__fish_seen_subcommand_from sync-kimi" -l apply
164
+ complete -c cairn -n "__fish_seen_subcommand_from sync-kimi" -l live-root -r
157
165
  complete -c cairn -n "__fish_seen_subcommand_from bootstrap" -l untracked
158
166
  complete -c cairn -n "__fish_seen_subcommand_from memory" -a "path export import"
159
167
  complete -c cairn -n "__fish_seen_subcommand_from doctor" -l repair
@@ -183,8 +191,11 @@ complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcomma
183
191
  complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from prune" -l older-than-days -r
184
192
  complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from prune delete" -l dry-run
185
193
  complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from validate run ablate report prune delete" -l json
194
+ complete -c cairn -n "__fish_seen_subcommand_from graph" -a "build query status diff explain path"
195
+ complete -c cairn -n "__fish_seen_subcommand_from graph; and __fish_seen_subcommand_from build" -l force
186
196
  complete -c cairn -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
187
197
  complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l pi-live-root -r
198
+ complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l kimi-live-root -r
188
199
  EOF
189
200
  ;;
190
201
  *)
@@ -31,6 +31,7 @@ SCRIPTS=(
31
31
  scripts/sync-opencode-explore-assets.sh
32
32
  scripts/sync-opencode-wiki-assets.sh
33
33
  scripts/sync-pi-assets.sh
34
+ scripts/sync-kimi-assets.sh
34
35
  )
35
36
 
36
37
  fails=0
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ usage() {
5
+ cat <<'EOF'
6
+ Usage: sync-kimi-assets.sh [--check|--apply] [--live-root PATH]
7
+
8
+ Compare or sync Cairnkeep's thin graph Skill against the live Kimi Code tree.
9
+
10
+ Options:
11
+ --check Verify managed live assets match the repo copies (default)
12
+ --apply Install managed assets, then verify
13
+ --live-root PATH Override the Kimi Code root (default: $KIMI_CODE_HOME or ~/.kimi-code)
14
+ -h, --help Show this help text
15
+ EOF
16
+ }
17
+
18
+ ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
19
+ SOURCE_ROOT="$ROOT_DIR/kimi"
20
+ LIVE_ROOT="${KIMI_CODE_HOME:-$HOME/.kimi-code}"
21
+ MODE="check"
22
+ ASSETS=("skills/graphify/SKILL.md")
23
+
24
+ while [[ $# -gt 0 ]]; do
25
+ case "$1" in
26
+ --check) MODE="check"; shift ;;
27
+ --apply) MODE="apply"; shift ;;
28
+ --live-root) LIVE_ROOT="$2"; shift 2 ;;
29
+ -h|--help) usage; exit 0 ;;
30
+ *) echo "Unknown argument: $1" >&2; usage >&2; exit 2 ;;
31
+ esac
32
+ done
33
+
34
+ ensure_sources() {
35
+ local rel
36
+ for rel in "${ASSETS[@]}"; do
37
+ [[ -f "$SOURCE_ROOT/$rel" ]] || {
38
+ echo "Missing repo-managed source asset: $SOURCE_ROOT/$rel" >&2
39
+ return 2
40
+ }
41
+ done
42
+ }
43
+
44
+ check_assets() {
45
+ local rel
46
+ local failed=0
47
+ for rel in "${ASSETS[@]}"; do
48
+ if [[ ! -f "$LIVE_ROOT/$rel" ]]; then
49
+ echo "Missing live Kimi asset under $LIVE_ROOT: $rel" >&2
50
+ failed=1
51
+ elif ! cmp -s "$SOURCE_ROOT/$rel" "$LIVE_ROOT/$rel"; then
52
+ echo "Out-of-sync live Kimi asset under $LIVE_ROOT: $rel" >&2
53
+ failed=1
54
+ fi
55
+ done
56
+ return "$failed"
57
+ }
58
+
59
+ ensure_sources
60
+
61
+ if [[ "$MODE" == "apply" ]]; then
62
+ updated=0
63
+ unchanged=0
64
+ for rel in "${ASSETS[@]}"; do
65
+ mkdir -p "$(dirname "$LIVE_ROOT/$rel")"
66
+ if [[ -f "$LIVE_ROOT/$rel" ]] && cmp -s "$SOURCE_ROOT/$rel" "$LIVE_ROOT/$rel"; then
67
+ unchanged=$((unchanged + 1))
68
+ else
69
+ install -m 0644 "$SOURCE_ROOT/$rel" "$LIVE_ROOT/$rel"
70
+ updated=$((updated + 1))
71
+ fi
72
+ done
73
+ printf 'Applied %s Kimi asset(s); %s already matched.\n' "$updated" "$unchanged"
74
+ fi
75
+
76
+ check_assets
77
+ printf 'Kimi graph Skill is in sync under %s\n' "$LIVE_ROOT"
@@ -5,8 +5,8 @@ usage() {
5
5
  cat <<'EOF'
6
6
  Usage: sync-pi-assets.sh [--check|--apply] [--live-root PATH]
7
7
 
8
- Compare or sync the repo-managed Pi extension assets against the live Pi agent
9
- configuration tree.
8
+ Compare or sync the repo-managed Pi extension and prompt assets against the
9
+ live Pi agent configuration tree.
10
10
 
11
11
  Options:
12
12
  --check Verify managed live assets match the rendered repo copies (default)
@@ -20,7 +20,10 @@ ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
20
20
  SOURCE_ROOT="$ROOT_DIR/pi"
21
21
  LIVE_ROOT="${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}"
22
22
  MODE="check"
23
- ASSET="extensions/cairnkeep-trajectory.ts"
23
+ ASSETS=(
24
+ "extensions/cairnkeep-trajectory.ts"
25
+ "prompts/graphify.md"
26
+ )
24
27
 
25
28
  while [[ $# -gt 0 ]]; do
26
29
  case "$1" in
@@ -33,40 +36,58 @@ while [[ $# -gt 0 ]]; do
33
36
  done
34
37
 
35
38
  render_asset() {
36
- sed "s|@@INFRA_ROOT@@|$ROOT_DIR|g" "$SOURCE_ROOT/$ASSET"
39
+ local rel="$1"
40
+ if [[ "$rel" == "extensions/cairnkeep-trajectory.ts" ]]; then
41
+ sed "s|@@INFRA_ROOT@@|$ROOT_DIR|g" "$SOURCE_ROOT/$rel"
42
+ else
43
+ cat "$SOURCE_ROOT/$rel"
44
+ fi
45
+ }
46
+
47
+ ensure_sources() {
48
+ local rel
49
+ for rel in "${ASSETS[@]}"; do
50
+ [[ -f "$SOURCE_ROOT/$rel" ]] || {
51
+ echo "Missing repo-managed source asset: $SOURCE_ROOT/$rel" >&2
52
+ return 2
53
+ }
54
+ done
37
55
  }
38
56
 
39
- check_asset() {
40
- [[ -f "$SOURCE_ROOT/$ASSET" ]] || {
41
- echo "Missing repo-managed source asset: $SOURCE_ROOT/$ASSET" >&2
42
- return 2
43
- }
44
- [[ -f "$LIVE_ROOT/$ASSET" ]] || {
45
- echo "Missing live Pi extension under $LIVE_ROOT: $ASSET" >&2
46
- return 1
47
- }
48
- cmp -s <(render_asset) "$LIVE_ROOT/$ASSET" || {
49
- echo "Out-of-sync live Pi extension under $LIVE_ROOT: $ASSET" >&2
50
- return 1
51
- }
57
+ check_assets() {
58
+ local rel
59
+ local failed=0
60
+ for rel in "${ASSETS[@]}"; do
61
+ if [[ ! -f "$LIVE_ROOT/$rel" ]]; then
62
+ echo "Missing live Pi asset under $LIVE_ROOT: $rel" >&2
63
+ failed=1
64
+ elif ! cmp -s <(render_asset "$rel") "$LIVE_ROOT/$rel"; then
65
+ echo "Out-of-sync live Pi asset under $LIVE_ROOT: $rel" >&2
66
+ failed=1
67
+ fi
68
+ done
69
+ return "$failed"
52
70
  }
53
71
 
72
+ ensure_sources
73
+
54
74
  if [[ "$MODE" == "apply" ]]; then
55
- [[ -f "$SOURCE_ROOT/$ASSET" ]] || {
56
- echo "Missing repo-managed source asset: $SOURCE_ROOT/$ASSET" >&2
57
- exit 2
58
- }
59
- mkdir -p "$(dirname "$LIVE_ROOT/$ASSET")"
60
- if [[ -f "$LIVE_ROOT/$ASSET" ]] && cmp -s <(render_asset) "$LIVE_ROOT/$ASSET"; then
61
- echo "Applied 0 Pi extension asset(s); 1 already matched."
62
- else
75
+ updated=0
76
+ unchanged=0
77
+ for rel in "${ASSETS[@]}"; do
78
+ mkdir -p "$(dirname "$LIVE_ROOT/$rel")"
79
+ if [[ -f "$LIVE_ROOT/$rel" ]] && cmp -s <(render_asset "$rel") "$LIVE_ROOT/$rel"; then
80
+ unchanged=$((unchanged + 1))
81
+ continue
82
+ fi
63
83
  rendered_tmp=$(mktemp)
64
- render_asset > "$rendered_tmp"
65
- install -m 0644 "$rendered_tmp" "$LIVE_ROOT/$ASSET"
84
+ render_asset "$rel" > "$rendered_tmp"
85
+ install -m 0644 "$rendered_tmp" "$LIVE_ROOT/$rel"
66
86
  rm -f "$rendered_tmp"
67
- echo "Applied 1 Pi extension asset(s); 0 already matched."
68
- fi
87
+ updated=$((updated + 1))
88
+ done
89
+ printf 'Applied %s Pi asset(s); %s already matched.\n' "$updated" "$unchanged"
69
90
  fi
70
91
 
71
- check_asset
72
- printf 'Pi extension assets are in sync under %s\n' "$LIVE_ROOT"
92
+ check_assets
93
+ printf 'Pi extension and graph prompt are in sync under %s\n' "$LIVE_ROOT"
@@ -56,6 +56,27 @@ git -C "$tmp/repo" init -q
56
56
  [[ -x "$tmp/repo/.ai/start-kimi.sh" ]] || fail "Kimi launcher missing"
57
57
  [[ -x "$tmp/repo/.ai/start-qwen.sh" ]] || fail "Qwen launcher missing"
58
58
  [[ -f "$tmp/repo/.planning/config.json" ]] || fail "planning layer missing"
59
+ graph_policy="$tmp/repo/.planning/graphs/policy.md"
60
+ grep -qF '`uv tool install graphifyy`' "$graph_policy" ||
61
+ fail "Graphify policy must install the CLI in an isolated uv tool environment"
62
+ if grep -qF '`uv pip install graphifyy && graphify install`' "$graph_policy"; then
63
+ fail "Graphify policy must not install Graphify-owned skills or hooks"
64
+ fi
65
+ if ! grep -qF 'Do not run' "$graph_policy" ||
66
+ ! grep -qF '`graphify install`: Cairnkeep owns' "$graph_policy"; then
67
+ fail "Graphify policy must explain that Cairnkeep owns the harness wiring"
68
+ fi
69
+ grep -qF '`/graphify build`' "$graph_policy" ||
70
+ fail "Graphify policy must name Cairnkeep's installed build command"
71
+ grep -qF '`cairn sync-kimi' "$graph_policy" ||
72
+ fail "Graphify policy must identify the Kimi thin adapter"
73
+ grep -qF '`cairn sync-pi' "$graph_policy" ||
74
+ fail "Graphify policy must identify the Pi thin adapter"
75
+ grep -qF '`cairn graph build`' "$graph_policy" ||
76
+ fail "Graphify policy must provide the portable CLI equivalent"
77
+ if grep -qF '/gsd-graphify' "$graph_policy"; then
78
+ fail "Graphify policy must not name the GSD-internal command"
79
+ fi
59
80
  [[ -f "$tmp/repo/.agentfs/.gitignore" ]] || fail "project-memory ignore guard missing"
60
81
  [[ -z "$(git -C "$tmp/repo" status --porcelain)" ]] || fail "scaffold visible to git"
61
82
  grep -qxF "/.ai/" "$tmp/repo/.git/info/exclude" || fail "missing /.ai/ exclude entry"
@@ -11,15 +11,19 @@ tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
11
11
  "$cairn" help | grep -q "cairn audit-timer" || fail "help missing audit-timer"
12
12
  "$cairn" help | grep -q "cairn sync" || fail "help missing sync"
13
13
  "$cairn" help | grep -q "cairn sync-pi" || fail "help missing sync-pi"
14
+ "$cairn" help | grep -q "cairn sync-kimi" || fail "help missing sync-kimi"
14
15
  "$cairn" help | grep -q "cairn memory-server" || fail "help missing memory-server"
15
16
  "$cairn" help | grep -q "cairn notes" || fail "help missing notes"
16
17
  "$cairn" help | grep -q "cairn artifact <list|show|delete|prune>" || fail "help missing artifact"
17
18
  "$cairn" help | grep -q "cairn capabilities <list|status|enable|disable|reset|logging>" || fail "help missing capabilities"
19
+ "$cairn" help | grep -q "cairn graph <build|query|status|diff|explain|path>" || fail "help missing graph"
18
20
  "$cairn" sync --help >/dev/null 2>&1 || fail "cairn sync dispatch"
19
21
  "$cairn" sync-pi --help >/dev/null 2>&1 || fail "cairn sync-pi dispatch"
22
+ "$cairn" sync-kimi --help >/dev/null 2>&1 || fail "cairn sync-kimi dispatch"
20
23
  env -u CAIRN_NOTE_DISTILLATION "$cairn" notes --help >/dev/null 2>&1 || fail "cairn notes dispatch"
21
24
  "$cairn" artifact --help | grep -q "cairn artifact list" || fail "cairn artifact dispatch"
22
25
  "$cairn" capabilities --help >"$tmp/capabilities-help" 2>/dev/null || fail "cairn capabilities dispatch"
26
+ "$cairn" graph --help | grep -q "cairn graph explain <symbol>" || fail "cairn graph dispatch"
23
27
  grep -qxF 'MCP capability changes require a memory-server restart. Operating capability' "$tmp/capabilities-help" || fail "capability help missing exact restart wording"
24
28
  grep -qxF 'changes apply on the next invocation.' "$tmp/capabilities-help" || fail "capability help missing exact invocation wording"
25
29
  if grep -Eq '^ cairn capabilities (guard|start|finish|doctor)' "$tmp/capabilities-help"; then
@@ -71,14 +71,19 @@ grep -q '#compdef cairn' "$tmp/zsh"
71
71
  grep -q 'complete -c cairn' "$tmp/fish"
72
72
  for shell in bash zsh; do
73
73
  grep -q 'sync-pi' "$tmp/$shell"
74
+ grep -q 'sync-kimi' "$tmp/$shell"
74
75
  grep -q -- '--live-root' "$tmp/$shell"
75
76
  done
76
77
  grep -q 'sync-pi' "$tmp/fish"
78
+ grep -q 'sync-kimi' "$tmp/fish"
79
+ grep -q 'not __fish_seen_subcommand_from .*sync-pi sync-kimi' "$tmp/fish"
77
80
  grep -q -- '-l live-root' "$tmp/fish"
78
81
  for shell in bash zsh fish; do
79
82
  grep -q 'notes' "$tmp/$shell"
80
83
  grep -q 'distill.*search-error.*promote.*doctor\|distill search-error promote doctor' "$tmp/$shell"
81
84
  grep -q 'artifact' "$tmp/$shell"
85
+ grep -q 'graph' "$tmp/$shell"
86
+ grep -q 'build.*query.*status.*diff.*explain.*path\|build query status diff explain path' "$tmp/$shell"
82
87
  grep -q 'list.*show.*delete.*prune' "$tmp/$shell"
83
88
  grep -q -- '--json\|-l json' "$tmp/$shell"
84
89
  grep -q -- '--dry-run\|-l dry-run' "$tmp/$shell"
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bash
2
+ # Contract test: Pi and Kimi expose thin graph adapters owned by `cairn graph`.
3
+ set -euo pipefail
4
+
5
+ ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
6
+ tmp=$(mktemp -d)
7
+ trap 'rm -rf "$tmp"' EXIT
8
+ fail() { echo "FAIL: $1" >&2; exit 1; }
9
+
10
+ PI_SOURCE="$ROOT/pi/prompts/graphify.md"
11
+ KIMI_SOURCE="$ROOT/kimi/skills/graphify/SKILL.md"
12
+
13
+ [[ -f "$PI_SOURCE" ]] || fail "Pi /graphify prompt source is missing"
14
+ [[ -f "$KIMI_SOURCE" ]] || fail "Kimi graphify skill source is missing"
15
+
16
+ for adapter in "$PI_SOURCE" "$KIMI_SOURCE"; do
17
+ grep -qF 'cairn graph' "$adapter" || fail "adapter does not delegate to cairn graph: $adapter"
18
+ if grep -Ei '(^|[^/[:alnum:]_-])graphify[[:space:]]+(build|update|query|status|diff|explain|path)' "$adapter" >/dev/null; then
19
+ fail "adapter invokes Graphify directly: $adapter"
20
+ fi
21
+ if grep -Ei '(^|[[:space:]`])(curl|git|node|npm|npx|python|python3)[[:space:]]' "$adapter" >/dev/null; then
22
+ fail "adapter introduces a second executable delegate: $adapter"
23
+ fi
24
+ done
25
+
26
+ grep -qF '$ARGUMENTS' "$PI_SOURCE" || fail "Pi prompt does not forward command arguments"
27
+ grep -qF 'name: graphify' "$KIMI_SOURCE" || fail "Kimi skill does not register as graphify"
28
+ grep -qF '$ARGUMENTS' "$KIMI_SOURCE" || fail "Kimi skill does not forward command arguments"
29
+
30
+ PI_LIVE="$tmp/pi"
31
+ "$ROOT/scripts/sync-pi-assets.sh" --apply --live-root "$PI_LIVE" >"$tmp/pi-first"
32
+ [[ -f "$PI_LIVE/extensions/cairnkeep-trajectory.ts" ]] || fail "Pi sync omitted trajectory extension"
33
+ cmp -s "$PI_SOURCE" "$PI_LIVE/prompts/graphify.md" || fail "Pi sync changed graphify prompt bytes"
34
+ "$ROOT/scripts/sync-pi-assets.sh" --apply --live-root "$PI_LIVE" >"$tmp/pi-second"
35
+ grep -qF 'Applied 0 Pi asset(s); 2 already matched.' "$tmp/pi-second" || fail "Pi sync is not idempotent"
36
+
37
+ KIMI_LIVE="$tmp/kimi"
38
+ "$ROOT/scripts/sync-kimi-assets.sh" --apply --live-root "$KIMI_LIVE" >"$tmp/kimi-first"
39
+ cmp -s "$KIMI_SOURCE" "$KIMI_LIVE/skills/graphify/SKILL.md" || fail "Kimi sync changed graphify skill bytes"
40
+ "$ROOT/scripts/sync-kimi-assets.sh" --apply --live-root "$KIMI_LIVE" >"$tmp/kimi-second"
41
+ grep -qF 'Applied 0 Kimi asset(s); 1 already matched.' "$tmp/kimi-second" || fail "Kimi sync is not idempotent"
42
+
43
+ "$ROOT/bin/cairn" help | grep -qF 'cairn sync-kimi' || fail "CLI help omits sync-kimi"
44
+ "$ROOT/bin/cairn" sync-kimi --help >/dev/null || fail "CLI does not dispatch sync-kimi"
45
+
46
+ echo "PASS: thin Pi and Kimi graph adapters delegate only to cairn graph"
@@ -433,8 +433,10 @@ qwen_launcher="$repo/.ai/start-qwen.sh"
433
433
  # than requiring a standalone banner before the config gate.
434
434
  ! grep -qF '**Before ANY tool calls**, display this banner:' "$ROOT/opencode/command/graphify.md" \
435
435
  || fail "OpenCode graphify can stop after its pre-tool banner"
436
- grep -qF '**First action:** invoke the Read tool' "$ROOT/opencode/command/graphify.md" \
437
- || fail "OpenCode graphify does not require the config-gate tool call first"
436
+ ! grep -qF '**First action:** invoke the Read tool' "$ROOT/opencode/command/graphify.md" \
437
+ || fail "OpenCode graphify still duplicates the Cairnkeep-owned capability gate"
438
+ grep -qF '`cairn graph` operation enforces the typed `graph` capability' "$ROOT/opencode/command/graphify.md" \
439
+ || fail "OpenCode graphify does not delegate its capability gate to the owner"
438
440
  grep -qF '**Invoke the shell tool** with this exact command' "$ROOT/opencode/command/graphify.md" \
439
441
  || fail "OpenCode graphify does not require real shell delegation"
440
442
  grep -qF '<argument>$ARGUMENTS</argument>' "$ROOT/opencode/command/graphify.md" \
@@ -6,11 +6,10 @@ cd "$ROOT"
6
6
 
7
7
  version=$(node -p "require('./package.json').version")
8
8
  landing=docs/learning/README.md
9
- production=docs/learning/PRODUCTION-PLAN.md
10
9
  coverage=docs/learning/CURRICULUM-MAP.md
11
10
  feature_guide=docs/learning/FEATURE-GUIDE.md
12
11
 
13
- [[ -f "$landing" && -f "$production" && -f "$coverage" && -f "$feature_guide" ]]
12
+ [[ -f "$landing" && -f "$coverage" && -f "$feature_guide" ]]
14
13
  grep -qF 'docs/learning/README.md' README.md
15
14
  grep -qF "**Baseline:** Cairnkeep $version" "$coverage"
16
15
  grep -qF "**Baseline:** Cairnkeep $version" "$feature_guide"
@@ -33,17 +32,11 @@ for number in $(seq -w 0 17); do
33
32
  if grep -q '^\*\*Status:\*\* Ready' "$lesson"; then
34
33
  ready=$((ready + 1))
35
34
  grep -qF "Tested with:** Cairnkeep $version" "$lesson"
36
- script=$(sed -n 's|.*(\.\./video-scripts/\([^)]*\)).*|docs/learning/video-scripts/\1|p' "$lesson")
37
- [[ -n "$script" && -f "$script" ]] || {
38
- echo "ready lesson has no presenter script: $lesson" >&2
39
- exit 1
40
- }
41
35
  grep -q '^## Common failures$' "$lesson"
42
36
  grep -q '^## Privacy and trust boundary$' "$lesson"
43
37
  elif grep -q '^\*\*Status:\*\* Brief' "$lesson"; then
44
38
  brief=$((brief + 1))
45
39
  grep -q '^## Acceptance criteria$' "$lesson"
46
- grep -q '^## Planned video$' "$lesson"
47
40
  else
48
41
  echo "lesson has an unsupported status: $lesson" >&2
49
42
  exit 1
@@ -91,4 +84,4 @@ for (const file of markdownFiles("docs/learning")) {
91
84
  }
92
85
  NODE
93
86
 
94
- echo "PASS: learning path structure, readiness, scripts, and version alignment"
87
+ echo "PASS: public learning path structure, readiness, links, and version alignment"
@@ -218,8 +218,14 @@ NODE
218
218
  fail "npm tarball omitted the default AnythingLLM sync script"
219
219
  [[ -f "$installed_root/pi/extensions/cairnkeep-trajectory.ts" ]] || \
220
220
  fail "npm tarball omitted the Pi trajectory extension"
221
+ [[ -f "$installed_root/pi/prompts/graphify.md" ]] || \
222
+ fail "npm tarball omitted the Pi graph prompt"
223
+ [[ -f "$installed_root/kimi/skills/graphify/SKILL.md" ]] || \
224
+ fail "npm tarball omitted the Kimi graph Skill"
221
225
  [[ -x "$installed_root/scripts/sync-pi-assets.sh" ]] || \
222
226
  fail "npm tarball omitted the Pi sync command"
227
+ [[ -x "$installed_root/scripts/sync-kimi-assets.sh" ]] || \
228
+ fail "npm tarball omitted the Kimi sync command"
223
229
  [[ -f "$installed_root/templates/start-pi.sh.template" ]] || \
224
230
  fail "npm tarball omitted the Pi launcher template"
225
231
  [[ -f "$installed_root/templates/start-kimi.sh.template" ]] || \
@@ -127,6 +127,8 @@ pi_live="$tmp/pi-live"
127
127
  render "$ROOT/pi/extensions/cairnkeep-trajectory.ts" "$tmp/expected-pi-capture.ts"
128
128
  cmp -s "$tmp/expected-pi-capture.ts" "$pi_live/extensions/cairnkeep-trajectory.ts" \
129
129
  || fail "installed Pi trajectory extension differs from rendered source"
130
+ cmp -s "$ROOT/pi/prompts/graphify.md" "$pi_live/prompts/graphify.md" \
131
+ || fail "installed Pi graph prompt differs from source"
130
132
  [[ $(find "$pi_live" -type f -name 'cairnkeep-trajectory.ts' | wc -l) -eq 1 ]] \
131
133
  || fail "Pi trajectory extension is duplicated"
132
134
 
@@ -136,7 +138,9 @@ cmp -s "$tmp/expected-pi-capture.ts" "$pi_live/extensions/cairnkeep-trajectory.t
136
138
  || fail "Claude memory-capture hook registration is missing or duplicated"
137
139
  [[ $(grep -c 'plugins/memory-capture.ts' "$ROOT/scripts/sync-opencode-plugin-assets.sh") -eq 1 ]] \
138
140
  || fail "OpenCode memory-capture plugin asset is missing or duplicated"
139
- [[ $(grep -c 'extensions/cairnkeep-trajectory.ts' "$ROOT/scripts/sync-pi-assets.sh") -eq 1 ]] \
141
+ [[ $(grep -c '^ "extensions/cairnkeep-trajectory.ts"' "$ROOT/scripts/sync-pi-assets.sh") -eq 1 ]] \
140
142
  || fail "Pi trajectory extension asset is missing or duplicated"
143
+ [[ $(grep -c '^ "prompts/graphify.md"' "$ROOT/scripts/sync-pi-assets.sh") -eq 1 ]] \
144
+ || fail "Pi graph prompt asset is missing or duplicated"
141
145
 
142
146
  echo "PASS: Claude/OpenCode/Pi trajectory hooks and flag-off regression"
@@ -82,12 +82,14 @@ chmod +x "$SB/bin/"*
82
82
  export HOME="$SB/home" XDG_CONFIG_HOME="$SB/home/.config" PATH="$SB/bin:$PATH"
83
83
  LIVE="$SB/live"
84
84
  PI_LIVE="$SB/pi-live"
85
+ KIMI_LIVE="$SB/kimi-live"
85
86
 
86
87
  echo "test-uninstall"
87
88
 
88
89
  # --- install the operating layer -------------------------------------------
89
90
  "$ROOT_DIR/scripts/sync-claude-assets.sh" --apply --live-root "$LIVE" >/dev/null 2>&1
90
91
  "$ROOT_DIR/scripts/sync-pi-assets.sh" --apply --live-root "$PI_LIVE" >/dev/null 2>&1
92
+ "$ROOT_DIR/scripts/sync-kimi-assets.sh" --apply --live-root "$KIMI_LIVE" >/dev/null 2>&1
91
93
  md_installed=$(find "$LIVE" -type f -name '*.md' | wc -l | tr -d ' ')
92
94
  check "assets installed" "$([[ $md_installed -gt 0 ]] && echo yes || echo no)" "yes"
93
95
  check "managed hooks registered" "$(managed_hook_count "$LIVE/settings.json")" "5"
@@ -105,6 +107,8 @@ fs.writeFileSync(path, JSON.stringify(settings, null, 2) + "\n")
105
107
  NODE
106
108
  cp "$LIVE/settings.json" "$SB/settings.before.json"
107
109
  cp "$PI_LIVE/extensions/cairnkeep-trajectory.ts" "$SB/pi.before.ts"
110
+ cp "$PI_LIVE/prompts/graphify.md" "$SB/pi-graph.before.md"
111
+ cp "$KIMI_LIVE/skills/graphify/SKILL.md" "$SB/kimi-graph.before.md"
108
112
  mkdir -p "$SB/home/.cairnkeep/notes/projects/example/hindsight"
109
113
  printf 'durable note bytes\n' >"$SB/home/.cairnkeep/notes/projects/example/hindsight/failure.md"
110
114
  mkdir -p "$SB/home/.cairnkeep/notes/.cairnkeep/history/project-notes/knowledge/example" \
@@ -204,10 +208,12 @@ overlay_before=$(tree_hash "$PROJECT_DATA/.ai/capability-contract")
204
208
  project_before=$(tree_hash "$PROJECT_DATA")
205
209
 
206
210
  # --- dry-run must change nothing -------------------------------------------
207
- "$ROOT_DIR/scripts/uninstall.sh" --dry-run --live-root "$LIVE" --pi-live-root "$PI_LIVE" "$PROJECT_DATA" >/dev/null 2>&1
211
+ "$ROOT_DIR/scripts/uninstall.sh" --dry-run --live-root "$LIVE" --pi-live-root "$PI_LIVE" --kimi-live-root "$KIMI_LIVE" "$PROJECT_DATA" >/dev/null 2>&1
208
212
  check "dry-run leaves assets" "$(find "$LIVE" -type f -name '*.md' | wc -l | tr -d ' ')" "$md_installed"
209
213
  check "dry-run makes no bundle" "$(ls -d "$SB/home/.cairnkeep-uninstall-"* 2>/dev/null | wc -l | tr -d ' ')" "0"
210
214
  check "dry-run leaves Pi extension" "$([[ -f "$PI_LIVE/extensions/cairnkeep-trajectory.ts" ]] && echo yes || echo no)" "yes"
215
+ check "dry-run leaves Pi graph prompt" "$([[ -f "$PI_LIVE/prompts/graphify.md" ]] && echo yes || echo no)" "yes"
216
+ check "dry-run leaves Kimi graph Skill" "$([[ -f "$KIMI_LIVE/skills/graphify/SKILL.md" ]] && echo yes || echo no)" "yes"
211
217
  check "dry-run leaves settings identical" "$(cmp -s "$SB/settings.before.json" "$LIVE/settings.json" && echo yes || echo no)" "yes"
212
218
  check "dry-run leaves artifact bytes exact" "$(cmp -s "$SB/artifacts.before.db" "$PROJECT_DATA/.agentfs/artifacts.db" && echo yes || echo no)" "yes"
213
219
  check "dry-run leaves eval tree, bytes, and modes exact" "$(tree_identity "$PROJECT_DATA/.agentfs/eval")" "$eval_before"
@@ -216,11 +222,13 @@ check "dry-run leaves adjacent project exact" "$(tree_identity "$ADJACENT_PROJEC
216
222
  check "dry-run leaves project state byte-identical" "$(tree_hash "$PROJECT_DATA")" "$project_before"
217
223
 
218
224
  # --- real uninstall ---------------------------------------------------------
219
- "$ROOT_DIR/scripts/uninstall.sh" --yes --live-root "$LIVE" --pi-live-root "$PI_LIVE" "$PROJECT_DATA" >/dev/null 2>&1
225
+ "$ROOT_DIR/scripts/uninstall.sh" --yes --live-root "$LIVE" --pi-live-root "$PI_LIVE" --kimi-live-root "$KIMI_LIVE" "$PROJECT_DATA" >/dev/null 2>&1
220
226
  check "assets removed" "$(find "$LIVE" -type f -name '*.md' | wc -l | tr -d ' ')" "0"
221
227
  check "managed hooks de-registered" "$(managed_hook_count "$LIVE/settings.json")" "0"
222
228
  check "unrelated hook preserved" "$(grep -cF 'keep-me.sh' "$LIVE/settings.json" 2>/dev/null || true)" "1"
223
229
  check "Pi extension removed" "$([[ -e "$PI_LIVE/extensions/cairnkeep-trajectory.ts" ]] && echo no || echo yes)" "yes"
230
+ check "Pi graph prompt removed" "$([[ -e "$PI_LIVE/prompts/graphify.md" ]] && echo no || echo yes)" "yes"
231
+ check "Kimi graph Skill removed" "$([[ -e "$KIMI_LIVE/skills/graphify/SKILL.md" ]] && echo no || echo yes)" "yes"
224
232
  check "default uninstall keeps notes" "$(sha256sum "$SB/home/.cairnkeep/notes/projects/example/hindsight/failure.md" | cut -d' ' -f1)" "$note_before"
225
233
  check "default uninstall keeps all typed and journal bytes" "$(tree_hash "$SB/home/.cairnkeep")" "$store_before"
226
234
  check "default uninstall keeps artifact bytes exact" "$(cmp -s "$SB/artifacts.before.db" "$PROJECT_DATA/.agentfs/artifacts.db" && echo yes || echo no)" "yes"
@@ -243,6 +251,8 @@ bash "$BK/revert.sh" >/dev/null 2>&1
243
251
  check "assets restored" "$(find "$LIVE" -type f -name '*.md' | wc -l | tr -d ' ')" "$md_installed"
244
252
  check "settings.json identical" "$(cmp -s "$SB/settings.before.json" "$LIVE/settings.json" && echo yes || echo no)" "yes"
245
253
  check "Pi extension restored" "$(cmp -s "$SB/pi.before.ts" "$PI_LIVE/extensions/cairnkeep-trajectory.ts" && echo yes || echo no)" "yes"
254
+ check "Pi graph prompt restored" "$(cmp -s "$SB/pi-graph.before.md" "$PI_LIVE/prompts/graphify.md" && echo yes || echo no)" "yes"
255
+ check "Kimi graph Skill restored" "$(cmp -s "$SB/kimi-graph.before.md" "$KIMI_LIVE/skills/graphify/SKILL.md" && echo yes || echo no)" "yes"
246
256
  check "capability config bytes restored" "$(cmp -s "$SB/capabilities.before.json" "$PROJECT_DATA/.ai/capabilities.json" && echo yes || echo no)" "yes"
247
257
  check "capability overlay bytes restored" "$(tree_hash "$PROJECT_DATA/.ai/capability-contract")" "$overlay_before"
248
258
  check "capability hook registrations restored" "$(capability_hook_count "$CLAUDE_OVERLAY/settings.json")" "5"
@@ -22,6 +22,7 @@ TPL="$CAIRN_ROOT/templates"
22
22
 
23
23
  LIVE_ROOT="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
24
24
  PI_LIVE_ROOT="${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}"
25
+ KIMI_LIVE_ROOT="${KIMI_CODE_HOME:-$HOME/.kimi-code}"
25
26
  STORE_DIR="${CAIRN_AGENTFS_BASE_DIR:-$HOME/.cairnkeep}"
26
27
  STORE_DIR="${STORE_DIR/#\~/$HOME}"
27
28
  DRY_RUN=0
@@ -49,7 +50,7 @@ PROJECT_AI_FILES=(
49
50
  usage() {
50
51
  cat <<'EOF'
51
52
  Usage: uninstall.sh [--dry-run] [--yes] [--purge-memory] [--live-root PATH]
52
- [--pi-live-root PATH] [PROJECT ...]
53
+ [--pi-live-root PATH] [--kimi-live-root PATH] [PROJECT ...]
53
54
 
54
55
  Reverse cairnkeep's install. Everything removed/edited is backed up into
55
56
  $HOME/.cairnkeep-uninstall-<ts>/ with a revert.sh before any change.
@@ -60,6 +61,7 @@ $HOME/.cairnkeep-uninstall-<ts>/ with a revert.sh before any change.
60
61
  trajectories in each PROJECT. Backed up first; off by default.
61
62
  --live-root PATH Claude root to clean (default: $CLAUDE_CONFIG_DIR or ~/.claude).
62
63
  --pi-live-root PATH Pi agent root to clean (default: $PI_CODING_AGENT_DIR or ~/.pi/agent).
64
+ --kimi-live-root PATH Kimi Code root to clean (default: $KIMI_CODE_HOME or ~/.kimi-code).
63
65
  PROJECT ... Also revert `cairn bootstrap` in these project dirs
64
66
  (.ai/, .planning/, and any .git/info/exclude entries).
65
67
  -h, --help Show this help.
@@ -73,6 +75,7 @@ while [[ $# -gt 0 ]]; do
73
75
  --purge-memory) PURGE_MEMORY=1; shift ;;
74
76
  --live-root) LIVE_ROOT="$2"; shift 2 ;;
75
77
  --pi-live-root) PI_LIVE_ROOT="$2"; shift 2 ;;
78
+ --kimi-live-root) KIMI_LIVE_ROOT="$2"; shift 2 ;;
76
79
  -h|--help) usage; exit 0 ;;
77
80
  -*) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
78
81
  *) PROJECTS+=("$1"); shift ;;
@@ -137,6 +140,7 @@ echo "cairn uninstall"
137
140
  [[ $DRY_RUN -eq 1 ]] && echo "(dry run — nothing will change)"
138
141
  echo " live root: $LIVE_ROOT"
139
142
  echo " Pi live root: $PI_LIVE_ROOT"
143
+ echo " Kimi root: $KIMI_LIVE_ROOT"
140
144
  echo " memory store: $STORE_DIR ($([[ $PURGE_MEMORY -eq 1 ]] && echo 'WILL be purged' || echo 'kept'))"
141
145
  [[ ${#PROJECTS[@]} -gt 0 ]] && echo " projects: ${PROJECTS[*]}"
142
146
 
@@ -150,10 +154,13 @@ fi
150
154
  echo "Operating layer (assets):"
151
155
  while IFS= read -r dst; do remove_path "$dst"; done < <(asset_dests)
152
156
 
153
- # The Pi adapter is one precisely owned extension; do not touch any other Pi
154
- # configuration or extensions in the same user root.
155
- echo "Pi extension:"
157
+ # These are precisely owned adapter paths; do not touch neighboring harness
158
+ # configuration in either user root.
159
+ echo "Pi adapters:"
156
160
  remove_path "$PI_LIVE_ROOT/extensions/cairnkeep-trajectory.ts"
161
+ remove_path "$PI_LIVE_ROOT/prompts/graphify.md"
162
+ echo "Kimi adapter:"
163
+ remove_path "$KIMI_LIVE_ROOT/skills/graphify/SKILL.md"
157
164
 
158
165
  # 2. settings.json hook registrations (back up whole file, then de-register).
159
166
  SETTINGS="$LIVE_ROOT/settings.json"