@ainova-systems/intelligence 0.11.4 → 0.11.5

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.
@@ -57,9 +57,10 @@ if [ "$compact" -eq 0 ]; then
57
57
  exit $?
58
58
  fi
59
59
 
60
- # Compact mode is intentionally quiet only on success. Buffering the complete
61
- # combined stream means a failure still returns every diagnostic emitted by
62
- # lifecycle preflight, locked restore or the engine, together with its real rc.
60
+ # Compact mode keeps actionable one-line warnings on success. Buffering the
61
+ # complete combined stream means a failure still returns every diagnostic
62
+ # emitted by lifecycle preflight, locked restore or the engine, together with
63
+ # its real rc.
63
64
  compact_output="$(mktemp -t intelligence-sync-XXXXXX)"
64
65
  trap 'rm -f "$compact_output"' EXIT
65
66
  rc=0
@@ -76,5 +77,6 @@ if [ -z "$status_line" ] || [ -z "$done_line" ]; then
76
77
  echo "ERROR: sync succeeded without its final status contract" >&2
77
78
  exit 1
78
79
  fi
80
+ grep -E '^(WARNING:|CONTEXT:)' "$compact_output" || true
79
81
  echo "$status_line"
80
82
  echo "$done_line"
package/cli/intelligence CHANGED
@@ -47,7 +47,7 @@ Usage: intelligence <command> [args]
47
47
  --targets a,b --dir name --bare --no-sync New-project options
48
48
  --force Accept a dirty worktree during legacy project conversion
49
49
  sync [adapter] [--compact] Restore locked content, then render enabled adapters
50
- --compact On success show only final status; on failure show diagnostics
50
+ --compact On success show context, warnings and final status; on failure show diagnostics
51
51
  update [@scope/name] Show an update plan; ask before applying it
52
52
  --preview Show the plan without asking or writing
53
53
  --apply Apply the plan without asking
package/engine/ENGINE_SHA CHANGED
@@ -1 +1 @@
1
- a8e3accf49ce60d8e0b04f04bc68ef6f813f2a2e
1
+ bd688bcdb5443d808a72ed4e63805a65255a7d02
package/engine/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.4
1
+ 0.11.5
@@ -58,22 +58,11 @@ agents_md_append_agents_table() {
58
58
  local rows=""
59
59
  local count=0
60
60
 
61
- local src f
61
+ local f
62
62
  local -a files=()
63
- load_yaml_list "$config_file" "agents"
64
- local list="$IS_YAML_LIST"
65
- while IFS= read -r src; do
66
- [ -z "$src" ] && continue
67
- local dir="$repo_root/$src"
68
- [ -d "$dir" ] || continue
69
- # Byte-order (LC_ALL=C) sort so generated output is identical across
70
- # platforms — bash glob order follows LC_COLLATE, which differs between
71
- # Linux CI (UTF-8, ignores `-`) and Git Bash (C, byte order).
72
- while IFS= read -r f; do
73
- [ -f "$f" ] || continue
74
- files+=("$f")
75
- done < <(find "$dir" -maxdepth 1 -type f -name '*.md' -print | LC_ALL=C sort)
76
- done <<< "$list"
63
+ while IFS= read -r f; do
64
+ [ -n "$f" ] && files+=("$f")
65
+ done < <(source_artifact_files "$repo_root" "$config_file" "agents")
77
66
 
78
67
  if [ "${#files[@]}" -gt 0 ]; then
79
68
  local path tier access desc name
@@ -112,24 +101,11 @@ agents_md_append_skills_table() {
112
101
  local rows=""
113
102
  local count=0
114
103
 
115
- local src skill_dir dirname
104
+ local f dirname
116
105
  local -a skill_files=()
117
- load_yaml_list "$config_file" "skills"
118
- local list="$IS_YAML_LIST"
119
- while IFS= read -r src; do
120
- [ -z "$src" ] && continue
121
- local dir="$repo_root/$src"
122
- [ -d "$dir" ] || continue
123
- # Byte-order (LC_ALL=C) sort so generated output is identical across
124
- # platforms — see the note in agents_md_append_agents_table.
125
- while IFS= read -r skill_dir; do
126
- [ -d "$skill_dir" ] || continue
127
- dirname="${skill_dir##*/}"
128
- case "$dirname" in _*) continue ;; esac
129
- [ -f "${skill_dir%/}/SKILL.md" ] || continue
130
- skill_files+=("${skill_dir%/}/SKILL.md")
131
- done < <(find "$dir" -mindepth 1 -maxdepth 1 -type d -print | LC_ALL=C sort)
132
- done <<< "$list"
106
+ while IFS= read -r f; do
107
+ [ -n "$f" ] && skill_files+=("$f")
108
+ done < <(source_artifact_files "$repo_root" "$config_file" "skills")
133
109
 
134
110
  if [ "${#skill_files[@]}" -gt 0 ]; then
135
111
  local path desc
@@ -169,22 +145,11 @@ agents_md_append_rules_list() {
169
145
  local count=0
170
146
  local global_rule_files=()
171
147
 
172
- local src f
148
+ local f
173
149
  local -a files=()
174
- load_yaml_list "$config_file" "rules"
175
- local list="$IS_YAML_LIST"
176
- while IFS= read -r src; do
177
- [ -z "$src" ] && continue
178
- local dir="$repo_root/$src"
179
- [ -d "$dir" ] || continue
180
- # Byte-order (LC_ALL=C) sort so generated output — and the inline order
181
- # of always-on rules below — is identical across platforms. See the
182
- # note in agents_md_append_agents_table.
183
- while IFS= read -r f; do
184
- [ -f "$f" ] || continue
185
- files+=("$f")
186
- done < <(find "$dir" -maxdepth 1 -type f -name '*.md' -print | LC_ALL=C sort)
187
- done <<< "$list"
150
+ while IFS= read -r f; do
151
+ [ -n "$f" ] && files+=("$f")
152
+ done < <(source_artifact_files "$repo_root" "$config_file" "rules")
188
153
 
189
154
  if [ "${#files[@]}" -gt 0 ]; then
190
155
  local path hp name scope
@@ -251,10 +216,8 @@ agents_md_append_rules_list() {
251
216
 
252
217
  # Main entry point for AGENTS.md adapter
253
218
  adapter_contract_agents() {
254
- local output="$1"
255
- if [[ "$output" == */ ]] || [[ "$output" != *.md ]]; then
256
- output="${output%/}/AGENTS.md"
257
- fi
219
+ local output
220
+ output="$(agents_output_path "$1")"
258
221
  adapter_contract_version 1
259
222
  adapter_contract_owned "$output"
260
223
  adapter_contract_legacy "AGENTS.md"
@@ -271,10 +234,8 @@ sync_to_agents() {
271
234
  # If it looks like a directory lexically (trailing slash or no .md
272
235
  # extension), append the default filename. The ownership contract uses the
273
236
  # same rule, so filesystem state cannot make its write-set ambiguous.
274
- local output_file="$output_dir"
275
- if [[ "$output_file" == */ ]] || [[ "$output_file" != *.md ]]; then
276
- output_file="${output_file%/}/AGENTS.md"
277
- fi
237
+ local output_file
238
+ output_file="$(agents_output_path "$output_dir")"
278
239
 
279
240
  mkdir -p "$(dirname "$output_file")"
280
241
 
@@ -26,6 +26,44 @@ adapter_contract_codex() {
26
26
  adapter_contract_ignore "$output/agents/"
27
27
  }
28
28
 
29
+ # Codex-specific guard for its documented project-instruction byte budget.
30
+ # A personal/project Codex config may already raise the actual limit, so the
31
+ # manifest exposes one warning setting: false disables it, while a positive
32
+ # byte count matches an effective limit the adapter cannot discover itself.
33
+ codex_warn_project_doc_size() {
34
+ local repo_root="$1"
35
+ local config_file="$2"
36
+ local warning_setting warning_limit=32768
37
+ warning_setting="$(get_target_field "$config_file" "codex" "warn_project_doc_limit")"
38
+ case "$warning_setting" in
39
+ ''|true) ;;
40
+ false) return 0 ;;
41
+ *[!0-9]*|0|0*)
42
+ echo "ERROR: targets.codex.warn_project_doc_limit must be true, false, or a positive byte count without leading zeros." >&2
43
+ return 1
44
+ ;;
45
+ *) warning_limit="$warning_setting" ;;
46
+ esac
47
+
48
+ target_output_var "$config_file" "agents"
49
+ local output
50
+ output="$(agents_output_path "${IS_TGT_OUTPUT:-.agents}")"
51
+
52
+ local output_file="$repo_root/$output"
53
+ [ -f "$output_file" ] || return 0
54
+
55
+ local bytes
56
+ bytes="$(context_files_bytes "$output_file")"
57
+ [ "$bytes" -gt "$warning_limit" ] || return 0
58
+
59
+ local recommended="$warning_limit"
60
+ while [ "$recommended" -lt "$bytes" ]; do
61
+ recommended=$((recommended * 2))
62
+ done
63
+
64
+ echo "WARNING: Codex may truncate $output: $bytes bytes exceeds the $warning_limit-byte Intelligence warning threshold; set project_doc_max_bytes = $recommended in Codex config.toml and restart Codex, reduce/split the instructions, set targets.codex.warn_project_doc_limit to the effective byte limit, or set it to false to disable this warning."
65
+ }
66
+
29
67
  # Sync skills to Codex format (.agents/skills/{name}/SKILL.md)
30
68
  sync_codex_skills() {
31
69
  local repo_root="$1"
@@ -117,4 +155,6 @@ sync_to_codex() {
117
155
  rm -rf "$agents_dir"
118
156
  mkdir -p "$agents_dir"
119
157
  sync_codex_agents "$repo_root" "$config_file" "$agents_dir"
158
+
159
+ codex_warn_project_doc_size "$repo_root" "$config_file"
120
160
  }
@@ -641,23 +641,16 @@ sync_open_skill_dirs() {
641
641
  fi
642
642
  mkdir -p "$output_dir"
643
643
 
644
- local count=0 log="" d skill_name src list
644
+ local count=0 log="" d skill_file skill_name
645
645
  local -a skill_dirs=()
646
- load_yaml_list "$config_file" "skills"
647
- list="$IS_YAML_LIST"
648
- while IFS= read -r src; do
649
- [ -z "$src" ] && continue
650
- local dir="$repo_root/$src"
651
- [ -d "$dir" ] || continue
652
- for d in "$dir"/*/; do
653
- [ -d "$d" ] || continue
654
- skill_name="${d%/}"; skill_name="${skill_name##*/}"
655
- [ -f "$d/SKILL.md" ] || continue
656
- skill_dirs+=("$d")
657
- count=$((count + 1))
658
- log+=" skill: $skill_name"$'\n'
659
- done
660
- done <<< "$list"
646
+ while IFS= read -r skill_file; do
647
+ [ -n "$skill_file" ] || continue
648
+ d="${skill_file%/SKILL.md}"
649
+ skill_name="${d##*/}"
650
+ skill_dirs+=("$d/")
651
+ count=$((count + 1))
652
+ log+=" skill: $skill_name"$'\n'
653
+ done < <(source_artifact_files "$repo_root" "$config_file" "skills")
661
654
  # copy_skill_bundle_dirs owns the frontmatter-quoting pass, so every
662
655
  # target gets it — not just this open-standard dir.
663
656
  if [ "$count" -gt 0 ]; then
@@ -1335,6 +1328,109 @@ warn_unsynced() {
1335
1328
  fi
1336
1329
  }
1337
1330
 
1331
+ # Enumerate one manifest source kind using the same depth and ordering
1332
+ # everywhere. Source-list order is significant; entries inside each directory
1333
+ # use byte-order sorting for cross-platform determinism.
1334
+ source_artifact_files() {
1335
+ local repo_root="$1"
1336
+ local config_file="$2"
1337
+ local section="$3"
1338
+ local src f dir
1339
+
1340
+ load_yaml_list "$config_file" "$section"
1341
+ while IFS= read -r src; do
1342
+ [ -n "$src" ] || continue
1343
+ dir="$repo_root/$src"
1344
+ [ -d "$dir" ] || continue
1345
+ case "$section" in
1346
+ rules|agents)
1347
+ find "$dir" -maxdepth 1 -type f -name '*.md' -print | LC_ALL=C sort
1348
+ ;;
1349
+ skills)
1350
+ while IFS= read -r f; do
1351
+ [ -n "$f" ] || continue
1352
+ [ -f "$f/SKILL.md" ] && printf '%s\n' "$f/SKILL.md"
1353
+ done < <(find "$dir" -mindepth 1 -maxdepth 1 -type d -print | LC_ALL=C sort)
1354
+ ;;
1355
+ esac
1356
+ done <<< "$IS_YAML_LIST"
1357
+ }
1358
+
1359
+ # Apply the agents adapter's lexical output rule without consulting filesystem
1360
+ # state. An omitted output uses the generic adapter default directory.
1361
+ agents_output_path() {
1362
+ local output="${1:-.agents}"
1363
+ if [[ "$output" == */ ]] || [[ "$output" != *.md ]]; then
1364
+ output="${output%/}/AGENTS.md"
1365
+ fi
1366
+ printf '%s\n' "$output"
1367
+ }
1368
+
1369
+ # Report source prompt pressure independently of adapter formats. "Always-on"
1370
+ # means rules without paths; "custom" means scoped rules, agent prompts and
1371
+ # skill entry points. Supporting skill assets are excluded because tools load
1372
+ # them only when a skill explicitly reads them. When the shared agents target
1373
+ # exists, also report its rendered size; policy for any tool-specific limit
1374
+ # stays in that tool's adapter.
1375
+ context_files_bytes() {
1376
+ if [ "$#" -eq 0 ]; then
1377
+ echo 0
1378
+ return 0
1379
+ fi
1380
+ LC_ALL=C wc -c "$@" | awk 'END { print $1 + 0 }'
1381
+ }
1382
+
1383
+ report_context_source_sizes() {
1384
+ local repo_root="$1"
1385
+ local config_file="$2"
1386
+ local f path has_paths
1387
+ local -a rule_files=() always_on_rules=() scoped_rules=() agent_files=() skill_files=()
1388
+
1389
+ while IFS= read -r f; do
1390
+ [ -n "$f" ] && rule_files+=("$f")
1391
+ done < <(source_artifact_files "$repo_root" "$config_file" "rules")
1392
+ if [ "${#rule_files[@]}" -gt 0 ]; then
1393
+ while IFS=$'\x1f' read -r path has_paths; do
1394
+ [ -n "$path" ] || continue
1395
+ if [ "$has_paths" = "0" ]; then
1396
+ always_on_rules+=("$path")
1397
+ else
1398
+ scoped_rules+=("$path")
1399
+ fi
1400
+ done < <(frontmatter_index "paths#" "${rule_files[@]}")
1401
+ fi
1402
+
1403
+ while IFS= read -r f; do
1404
+ [ -n "$f" ] && agent_files+=("$f")
1405
+ done < <(source_artifact_files "$repo_root" "$config_file" "agents")
1406
+
1407
+ while IFS= read -r f; do
1408
+ [ -n "$f" ] && skill_files+=("$f")
1409
+ done < <(source_artifact_files "$repo_root" "$config_file" "skills")
1410
+
1411
+ local always_bytes custom_bytes agents_output agents_bytes=0 agents_status="disabled"
1412
+ always_bytes="$(context_files_bytes "${always_on_rules[@]+"${always_on_rules[@]}"}")"
1413
+ custom_bytes="$(context_files_bytes \
1414
+ "${scoped_rules[@]+"${scoped_rules[@]}"}" \
1415
+ "${agent_files[@]+"${agent_files[@]}"}" \
1416
+ "${skill_files[@]+"${skill_files[@]}"}")"
1417
+ target_enabled_var "$config_file" "agents"
1418
+ if [ "$IS_TGT_ENABLED" = "1" ]; then
1419
+ agents_status="not-generated"
1420
+ target_output_var "$config_file" "agents"
1421
+ agents_output="$(agents_output_path "${IS_TGT_OUTPUT:-.agents}")"
1422
+ if [ -f "$repo_root/$agents_output" ]; then
1423
+ agents_bytes="$(context_files_bytes "$repo_root/$agents_output")"
1424
+ agents_status="generated"
1425
+ fi
1426
+ fi
1427
+
1428
+ printf 'CONTEXT: always-on=%s bytes (%s rules); custom=%s bytes (%s scoped rules, %s agents, %s skills); agents-md=%s bytes; agents-md-status=%s\n' \
1429
+ "$always_bytes" "${#always_on_rules[@]}" "$custom_bytes" \
1430
+ "${#scoped_rules[@]}" "${#agent_files[@]}" "${#skill_files[@]}" \
1431
+ "$agents_bytes" "$agents_status"
1432
+ }
1433
+
1338
1434
  # --- Config Parsing ---
1339
1435
 
1340
1436
  # Read a simple list from config.yaml
@@ -1415,9 +1511,9 @@ load_yaml_list() {
1415
1511
 
1416
1512
  # load_targets_cache <file> — parse the whole targets: section once into the
1417
1513
  # global IS_TGT_TSV (one `name<TAB>enabled<TAB>output` row per target),
1418
- # replicating is_target_enabled and get_target_output semantics: inline and
1419
- # block forms, first occurrence wins, `enabled` defaults to 0 when the block
1420
- # ends without one and to empty at end of file. The engine warms this once;
1514
+ # matching is_target_enabled and get_target_output semantics: inline and block
1515
+ # forms, first occurrence wins, `enabled` defaults to 0 when the block ends
1516
+ # without one and to empty at end of file. The engine warms this once;
1421
1517
  # both readers consult it before spawning awk.
1422
1518
  load_targets_cache() {
1423
1519
  local file="$1"
@@ -1433,20 +1529,9 @@ load_targets_cache() {
1433
1529
  }
1434
1530
  { sub(/\r$/, "") }
1435
1531
  /^targets:[[:space:]]*$/ { in_targets = 1; next }
1436
- /^[a-zA-Z]/ { in_targets = 0 }
1437
- # The per-target readers scanned forward for the FIRST line containing
1438
- # `enabled:` / `output:` after the target header, checking it before
1439
- # the block-end test — so a sibling header line could donate its own
1440
- # inline values to a block that lacked them. These two rules run
1441
- # before the header rule below to keep that reading.
1442
- name != "" && enabled == "" && /enabled:/ {
1443
- enabled = ($0 ~ /true/) ? 1 : 0
1444
- }
1445
- name != "" && output == "" && /output:/ {
1446
- val = $0
1447
- sub(/.*output:[[:space:]]*["\047]?/, "", val)
1448
- sub(/["\047]?[[:space:]]*}?$/, "", val)
1449
- output = val
1532
+ /^[a-zA-Z]/ {
1533
+ if (in_targets) flush_target(0)
1534
+ in_targets = 0
1450
1535
  }
1451
1536
  in_targets && $0 ~ /^ [a-zA-Z0-9_-]+:/ {
1452
1537
  flush_target(1)
@@ -1465,7 +1550,15 @@ load_targets_cache() {
1465
1550
  }
1466
1551
  next
1467
1552
  }
1468
- name != "" && /^ [a-zA-Z]/ { flush_target(1) }
1553
+ name != "" && enabled == "" && /^ enabled:/ {
1554
+ enabled = ($0 ~ /true/) ? 1 : 0
1555
+ }
1556
+ name != "" && output == "" && /^ output:/ {
1557
+ val = $0
1558
+ sub(/.*output:[[:space:]]*["\047]?/, "", val)
1559
+ sub(/["\047]?[[:space:]]*}?$/, "", val)
1560
+ output = val
1561
+ }
1469
1562
  END { flush_target(0) }
1470
1563
  ' "$file")"
1471
1564
  IS_TGT_FILE="$file"
@@ -1530,6 +1623,7 @@ is_target_enabled() {
1530
1623
 
1531
1624
  # Enter/leave the targets: section
1532
1625
  /^targets:[[:space:]]*$/ { in_targets = 1; next }
1626
+ in_target && /^[a-zA-Z]/ { exit }
1533
1627
  /^[a-zA-Z]/ { in_targets = 0 }
1534
1628
 
1535
1629
  in_targets && $0 ~ "^ " target ":" {
@@ -1537,11 +1631,11 @@ is_target_enabled() {
1537
1631
  if ($0 ~ /enabled:[[:space:]]*false/) { print 0; exit }
1538
1632
  in_target = 1; next
1539
1633
  }
1540
- in_target && /enabled:/ {
1634
+ in_target && /^ [a-zA-Z0-9_-]+:/ { print 0; exit }
1635
+ in_target && /^ enabled:/ {
1541
1636
  if ($0 ~ /true/) { print 1 } else { print 0 }
1542
1637
  exit
1543
1638
  }
1544
- in_target && /^ [a-zA-Z]/ { print 0; exit }
1545
1639
  ' "$file"
1546
1640
  }
1547
1641
 
@@ -1556,6 +1650,7 @@ get_target_field() {
1556
1650
  awk -v target="$target" -v field="$field" '
1557
1651
  { sub(/\r$/, "") }
1558
1652
  /^targets:[[:space:]]*$/ { in_targets = 1; next }
1653
+ in_target && /^[a-zA-Z]/ { exit }
1559
1654
  /^[a-zA-Z]/ { in_targets = 0 }
1560
1655
 
1561
1656
  in_targets && $0 ~ "^ " target ":" {
@@ -1601,6 +1696,7 @@ get_target_output() {
1601
1696
  { sub(/\r$/, "") }
1602
1697
 
1603
1698
  /^targets:[[:space:]]*$/ { in_targets = 1; next }
1699
+ in_target && /^[a-zA-Z]/ { exit }
1604
1700
  /^[a-zA-Z]/ { in_targets = 0 }
1605
1701
 
1606
1702
  in_targets && $0 ~ "^ " target ":" {
@@ -1616,14 +1712,14 @@ get_target_output() {
1616
1712
  }
1617
1713
  in_target = 1; next
1618
1714
  }
1619
- in_target && /output:/ {
1715
+ in_target && /^ [a-zA-Z0-9_-]+:/ { exit }
1716
+ in_target && /^ output:/ {
1620
1717
  val = $0
1621
1718
  sub(/.*output:[[:space:]]*["\047]?/, "", val)
1622
1719
  sub(/["\047]?[[:space:]]*}?$/, "", val)
1623
1720
  print val
1624
1721
  exit
1625
1722
  }
1626
- in_target && /^ [a-zA-Z]/ { exit }
1627
1723
  ' "$file"
1628
1724
  }
1629
1725
 
package/engine/sync.sh CHANGED
@@ -311,6 +311,9 @@ trap - EXIT INT TERM
311
311
  # Warn about unsynced directories
312
312
  warn_unsynced "$REPO_ROOT" "$CONFIG_FILE"
313
313
 
314
+ # Report adapter-agnostic source context pressure on every successful sync.
315
+ report_context_source_sizes "$REPO_ROOT" "$CONFIG_FILE"
316
+
314
317
  # Report model overrides that drift from intelligence-sync defaults
315
318
  # (helpful when defaults move forward — e.g., gpt-5.5 -> gpt-5.6).
316
319
  report_model_drift "$CONFIG_FILE"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainova-systems/intelligence",
3
- "version": "0.11.4",
3
+ "version": "0.11.5",
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"
@@ -8,6 +8,7 @@ skills:
8
8
  - intelligence-add-agent
9
9
  - intelligence-add-skill
10
10
  - intelligence-extract-skill
11
+ - intelligence-compact-context
11
12
  - intelligence-review-skills
12
13
  - intelligence-learn-from-repository
13
14
  - intelligence-learn-from-context
@@ -45,6 +46,7 @@ The per-artifact checks are procedure, so they live in the meta-skills rather th
45
46
  |---|---|
46
47
  | `intelligence-add-rule` / `intelligence-add-agent` / `intelligence-add-skill` | author one artifact |
47
48
  | `intelligence-extract-skill` | turn an observed workflow into a skill |
49
+ | `intelligence-compact-context` | reduce context without changing behavior or teaching terse output |
48
50
  | `intelligence-review-skills` | audit the layer for duplication, drift, size, hardcoded paths |
49
51
  | `intelligence-learn-from-repository` | recover and complete first-time repository onboarding |
50
52
  | `intelligence-learn-from-context` | fold one later session lesson into an established layer |
@@ -172,6 +172,10 @@ Intelligence routes always-on rules once through `AGENTS.md` for tools that cons
172
172
 
173
173
  If a new adapter relies on `AGENTS.md` for always-on rules, its target must require `agents`. Add that invariant to `engine/sync.sh` when contributing the adapter upstream.
174
174
 
175
+ Every successful sync prints an adapter-agnostic `CONTEXT:` summary with source byte totals and file counts. It separates always-on rules from custom context (scoped rules, agent prompts and skill entry points), then reports a numeric `agents-md` byte count and `generated`, `not-generated`, or `disabled` status; supporting skill assets are excluded until explicitly read. Adapter-specific hard limits and suppression controls stay inside the adapter that owns them.
176
+
177
+ The Codex adapter checks its `project_doc_max_bytes` default (32 KiB). When generated `AGENTS.md` exceeds it, sync prints the byte count and a sufficient Codex setting. The warning says "may truncate" because a developer can already have a larger override. `targets.codex.warn_project_doc_limit` accepts `true` or omission for the default threshold, a positive byte count to match another effective limit, or `false` to disable the Intelligence warning. Both inline and block target forms work, and the field does not change Codex configuration. The warning remains visible in `sync --compact`.
178
+
175
179
  ### Skills
176
180
 
177
181
  Skills follow the [Agent Skills standard](https://agentskills.io). Copy each skill directory as a complete bundle—not only `SKILL.md`—because its body may reference `references/`, `scripts/` or `assets/` beside it.
@@ -385,7 +385,7 @@ The permanent applied-schema key is the top-level scalar `schema_version` in `in
385
385
  The public lifecycle is deliberately compact:
386
386
 
387
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.
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 context sizes, actionable warnings and 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.
389
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.
390
390
  - `intelligence package add|remove|list|search` owns package inventory.
391
391
  - `intelligence adapter list|create|enable|disable|remove` owns adapter inventory and target state.
@@ -60,7 +60,7 @@ The mistakes that actually happen, in order of frequency:
60
60
 
61
61
  ### Invariants
62
62
 
63
- - **Never state behaviour of a tool or engine you have not verified in its documentation or source.** This invariant exists because the claim *"Claude Code does not auto-load `.claude/rules/`"* was once written into this layer as fact. It is false — rules without `paths:` load at launch, path-scoped ones activate on matching files, and custom subagents inherit both (Claude Code docs: *Memory → Organize rules with `.claude/rules/`*, and *Subagents → What loads at startup*). An unverified claim about tooling is worse than a gap: nothing in the repository contradicts it, so it silently reshapes every decision downstream.
63
+ - **Never state behaviour of a tool or engine you have not verified in its documentation or source.** An unverified claim about tooling is worse than a gap: nothing in the repository contradicts it, so it silently reshapes every decision downstream. Verified means a page you can cite - for how rules load, the Claude Code docs *Memory → Organize rules with `.claude/rules/`* and *Subagents → What loads at startup*.
64
64
  - **Never write a current defect into a rule as if it were the design.** Known breakage belongs in one place that says so. Every other rule describes the project *as it is meant to work* — a workaround documented as procedure becomes permanent.
65
65
  - **Never link from one always-on rule to another.** Always-on rules are inlined verbatim into `AGENTS.md`, and the path-scoped channels carry only scoped rules, so a relative link is dead in at least one output. Name the rule instead; it loads on its own.
66
66
 
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: intelligence-compact-context
3
+ description: "Reduce rules, agents, and skills without changing behavior or teaching terse output"
4
+ argument-hint: "[target: rules|agents|skills|all]"
5
+ agent: intelligence-architect
6
+ ---
7
+
8
+ # Compact intelligence context
9
+
10
+ Reduce persistent and on-demand prompt cost by changing structure before wording.
11
+ The result must preserve the layer's behavioral contract and ordinary, complete
12
+ language; a smaller file is not a success if agents become terse, vague, or less
13
+ reliable.
14
+
15
+ ## Analyze
16
+
17
+ 1. Resolve `<manifest>`, `<content-dir>`, and `<module>`. Enumerate the source
18
+ directories declared under `sources.rules`, `sources.agents`, and
19
+ `sources.skills`; skip installed package sources and generated adapter output.
20
+
21
+ 2. Read `<module>/references/conventions.md`, the `intelligence-authoring` rule,
22
+ and [references/principles.md](references/principles.md). The reference
23
+ explains which forms of indirection save context and which merely move text.
24
+
25
+ 3. Run `<sync-cmd> --compact` and save the `CONTEXT:` line as the baseline,
26
+ including its rendered `agents-md` byte count. Record individual source-file
27
+ byte and line counts for the requested target.
28
+
29
+ 4. Invoke `intelligence-review-skills` for the same target. Reuse its findings
30
+ for duplication, misplaced content, scope, stale artifacts, pressure markers,
31
+ history narrative, and description budget; do not reproduce its audit.
32
+
33
+ 5. Build a semantic ledger before drafting edits. For every candidate passage,
34
+ record:
35
+
36
+ - the behavior, constraint, procedure, or expertise it carries;
37
+ - its one authoritative owner;
38
+ - when it must load;
39
+ - the reason or example needed to apply it correctly;
40
+ - the repository evidence or external documentation that supports it.
41
+
42
+ Two passages are duplicates only when those meanings match. Similar wording
43
+ with different scope, priority, or failure behavior is not duplication.
44
+
45
+ ## Draft the compaction
46
+
47
+ 6. Apply structural reductions in this order:
48
+
49
+ 1. Replace an instruction with a deterministic gate or command when the
50
+ repository already enforces it.
51
+ 2. Delete generic knowledge and facts the agent can read directly from the
52
+ repository, unless a non-obvious interpretation is the instruction.
53
+ 3. Keep one owner for duplicated guidance and remove the copies. A skill may
54
+ invoke another skill by name; an agent may list a skill; neither restates
55
+ the called artifact.
56
+ 4. Add `paths:` to rules that matter only in part of the repository.
57
+ 5. Move multi-step procedures from rules or agents into skills, and move
58
+ reusable constraints or expertise to the artifact type that owns them.
59
+ 6. Move optional skill detail into skill-local `references/` and state the
60
+ exact condition that requires each file. Do not use an always-loaded
61
+ import or an unconditional read step and call that compaction.
62
+ 7. Tighten prose only after the preceding reductions are exhausted.
63
+
64
+ 7. Preserve language quality while tightening prose:
65
+
66
+ - Use complete grammatical sentences and ordinary project vocabulary.
67
+ - Preserve the reason when it guides judgment, and keep one minimal example
68
+ when the rule would otherwise be ambiguous.
69
+ - Preserve triggers, boundaries, ordering, failure behavior, verification,
70
+ and output contracts exactly.
71
+ - Shorten descriptions by retaining the unique trigger that distinguishes a
72
+ sibling; never reduce them to vague labels.
73
+ - Do not add instructions telling agents to be terse, abbreviated, clipped,
74
+ or concise unless that response style is an explicit product requirement.
75
+ - Do not turn prose into fragments, dense acronyms, slash-separated phrases,
76
+ or unexplained labels. Compression targets redundancy, not grammar.
77
+
78
+ 8. Treat references according to load behavior:
79
+
80
+ - A conditional skill reference saves startup context.
81
+ - An always-loaded import improves organization but does not save context.
82
+ - A plain link is navigation, not guaranteed instruction loading; never hide
83
+ a critical constraint behind one.
84
+ - An always-on rule that is too large normally needs deletion, scoping, a
85
+ gate, or conversion of its procedure into a skill—not a reference index.
86
+
87
+ ## Approval and apply
88
+
89
+ 9. Present a proposal grouped as `DELETE`, `MERGE`, `SCOPE`, `MOVE`,
90
+ `REFERENCE`, or `REWRITE`. For each item show the owner, semantic contract,
91
+ estimated bytes saved, and any behavior that could change. Ask for approval
92
+ before changing meaning, ownership, scope, or load timing.
93
+
94
+ 10. Apply only accepted items to project-owned sources. Preserve unapproved
95
+ passages byte-for-byte and never edit generated output or installed package
96
+ sources locally.
97
+
98
+ ## Verify
99
+
100
+ 11. Compare the semantic ledger with the diff. Every original behavior must be
101
+ present once in its authoritative owner, deliberately removed with approval,
102
+ or enforced by the named deterministic mechanism. Check that no move created
103
+ a dead link, unconditional reference load, conflicting instruction, or
104
+ broader scope.
105
+
106
+ 12. Run `<sync-cmd> --compact`, require `IS_STATUS=ok`, then run
107
+ `intelligence status --check`. Compare the new `CONTEXT:` line and per-file
108
+ counts with the baseline.
109
+
110
+ 13. Exercise three representative prompts when the environment supports agent
111
+ evaluation: one direct case governed by a compacted instruction, one adjacent
112
+ judgment case that needs its reason, and one ordinary explanation that would
113
+ reveal clipped language. If behavioral evaluation is unavailable, report
114
+ that explicitly; a smaller byte count proves size reduction, not quality.
115
+
116
+ 14. Report bytes and percentage saved for always-on and custom context, the
117
+ before-and-after `agents-md` size, the artifacts changed, the semantic
118
+ checks performed, and any remaining item that needs an owner decision.
@@ -0,0 +1,58 @@
1
+ # Context compaction principles
2
+
3
+ Use these principles to decide what to remove, relocate, or keep. They summarize
4
+ current primary guidance; they do not replace repository evidence or an
5
+ artifact's semantic ledger.
6
+
7
+ ## What consistently improves instruction context
8
+
9
+ - Keep persistent instructions specific, focused, and grounded in behavior the
10
+ agent would otherwise miss. Current vendor guidance consistently recommends
11
+ removing unclear or conflicting instructions because they reduce adherence.
12
+ - Scope narrow guidance so it loads only for matching work. Anthropic, GitHub,
13
+ and Cursor all recommend path-specific rules instead of making framework or
14
+ component guidance repository-wide.
15
+ - Prefer one authoritative statement. Duplicate instructions spend context;
16
+ slightly different copies can also become a conflict whose winner is
17
+ unpredictable.
18
+ - Keep what is non-obvious: project conventions, pitfalls, rationale, failure
19
+ behavior, and evidence-backed exceptions. Remove generic tutorials and facts
20
+ the agent can obtain directly from code or configuration.
21
+ - Use progressive disclosure for skills. Keep the executable core in
22
+ `SKILL.md`; move optional detail to a nearby reference and name the exact
23
+ condition under which the agent reads it.
24
+ - Test changes on representative work. Instruction quality is behavioral, so a
25
+ byte reduction alone cannot prove that meaning or adherence survived.
26
+
27
+ ## References are not automatically compression
28
+
29
+ Indirection saves context only when the target is not loaded until it is needed.
30
+ Anthropic explicitly notes that `@path` imports still enter startup context. A
31
+ plain Markdown link has the opposite risk: some tools will not load it at all.
32
+
33
+ Use a reference when all three conditions hold:
34
+
35
+ 1. the parent artifact remains actionable without the detail;
36
+ 2. the parent gives a precise condition for reading the reference; and
37
+ 3. every adapter that needs the detail copies or can resolve the reference.
38
+
39
+ This works naturally for skill-local `references/`. It is usually the wrong fix
40
+ for an always-on rule: scope the rule, convert its procedure to a skill, enforce
41
+ it mechanically, or delete redundant material instead.
42
+
43
+ ## Preserve natural language
44
+
45
+ Compaction changes the information architecture, not the desired voice of the
46
+ agent. Keep complete sentences, clear headings, reasons that support judgment,
47
+ and one concrete example where it prevents ambiguity. Do not achieve a smaller
48
+ file by instructing the agent to answer tersely or by rewriting the source into
49
+ telegraphic fragments. Persistent instructions shape behavior as well as task
50
+ decisions, so clipped source language is a quality risk rather than a valid
51
+ optimization.
52
+
53
+ ## Primary sources
54
+
55
+ - [Claude Code memory documentation](https://code.claude.com/docs/en/memory) — specific instructions, path scoping, conflict removal, and why imports do not reduce startup context.
56
+ - [Agent Skills best practices](https://agentskills.io/skill-creation/best-practices) — omit generic knowledge, keep coherent units, and use conditional progressive disclosure.
57
+ - [GitHub Copilot custom-instruction guidance](https://docs.github.com/en/copilot/tutorials/customize-code-review) — short, focused instructions, path-specific files, concrete examples, and iteration.
58
+ - [Cursor rules documentation](https://docs.cursor.com/context/rules) — focused, actionable, scoped rules and composable rule files.
@@ -19,23 +19,26 @@ The name uses "skills" as shorthand for all AI artifacts (rules, agents, and ski
19
19
 
20
20
  3. **Skip installed package sources.** Sources under `<module>/` (`<module>/rules`, `<module>/agents`, `<module>/skills/intelligence-*`) are package-owned and restored by CLI lifecycle operations, so a local "fix" is not durable. Never propose a project-local edit to them. If one is wrong, make an upstream proposal instead.
21
21
 
22
- 4. **Never read or edit generated output** (`.claude/`, `.cursor/`, `.github/`, `.codex/`, `.agents/`, `.pi/`, `.opencode/`, `AGENTS.md`). Sync owns those entirely; the finding always belongs to the source.
22
+ 4. **Never read or edit generated output** (`.claude/`, `.cursor/`, `.github/`, `.codex/`, `.agents/`, `.pi/`, `.opencode/`, `AGENTS.md`). Sync owns those entirely; the finding always belongs to the source. Reading its byte count from sync's `CONTEXT:` summary or a byte-count command is the metadata-only exception—do not open the output to audit its prose.
23
23
 
24
24
  ## Steps
25
25
 
26
26
  5. **Pull git history** (when available) for each artifact — last edit, edit count, first-add date. A stale candidate has no recent edits *and* nothing cross-referencing it.
27
27
 
28
- 6. **Run the detection checks.** Judgement decides; the checks only make a finding evidence rather than an impression.
28
+ 6. **Run the detection checks.** Resolve the shared agents target output from `<manifest>` and measure only its byte count; use the `agents-md` value when a fresh `CONTEXT:` summary is already available. Apply the shared instruction budget below, but do not run sync during this read-only audit. Judgement decides; the checks only make a finding evidence rather than an impression.
29
29
 
30
30
  | Check | What it is | Proposed action |
31
31
  |---|---|---|
32
32
  | **Duplicate content** | Two artifacts cover overlapping scope, or their descriptions share trigger phrases | `MERGE` — present both, propose one |
33
33
  | **Misplaced content** | A checklist or procedure in an agent body; a convention in an agent; a workflow in a rule; expertise in a skill (the *Pick the right artifact* table in `intelligence-authoring`) | `MOVE` — a move, not a rewrite: both files change together |
34
34
  | **Over the cap** | `SKILL.md` over 1000 lines, rule over 500, agent over 200 | `SPLIT` — two artifacts, or move detail into `references/<topic>.md` |
35
+ | **Shared instruction budget** | The measured shared agents output, or `agents-md` in sync's `CONTEXT:` summary, is over 32 KiB (32,768 bytes) | `COMPACT` — this is Intelligence's recommended maximum, not an adapter rejection threshold; use `intelligence-compact-context` to reduce the owning sources without teaching terse output |
35
36
  | **Rule links to a rule** | A markdown link from one rule to another (`R1`) | `UNLINK` — name the rule instead: always-on rules are inlined into `AGENTS.md` and the scoped channels carry only scoped rules, so the link is dead in at least one output |
36
37
  | **Machine facts in a rule** | OS, shell, editor or a local absolute path (`R2`) | `MOVE` — these belong in a personal, gitignored `CLAUDE.md`; a rule is committed and read by everyone, including whoever is on another platform |
37
38
  | **Literal path or command in a skill** | A path *outside the skill's own folder* baked into a procedure (`R3`) | `PARAMETERIZE` — a skill is *executed*, so a literal path breaks the moment the layout moves; resolve it from a rule or from `<manifest>`. **Exempt:** the skill's own bundle (`references/`, `scripts/`, `assets/` — content is co-located with its skill by default); rules and agents (describing the repository is their job); an example inside an output-format block; the resolution step itself |
38
39
  | **Skill with no verification** | Nothing at the end proves the procedure worked (`R4`) | `FLAG` — a procedure that proves nothing is a note, or just the work: give it a verification, or delete it |
40
+ | **Pressure marker** | A heading or section named CRITICAL / MANDATORY / HARD RULE / READ FIRST, or a density of `MUST` / `NEVER` / `ALWAYS` with no reason beside it (`R5`) | `REWRITE` - plain heading, one reason per constraint; when several instructions are each marked critical the marker stops carrying information, so keep emphasis for the one instruction demonstrably under-weighted without it |
41
+ | **History narrative** | A PR number, incident id, commit SHA, date or "this session" inside a rule body (`R6`) | `REWRITE` - keep the causal sentence, drop the archaeology; a rule's authority is the behaviour it prescribes, and git history keeps the date |
39
42
  | **Reserved prefix** | A project artifact named `intelligence-*` | `RENAME` — the prefix belongs to the sync package and collides in generated output |
40
43
  | **Naming** | A skill that is not `<domain>-<verb>-<noun>`, or a domain invented rather than reused | `RENAME` — or introduce the new domain deliberately |
41
44
  | **Stale** | No edits in 6+ months and nothing cross-references it | `ARCHIVE` — move to `<content-dir>/_archive/` |
@@ -50,6 +53,9 @@ The name uses "skills" as shorthand for all AI artifacts (rules, agents, and ski
50
53
  Detection commands, portable on purpose — no `\b` and no `-P`, so the same command works in Git Bash on Windows, on macOS (BSD grep) and on Linux. Run each over the source directories resolved in step 2, never over generated output:
51
54
 
52
55
  ```sh
56
+ # Shared instruction budget — resolve this output path from <manifest>
57
+ wc -c "<agents-output>"
58
+
53
59
  # R1 — a markdown link from one rule to another
54
60
  grep -rnE '\]\([^)]*\.md\)' <rule-dirs>
55
61
 
@@ -62,9 +68,17 @@ The name uses "skills" as shorthand for all AI artifacts (rules, agents, and ski
62
68
 
63
69
  # R4 — skills whose body never mentions verifying anything (-L lists files with NO match)
64
70
  grep -riLE --include=SKILL.md 'verif|expect|assert|check|test|IS_STATUS' <skill-dirs>
71
+
72
+ # R5 - pressure markers: a heading or label named for urgency, then absolute-language density per file
73
+ grep -rnE '^#+ .*(CRITICAL|MANDATORY|HARD RULE|READ FIRST)|\((CRITICAL|MANDATORY|HARD RULE)\)' <rule-dirs> <agent-dirs> <skill-dirs>
74
+ grep -rcE '(MUST|NEVER|ALWAYS)' <rule-dirs> <agent-dirs> <skill-dirs> | grep -vE ':0$'
75
+
76
+ # R6 - history narrative in a rule body: PR numbers, incident ids, dates, "this session", commit SHAs
77
+ grep -rniE -e '(#|PR )[0-9]{3,}' -e '[0-9]{4}-[0-9]{2}-[0-9]{2}' -e 'this session|origin session' \
78
+ -e '`[0-9a-f]{7,40}`' <rule-dirs>
65
79
  ```
66
80
 
67
- `R4` is a coarse net, not a verdict: a skill that merely *mentions* a verification command anywhere passes it. Read the final step of every skill regardless — the question is whether something at the end **proves the work landed**, not whether the word appears.
81
+ `R4` is a coarse net, not a verdict: a skill that merely *mentions* a verification command anywhere passes it. Read the final step of every skill regardless — the question is whether something at the end **proves the work landed**, not whether the word appears. So are `R5` and `R6`: a `NEVER` that carries its reason and a date inside a frontmatter template are both legitimate hits, and the row's action applies only where the marker or the id is doing no work.
68
82
 
69
83
  7. **Ask subtraction first.** Before proposing any `SPLIT`, `REWRITE` or `PATCH`, ask whether the artifact should exist at all, whether two should become one, and whether the rule could be replaced by a gate the model cannot skip. A deletion is a better outcome than a tidy-up, and the punch-list should say so when it is true.
70
84
 
@@ -84,3 +98,4 @@ The user accepts items individually; bulk-accept for low-impact tweaks is fine.
84
98
 
85
99
  - `intelligence-learn-from-context` — single-session lesson capture; this skill delegates accepted edits to its Phase B
86
100
  - `intelligence-extract-skill` — when the audit surfaces a workflow that should become a skill
101
+ - `intelligence-compact-context` — approval-gated structural compaction when the shared instruction budget or source size needs reduction