@ainova-systems/intelligence 0.11.0-rc.9 → 0.11.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.
Files changed (47) hide show
  1. package/cli/commands/adapter.sh +46 -6
  2. package/cli/commands/init.sh +182 -33
  3. package/cli/commands/package.sh +2 -2
  4. package/cli/commands/registry.sh +3 -3
  5. package/cli/commands/status.sh +4 -4
  6. package/cli/commands/sync.sh +76 -23
  7. package/cli/commands/update.sh +1 -1
  8. package/cli/intelligence +18 -3
  9. package/cli/internal/{upgrade-v2.sh → align-project.sh} +9 -8
  10. package/cli/internal/check.sh +51 -2
  11. package/cli/internal/{migrate-v1.sh → convert-legacy.sh} +33 -29
  12. package/cli/internal/package-add.sh +1 -1
  13. package/cli/internal/package-list.sh +1 -1
  14. package/cli/internal/package-remove.sh +1 -1
  15. package/cli/internal/package-search.sh +1 -1
  16. package/cli/internal/package-update.sh +1 -1
  17. package/cli/internal/restore.sh +1 -1
  18. package/cli/internal/target-state.sh +26 -18
  19. package/cli/lib/adapter-lifecycle.sh +43 -0
  20. package/cli/lib/cli-common.sh +12 -8
  21. package/cli/lib/gitignore.sh +215 -0
  22. package/cli/lib/manifest.sh +35 -1
  23. package/cli/lib/onboarding.sh +137 -0
  24. package/engine/ENGINE_SHA +1 -1
  25. package/engine/VERSION +1 -1
  26. package/engine/adapters/_template.sh +19 -2
  27. package/engine/adapters/agents.sh +14 -3
  28. package/engine/adapters/claude.sh +15 -0
  29. package/engine/adapters/codex.sh +11 -1
  30. package/engine/adapters/copilot.sh +11 -0
  31. package/engine/adapters/cursor.sh +15 -0
  32. package/engine/adapters/opencode.sh +13 -2
  33. package/engine/adapters/pi.sh +18 -5
  34. package/engine/lib/adapter-contract.sh +100 -0
  35. package/engine/lib/common.sh +5 -0
  36. package/engine/lib/contract.sh +2 -2
  37. package/engine/sync.sh +87 -25
  38. package/package.json +1 -1
  39. package/packages/sync/agents/intelligence-architect.md +2 -2
  40. package/packages/sync/references/adapters.md +51 -7
  41. package/packages/sync/references/conventions.md +60 -21
  42. package/packages/sync/references/onboarding-migration.md +87 -0
  43. package/packages/sync/skills/intelligence-install-adapter/SKILL.md +12 -5
  44. package/packages/sync/skills/intelligence-learn-from-context/SKILL.md +23 -4
  45. package/packages/sync/skills/intelligence-learn-from-repository/SKILL.md +94 -38
  46. package/packages/sync/skills/intelligence-review-skills/SKILL.md +1 -1
  47. package/packages/sync/skills/intelligence-sync/SKILL.md +9 -1
@@ -0,0 +1,100 @@
1
+ #!/bin/bash
2
+ # Declarative adapter ownership contract shared by the engine and CLI.
3
+ #
4
+ # Every adapter exposes adapter_contract_<name> <configured-output>. The
5
+ # function emits tab-separated records through the helpers below. Keeping the
6
+ # declaration beside sync_to_<name>() makes backup, rollback, git policy and
7
+ # lifecycle checks consume the same ownership model as the writer itself.
8
+
9
+ adapter_contract_version() { printf 'version\t%s\n' "$1"; }
10
+ adapter_contract_requires() { printf 'requires\t%s\n' "$1"; }
11
+ adapter_contract_owned() { printf 'owned\t%s\n' "$1"; }
12
+ adapter_contract_managed() { printf 'managed\t%s\n' "$1"; }
13
+ adapter_contract_legacy() { printf 'legacy\t%s\n' "$1"; }
14
+ adapter_contract_preserve() { printf 'preserve\t%s\n' "$1"; }
15
+ adapter_contract_ignore() { printf 'ignore\t%s\n' "$1"; }
16
+ adapter_contract_include() { printf 'include\t%s\n' "$1"; }
17
+
18
+ adapter_contract_function() {
19
+ printf 'adapter_contract_%s' "$1"
20
+ }
21
+
22
+ # Reject records that could address anything outside the repository. Contract
23
+ # paths are always repo-relative; ignore/include records may contain globs.
24
+ adapter_contract_safe_path() {
25
+ local path="$1"
26
+ case "$path" in
27
+ ""|/*|*\\*|[A-Za-z]:*|..|../*|*/../*|*/..|*$'\t'*|*$'\n'*) return 1 ;;
28
+ *) return 0 ;;
29
+ esac
30
+ }
31
+
32
+ adapter_contract_safe_concrete_path() {
33
+ adapter_contract_safe_path "$1" || return 1
34
+ case "$1" in
35
+ *'*'*|*'?'*|*'['*) return 1 ;;
36
+ *) return 0 ;;
37
+ esac
38
+ }
39
+
40
+ # adapter_contract_records <adapter-name> <adapter-file> <configured-output>
41
+ # Source and query in a subshell so a project adapter cannot leak shell state
42
+ # into the caller. Project adapters are trusted executable code during sync;
43
+ # the isolation here is for correctness, not a security boundary.
44
+ adapter_contract_records() (
45
+ local name="$1" file="$2" output="$3" fn line kind value saw_version=0
46
+ # shellcheck source=/dev/null
47
+ source "$file"
48
+ fn="$(adapter_contract_function "$name")"
49
+ declare -F "$fn" >/dev/null 2>&1 || {
50
+ echo "ERROR: adapter '$name' has no $fn contract" >&2
51
+ return 1
52
+ }
53
+ while IFS= read -r line; do
54
+ [ -n "$line" ] || continue
55
+ kind="${line%%$'\t'*}"
56
+ if [ "$kind" = "$line" ]; then
57
+ echo "ERROR: adapter '$name' emitted a malformed contract record" >&2
58
+ return 1
59
+ fi
60
+ value="${line#*$'\t'}"
61
+ case "$kind" in
62
+ version)
63
+ [ "$value" = "1" ] || {
64
+ echo "ERROR: adapter '$name' uses unsupported contract version '$value'" >&2
65
+ return 1
66
+ }
67
+ saw_version=1
68
+ ;;
69
+ requires)
70
+ case "$value" in
71
+ ""|[!abcdefghijklmnopqrstuvwxyz]*|*[!abcdefghijklmnopqrstuvwxyz0123456789_]*)
72
+ echo "ERROR: adapter '$name' declares invalid requirement '$value'" >&2
73
+ return 1
74
+ ;;
75
+ esac
76
+ ;;
77
+ owned|managed|legacy|preserve)
78
+ adapter_contract_safe_concrete_path "$value" || {
79
+ echo "ERROR: adapter '$name' declares unsafe $kind path '$value'" >&2
80
+ return 1
81
+ }
82
+ ;;
83
+ ignore|include)
84
+ adapter_contract_safe_path "$value" || {
85
+ echo "ERROR: adapter '$name' declares unsafe $kind path '$value'" >&2
86
+ return 1
87
+ }
88
+ ;;
89
+ *)
90
+ echo "ERROR: adapter '$name' emitted unknown contract record '$kind'" >&2
91
+ return 1
92
+ ;;
93
+ esac
94
+ printf '%s\n' "$line"
95
+ done < <("$fn" "$output")
96
+ [ "$saw_version" -eq 1 ] || {
97
+ echo "ERROR: adapter '$name' contract did not declare version 1" >&2
98
+ return 1
99
+ }
100
+ )
@@ -806,6 +806,11 @@ warn_unsynced() {
806
806
  case "$rel_dir" in
807
807
  .claude/*|.cursor/*|.github/*|.codex/*|.agents/*|.intelligence/*|*/node_modules/*|*/vendor/*|*/dist/*) continue ;;
808
808
  esac
809
+ # Initial onboarding backups are immutable migration evidence, never
810
+ # source directories. Suggesting one would reintroduce legacy content.
811
+ case "/$rel_dir/" in
812
+ *"/$intel_basename/_backup/"*) continue ;;
813
+ esac
809
814
 
810
815
  # Skip ignore/submodule patterns.
811
816
  local skip=false
@@ -9,8 +9,8 @@
9
9
  # * the IS_STATUS / IS_RC_* codes every engine flow reports.
10
10
  #
11
11
  # Schema migrations themselves are NOT here: the CLI owns them behind
12
- # `intelligence init`, and a v1 project is brought forward by the archived v1
13
- # engine before `intelligence init` converts it.
12
+ # `intelligence init`, and a legacy Intelligence Sync project is brought forward
13
+ # by its archived engine before `intelligence init` converts it.
14
14
 
15
15
  # The applied-schema version is a managed key in the manifest.
16
16
  #
package/engine/sync.sh CHANGED
@@ -19,6 +19,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
19
19
 
20
20
  source "$SCRIPT_DIR/lib/common.sh"
21
21
  source "$SCRIPT_DIR/lib/contract.sh"
22
+ source "$SCRIPT_DIR/lib/adapter-contract.sh"
22
23
 
23
24
  if [ -z "${CONFIG_FILE:-}" ] || [ ! -f "${CONFIG_FILE:-}" ]; then
24
25
  is_status config-missing "CONFIG_FILE=${CONFIG_FILE:-}"
@@ -85,31 +86,6 @@ echo " Config: $CONFIG_FILE"
85
86
  echo " Root: $REPO_ROOT"
86
87
  echo ""
87
88
 
88
- # Invariant: AGENTS.md is the canonical carrier of always-on rules for
89
- # Cursor / Copilot / Codex / Pi / opencode (their adapters skip always-on
90
- # rules to avoid duplication, since each tool reads AGENTS.md natively for
91
- # baseline project context). If those targets are enabled, `agents` must
92
- # also be enabled — otherwise always-on rules go nowhere for those tools.
93
- # Skip the check when the user requested a single target via $TARGET_FILTER:
94
- # they may be syncing only one IDE intentionally.
95
- if [ -z "$TARGET_FILTER" ]; then
96
- agents_enabled=$(is_target_enabled "$CONFIG_FILE" "agents")
97
- if [ "$agents_enabled" != "1" ]; then
98
- # AGENTS.md-dependent adapters: any tool whose adapter skips always-on
99
- # rule emission (because the tool reads AGENTS.md natively) must be
100
- # listed here. Add new adapters to this list when they ship.
101
- for tool in cursor copilot codex pi opencode; do
102
- if [ "$(is_target_enabled "$CONFIG_FILE" "$tool")" = "1" ]; then
103
- echo "ERROR: targets.$tool is enabled but targets.agents is not." >&2
104
- echo " $tool relies on AGENTS.md to deliver always-on rules — without it," >&2
105
- echo " always-on rules would be invisible to $tool." >&2
106
- echo " Either enable targets.agents in $CONFIG_FILE, or disable targets.$tool." >&2
107
- exit 1
108
- fi
109
- done
110
- fi
111
- fi
112
-
113
89
  # Lint frontmatter across all source files (rules, agents, skills).
114
90
  # Catches issues like unquoted colons that strict YAML consumers reject.
115
91
  for section in rules agents skills; do
@@ -167,6 +143,88 @@ for adapters_dir in "$SCRIPT_DIR/adapters" "$INTELLIGENCE_DIR/adapters"; do
167
143
  done
168
144
  done
169
145
 
146
+ # Validate every selected adapter contract before any output is touched, then
147
+ # snapshot the declared write-set. If a later adapter fails, the EXIT handler
148
+ # restores all earlier adapter outputs so sync is atomic from the repository's
149
+ # point of view.
150
+ SYNC_TX_DIR="$(mktemp -d -t intelligence-sync-XXXXXX)"
151
+ SYNC_TX_INDEX="$SYNC_TX_DIR/paths.tsv"
152
+ SYNC_TX_SEEN="$SYNC_TX_DIR/seen"
153
+ mkdir -p "$SYNC_TX_DIR/data"
154
+ : > "$SYNC_TX_INDEX"
155
+ : > "$SYNC_TX_SEEN"
156
+ SYNC_TX_ACTIVE=0
157
+
158
+ snapshot_sync_path() {
159
+ local adapter_name="$1" rel="$2" src index present=0
160
+ grep -Fqx -- "$rel" "$SYNC_TX_SEEN" && return 0
161
+ printf '%s\n' "$rel" >> "$SYNC_TX_SEEN"
162
+ validate_output_path "$REPO_ROOT" "$CONFIG_FILE" "$adapter_name" "$REPO_ROOT/$rel"
163
+ index="$(wc -l < "$SYNC_TX_INDEX" | tr -d ' ')"
164
+ src="$REPO_ROOT/$rel"
165
+ if [ -e "$src" ] || [ -L "$src" ]; then
166
+ cp -a "$src" "$SYNC_TX_DIR/data/$index"
167
+ present=1
168
+ fi
169
+ printf '%s\t%s\t%s\n' "$index" "$rel" "$present" >> "$SYNC_TX_INDEX"
170
+ }
171
+
172
+ restore_sync_snapshot() {
173
+ local index rel present dst
174
+ while IFS=$'\t' read -r index rel present; do
175
+ [ -n "$rel" ] || continue
176
+ dst="$REPO_ROOT/$rel"
177
+ rm -rf "$dst"
178
+ if [ "$present" = "1" ]; then
179
+ mkdir -p "$(dirname "$dst")"
180
+ cp -a "$SYNC_TX_DIR/data/$index" "$dst"
181
+ fi
182
+ done < "$SYNC_TX_INDEX"
183
+ }
184
+
185
+ finish_sync_transaction() {
186
+ local rc=$?
187
+ trap - EXIT INT TERM
188
+ set +e
189
+ if [ "${SYNC_TX_ACTIVE:-0}" = "1" ] && [ "$rc" -ne 0 ]; then
190
+ restore_sync_snapshot
191
+ echo "ERROR: sync failed; all adapter-owned paths were restored to their pre-sync state." >&2
192
+ fi
193
+ rm -rf "$SYNC_TX_DIR"
194
+ exit "$rc"
195
+ }
196
+ trap finish_sync_transaction EXIT
197
+ trap 'exit 130' INT TERM
198
+
199
+ preflight_idx=0
200
+ while [ "$preflight_idx" -lt "${#ADAPTERS[@]}" ]; do
201
+ adapter="${ADAPTERS[$preflight_idx]}"
202
+ adapter_file="${ADAPTER_FILES[$preflight_idx]}"
203
+ preflight_idx=$((preflight_idx + 1))
204
+ if [ -n "$TARGET_FILTER" ] && [ "$adapter" != "$TARGET_FILTER" ]; then
205
+ continue
206
+ fi
207
+ [ "$(is_target_enabled "$CONFIG_FILE" "$adapter")" = "1" ] || continue
208
+ output="$(get_target_output "$CONFIG_FILE" "$adapter")"
209
+ [ -n "$output" ] || output=".$adapter"
210
+ validate_output_path "$REPO_ROOT" "$CONFIG_FILE" "$adapter" "$REPO_ROOT/$output"
211
+ records="$(adapter_contract_records "$adapter" "$adapter_file" "$output")" || exit 1
212
+ while IFS=$'\t' read -r kind value; do
213
+ [ "$kind" = "requires" ] || continue
214
+ if [ "$(is_target_enabled "$CONFIG_FILE" "$value")" != "1" ]; then
215
+ echo "ERROR: targets.$adapter requires enabled target '$value'." >&2
216
+ echo " Enable it first: intelligence adapter enable $value" >&2
217
+ exit 1
218
+ fi
219
+ done <<< "$records"
220
+ while IFS=$'\t' read -r kind value; do
221
+ case "$kind" in
222
+ owned|managed) snapshot_sync_path "$adapter" "$value" ;;
223
+ esac
224
+ done <<< "$records"
225
+ done
226
+ SYNC_TX_ACTIVE=1
227
+
170
228
  synced=0
171
229
  adapter_count=${#ADAPTERS[@]}
172
230
  adapter_idx=0
@@ -224,6 +282,10 @@ if [ $synced -eq 0 ]; then
224
282
  exit 1
225
283
  fi
226
284
 
285
+ SYNC_TX_ACTIVE=0
286
+ rm -rf "$SYNC_TX_DIR"
287
+ trap - EXIT INT TERM
288
+
227
289
  # Warn about unsynced directories
228
290
  warn_unsynced "$REPO_ROOT" "$CONFIG_FILE"
229
291
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainova-systems/intelligence",
3
- "version": "0.11.0-rc.9",
3
+ "version": "0.11.1",
4
4
  "description": "Build, version and distribute AI agent intelligence across your organization — one CLI, versioned Intelligence Packages, and a sync engine for Claude Code, Cursor, Copilot, Codex, Pi and OpenCode.",
5
5
  "bin": {
6
6
  "intelligence": "bin/intelligence.js"
@@ -46,8 +46,8 @@ The per-artifact checks are procedure, so they live in the meta-skills rather th
46
46
  | `intelligence-add-rule` / `intelligence-add-agent` / `intelligence-add-skill` | author one artifact |
47
47
  | `intelligence-extract-skill` | turn an observed workflow into a skill |
48
48
  | `intelligence-review-skills` | audit the layer for duplication, drift, size, hardcoded paths |
49
- | `intelligence-learn-from-repository` | propose the initial project-owned layer from repository evidence |
50
- | `intelligence-learn-from-context` | fold a session's lessons back into the layer |
49
+ | `intelligence-learn-from-repository` | recover and complete first-time repository onboarding |
50
+ | `intelligence-learn-from-context` | fold one later session lesson into an established layer |
51
51
  | `intelligence-sync` | project the source to every tool channel |
52
52
  | `intelligence-update` | interpret and apply the CLI's unified update plan |
53
53
  | `intelligence-install-adapter` / `intelligence-uninstall-adapter` | research and manage a tool adapter |
@@ -42,14 +42,25 @@ To stop syncing a target:
42
42
  intelligence adapter disable mytool
43
43
  ```
44
44
 
45
- Disabling changes only target state. Generated output is deliberately kept because a generic command cannot know which paths a custom adapter owns. Remove only documented owned paths after reviewing them. A disabled project adapter can be deleted with `intelligence adapter remove mytool`; removal prompts by default, accepts `--apply` for explicit non-interactive use, and also keeps generated output. Built-in adapter source cannot be removed. Use `intelligence adapter list` to inspect source, state and output.
45
+ Disabling changes only target state. Generated output is deliberately kept so disabling is reversible; the adapter contract identifies its paths for review. A disabled project adapter can be deleted with `intelligence adapter remove mytool`; removal prompts by default, accepts `--apply` for explicit non-interactive use, and also keeps generated output. Built-in adapter source cannot be removed. Use `intelligence adapter list` to inspect source, state and output.
46
46
 
47
- ## Required function
47
+ ## Required interface
48
48
 
49
- The file name and function name form the adapter's identity:
49
+ The file name, contract function and sync function form the adapter's identity:
50
50
 
51
51
  ```bash
52
52
  # <content-dir>/adapters/mytool.sh
53
+ adapter_contract_mytool() {
54
+ local output="${1%/}"
55
+ adapter_contract_version 1
56
+ adapter_contract_owned "$output/rules"
57
+ adapter_contract_owned "$output/agents"
58
+ adapter_contract_owned "$output/skills"
59
+ adapter_contract_ignore "$output/rules/"
60
+ adapter_contract_ignore "$output/agents/"
61
+ adapter_contract_ignore "$output/skills/"
62
+ }
63
+
53
64
  sync_to_mytool() {
54
65
  local repo_root="$1"
55
66
  local config_file="$2"
@@ -59,6 +70,30 @@ sync_to_mytool() {
59
70
  }
60
71
  ```
61
72
 
73
+ The contract accepts the configured repo-relative output path and emits only
74
+ records through these helpers:
75
+
76
+ | Record | Meaning |
77
+ |---|---|
78
+ | `adapter_contract_version 1` | Required interface version |
79
+ | `adapter_contract_requires <name>` | Another target that must be enabled for a full sync |
80
+ | `adapter_contract_owned <path>` | Path exclusively regenerated by this adapter |
81
+ | `adapter_contract_managed <path>` | Shared or marker-managed path modified by this adapter |
82
+ | `adapter_contract_legacy <path>` | Pre-Intelligence input backed up, then quarantined for the first transactional render |
83
+ | `adapter_contract_preserve <path>` | Settings or state preserved in place and included in the initial backup |
84
+ | `adapter_contract_ignore <pattern>` | Exact `.gitignore` pattern managed on enable/init |
85
+ | `adapter_contract_include <pattern>` | Exact negated `.gitignore` pattern managed on enable/init |
86
+
87
+ All paths are repository-relative. The CLI refuses missing, malformed, unsafe,
88
+ or unsupported contracts before enabling or syncing an adapter. `owned` and
89
+ `managed` paths form the transactional write-set: if any adapter fails, the
90
+ engine restores every selected adapter path to its pre-sync state.
91
+
92
+ For an existing `.vscodeignore`, `.npmignore`, or `.dockerignore`, enable/init
93
+ also excludes the configured adapter output plus its `owned`, `managed`, and
94
+ `legacy` paths from published or build artifacts. This packaging policy is
95
+ separate from the narrower Git policy expressed by `ignore` and `include`.
96
+
62
97
  The engine calls:
63
98
 
64
99
  ```text
@@ -162,7 +197,7 @@ Built-ins currently emit Claude and Cursor Markdown, Copilot `.agent.md`, Codex
162
197
 
163
198
  Content shipped in `@ainova-systems/sync` cannot assume the project's content-directory name or package-store location. It uses these tokens:
164
199
 
165
- | Token | v2 expansion |
200
+ | Token | Expansion |
166
201
  |---|---|
167
202
  | `<content-dir>` | Project content directory, usually `intelligence` |
168
203
  | `<module>` | Installed sync package, usually `.intelligence/packages/@ainova-systems/sync` |
@@ -177,8 +212,8 @@ Call `finalize_output_file` on every text file after transformation. It expands
177
212
 
178
213
  Adapters regenerate output, so cleanup is part of their public contract.
179
214
 
180
- 1. Delete only paths the adapter owns. Preserve sibling settings, commands, extensions, workflows and hand-authored files.
181
- 2. Make ownership obvious in `sync_to_<name>()`; the same list is what a user removes after disabling or uninstalling the adapter.
215
+ 1. Delete only paths declared `owned`. Preserve sibling settings, commands, extensions, workflows and hand-authored files.
216
+ 2. Keep `adapter_contract_<name>()` exactly aligned with every path `sync_to_<name>()` writes or deletes.
182
217
  3. Use marker-based cleanup when generated and hand-authored files share a directory. The OpenCode adapter is the reference implementation.
183
218
  4. Use `sync_open_skill_dirs` for `.agents/skills/`; multiple adapters share it.
184
219
  5. Write only beneath the supplied `output_dir`, except for an explicitly shared standard path handled by a shared helper.
@@ -211,6 +246,13 @@ sync_mytool_rules() {
211
246
  done < <(read_yaml_list "$config_file" "rules")
212
247
  }
213
248
 
249
+ adapter_contract_mytool() {
250
+ local output="${1%/}"
251
+ adapter_contract_version 1
252
+ adapter_contract_owned "$output/rules"
253
+ adapter_contract_ignore "$output/rules/"
254
+ }
255
+
214
256
  sync_to_mytool() {
215
257
  local repo_root="$1" config_file="$2" output_dir="$3"
216
258
 
@@ -221,7 +263,7 @@ sync_to_mytool() {
221
263
 
222
264
  ## Testing
223
265
 
224
- Use a disposable Git repository with a v2 manifest and representative always-on/scoped rules, agents, skills and bundled skill resources.
266
+ Use a disposable Git repository with an Intelligence manifest and representative always-on/scoped rules, agents, skills and bundled skill resources.
225
267
 
226
268
  ```bash
227
269
  intelligence sync mytool
@@ -234,6 +276,8 @@ Verify:
234
276
  - skill resources are present;
235
277
  - no literal layout tokens remain;
236
278
  - hand-authored siblings under the tool root survive;
279
+ - a deliberately failing later adapter restores all earlier output byte-for-byte;
280
+ - `intelligence status --check` accepts the contract and its Git policy;
237
281
  - output paths cannot overlap sources or escape the repository;
238
282
  - a second sync produces no Git diff.
239
283
 
@@ -18,7 +18,7 @@ Use these tests:
18
18
 
19
19
  Do not bury conventions in agents, workflows in rules or reusable expertise in skills. Each misplaced concern either fails to load when needed or consumes context when it is not needed.
20
20
 
21
- ## v2 project structure
21
+ ## Intelligence project structure
22
22
 
23
23
  ```text
24
24
  project/
@@ -57,7 +57,7 @@ project:
57
57
  name: payments
58
58
  intelligence_dir: "intelligence" # optional; this is the default
59
59
 
60
- schema_version: "0.11.0"
60
+ schema_version: "0.11.1"
61
61
 
62
62
  sources:
63
63
  rules:
@@ -104,7 +104,7 @@ Commit `intelligence.lock`. It records requested versions, source URLs and paths
104
104
 
105
105
  Package-owned artifacts cannot assume the project's content-directory name or their installed package path. They use tokens expanded by every adapter through `finalize_output_file`:
106
106
 
107
- | Token | v2 expansion |
107
+ | Token | Expansion |
108
108
  |---|---|
109
109
  | `<content-dir>` | Repo-relative content directory, usually `intelligence` |
110
110
  | `<module>` | Installed sync package, usually `.intelligence/packages/@ainova-systems/sync` |
@@ -283,7 +283,7 @@ Size limits are backstops, not quotas:
283
283
 
284
284
  Every line enters a finite context budget. Prefer subtraction, consolidation and precise scope over exhaustive prose.
285
285
 
286
- ## Generated output
286
+ ## Generated output and version control
287
287
 
288
288
  | Target | Rules | Skills | Agents |
289
289
  |---|---|---|---|
@@ -297,22 +297,26 @@ Every line enters a finite context budget. Prefer subtraction, consolidation and
297
297
 
298
298
  `AGENTS.md` is regenerated by the `agents` adapter. Its optional static header is `targets.agents.header` in `intelligence.yaml`; generated rule, agent and skill sections follow it. Commit `AGENTS.md` when it is the project's shared canonical context.
299
299
 
300
- Generated IDE output may be gitignored when every collaborator can reproduce it with `intelligence sync`. Use narrow ownership patterns so hand-authored tool settings remain trackable:
300
+ By default, commit the manifest, lock, project-owned content, `AGENTS.md`, and shared `.github/` output. Ignore the restorable package store and tool output owned by enabled adapters. `intelligence init` and `intelligence adapter enable` add these patterns without ignoring shared tool roots or settings:
301
301
 
302
302
  ```gitignore
303
303
  # CLI-managed package store
304
304
  .intelligence/
305
305
 
306
- # Generated Claude and Cursor content; settings remain trackable
307
- .claude/rules/
308
- .claude/agents/
309
- .claude/skills/
310
- .cursor/rules/
311
- .cursor/agents/
312
- .cursor/skills/
306
+ # Local root instructions migrate into project rules; local preferences stay ignored
307
+ CLAUDE.md
308
+ .cursorrules
309
+
310
+ # Generated Claude and Cursor content; shared settings remain trackable
311
+ .claude/*
312
+ !.claude/
313
+ !.claude/settings.json
314
+ .cursor/*
315
+ !.cursor/
316
+ !.cursor/settings.json
313
317
 
314
318
  # Generated open-standard and Codex content
315
- .agents/
319
+ .agents/skills/
316
320
  .codex/agents/
317
321
 
318
322
  # Generated Pi content
@@ -320,12 +324,47 @@ Generated IDE output may be gitignored when every collaborator can reproduce it
320
324
  .pi/extensions/intelligence-sync-rules.ts
321
325
  .pi/prompts/intelligence-agent-*.md
322
326
 
323
- # Generated OpenCode agents. Its commands directory may also contain
324
- # hand-authored files, so choose per-project ignores there.
327
+ # Generated OpenCode agents. Commands share a directory with hand-authored
328
+ # files, so they remain tracked unless the project chooses exact file ignores.
325
329
  .opencode/agents/
326
330
  ```
327
331
 
328
- Copilot output lives under `.github/`; choose whether to commit it with other repository-level GitHub configuration. Do not ignore `.github/` wholesale.
332
+ Copilot output lives under `.github/` and is committed with other repository-level GitHub configuration. Do not ignore `.github/` wholesale. `AGENTS.md` is also committed so every clone has the shared tool-neutral entry point before sync.
333
+
334
+ Git tracking and release packaging are separate policies. When a project
335
+ already has `.vscodeignore`, `.npmignore`, or `.dockerignore`, the CLI appends a
336
+ small idempotent block excluding the package store, `intelligence.yaml`,
337
+ `intelligence.lock`, the complete project content directory, and enabled
338
+ adapter output. Existing entries remain untouched and absent secondary ignore
339
+ files are not created.
340
+
341
+ An ignore rule does not untrack a file already in Git. After init or adapter
342
+ enable, the CLI reports each affected tracked path that remains in the
343
+ worktree with an exact `git rm --cached -- '<path>'` command; this preserves
344
+ the local file while removing it from the index. Legacy root entry points
345
+ quarantined into the initial backup are ordinary worktree deletions to review
346
+ and stage, not candidates for `git rm --cached`.
347
+
348
+ Before release, inspect the packager's actual file list. An npm `files`
349
+ allowlist can force inclusion despite `.npmignore`, and a Dockerfile-specific
350
+ `<name>.Dockerfile.dockerignore` takes precedence over the root
351
+ `.dockerignore`. Use the relevant pack/list command as the final proof rather
352
+ than inferring contents from Git status.
353
+
354
+ `AGENTS.md` is the only shared root instruction entry point. During onboarding,
355
+ move useful repository guidance from legacy root files such as `.cursorrules`
356
+ and instruction-bearing `CLAUDE.md` out of their quarantined backup copies and
357
+ into project-owned rules, then verify the generated tool output. Do not restore
358
+ the original root monolith. Create a new root tool-specific file only when it
359
+ contains genuinely local configuration that an adapter cannot represent; keep
360
+ that exception gitignored rather than maintaining a second committed source.
361
+
362
+ Before the first render, `intelligence init` preserves existing AI prompt paths
363
+ under `<content-dir>/_backup/`. Its `manifest.tsv` labels the snapshot
364
+ `initial-onboarding`, lists exact original paths, and marks legacy entry points.
365
+ Those legacy paths are quarantined only for the transactional first render; a
366
+ failed render restores them, while a successful render leaves them inactive for
367
+ repository learning. The backup remains until the user approves removal.
329
368
 
330
369
  ## Project-owned adapters
331
370
 
@@ -337,7 +376,7 @@ intelligence adapter create mytool
337
376
  intelligence adapter enable mytool
338
377
  ```
339
378
 
340
- Project adapters survive CLI upgrades and may override a built-in by name. `intelligence adapter enable mytool` runs a full sync so shared context stays current. `intelligence adapter disable mytool` keeps generated output for explicit, adapter-aware cleanup; a disabled project adapter can then be deleted with `intelligence adapter remove mytool`. See `adapters.md` for the function, ownership and safety contracts.
379
+ Project adapters survive CLI upgrades and may override a built-in by name. Each adapter declares a versioned ownership contract beside its sync function; backup, rollback, dependencies and Git policy all consume it. `intelligence adapter enable mytool` runs a full transactional sync so shared context stays current. `intelligence adapter disable mytool` keeps generated output for explicit cleanup; a disabled project adapter can then be deleted with `intelligence adapter remove mytool`. See `adapters.md` for the interface and safety contract.
341
380
 
342
381
  ## Schema and command boundaries
343
382
 
@@ -345,14 +384,14 @@ The permanent applied-schema key is the top-level scalar `schema_version` in `in
345
384
 
346
385
  The public lifecycle is deliberately compact:
347
386
 
348
- - `intelligence init [--preview|--apply]` is universal: it creates a new setup, aligns an existing v2 project, or plans/applies conversion of an eligible v1 project.
349
- - `intelligence sync [adapter]` first aligns an existing v2 project with the installed CLI, restores a missing store strictly from `intelligence.lock`, then renders. In CI it refuses an upgrade that would change tracked files and points to a local `intelligence init --apply` plus review/commit.
387
+ - `intelligence init [--preview|--apply]` is universal: it creates a new setup, aligns an existing Intelligence project, or plans/applies conversion of an eligible legacy Intelligence Sync project.
388
+ - `intelligence sync [adapter] [--compact]` first aligns an existing Intelligence project with the installed CLI, restores a missing store strictly from `intelligence.lock`, then renders. Compact mode shows only final status on success and all diagnostics on failure. In CI it refuses an alignment that would change tracked files and points to a local `intelligence init --apply` plus review/commit.
350
389
  - `intelligence update [@scope/name] [--preview|--apply]` is the only update surface. It prints the CLI/project/package plan; default mode prompts, `--preview` never writes, and `--apply` does not prompt. It never moves `ref:` pins.
351
390
  - `intelligence package add|remove|list|search` owns package inventory.
352
391
  - `intelligence adapter list|create|enable|disable|remove` owns adapter inventory and target state.
353
392
  - `intelligence status [--check]` reports state; `--check` runs deep consistency checks.
354
393
 
355
- Implement v2 schema changes as idempotent structural checks. Stage and verify replacement state before deleting or replacing prior state. A stale engine refuses a manifest whose `schema_version` is newer; normal v2 entry points close a behind-project gap through lifecycle preflight.
394
+ Implement Intelligence schema changes as idempotent structural checks. Stage and verify replacement state before deleting or replacing prior state. A stale engine refuses a manifest whose `schema_version` is newer; normal project entry points close a behind-project gap through lifecycle preflight.
356
395
 
357
396
  Breaking changelog entries use a `### Breaking` checklist of verifiable post-conditions. The update skill reads every release across the version gap, chooses the package/CLI/project command sequence and verifies those conditions after the deterministic command completes.
358
397
 
@@ -382,4 +421,4 @@ Callers capture the real code with `command || rc=$?`. Do not use `if ! command;
382
421
  | `<content-dir>/{rules,agents,skills,adapters}/` | Project source of truth | Tracked |
383
422
  | `.intelligence/` | Restorable package store | Ignored |
384
423
  | `AGENTS.md` | Generated canonical project context | Normally tracked |
385
- | Tool output directories | Generated native content | Project policy; use narrow ignores |
424
+ | Tool output directories | Generated native content | Built-in adapter-owned paths ignored; shared settings tracked |
@@ -0,0 +1,87 @@
1
+ # Migrating Existing AI Instructions
2
+
3
+ Read this reference only when repository onboarding finds pre-existing AI
4
+ instructions, an `<content-dir>/_backup/` created by `intelligence init`, or a
5
+ Git diff showing that the first sync replaced tracked tool output.
6
+
7
+ ## Inventory and recovery
8
+
9
+ When `<content-dir>/_backup/manifest.tsv` contains
10
+ `state<TAB>initial-onboarding`, it is the authoritative inventory from before
11
+ the first generated write. Read each `target`, `path`, and `legacy` record
12
+ before looking at current adapter output. A `legacy` record means the CLI
13
+ quarantined that active entry point before the first successful render. If
14
+ `path<TAB>AGENTS.md` is present, the backed-up
15
+ file is the original custom project contract; keep following it while deciding
16
+ how to migrate its durable guidance.
17
+
18
+ Treat these as migration inputs, not as current generated output:
19
+
20
+ - root `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, and
21
+ `.github/copilot-instructions.md`;
22
+ - Claude and Cursor rules, agents, skills, and commands;
23
+ - Copilot instructions, prompts, agents, and skills;
24
+ - Codex/Open Agent Skills, Pi rules/prompts, and OpenCode agents/commands;
25
+ - scripts or documentation that describe an older sync path.
26
+
27
+ Prefer the copy under `<content-dir>/_backup/`; do not restore quarantined root
28
+ monoliths as active instructions. If the backup is absent and the first
29
+ sync changed tracked files, inspect their pre-sync content read-only through
30
+ Git (`git diff` and `git show HEAD:<path>`). Never restore old content directly
31
+ into an adapter output directory.
32
+
33
+ Build one conflict report before proposing changes:
34
+
35
+ - `MIGRATE`: instruction-bearing files whose useful content needs a
36
+ project-owned destination;
37
+ - `PRESERVE`: settings and unrelated shared files the adapters do not own;
38
+ - `REPLACE`: adapter-owned paths that sync regenerates;
39
+ - `STALE`: references to removed paths or commands requiring a decision.
40
+
41
+ Always preserve `.claude/settings.json`, `.claude/settings.local.json`,
42
+ `.cursor/settings.json`, Git metadata, workflows, and non-AI repository files.
43
+
44
+ ## Reverse mappings
45
+
46
+ Migrate meaning, not tool syntax:
47
+
48
+ | Existing format | Project-owned destination |
49
+ |---|---|
50
+ | Root `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, Copilot root instructions | Split verified guidance by topic into rules; keep local machine preferences in a gitignored root file only when no adapter representation exists |
51
+ | `.claude/rules/*.md` | Rule; preserve valid `paths:` |
52
+ | `.cursor/rules/*.mdc` | Rule; rename `globs:` to `paths:` and remove `alwaysApply:` |
53
+ | Claude/Cursor/Copilot agents | Agent; map native model/readonly/tool fields back to `tier:` and `access:` |
54
+ | Claude/Cursor/Copilot skills or commands | Skill when the procedure is repeated, multi-step, stable, and verifiable; otherwise a rule or no artifact |
55
+ | Pi/OpenCode/Codex prompt artifacts | Rule, agent, or skill according to responsibility, after removing tool-specific wrappers |
56
+
57
+ Verify every retained claim against repository code or executable
58
+ configuration. Do not preserve stale instructions merely because they existed.
59
+ Prefer updating an existing project-owned artifact to creating a sibling.
60
+
61
+ ## Apply and cleanup
62
+
63
+ Obtain approval per `CREATE`, `UPDATE`, `REMOVE`, or `KEEP` proposal. Apply
64
+ project-owned source changes first, then run `intelligence sync` and
65
+ `intelligence status --check`. Inspect the enabled targets to prove the
66
+ migrated guidance arrived and verify quarantined old root instructions remain
67
+ absent. Create a new root tool file only from a separately approved, genuinely
68
+ machine-local subset that has no adapter representation; never restore the
69
+ original instruction monolith.
70
+
71
+ For every removed or renamed path, search all tracked files with `git ls-files`
72
+ and report remaining references with file and line number. Apply an unambiguous
73
+ replacement directly; ask about narrative or otherwise ambiguous references.
74
+
75
+ The CLI owns generated-output `.gitignore` entries and its blocks in existing
76
+ `.vscodeignore`, `.npmignore`, and `.dockerignore` files. Verify them against
77
+ the enabled adapters. Treat CLI-reported tracked ignored paths that still exist
78
+ locally as unresolved until the user approves the exact `git rm --cached`
79
+ commands. A quarantined tracked legacy path is already a worktree deletion;
80
+ review and stage that deletion normally instead of using `git rm --cached`. Preserve
81
+ `AGENTS.md`, `.github/`, shared settings, and unrelated files under shared tool
82
+ roots in Git, while excluding development-only Intelligence content from
83
+ published artifacts. Inspect the packager's actual file list before release;
84
+ do not infer package or Docker context contents from Git status.
85
+
86
+ Keep `<content-dir>/_backup/` until the user separately approves its removal
87
+ after migration and reference checks pass. The backup remains gitignored.