omniconductor 0.5.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/README.md +59 -19
- package/VISION.md +2 -2
- package/adapters/README.md +8 -8
- package/adapters/claude/README.md +3 -6
- package/adapters/claude/SUPPORTED-FEATURES.md +4 -4
- package/adapters/claude/metadata.json +39 -0
- package/adapters/claude/transform-spec.md +1 -1
- package/adapters/claude/transform.sh +208 -38
- package/adapters/codex/README.md +23 -27
- package/adapters/codex/metadata.json +35 -0
- package/adapters/codex/transform-spec.md +5 -6
- package/adapters/codex/transform.sh +284 -37
- package/adapters/copilot/README.md +26 -29
- package/adapters/copilot/metadata.json +36 -0
- package/adapters/copilot/transform.sh +126 -35
- package/adapters/cursor/README.md +31 -30
- package/adapters/cursor/metadata.json +35 -0
- package/adapters/cursor/transform.sh +117 -28
- package/adapters/gemini/README.md +14 -15
- package/adapters/gemini/metadata.json +36 -0
- package/adapters/gemini/transform.sh +312 -36
- package/adapters/windsurf/README.md +20 -19
- package/adapters/windsurf/metadata.json +36 -0
- package/adapters/windsurf/transform.sh +139 -55
- package/bin/doctor.js +257 -0
- package/bin/omniconductor.js +15 -2
- package/core/anti-patterns/frequent-rule-file-edit.md +1 -1
- package/core/anti-patterns/single-monolithic-rule-file.md +1 -1
- package/core/hooks/README.md +1 -0
- package/core/hooks/pretool-loop-guard.sh.template +177 -0
- package/core/recipes/README.md +6 -4
- package/core/recipes/loop-engineering.md +73 -0
- package/core/universal-rules/README.md +4 -4
- package/core/universal-rules/meta-discipline.md +4 -4
- package/core/universal-rules/spec-as-you-go.md +1 -1
- package/docs/ADAPTER-LIVE-VERIFICATION.md +73 -0
- package/docs/COMPARISON.md +133 -0
- package/docs/COMPATIBILITY-MATRIX.md +126 -0
- package/docs/DESIGN-DECISIONS.md +1268 -0
- package/docs/MANUAL-INSTALL.md +15 -15
- package/docs/PUBLICATION-POLICY.md +46 -0
- package/docs/PUBLISH-GUIDE.md +141 -0
- package/package.json +7 -1
- package/tools/check-adapter-metadata.sh +211 -0
- package/tools/check-stale-tokens.sh +130 -0
- package/tools/generate-adapter-docs.js +123 -0
- package/tools/live-verify.sh +195 -0
- package/tools/manifest-safety.sh +118 -0
- package/tools/stale-tokens.txt +32 -0
- package/tools/test-install-modes.sh +277 -0
- package/tools/validate-adapter-output.sh +1 -1
|
@@ -34,6 +34,7 @@ set -eu
|
|
|
34
34
|
|
|
35
35
|
TARGET=""
|
|
36
36
|
RECIPES=""
|
|
37
|
+
MODE="full"
|
|
37
38
|
DRY_RUN="false"
|
|
38
39
|
MEASURE_BASELINE="false"
|
|
39
40
|
NO_PROMPT="false"
|
|
@@ -48,6 +49,7 @@ WIZARD_SHOW_ANTI_PATTERNS="false"
|
|
|
48
49
|
while [ $# -gt 0 ]; do
|
|
49
50
|
case "$1" in
|
|
50
51
|
--recipes=*) RECIPES="${1#--recipes=}" ;;
|
|
52
|
+
--mode=*) MODE="${1#--mode=}" ;;
|
|
51
53
|
--dry-run) DRY_RUN="true" ;;
|
|
52
54
|
--measure-baseline) MEASURE_BASELINE="true" ;;
|
|
53
55
|
--no-prompt) NO_PROMPT="true" ;;
|
|
@@ -60,6 +62,11 @@ Usage: bash adapters/claude/transform.sh <target-project> [options]
|
|
|
60
62
|
|
|
61
63
|
Options:
|
|
62
64
|
--recipes=A,B,C Comma-separated list of recipes to install
|
|
65
|
+
--mode=<m> Install preset (ADR-044): full (default) | minimal (rules + recipes
|
|
66
|
+
text + docs + CLAUDE.md; no agents/hooks/hookify) | strict (abort if
|
|
67
|
+
CLAUDE.md exists) | recipes-only (ONLY the selected recipe rule files;
|
|
68
|
+
requires --recipes=) | reflector-only (self-improvement loop standalone:
|
|
69
|
+
recipe + reflector agent + trajectory hook + /reflect)
|
|
63
70
|
--dry-run Preview only — no files written
|
|
64
71
|
--measure-baseline After install, measure cache token baseline (opt-in)
|
|
65
72
|
--no-prompt Skip all interactive prompts; apply sensible defaults (CI-safe)
|
|
@@ -70,7 +77,7 @@ Options:
|
|
|
70
77
|
manifest are preserved.
|
|
71
78
|
--force Bypass uninstall safety checks (active worktrees, missing manifest)
|
|
72
79
|
|
|
73
|
-
Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement, git-hygiene
|
|
80
|
+
Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement, git-hygiene, loop-engineering
|
|
74
81
|
EOF
|
|
75
82
|
exit 0
|
|
76
83
|
;;
|
|
@@ -92,12 +99,32 @@ if [ -z "$TARGET" ]; then
|
|
|
92
99
|
exit 1
|
|
93
100
|
fi
|
|
94
101
|
|
|
102
|
+
case "$MODE" in
|
|
103
|
+
full|minimal|strict|recipes-only|reflector-only) : ;;
|
|
104
|
+
*) echo "Error: unknown --mode '$MODE' (one of: full, minimal, strict, recipes-only, reflector-only)" >&2; exit 1 ;;
|
|
105
|
+
esac
|
|
106
|
+
if [ "$MODE" = "reflector-only" ]; then
|
|
107
|
+
if [ -n "$RECIPES" ] && [ "$RECIPES" != "self-improvement" ]; then
|
|
108
|
+
echo "NOTE: --mode=reflector-only ignores --recipes (installs self-improvement only)" >&2
|
|
109
|
+
fi
|
|
110
|
+
RECIPES="self-improvement"
|
|
111
|
+
fi
|
|
112
|
+
if [ "$MODE" = "recipes-only" ] && [ -z "$RECIPES" ] && [ "$UNINSTALL" != "true" ]; then
|
|
113
|
+
echo "Error: --mode=recipes-only requires --recipes=A,B,..." >&2
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
|
|
95
117
|
# Resolve CONDUCTOR root (where this script lives: adapters/claude/).
|
|
96
118
|
CONDUCTOR_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
97
119
|
CORE_ROOT="$CONDUCTOR_ROOT/core"
|
|
98
120
|
TOOLS_ROOT="$CONDUCTOR_ROOT/tools"
|
|
99
121
|
[ -d "$CORE_ROOT" ] || { echo "Error: core/ not found at $CORE_ROOT" >&2; exit 1; }
|
|
100
122
|
|
|
123
|
+
# CONDUCTOR package version for the manifest — parsed at runtime from package.json
|
|
124
|
+
# so releases never drift the manifest (falls back to "unknown" on any error).
|
|
125
|
+
CONDUCTOR_VERSION="$(/usr/bin/sed -n -E 's/^[[:space:]]*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p' "$CONDUCTOR_ROOT/package.json" 2>/dev/null | /usr/bin/head -n 1)"
|
|
126
|
+
[ -n "$CONDUCTOR_VERSION" ] || CONDUCTOR_VERSION="unknown"
|
|
127
|
+
|
|
101
128
|
if [ "$DRY_RUN" = "true" ]; then
|
|
102
129
|
mkdir -p "$TARGET"
|
|
103
130
|
fi
|
|
@@ -243,7 +270,7 @@ backup_if_exists() {
|
|
|
243
270
|
# Manifest is generated using only POSIX shell (no jq dependency). Format:
|
|
244
271
|
#
|
|
245
272
|
# {
|
|
246
|
-
# "version": "
|
|
273
|
+
# "version": "v<CONDUCTOR package.json version>",
|
|
247
274
|
# "install_timestamp": "2026-05-10T12:00:00Z",
|
|
248
275
|
# "conductor_root": "/abs/path/to/conductor",
|
|
249
276
|
# "recipes_enabled": ["monorepo", "i18n"],
|
|
@@ -267,6 +294,9 @@ MANIFEST_STAGE_PATH="" # set by init_manifest()
|
|
|
267
294
|
MANIFEST_TS="" # ISO-8601 install timestamp (set by init_manifest)
|
|
268
295
|
MANIFEST_LAST_BACKUP="" # backup_if_exists writes the backup path here; emit helpers read it
|
|
269
296
|
|
|
297
|
+
# shellcheck source=../../tools/manifest-safety.sh
|
|
298
|
+
. "$CONDUCTOR_ROOT/tools/manifest-safety.sh"
|
|
299
|
+
|
|
270
300
|
init_manifest() {
|
|
271
301
|
# Called once at install start (after wizard, before any emit).
|
|
272
302
|
if [ "$DRY_RUN" = "true" ]; then
|
|
@@ -289,12 +319,13 @@ record_emit() {
|
|
|
289
319
|
local had_backup="false"
|
|
290
320
|
[ -n "$backup" ] && had_backup="true"
|
|
291
321
|
# Escape backslashes and double quotes for JSON.
|
|
292
|
-
local esc_path esc_src esc_backup
|
|
322
|
+
local esc_path esc_src esc_backup emitted_sha
|
|
293
323
|
esc_path="$(printf '%s' "$relpath" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
294
324
|
esc_src="$(printf '%s' "$src" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
295
325
|
esc_backup="$(printf '%s' "$backup" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
296
|
-
|
|
297
|
-
"
|
|
326
|
+
emitted_sha="$(conductor_sha256_file "$TARGET_ABS/$relpath")"
|
|
327
|
+
printf ' {"path": "%s", "source": "%s", "had_backup": %s, "backup_path": "%s", "sha256": "%s"},\n' \
|
|
328
|
+
"$esc_path" "$esc_src" "$had_backup" "$esc_backup" "$emitted_sha" >> "$MANIFEST_STAGE_PATH"
|
|
298
329
|
}
|
|
299
330
|
|
|
300
331
|
finalize_manifest() {
|
|
@@ -343,7 +374,9 @@ finalize_manifest() {
|
|
|
343
374
|
|
|
344
375
|
/bin/cat > "$MANIFEST_PATH" <<EOF
|
|
345
376
|
{
|
|
346
|
-
"version": "
|
|
377
|
+
"version": "v$CONDUCTOR_VERSION",
|
|
378
|
+
"adapter": "claude",
|
|
379
|
+
"mode": "$MODE",
|
|
347
380
|
"install_timestamp": "$MANIFEST_TS",
|
|
348
381
|
"conductor_root": "$CONDUCTOR_ROOT",
|
|
349
382
|
"recipes_enabled": $recipes_json,
|
|
@@ -359,21 +392,19 @@ EOF
|
|
|
359
392
|
# Wrappers around backup_if_exists / cp / write that also remember the backup path so the
|
|
360
393
|
# next record_emit() call can reference it. Keeps emit-step changes minimal.
|
|
361
394
|
backup_and_remember() {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
MANIFEST_LAST_BACKUP="${backup#$TARGET_ABS/}"
|
|
376
|
-
fi
|
|
395
|
+
conductor_manifest_backup_and_remember "$1"
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
# ----- framework detection (ADR-044 — suggest, NEVER auto-switch) ----------
|
|
399
|
+
|
|
400
|
+
detect_coexisting_frameworks() {
|
|
401
|
+
local found=""
|
|
402
|
+
[ -d "$TARGET_ABS/.specify" ] && found="$found Spec-Kit"
|
|
403
|
+
{ [ -d "$TARGET_ABS/_bmad" ] || [ -d "$TARGET_ABS/.bmad-core" ]; } && found="$found BMAD"
|
|
404
|
+
if [ -n "$found" ] && [ "$MODE" = "full" ]; then
|
|
405
|
+
log "NOTE: detected coexisting framework(s):$found"
|
|
406
|
+
log " Consider --mode=recipes-only or --mode=reflector-only to coexist without"
|
|
407
|
+
log " overlapping workflow rules (suggestion only — nothing was changed)."
|
|
377
408
|
fi
|
|
378
409
|
}
|
|
379
410
|
|
|
@@ -424,6 +455,7 @@ do_uninstall() {
|
|
|
424
455
|
local restored=0
|
|
425
456
|
local deleted=0
|
|
426
457
|
local missing=0
|
|
458
|
+
local preserved=0
|
|
427
459
|
|
|
428
460
|
# Iterate manifest entries by line. Tolerate trailing comma absence on last entry.
|
|
429
461
|
while IFS= read -r line; do
|
|
@@ -433,16 +465,27 @@ do_uninstall() {
|
|
|
433
465
|
*) continue ;;
|
|
434
466
|
esac
|
|
435
467
|
entries_count=$((entries_count + 1))
|
|
436
|
-
local rel_path src had_backup backup_path
|
|
468
|
+
local rel_path src had_backup backup_path expected_sha
|
|
437
469
|
rel_path="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"path": *"([^"]*)".*/\1/')"
|
|
438
470
|
src="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"source": *"([^"]*)".*/\1/')"
|
|
439
471
|
had_backup="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"had_backup": *(true|false).*/\1/')"
|
|
440
472
|
backup_path="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"backup_path": *"([^"]*)".*/\1/')"
|
|
473
|
+
expected_sha="$(conductor_manifest_field "$line" sha256 2>/dev/null || true)"
|
|
441
474
|
|
|
442
475
|
local abs_dest="$TARGET_ABS/$rel_path"
|
|
443
476
|
local abs_backup=""
|
|
444
477
|
[ -n "$backup_path" ] && abs_backup="$TARGET_ABS/$backup_path"
|
|
445
478
|
|
|
479
|
+
if [ -f "$abs_dest" ] && ! conductor_manifest_file_matches "$abs_dest" "$expected_sha"; then
|
|
480
|
+
if [ -z "$expected_sha" ]; then
|
|
481
|
+
log " WARNING: preserving $rel_path (legacy manifest has no checksum)"
|
|
482
|
+
else
|
|
483
|
+
log " WARNING: preserving user-modified $rel_path"
|
|
484
|
+
fi
|
|
485
|
+
preserved=$((preserved + 1))
|
|
486
|
+
continue
|
|
487
|
+
fi
|
|
488
|
+
|
|
446
489
|
if [ "$had_backup" = "true" ] && [ -n "$abs_backup" ]; then
|
|
447
490
|
if [ -f "$abs_backup" ]; then
|
|
448
491
|
if [ "$DRY_RUN" = "true" ]; then
|
|
@@ -518,6 +561,7 @@ do_uninstall() {
|
|
|
518
561
|
echo " Backups restored: $restored"
|
|
519
562
|
echo " Files deleted: $deleted"
|
|
520
563
|
echo " Backup-missing deletes: $missing"
|
|
564
|
+
[ "$preserved" -gt 0 ] && echo " User-modified files preserved: $preserved"
|
|
521
565
|
echo "========================================================"
|
|
522
566
|
}
|
|
523
567
|
|
|
@@ -565,6 +609,26 @@ if [ -d "$TARGET_ABS/.claude" ] || [ -f "$TARGET_ABS/CLAUDE.md" ]; then
|
|
|
565
609
|
IS_ADOPTER_CASE="true"
|
|
566
610
|
fi
|
|
567
611
|
|
|
612
|
+
detect_coexisting_frameworks
|
|
613
|
+
|
|
614
|
+
# --mode=strict: never overwrite an existing baseline, even with a backup (ADR-044).
|
|
615
|
+
if [ "$MODE" = "strict" ]; then
|
|
616
|
+
if [ -f "$TARGET_ABS/CLAUDE.md" ]; then
|
|
617
|
+
echo "Error (--mode=strict): $TARGET_ABS/CLAUDE.md already exists — strict mode aborts instead of overwriting a baseline." >&2
|
|
618
|
+
echo " Use --mode=full (timestamped backup + manifest-based restore), or move the file first." >&2
|
|
619
|
+
exit 3
|
|
620
|
+
fi
|
|
621
|
+
if [ -d "$TARGET_ABS/.claude/rules" ] && [ -n "$(/bin/ls -A "$TARGET_ABS/.claude/rules" 2>/dev/null)" ]; then
|
|
622
|
+
echo "Error (--mode=strict): $TARGET_ABS/.claude/rules/ already has files — strict mode never writes next to an existing rules surface." >&2
|
|
623
|
+
exit 3
|
|
624
|
+
fi
|
|
625
|
+
fi
|
|
626
|
+
|
|
627
|
+
# À-la-carte modes are non-interactive by design.
|
|
628
|
+
if [ "$MODE" != "full" ] && [ "$MODE" != "strict" ]; then
|
|
629
|
+
NO_PROMPT="true"
|
|
630
|
+
fi
|
|
631
|
+
|
|
568
632
|
if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN" = "false" ]; then
|
|
569
633
|
echo ""
|
|
570
634
|
echo "========================================================"
|
|
@@ -593,7 +657,7 @@ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN"
|
|
|
593
657
|
# 3. Select recipes
|
|
594
658
|
echo ""
|
|
595
659
|
echo "Available recipes:"
|
|
596
|
-
echo " web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement, git-hygiene"
|
|
660
|
+
echo " web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement, git-hygiene, loop-engineering"
|
|
597
661
|
printf "Select recipes (comma-separated, or leave blank for none): "
|
|
598
662
|
read -r _recipe_answer
|
|
599
663
|
if [ -n "$_recipe_answer" ]; then
|
|
@@ -633,7 +697,9 @@ fi
|
|
|
633
697
|
# Initialize manifest before any emit happens.
|
|
634
698
|
init_manifest
|
|
635
699
|
|
|
636
|
-
if [ "$
|
|
700
|
+
if [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
701
|
+
log "Step 1/6: universal-rules — skipped (--mode=$MODE is à la carte)"
|
|
702
|
+
elif [ "$WIZARD_APPLY_RULES" = "true" ]; then
|
|
637
703
|
log "Step 1/6: universal-rules → .claude/rules/"
|
|
638
704
|
mkdir_if_real "$TARGET_ABS/.claude/rules"
|
|
639
705
|
|
|
@@ -654,9 +720,16 @@ fi
|
|
|
654
720
|
|
|
655
721
|
# ----- step 2: roles -----------------------------------------------------
|
|
656
722
|
|
|
657
|
-
if [ "$
|
|
723
|
+
if [ "$MODE" = "minimal" ]; then
|
|
724
|
+
log "Step 2/6: roles — skipped (--mode=minimal ships text only)"
|
|
725
|
+
elif [ "$WIZARD_APPLY_RULES" = "true" ]; then
|
|
658
726
|
log "Step 2/6: roles → .claude/agents/"
|
|
659
|
-
|
|
727
|
+
# À la carte without self-improvement must not leave an empty .claude/agents/.
|
|
728
|
+
if [ "$MODE" != "recipes-only" ] && [ "$MODE" != "reflector-only" ]; then
|
|
729
|
+
mkdir_if_real "$TARGET_ABS/.claude/agents"
|
|
730
|
+
else
|
|
731
|
+
case ",$RECIPES," in *",self-improvement,"*) mkdir_if_real "$TARGET_ABS/.claude/agents" ;; esac
|
|
732
|
+
fi
|
|
660
733
|
|
|
661
734
|
# Map each universal role to Claude-native agent frontmatter.
|
|
662
735
|
declare_agent() {
|
|
@@ -683,12 +756,16 @@ EOF
|
|
|
683
756
|
record_emit ".claude/agents/$role.md" "core/roles/$role.md" "$MANIFEST_LAST_BACKUP"
|
|
684
757
|
}
|
|
685
758
|
|
|
759
|
+
if [ "$MODE" != "recipes-only" ] && [ "$MODE" != "reflector-only" ]; then
|
|
686
760
|
declare_agent planner "Architecture, gap analysis, ADRs, trade-off decisions. No implementation code." opus
|
|
687
761
|
declare_agent builder "Multi-file or cross-cutting code implementation (3+ files)." opus
|
|
688
762
|
declare_agent reviewer "Plan validation before implementation. Read-only gatekeeper." opus
|
|
689
763
|
declare_agent helper "Single-file or 1-2-file work where the pattern is established." sonnet
|
|
690
764
|
declare_agent designer "UI / UX implementation. Visual components, design tokens, accessibility." sonnet
|
|
691
765
|
declare_agent scribe "Documentation sync after implementation. No code edits." sonnet
|
|
766
|
+
else
|
|
767
|
+
log " (à la carte — the 6 universal role agents skipped)"
|
|
768
|
+
fi
|
|
692
769
|
case ",$RECIPES," in *",self-improvement,"*)
|
|
693
770
|
declare_agent reflector "Reads session trajectories; proposes atomic lesson deltas for human approval. No code, no auto-apply." opus ;;
|
|
694
771
|
esac
|
|
@@ -699,7 +776,9 @@ fi
|
|
|
699
776
|
# ----- step 3: recipes (opt-in) ------------------------------------------
|
|
700
777
|
|
|
701
778
|
log "Step 3/6: recipes (opt-in) → .claude/rules/"
|
|
779
|
+
RECIPES_EMITTED=0
|
|
702
780
|
if [ -n "$RECIPES" ]; then
|
|
781
|
+
mkdir_if_real "$TARGET_ABS/.claude/rules"
|
|
703
782
|
IFS=',' read -ra RECIPE_LIST <<< "$RECIPES"
|
|
704
783
|
for r in "${RECIPE_LIST[@]}"; do
|
|
705
784
|
src="$CORE_ROOT/recipes/$r.md"
|
|
@@ -711,21 +790,72 @@ if [ -n "$RECIPES" ]; then
|
|
|
711
790
|
backup_and_remember "$dest"
|
|
712
791
|
copy_with_paths_frontmatter "$src" "$dest" "**"
|
|
713
792
|
record_emit ".claude/rules/$r.md" "core/recipes/$r.md" "$MANIFEST_LAST_BACKUP"
|
|
793
|
+
RECIPES_EMITTED=$((RECIPES_EMITTED + 1))
|
|
714
794
|
done
|
|
715
795
|
else
|
|
716
796
|
log " (no recipes selected — pass --recipes=name1,name2 to install)"
|
|
717
797
|
fi
|
|
798
|
+
if [ "$MODE" = "recipes-only" ] && [ "${RECIPES_EMITTED:-0}" -eq 0 ] && [ "$DRY_RUN" != "true" ]; then
|
|
799
|
+
echo "Error: --mode=recipes-only resolved ZERO valid recipes from '--recipes=$RECIPES' — nothing to install (check the names)." >&2
|
|
800
|
+
/bin/rm -f "$MANIFEST_STAGE_PATH"
|
|
801
|
+
exit 1
|
|
802
|
+
fi
|
|
718
803
|
|
|
719
804
|
# ----- step 4: hooks + settings.json -------------------------------------
|
|
720
805
|
|
|
806
|
+
INSTALLED_HOOKS=()
|
|
807
|
+
|
|
808
|
+
if [ "$MODE" = "minimal" ]; then
|
|
809
|
+
log "Step 4/6: hooks + settings.json — skipped (--mode=minimal ships text only)"
|
|
810
|
+
elif [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
811
|
+
# À la carte: only the Reflector's trajectory hook (when self-improvement is selected).
|
|
812
|
+
case ",$RECIPES," in
|
|
813
|
+
*",self-improvement,"*)
|
|
814
|
+
log "Step 4/6: hooks — à la carte: stop-trajectory-log only (--mode=$MODE)"
|
|
815
|
+
mkdir_if_real "$TARGET_ABS/.claude/hooks"
|
|
816
|
+
src="$CORE_ROOT/hooks/stop-trajectory-log.sh.template"
|
|
817
|
+
dest="$TARGET_ABS/.claude/hooks/stop-trajectory-log.sh"
|
|
818
|
+
if [ -f "$src" ]; then
|
|
819
|
+
backup_and_remember "$dest"
|
|
820
|
+
substitute_template "$src" "$dest"
|
|
821
|
+
record_emit ".claude/hooks/stop-trajectory-log.sh" "core/hooks/stop-trajectory-log.sh.template" "$MANIFEST_LAST_BACKUP"
|
|
822
|
+
fi
|
|
823
|
+
SETTINGS_PATH="$TARGET_ABS/.claude/settings.json"
|
|
824
|
+
if [ -f "$SETTINGS_PATH" ]; then
|
|
825
|
+
log " $SETTINGS_PATH exists — add the Stop hook manually: \"\$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-trajectory-log.sh"
|
|
826
|
+
elif [ "$DRY_RUN" = "true" ]; then
|
|
827
|
+
log "would write minimal $SETTINGS_PATH (trajectory Stop hook only)"
|
|
828
|
+
else
|
|
829
|
+
/bin/cat > "$SETTINGS_PATH" <<'MINSETTINGS_EOF'
|
|
830
|
+
{
|
|
831
|
+
"$comment": "Minimal project settings generated by CONDUCTOR (à-la-carte mode): registers only the Reflector trajectory Stop hook.",
|
|
832
|
+
"hooks": {
|
|
833
|
+
"Stop": [
|
|
834
|
+
{
|
|
835
|
+
"hooks": [
|
|
836
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-trajectory-log.sh" }
|
|
837
|
+
]
|
|
838
|
+
}
|
|
839
|
+
]
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
MINSETTINGS_EOF
|
|
843
|
+
log " wrote minimal $SETTINGS_PATH (trajectory Stop hook only)"
|
|
844
|
+
record_emit ".claude/settings.json" "<synthesized:minimal>" ""
|
|
845
|
+
fi
|
|
846
|
+
;;
|
|
847
|
+
*)
|
|
848
|
+
log "Step 4/6: hooks — skipped (--mode=$MODE without self-improvement)"
|
|
849
|
+
;;
|
|
850
|
+
esac
|
|
851
|
+
else
|
|
721
852
|
log "Step 4/6: hooks → .claude/hooks/"
|
|
722
853
|
mkdir_if_real "$TARGET_ABS/.claude/hooks"
|
|
723
854
|
|
|
724
855
|
# Core hooks (always emitted when template exists). Optional hooks (cache-hit baseline, large-file
|
|
725
856
|
# read guard) emit only if their templates are present in the CONDUCTOR core/ tree, allowing the
|
|
726
857
|
# adapter to remain forward-compatible with P1.7 work in progress.
|
|
727
|
-
|
|
728
|
-
for hook in pretool-agent-routing stop-session-log-check stop-r6-review-check stop-cache-hit-baseline-check pretool-large-file-read-guard pretool-commit-current-work-check pretool-commit-test-coverage-check stop-trajectory-log stop-git-hygiene-guard; do
|
|
858
|
+
for hook in pretool-agent-routing stop-session-log-check stop-r6-review-check stop-cache-hit-baseline-check pretool-large-file-read-guard pretool-commit-current-work-check pretool-commit-test-coverage-check stop-trajectory-log stop-git-hygiene-guard pretool-loop-guard; do
|
|
729
859
|
src="$CORE_ROOT/hooks/$hook.sh.template"
|
|
730
860
|
dest="$TARGET_ABS/.claude/hooks/$hook.sh"
|
|
731
861
|
if [ ! -f "$src" ]; then
|
|
@@ -796,6 +926,12 @@ else
|
|
|
796
926
|
"hooks": [
|
|
797
927
|
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/pretool-large-file-read-guard.sh" }
|
|
798
928
|
]
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
"matcher": "*",
|
|
932
|
+
"hooks": [
|
|
933
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/pretool-loop-guard.sh" }
|
|
934
|
+
]
|
|
799
935
|
}
|
|
800
936
|
],
|
|
801
937
|
"Stop": [
|
|
@@ -812,9 +948,10 @@ else
|
|
|
812
948
|
}
|
|
813
949
|
}
|
|
814
950
|
SETTINGS_EOF
|
|
815
|
-
log " wrote $SETTINGS_PATH ($(printf '%s' "${INSTALLED_HOOKS[*]}" | /usr/bin/wc -w | /usr/bin/tr -d ' ') hook(s) installed in .claude/hooks; settings.json registers
|
|
951
|
+
log " wrote $SETTINGS_PATH ($(printf '%s' "${INSTALLED_HOOKS[*]}" | /usr/bin/wc -w | /usr/bin/tr -d ' ') hook(s) installed in .claude/hooks; settings.json registers 10 core hooks: 5 PreToolUse + 5 Stop)"
|
|
816
952
|
record_emit ".claude/settings.json" "<synthesized>" ""
|
|
817
953
|
fi
|
|
954
|
+
fi
|
|
818
955
|
|
|
819
956
|
# ----- step 4.5: hookify rule templates ----------------------------------
|
|
820
957
|
#
|
|
@@ -827,7 +964,9 @@ fi
|
|
|
827
964
|
# Forward-compat: silent skip if the hookify-templates directory is empty or missing.
|
|
828
965
|
|
|
829
966
|
HOOKIFY_TEMPLATE_DIR="$CONDUCTOR_ROOT/adapters/claude/hookify-templates"
|
|
830
|
-
if [
|
|
967
|
+
if [ "$MODE" != "full" ] && [ "$MODE" != "strict" ]; then
|
|
968
|
+
log "Step 4.5/6: hookify rules — skipped (--mode=$MODE)"
|
|
969
|
+
elif [ -d "$HOOKIFY_TEMPLATE_DIR" ]; then
|
|
831
970
|
log "Step 4.5/6: hookify rules → .claude/hookify.*.local.md"
|
|
832
971
|
HOOKIFY_INSTALLED=0
|
|
833
972
|
HOOKIFY_SKIPPED=0
|
|
@@ -860,7 +999,13 @@ if [ -d "$HOOKIFY_TEMPLATE_DIR" ]; then
|
|
|
860
999
|
fi
|
|
861
1000
|
|
|
862
1001
|
# ---- Step 4.6: self-improvement runtime artifacts (only when recipe selected) ----
|
|
863
|
-
|
|
1002
|
+
if [ "$MODE" = "minimal" ]; then
|
|
1003
|
+
RECIPES_FOR_RUNTIME=""
|
|
1004
|
+
log "Step 4.6: self-improvement runtime — skipped (--mode=minimal ships text only)"
|
|
1005
|
+
else
|
|
1006
|
+
RECIPES_FOR_RUNTIME="$RECIPES"
|
|
1007
|
+
fi
|
|
1008
|
+
case ",$RECIPES_FOR_RUNTIME," in
|
|
864
1009
|
*",self-improvement,"*)
|
|
865
1010
|
log "Step 4.6: emitting self-improvement runtime (prune script + /reflect command)"
|
|
866
1011
|
# prune script → .conductor/reflect/prune-lessons.sh
|
|
@@ -923,6 +1068,9 @@ esac
|
|
|
923
1068
|
|
|
924
1069
|
# ----- step 5: docs templates --------------------------------------------
|
|
925
1070
|
|
|
1071
|
+
if [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
1072
|
+
log "Step 5/6: docs templates — skipped (--mode=$MODE is à la carte)"
|
|
1073
|
+
else
|
|
926
1074
|
log "Step 5/6: docs templates → docs/"
|
|
927
1075
|
mkdir_if_real "$TARGET_ABS/docs"
|
|
928
1076
|
mkdir_if_real "$TARGET_ABS/docs/specs"
|
|
@@ -956,8 +1104,13 @@ if [ -f "$CORE_ROOT/docs-templates/specs/_example.md" ]; then
|
|
|
956
1104
|
fi
|
|
957
1105
|
fi
|
|
958
1106
|
|
|
1107
|
+
fi
|
|
1108
|
+
|
|
959
1109
|
# ----- step 6: synthesize CLAUDE.md --------------------------------------
|
|
960
1110
|
|
|
1111
|
+
if [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
1112
|
+
log "Step 6/6: CLAUDE.md — skipped (--mode=$MODE is à la carte)"
|
|
1113
|
+
else
|
|
961
1114
|
log "Step 6/6: synthesize CLAUDE.md"
|
|
962
1115
|
CLAUDE_MD="$TARGET_ABS/CLAUDE.md"
|
|
963
1116
|
|
|
@@ -1044,6 +1197,8 @@ else
|
|
|
1044
1197
|
fi
|
|
1045
1198
|
|
|
1046
1199
|
# Finalize manifest now that all emits are complete (before optional baseline measurement).
|
|
1200
|
+
fi
|
|
1201
|
+
|
|
1047
1202
|
finalize_manifest
|
|
1048
1203
|
|
|
1049
1204
|
# ----- step 7 (optional): baseline measurement ---------------------------
|
|
@@ -1151,20 +1306,35 @@ echo ""
|
|
|
1151
1306
|
echo "========================================================"
|
|
1152
1307
|
echo " Done."
|
|
1153
1308
|
echo " Target: $TARGET_ABS"
|
|
1154
|
-
echo "
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1309
|
+
echo " Mode: $MODE"
|
|
1310
|
+
if [ "$MODE" = "recipes-only" ] || [ "$MODE" = "reflector-only" ]; then
|
|
1311
|
+
echo " Universal rules: 0 (à la carte)"
|
|
1312
|
+
case ",$RECIPES," in
|
|
1313
|
+
*",self-improvement,"*) echo " Roles: 1 (reflector only)" ;;
|
|
1314
|
+
*) echo " Roles: 0" ;;
|
|
1315
|
+
esac
|
|
1316
|
+
else
|
|
1317
|
+
echo " Universal rules: 5"
|
|
1318
|
+
if [ "$MODE" = "minimal" ]; then
|
|
1319
|
+
echo " Roles: 0 (--mode=minimal)"
|
|
1320
|
+
else
|
|
1321
|
+
case ",$RECIPES," in
|
|
1322
|
+
*",self-improvement,"*) echo " Roles: 7 (incl. reflector)" ;;
|
|
1323
|
+
*) echo " Roles: 6" ;;
|
|
1324
|
+
esac
|
|
1325
|
+
fi
|
|
1326
|
+
fi
|
|
1159
1327
|
echo " Recipes installed: ${RECIPES:-(none)}"
|
|
1160
1328
|
echo " Hooks: ${#INSTALLED_HOOKS[@]} (${INSTALLED_HOOKS[*]:-none})"
|
|
1161
|
-
|
|
1329
|
+
if [ -f "$TARGET_ABS/.claude/settings.json" ]; then
|
|
1330
|
+
echo " Settings: .claude/settings.json (permissions allowlist + hooks registry)"
|
|
1331
|
+
fi
|
|
1162
1332
|
echo ""
|
|
1163
1333
|
echo " Run \`claude\` (Claude Code restart) to activate new rules."
|
|
1164
1334
|
echo "========================================================"
|
|
1165
1335
|
echo ""
|
|
1166
1336
|
echo "Next steps for the project:"
|
|
1167
1337
|
echo " 1. Open $TARGET_ABS in Claude Code."
|
|
1168
|
-
echo " 2. Edit docs/CURRENT_WORK.md with your project's current state."
|
|
1338
|
+
[ -d "$TARGET_ABS/docs" ] && echo " 2. Edit docs/CURRENT_WORK.md with your project's current state."
|
|
1169
1339
|
echo " 3. Edit CLAUDE.md if you have project-specific orchestrator rules to add."
|
|
1170
1340
|
echo " 4. Verify hook installation: ls -la $TARGET_ABS/.claude/hooks/"
|
package/adapters/codex/README.md
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
# Adapter — Codex (
|
|
1
|
+
# Adapter — Codex (T2)
|
|
2
2
|
|
|
3
|
-
OpenAI Codex (the modern shell-driven agent — not the deprecated original Codex API) is a
|
|
3
|
+
OpenAI Codex (the modern shell-driven agent — not the deprecated original Codex API) is a T2 target because:
|
|
4
4
|
|
|
5
|
-
- It supports a single project rules file at `AGENTS.md` (project root — the established cross-agent convention).
|
|
6
|
-
- It excels at shell-driven scripting and
|
|
5
|
+
- It supports a single project rules file at `AGENTS.md` (project root — the established cross-agent convention), auto-loaded on session start.
|
|
6
|
+
- It excels at shell-driven scripting and agentic terminal work.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**Tool capability vs CONDUCTOR emission (ADR-031):** as of 2026 Codex ships hooks (default-on), sub-agent dispatch, custom agents, per-task model routing, commands, and built-in managed memory. What is limited today is what CONDUCTOR **emits** for it — rule text + docs + the opt-in Reflector loop; the enforcement guard hooks, role agents, and model-routing config are Phase-2 emission (ADR-034). That is a CONDUCTOR gap, not a Codex limitation. Real tool-side caveat: rules scope by nested-file hierarchy, not glob — the adapter bundles everything into one `AGENTS.md`.
|
|
9
9
|
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
- ❌ No per-call model routing.
|
|
14
|
-
- ❌ No built-in memory directory.
|
|
15
|
-
- ⚠️ Limited multi-step orchestration capability vs Claude/Cursor.
|
|
10
|
+
**Tier**: T2 (see `docs/COMPATIBILITY-MATRIX.md`). Live-verified via the automated headless probe (`tools/live-verify.sh` — current status in `docs/ADAPTER-LIVE-VERIFICATION.md`).
|
|
11
|
+
|
|
12
|
+
> Enumerable facts about this adapter (output paths / tier / capabilities / live verification / headless CLI) are machine-readable in [`metadata.json`](./metadata.json) and CI-checked against `transform.sh` + the validator (ADR-040).
|
|
16
13
|
|
|
17
|
-
**Tier**: T3 — Basic. Rule TEXT installs but most CONDUCTOR mechanism doesn't apply.
|
|
18
14
|
|
|
19
15
|
## Installation path
|
|
20
16
|
|
|
@@ -39,37 +35,37 @@ bash adapters/codex/transform.sh <target> --uninstall # revert (man
|
|
|
39
35
|
└── specs/_example.md
|
|
40
36
|
```
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
- `--recipes=self-improvement` additionally emits the Reflector loop: session-end trajectory hook config (`.codex/hooks.json`), `/reflect` command, reflector agent, prune script, and the `.conductor/reflect/` weekly runner (ADR-032/033).
|
|
39
|
+
|
|
40
|
+
## Native features supported (emitted today)
|
|
43
41
|
|
|
44
42
|
- ✅ Always-loaded baseline (`AGENTS.md`).
|
|
45
43
|
- ✅ All universal rule TEXT.
|
|
46
44
|
- ✅ All doc templates.
|
|
45
|
+
- ✅ Reflector loop (opt-in recipe).
|
|
47
46
|
- ✅ Strong shell-task execution (Codex's primary strength).
|
|
48
47
|
|
|
49
|
-
##
|
|
48
|
+
## Not emitted yet (Phase 2 — Codex supports these natively, ADR-031/034)
|
|
50
49
|
|
|
51
|
-
| Feature |
|
|
50
|
+
| Feature | Interim workaround |
|
|
52
51
|
|---|---|
|
|
53
|
-
| Per-pattern rule scoping | All rules always-loaded. |
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
| Per-call model
|
|
57
|
-
|
|
|
58
|
-
| Multi-step orchestration | Limited — Codex shines at one-shot shell tasks. For multi-step, use Claude/Cursor. |
|
|
52
|
+
| Per-pattern rule scoping | All rules always-loaded in one `AGENTS.md` (Codex scopes by nested-file hierarchy, not globs). |
|
|
53
|
+
| Enforcement guard hooks | Self-police, or pair with project pre-commit git hooks. Only the Reflector session-end hook is emitted today (`--recipes=self-improvement`). |
|
|
54
|
+
| The 6 role agents (sub-agent dispatch) | Codex has native sub-agents; CONDUCTOR doesn't emit its role definitions for Codex yet. Human plays orchestrator. |
|
|
55
|
+
| Per-call model-routing config | Pick the model per invocation via Codex's own model selection. |
|
|
56
|
+
| 4-type memory pattern | Self-managed at `.memory/` (gitignored); Codex's built-in managed memory is separate. |
|
|
59
57
|
|
|
60
58
|
## Best fit use cases
|
|
61
59
|
|
|
62
|
-
- Shell
|
|
63
|
-
- One-shot file transformations.
|
|
64
|
-
-
|
|
65
|
-
- "Run this command and tell me the output" tasks.
|
|
60
|
+
- Shell-driven agentic work and scripting.
|
|
61
|
+
- One-shot file transformations and quick git operations.
|
|
62
|
+
- Headless automation (`codex exec` — the Reflector weekly runner uses it).
|
|
66
63
|
|
|
67
64
|
## After install — first steps
|
|
68
65
|
|
|
69
66
|
1. Verify Codex reads `AGENTS.md` (auto-loaded from project root on session start).
|
|
70
67
|
2. Customize `AGENTS.md` for your project as needed.
|
|
71
68
|
3. Add `.memory/` to `.gitignore`.
|
|
72
|
-
4. Use Codex for shell tasks; rely on Claude/Cursor for multi-step orchestration.
|
|
73
69
|
|
|
74
70
|
## Quirks / known issues
|
|
75
71
|
|
|
@@ -84,4 +80,4 @@ bash adapters/codex/transform.sh <target> --uninstall # revert (man
|
|
|
84
80
|
- ✅ `SUPPORTED-FEATURES.md`
|
|
85
81
|
- ✅ `transform-spec.md`
|
|
86
82
|
- ✅ `transform.sh` (implemented — single-file `AGENTS.md` bundle, recipes, dry-run, manifest-based uninstall)
|
|
87
|
-
-
|
|
83
|
+
- ✅ Live-verified (auto-probe `tools/live-verify.sh` — see `docs/ADAPTER-LIVE-VERIFICATION.md`)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Single source for enumerable adapter facts (ADR-040). CI asserts transform.sh / validator / matrix agree with this file. Update HERE first; docs follow.",
|
|
3
|
+
"tool": "codex",
|
|
4
|
+
"display_name": "Codex",
|
|
5
|
+
"tier": "T2",
|
|
6
|
+
"outputs": [
|
|
7
|
+
{ "path": "AGENTS.md", "kind": "always_loaded", "validated": true },
|
|
8
|
+
{ "path": "docs/CURRENT_WORK.md", "kind": "docs", "validated": false }
|
|
9
|
+
],
|
|
10
|
+
"reflector_outputs": [
|
|
11
|
+
{ "path": ".codex/hooks.json", "note": "Stop trajectory hook config (recipe-gated)" },
|
|
12
|
+
{ "path": ".conductor/reflect", "note": "runner + brief + scheduling (recipe-gated)" }
|
|
13
|
+
],
|
|
14
|
+
"install": { "ala_carte": "block" },
|
|
15
|
+
"legacy_paths": [".codex/codex.md"],
|
|
16
|
+
"capabilities": {
|
|
17
|
+
"tool_native": {
|
|
18
|
+
"hooks": "yes",
|
|
19
|
+
"sub_agents": "yes",
|
|
20
|
+
"model_routing": "yes",
|
|
21
|
+
"commands": "yes",
|
|
22
|
+
"glob_scoping": "no",
|
|
23
|
+
"scheduler": "local"
|
|
24
|
+
},
|
|
25
|
+
"conductor_emitted": {
|
|
26
|
+
"rules": "full",
|
|
27
|
+
"guard_hooks": "none",
|
|
28
|
+
"reflector_loop": "recipe",
|
|
29
|
+
"role_agents": "none",
|
|
30
|
+
"model_routing": "none"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"live_verification": { "status": "verified", "date": "2026-07-09", "cli": "codex-cli 0.144.0", "note": "headless probe listed 4/5 rules + read-CURRENT_WORK-first" },
|
|
34
|
+
"headless_cli": { "command": "codex", "invocation": "codex exec" }
|
|
35
|
+
}
|
|
@@ -41,7 +41,7 @@ adapters/codex/_native/codex.md.tpl # Header template (Codex-flavor
|
|
|
41
41
|
└── specs/_example.md
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## `AGENTS.md` composition (in order)
|
|
45
45
|
|
|
46
46
|
1. **Header from `_native/codex.md.tpl`** — bilingual (한/영) intro adapted for Codex (one-shot model, shell-task strength).
|
|
47
47
|
2. **ABSOLUTE rules section** — R1-R8 minus Claude-only sub-agent enforcement. R-prefix renumbered.
|
|
@@ -60,9 +60,8 @@ Same as Gemini adapter — strip front-matter, concatenate, replace tool-specifi
|
|
|
60
60
|
|
|
61
61
|
| Case | Adapter behavior |
|
|
62
62
|
|---|---|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
| `.codex/codex.md` exceeds Codex context budget | Warn; document trim strategy in `notes.md`. |
|
|
63
|
+
| Existing `AGENTS.md` | Back up, then write (manifest-tracked; `--uninstall` restores). |
|
|
64
|
+
| `AGENTS.md` exceeds Codex context budget | Warn; document trim strategy in `notes.md`. |
|
|
66
65
|
|
|
67
66
|
## Idempotency check
|
|
68
67
|
|
|
@@ -71,14 +70,14 @@ Re-run reports "SKIP (exists)" for everything.
|
|
|
71
70
|
## Verification commands (P3.5 will fill)
|
|
72
71
|
|
|
73
72
|
```bash
|
|
74
|
-
test -f "<target
|
|
73
|
+
test -f "<target>/AGENTS.md" || echo "MISSING AGENTS.md"
|
|
75
74
|
|
|
76
75
|
# Run Codex in <target>; verify it follows ABSOLUTE rules + universal conventions.
|
|
77
76
|
```
|
|
78
77
|
|
|
79
78
|
## P3.5 Codex version compatibility check
|
|
80
79
|
|
|
81
|
-
- Confirm
|
|
80
|
+
- Confirm `AGENTS.md` IS the canonical project-rules location. (Confirmed — live-verified; current status in `docs/ADAPTER-LIVE-VERIFICATION.md`.)
|
|
82
81
|
- Confirm Codex auto-loads it on session start.
|
|
83
82
|
- Confirm Codex follows the rule TEXT in its inline code generation.
|
|
84
83
|
|