omniconductor 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +219 -0
  3. package/NOTICE +11 -0
  4. package/README.md +526 -0
  5. package/THIRD_PARTY_NOTICES.md +31 -0
  6. package/TRADEMARKS.md +26 -0
  7. package/VISION.md +106 -0
  8. package/adapters/README.md +121 -0
  9. package/adapters/claude/README.md +102 -0
  10. package/adapters/claude/SUPPORTED-FEATURES.md +66 -0
  11. package/adapters/claude/hookify-templates/.recipe-scoped +9 -0
  12. package/adapters/claude/hookify-templates/README.md +93 -0
  13. package/adapters/claude/hookify-templates/block-completion-claim-without-push.local.md.template +56 -0
  14. package/adapters/claude/hookify-templates/block-direct-push-protected-branch.local.md.template +18 -0
  15. package/adapters/claude/hookify-templates/block-force-push-protected-branch.local.md.template +42 -0
  16. package/adapters/claude/hookify-templates/block-server-secret-in-client.local.md.template +36 -0
  17. package/adapters/claude/hookify-templates/warn-any-type-added.local.md.template +44 -0
  18. package/adapters/claude/hookify-templates/warn-commit-without-pre-commit-review.local.md.template +52 -0
  19. package/adapters/claude/hookify-templates/warn-console-direct.local.md.template +55 -0
  20. package/adapters/claude/hookify-templates/warn-create-table-without-access-control.local.md.template +35 -0
  21. package/adapters/claude/hookify-templates/warn-current-work-without-remaining-tasks.local.md.template +36 -0
  22. package/adapters/claude/hookify-templates/warn-gh-pr-create-without-pre-merge-review.local.md.template +38 -0
  23. package/adapters/claude/hookify-templates/warn-hardcoded-text-without-i18n-key.local.md.template +21 -0
  24. package/adapters/claude/hookify-templates/warn-on-gh-pr-merge.local.md.template +33 -0
  25. package/adapters/claude/hookify-templates/warn-plan-spec-without-remaining-tasks.local.md.template +44 -0
  26. package/adapters/claude/hookify-templates/warn-raw-hex-instead-of-token.local.md.template +21 -0
  27. package/adapters/claude/hookify-templates/warn-security-definer-without-search-path.local.md.template +30 -0
  28. package/adapters/claude/hookify-templates/warn-stop-commit-without-current-work.local.md.template +47 -0
  29. package/adapters/claude/hookify-templates/warn-user-manual-completion.local.md.template +40 -0
  30. package/adapters/claude/transform-spec.md +140 -0
  31. package/adapters/claude/transform.sh +1169 -0
  32. package/adapters/codex/README.md +87 -0
  33. package/adapters/codex/SUPPORTED-FEATURES.md +66 -0
  34. package/adapters/codex/transform-spec.md +90 -0
  35. package/adapters/codex/transform.sh +748 -0
  36. package/adapters/copilot/README.md +88 -0
  37. package/adapters/copilot/SUPPORTED-FEATURES.md +73 -0
  38. package/adapters/copilot/transform-spec.md +111 -0
  39. package/adapters/copilot/transform.sh +757 -0
  40. package/adapters/cursor/README.md +87 -0
  41. package/adapters/cursor/SUPPORTED-FEATURES.md +90 -0
  42. package/adapters/cursor/transform-spec.md +124 -0
  43. package/adapters/cursor/transform.sh +731 -0
  44. package/adapters/gemini/README.md +93 -0
  45. package/adapters/gemini/SUPPORTED-FEATURES.md +80 -0
  46. package/adapters/gemini/transform-spec.md +102 -0
  47. package/adapters/gemini/transform.sh +844 -0
  48. package/adapters/windsurf/README.md +93 -0
  49. package/adapters/windsurf/SUPPORTED-FEATURES.md +67 -0
  50. package/adapters/windsurf/transform-spec.md +99 -0
  51. package/adapters/windsurf/transform.sh +727 -0
  52. package/bin/omniconductor.js +130 -0
  53. package/core/README.md +64 -0
  54. package/core/anti-patterns/README.md +142 -0
  55. package/core/anti-patterns/dynamic-system-prompt.md +113 -0
  56. package/core/anti-patterns/frequent-rule-file-edit.md +83 -0
  57. package/core/anti-patterns/large-file-read-no-range.md +90 -0
  58. package/core/anti-patterns/no-sub-agent-dispatch.md +89 -0
  59. package/core/anti-patterns/single-monolithic-rule-file.md +99 -0
  60. package/core/anti-patterns/skill-eager-load.md +83 -0
  61. package/core/anti-patterns/tool-call-spam.md +93 -0
  62. package/core/docs-templates/CURRENT_WORK.md +64 -0
  63. package/core/docs-templates/INDEX.md +57 -0
  64. package/core/docs-templates/PLANS.md +44 -0
  65. package/core/docs-templates/README.md +40 -0
  66. package/core/docs-templates/REMAINING_TASKS.md +43 -0
  67. package/core/docs-templates/TASKS.md +51 -0
  68. package/core/docs-templates/specs/_example.md +121 -0
  69. package/core/hooks/README.md +62 -0
  70. package/core/hooks/pretool-agent-routing.sh.template +97 -0
  71. package/core/hooks/pretool-commit-current-work-check.sh.template +103 -0
  72. package/core/hooks/pretool-commit-test-coverage-check.sh.template +116 -0
  73. package/core/hooks/pretool-large-file-read-guard.sh.template +117 -0
  74. package/core/hooks/stop-cache-hit-baseline-check.sh.template +133 -0
  75. package/core/hooks/stop-r6-review-check.sh.template +80 -0
  76. package/core/hooks/stop-session-log-check.sh.template +101 -0
  77. package/core/hooks/stop-trajectory-log.sh.template +96 -0
  78. package/core/memory-pattern/EXAMPLES.md +114 -0
  79. package/core/memory-pattern/README.md +133 -0
  80. package/core/recipes/README.md +46 -0
  81. package/core/recipes/auto-mock-data.md +82 -0
  82. package/core/recipes/branch-strategy.md +100 -0
  83. package/core/recipes/coding-conventions.md +123 -0
  84. package/core/recipes/database-discipline.md +65 -0
  85. package/core/recipes/debugging.md +143 -0
  86. package/core/recipes/design-system.md +30 -0
  87. package/core/recipes/i18n.md +118 -0
  88. package/core/recipes/monorepo.md +101 -0
  89. package/core/recipes/self-improvement.md +61 -0
  90. package/core/recipes/tdd.md +128 -0
  91. package/core/recipes/web-mobile-parity.md +87 -0
  92. package/core/reflector/SCHEDULING.md +83 -0
  93. package/core/reflector/prune-lessons.sh +105 -0
  94. package/core/reflector/reflect-brief.md +11 -0
  95. package/core/reflector/reflect.command.md +13 -0
  96. package/core/reflector/run-weekly.sh +54 -0
  97. package/core/reflector/trajectory-log.sh +55 -0
  98. package/core/roles/README.md +61 -0
  99. package/core/roles/builder.md +75 -0
  100. package/core/roles/designer.md +93 -0
  101. package/core/roles/helper.md +70 -0
  102. package/core/roles/planner.md +123 -0
  103. package/core/roles/reflector.md +72 -0
  104. package/core/roles/reviewer.md +104 -0
  105. package/core/roles/scribe.md +89 -0
  106. package/core/universal-rules/README.md +71 -0
  107. package/core/universal-rules/meta-discipline.md +292 -0
  108. package/core/universal-rules/operations.md +162 -0
  109. package/core/universal-rules/quality-gates.md +191 -0
  110. package/core/universal-rules/spec-as-you-go.md +123 -0
  111. package/core/universal-rules/workflow.md +153 -0
  112. package/core/workflow/PHASES.md +134 -0
  113. package/core/workflow/README.md +56 -0
  114. package/docs/MANUAL-INSTALL.md +456 -0
  115. package/package.json +52 -0
  116. package/tools/check-framework-purity.sh +91 -0
  117. package/tools/measure-tokens.sh +169 -0
  118. package/tools/validate-adapter-output.sh +611 -0
@@ -0,0 +1,748 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # CONDUCTOR — Codex adapter transform.sh
4
+ #
5
+ # Reads core/ assets and writes them into a target project as a single native
6
+ # Codex bundle (AGENTS.md at project root) plus universal doc templates.
7
+ #
8
+ # AGENTS.md is the established cross-agent project-rules convention adopted by
9
+ # OpenAI Codex / Codex CLI (supersedes the early-design .codex/codex.md guess —
10
+ # see adapters/codex/transform-spec.md Outputs note). Codex auto-loads AGENTS.md
11
+ # from the project root at session start.
12
+ #
13
+ # Usage:
14
+ # bash adapters/codex/transform.sh <target-project> [--recipes=<comma-list>] [--dry-run]
15
+ # [--no-prompt]
16
+ # bash adapters/codex/transform.sh <target-project> --uninstall [--dry-run] [--force]
17
+ #
18
+ # Examples:
19
+ # bash adapters/codex/transform.sh ~/Projects/my-app
20
+ # bash adapters/codex/transform.sh ~/Projects/my-app --recipes=tdd,debugging
21
+ # bash adapters/codex/transform.sh /tmp/test-project --dry-run
22
+ # bash adapters/codex/transform.sh . --no-prompt
23
+ # bash adapters/codex/transform.sh . --uninstall # revert install
24
+ # bash adapters/codex/transform.sh . --uninstall --force # bypass safety checks
25
+ #
26
+ # Layer 2 transformation (per ADR-004 honesty + ADR-021):
27
+ # <synthesized header> → <target>/AGENTS.md (Codex-flavored bilingual intro)
28
+ # core/universal-rules/*.md → <target>/AGENTS.md (each as "## <title>", body sans frontmatter)
29
+ # core/workflow/PHASES.md → <target>/AGENTS.md (compressed phase table)
30
+ # core/recipes/*.md (selected) → <target>/AGENTS.md (each as "## Recipe — <name>")
31
+ # core/docs-templates/*.md → <target>/docs/*.md (CURRENT_WORK, REMAINING_TASKS, etc.)
32
+ # core/hooks/*.sh.template → SKIPPED (Reflector hook emitted via --recipes=self-improvement, ADR-032; other guards Claude-only, ADR-034)
33
+ # core/roles/*.md → SKIPPED (Codex has no sub-agent dispatch)
34
+ # adapters/claude/hookify-... → SKIPPED (Claude-only plugin)
35
+ #
36
+ # Single-file model: Codex reads ONE always-loaded rules file. Everything that
37
+ # Cursor splits across .cursor/rules/*.mdc is concatenated into AGENTS.md here.
38
+
39
+ set -eu
40
+
41
+ # ----- arg parsing --------------------------------------------------------
42
+
43
+ TARGET=""
44
+ RECIPES=""
45
+ DRY_RUN="false"
46
+ NO_PROMPT="false"
47
+ UNINSTALL="false"
48
+ FORCE="false"
49
+
50
+ # Onboarding wizard state
51
+ WIZARD_APPLY_RULES="true"
52
+
53
+ while [ $# -gt 0 ]; do
54
+ case "$1" in
55
+ --recipes=*) RECIPES="${1#--recipes=}" ;;
56
+ --dry-run) DRY_RUN="true" ;;
57
+ --no-prompt) NO_PROMPT="true" ;;
58
+ --uninstall|--rollback) UNINSTALL="true" ;;
59
+ --force) FORCE="true" ;;
60
+ --help|-h)
61
+ /bin/cat <<EOF
62
+ Usage: bash adapters/codex/transform.sh <target-project> [options]
63
+
64
+ Options:
65
+ --recipes=A,B,C Comma-separated list of recipes to append into AGENTS.md
66
+ --dry-run Preview only — no files written
67
+ --no-prompt Skip all interactive prompts; apply sensible defaults (CI-safe)
68
+ --uninstall Revert a previous install using <target>/.conductor-manifest.json
69
+ (alias: --rollback). Restores backups when present, deletes
70
+ Conductor-emitted files when none. Customizations not in the
71
+ manifest are preserved.
72
+ --force Bypass uninstall safety checks (active worktrees, missing manifest)
73
+
74
+ Output (single-file Codex model):
75
+ <target>/AGENTS.md Bundled intro + 5 universal rules + compressed workflow + recipes
76
+ <target>/docs/*.md Universal doc templates (CURRENT_WORK, REMAINING_TASKS, ...)
77
+
78
+ Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement
79
+
80
+ What this adapter does NOT install (per ADR-004 honesty):
81
+ - Hook guards (CONDUCTOR emits the Reflector hook when --recipes=self-improvement, ADR-032; other guards remain Claude-only, ADR-034)
82
+ - Sub-agent personas (Codex has no sub-agent dispatch — single session per task)
83
+ - Per-pattern rule scoping (Codex loads AGENTS.md whole — all rules always-on)
84
+ - Hookify rule templates (Claude-only plugin)
85
+ EOF
86
+ exit 0
87
+ ;;
88
+ *)
89
+ if [ -z "$TARGET" ]; then
90
+ TARGET="$1"
91
+ else
92
+ echo "Unknown argument: $1" >&2
93
+ exit 1
94
+ fi
95
+ ;;
96
+ esac
97
+ shift
98
+ done
99
+
100
+ if [ -z "$TARGET" ]; then
101
+ echo "Error: target-project path is required." >&2
102
+ echo "Usage: bash adapters/codex/transform.sh <target-project> [--recipes=...]" >&2
103
+ exit 1
104
+ fi
105
+
106
+ # Resolve CONDUCTOR root (where this script lives: adapters/codex/).
107
+ CONDUCTOR_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
108
+ CORE_ROOT="$CONDUCTOR_ROOT/core"
109
+ [ -d "$CORE_ROOT" ] || { echo "Error: core/ not found at $CORE_ROOT" >&2; exit 1; }
110
+
111
+ if [ "$DRY_RUN" = "true" ]; then
112
+ mkdir -p "$TARGET"
113
+ fi
114
+ TARGET_ABS="$(cd "$TARGET" 2>/dev/null && pwd)" || { echo "Error: target directory does not exist or is not a directory: $TARGET" >&2; exit 1; }
115
+
116
+ # ----- helpers ------------------------------------------------------------
117
+
118
+ log() {
119
+ if [ "$DRY_RUN" = "true" ]; then
120
+ echo "[dry-run] $*"
121
+ else
122
+ echo "[conductor] $*"
123
+ fi
124
+ }
125
+
126
+ mkdir_if_real() {
127
+ if [ "$DRY_RUN" = "true" ]; then
128
+ log "would mkdir -p $1"
129
+ else
130
+ mkdir -p "$1"
131
+ fi
132
+ }
133
+
134
+ # Strip the CONDUCTOR universal frontmatter (first --- ... --- block) from src body.
135
+ # Print body to stdout. Codex does not consume YAML frontmatter.
136
+ strip_frontmatter() {
137
+ local src="$1"
138
+ /usr/bin/awk 'BEGIN{f=0} /^---$/{c++; if(c==2){f=1; next}} f==1' "$src"
139
+ }
140
+
141
+ # Derive a section title for a rule/recipe. First H1 line (sans frontmatter), or filename.
142
+ derive_title() {
143
+ local src="$1"
144
+ local title
145
+ title="$(strip_frontmatter "$src" | /usr/bin/grep -m1 '^# ' | /usr/bin/sed -e 's/^# *//' | /usr/bin/head -c 160)"
146
+ if [ -z "$title" ]; then
147
+ title="$(basename "$src" .md)"
148
+ fi
149
+ printf '%s' "$title"
150
+ }
151
+
152
+ # backup_and_remember <dest>
153
+ # If <dest> exists, copy it to <dest>.conductor-backup-<ts> and remember the relative
154
+ # backup path in MANIFEST_LAST_BACKUP for the next record_emit. Honors DRY_RUN.
155
+ # Origin: ADR-019 (Claude adapter pattern), mirrored per ADR-021.
156
+ backup_and_remember() {
157
+ MANIFEST_LAST_BACKUP=""
158
+ if [ -f "$1" ]; then
159
+ if [ "$DRY_RUN" = "true" ]; then
160
+ log "would back up existing $1 -> $1.conductor-backup-<ts>"
161
+ MANIFEST_LAST_BACKUP=""
162
+ else
163
+ local ts
164
+ ts="$(/bin/date +%Y%m%d-%H%M%S)"
165
+ local backup="$1.conductor-backup-$ts"
166
+ /bin/cp "$1" "$backup"
167
+ log " backed up existing $1 -> $backup"
168
+ MANIFEST_LAST_BACKUP="${backup#$TARGET_ABS/}"
169
+ fi
170
+ fi
171
+ }
172
+
173
+ # ----- manifest tracking (ADR-020, mirrored per ADR-021) ------------------
174
+ #
175
+ # Format identical to Claude/Cursor adapters' manifest. POSIX shell + sed only — no jq.
176
+
177
+ MANIFEST_PATH="$TARGET_ABS/.conductor-manifest.json"
178
+ MANIFEST_STAGE_PATH=""
179
+ MANIFEST_TS=""
180
+ MANIFEST_LAST_BACKUP=""
181
+
182
+ init_manifest() {
183
+ if [ "$DRY_RUN" = "true" ]; then
184
+ log "would init manifest staging at $MANIFEST_PATH.staging"
185
+ return
186
+ fi
187
+ MANIFEST_TS="$(/bin/date -u +%Y-%m-%dT%H:%M:%SZ)"
188
+ MANIFEST_STAGE_PATH="$TARGET_ABS/.conductor-manifest.json.staging"
189
+ /bin/rm -f "$MANIFEST_STAGE_PATH"
190
+ : > "$MANIFEST_STAGE_PATH"
191
+ }
192
+
193
+ record_emit() {
194
+ if [ "$DRY_RUN" = "true" ] || [ "$UNINSTALL" = "true" ]; then
195
+ return
196
+ fi
197
+ local relpath="$1" src="$2" backup="${3:-}"
198
+ local had_backup="false"
199
+ [ -n "$backup" ] && had_backup="true"
200
+ local esc_path esc_src esc_backup
201
+ esc_path="$(printf '%s' "$relpath" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
202
+ esc_src="$(printf '%s' "$src" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
203
+ esc_backup="$(printf '%s' "$backup" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
204
+ printf ' {"path": "%s", "source": "%s", "had_backup": %s, "backup_path": "%s"},\n' \
205
+ "$esc_path" "$esc_src" "$had_backup" "$esc_backup" >> "$MANIFEST_STAGE_PATH"
206
+ }
207
+
208
+ finalize_manifest() {
209
+ if [ "$DRY_RUN" = "true" ]; then
210
+ log "would finalize manifest -> $MANIFEST_PATH"
211
+ return
212
+ fi
213
+ [ -z "$MANIFEST_STAGE_PATH" ] && return
214
+ [ -f "$MANIFEST_STAGE_PATH" ] || return
215
+
216
+ if [ -f "$MANIFEST_PATH" ]; then
217
+ local ts
218
+ ts="$(/bin/date +%Y%m%d-%H%M%S)"
219
+ /bin/cp "$MANIFEST_PATH" "$MANIFEST_PATH.conductor-backup-$ts"
220
+ log " backed up existing $MANIFEST_PATH -> $MANIFEST_PATH.conductor-backup-$ts"
221
+ fi
222
+
223
+ local recipes_json="[]"
224
+ if [ -n "$RECIPES" ]; then
225
+ recipes_json="["
226
+ local IFS_BAK=$IFS
227
+ IFS=','
228
+ local first="true"
229
+ for r in $RECIPES; do
230
+ r="$(printf '%s' "$r" | /usr/bin/sed 's/^ *//; s/ *$//')"
231
+ [ -z "$r" ] && continue
232
+ if [ "$first" = "true" ]; then
233
+ recipes_json="${recipes_json}\"$r\""
234
+ first="false"
235
+ else
236
+ recipes_json="${recipes_json}, \"$r\""
237
+ fi
238
+ done
239
+ IFS=$IFS_BAK
240
+ recipes_json="${recipes_json}]"
241
+ fi
242
+
243
+ local entries
244
+ if [ -s "$MANIFEST_STAGE_PATH" ]; then
245
+ entries="$(/usr/bin/sed -e '$ s/,$//' "$MANIFEST_STAGE_PATH")"
246
+ else
247
+ entries=""
248
+ fi
249
+
250
+ /bin/cat > "$MANIFEST_PATH" <<EOF
251
+ {
252
+ "version": "v0.2.0",
253
+ "adapter": "codex",
254
+ "install_timestamp": "$MANIFEST_TS",
255
+ "conductor_root": "$CONDUCTOR_ROOT",
256
+ "recipes_enabled": $recipes_json,
257
+ "emitted_files": [
258
+ $entries
259
+ ]
260
+ }
261
+ EOF
262
+ /bin/rm -f "$MANIFEST_STAGE_PATH"
263
+ log " wrote manifest $MANIFEST_PATH"
264
+ }
265
+
266
+ # ----- uninstall flow (mirrored from Cursor/Claude adapter) ---------------
267
+
268
+ do_uninstall() {
269
+ log "uninstall mode (target: $TARGET_ABS)"
270
+
271
+ if [ ! -f "$MANIFEST_PATH" ]; then
272
+ if [ "$FORCE" = "true" ]; then
273
+ log "WARNING: no manifest at $MANIFEST_PATH — proceeding under --force (legacy backup scan only)"
274
+ uninstall_legacy_scan
275
+ return 0
276
+ fi
277
+ echo "Error: no manifest at $MANIFEST_PATH." >&2
278
+ echo " This target was either installed by a pre-manifest version or has already been uninstalled." >&2
279
+ echo " Re-run with --force to scan for legacy .conductor-backup-* files and delete them anyway:" >&2
280
+ echo " bash $0 $TARGET_ABS --uninstall --force" >&2
281
+ exit 1
282
+ fi
283
+
284
+ if [ -d "$TARGET_ABS/.git" ]; then
285
+ if [ -f "$TARGET_ABS/.git/MERGE_HEAD" ] || [ -f "$TARGET_ABS/.git/REBASE_HEAD" ] || [ -d "$TARGET_ABS/.git/rebase-merge" ]; then
286
+ if [ "$FORCE" != "true" ]; then
287
+ echo "Error: target has an active git operation (merge/rebase in progress)." >&2
288
+ echo " Resolve the in-flight operation first, or pass --force to override." >&2
289
+ exit 1
290
+ fi
291
+ log "WARNING: active git operation detected — proceeding under --force"
292
+ fi
293
+ fi
294
+
295
+ log "loading manifest entries..."
296
+ local entries_count=0
297
+ local restored=0
298
+ local deleted=0
299
+ local missing=0
300
+
301
+ while IFS= read -r line; do
302
+ case "$line" in
303
+ *'"path":'*'"source":'*'"had_backup":'*)
304
+ ;;
305
+ *) continue ;;
306
+ esac
307
+ entries_count=$((entries_count + 1))
308
+ local rel_path src had_backup backup_path
309
+ rel_path="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"path": *"([^"]*)".*/\1/')"
310
+ src="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"source": *"([^"]*)".*/\1/')"
311
+ had_backup="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"had_backup": *(true|false).*/\1/')"
312
+ backup_path="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"backup_path": *"([^"]*)".*/\1/')"
313
+
314
+ local abs_dest="$TARGET_ABS/$rel_path"
315
+ local abs_backup=""
316
+ [ -n "$backup_path" ] && abs_backup="$TARGET_ABS/$backup_path"
317
+
318
+ if [ "$had_backup" = "true" ] && [ -n "$abs_backup" ]; then
319
+ if [ -f "$abs_backup" ]; then
320
+ if [ "$DRY_RUN" = "true" ]; then
321
+ log " would restore $abs_backup -> $abs_dest"
322
+ else
323
+ /bin/mv -f "$abs_backup" "$abs_dest"
324
+ log " restored $abs_backup -> $abs_dest"
325
+ fi
326
+ restored=$((restored + 1))
327
+ else
328
+ if [ "$DRY_RUN" = "true" ]; then
329
+ log " would delete $abs_dest (backup $abs_backup missing)"
330
+ else
331
+ /bin/rm -f "$abs_dest"
332
+ log " deleted $abs_dest (backup $abs_backup missing)"
333
+ fi
334
+ missing=$((missing + 1))
335
+ fi
336
+ else
337
+ if [ -f "$abs_dest" ]; then
338
+ if [ "$DRY_RUN" = "true" ]; then
339
+ log " would delete $abs_dest"
340
+ else
341
+ /bin/rm -f "$abs_dest"
342
+ log " deleted $abs_dest"
343
+ fi
344
+ deleted=$((deleted + 1))
345
+ else
346
+ log " skip $abs_dest (already absent)"
347
+ fi
348
+ fi
349
+ done < "$MANIFEST_PATH"
350
+
351
+ if [ "$DRY_RUN" = "true" ]; then
352
+ log " would delete $MANIFEST_PATH"
353
+ for mb in "$MANIFEST_PATH".conductor-backup-*; do
354
+ [ -e "$mb" ] && log " would delete $mb"
355
+ done
356
+ else
357
+ /bin/rm -f "$MANIFEST_PATH"
358
+ for mb in "$MANIFEST_PATH".conductor-backup-*; do
359
+ [ -e "$mb" ] && /bin/rm -f "$mb"
360
+ done
361
+ log " deleted $MANIFEST_PATH"
362
+ fi
363
+
364
+ # Try to clean up empty dirs left behind (deepest first).
365
+ for d in .agents/skills/reflect .agents/skills .agents .codex/agents .codex .conductor/reflect .conductor docs/specs docs; do
366
+ local abs_d="$TARGET_ABS/$d"
367
+ if [ -d "$abs_d" ]; then
368
+ if [ "$DRY_RUN" = "true" ]; then
369
+ if [ -z "$(/bin/ls -A "$abs_d" 2>/dev/null)" ]; then
370
+ log " would rmdir empty $abs_d"
371
+ fi
372
+ else
373
+ /bin/rmdir "$abs_d" 2>/dev/null && log " rmdir empty $abs_d" || true
374
+ fi
375
+ fi
376
+ done
377
+
378
+ echo ""
379
+ echo "========================================================"
380
+ if [ "$DRY_RUN" = "true" ]; then
381
+ echo " Uninstall preview (dry-run)"
382
+ else
383
+ echo " Uninstall complete"
384
+ fi
385
+ echo " Target: $TARGET_ABS"
386
+ echo " Entries processed: $entries_count"
387
+ echo " Backups restored: $restored"
388
+ echo " Files deleted: $deleted"
389
+ echo " Backup-missing deletes: $missing"
390
+ echo "========================================================"
391
+ }
392
+
393
+ uninstall_legacy_scan() {
394
+ log "legacy scan mode — searching for .conductor-backup-* files under $TARGET_ABS"
395
+ local found=0
396
+ while IFS= read -r f; do
397
+ found=$((found + 1))
398
+ if [ "$DRY_RUN" = "true" ]; then
399
+ log " would delete legacy backup $f"
400
+ else
401
+ /bin/rm -f "$f"
402
+ log " deleted legacy backup $f"
403
+ fi
404
+ done < <(/usr/bin/find "$TARGET_ABS" -type f -name '*.conductor-backup-*' 2>/dev/null)
405
+ log "legacy scan: $found backup file(s)"
406
+ log "WARNING: legacy mode does not delete Conductor-emitted source files (no manifest)."
407
+ log " Delete AGENTS.md manually if desired."
408
+ }
409
+
410
+ if [ "$UNINSTALL" = "true" ]; then
411
+ do_uninstall
412
+ exit 0
413
+ fi
414
+
415
+ # ----- onboarding wizard --------------------------------------------------
416
+ # Wizard fires when adopter signal is detected: existing AGENTS.md OR existing .codex/.
417
+ # Otherwise (truly fresh target) wizard is skipped.
418
+
419
+ IS_ADOPTER_CASE="false"
420
+ if [ -f "$TARGET_ABS/AGENTS.md" ] || [ -d "$TARGET_ABS/.codex" ]; then
421
+ IS_ADOPTER_CASE="true"
422
+ fi
423
+
424
+ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN" = "false" ]; then
425
+ echo ""
426
+ echo "========================================================"
427
+ echo " Welcome to CONDUCTOR setup (Codex adapter)"
428
+ echo " Target: $TARGET_ABS"
429
+ echo "========================================================"
430
+ echo ""
431
+
432
+ printf "Detect existing config? (y/N): "
433
+ read -r _detect_answer
434
+ if [ "$_detect_answer" = "y" ] || [ "$_detect_answer" = "Y" ]; then
435
+ _has_agents="no"
436
+ [ -f "$TARGET_ABS/AGENTS.md" ] && _has_agents="yes"
437
+ _has_codex="no"
438
+ [ -d "$TARGET_ABS/.codex" ] && _has_codex="yes"
439
+ echo " AGENTS.md present: $_has_agents, legacy .codex/ present: $_has_codex"
440
+ fi
441
+
442
+ printf "Apply universal-rules? (Y/n): "
443
+ read -r _apply_answer
444
+ if [ "$_apply_answer" = "n" ] || [ "$_apply_answer" = "N" ]; then
445
+ WIZARD_APPLY_RULES="false"
446
+ echo " Skipping universal-rules — AGENTS.md will carry intro + workflow only."
447
+ fi
448
+
449
+ echo ""
450
+ echo "Available recipes:"
451
+ echo " web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement"
452
+ printf "Select recipes (comma-separated, or leave blank for none): "
453
+ read -r _recipe_answer
454
+ if [ -n "$_recipe_answer" ]; then
455
+ RECIPES="$_recipe_answer"
456
+ echo " Recipes selected: $RECIPES"
457
+ else
458
+ echo " No recipes selected."
459
+ fi
460
+
461
+ echo ""
462
+ elif [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "true" ]; then
463
+ log "Adopter case detected — applying defaults (--no-prompt): rules=yes, recipes=${RECIPES:-(none)}"
464
+ fi
465
+
466
+ # ----- step 1: build AGENTS.md (single-file Codex bundle) -----------------
467
+
468
+ init_manifest
469
+
470
+ UNIVERSAL_RULES="workflow spec-as-you-go quality-gates operations meta-discipline"
471
+
472
+ AGENTS_DEST="$TARGET_ABS/AGENTS.md"
473
+
474
+ log "Step 1/2: AGENTS.md → $AGENTS_DEST"
475
+ backup_and_remember "$AGENTS_DEST"
476
+
477
+ # Collect installed recipe ids (for the summary + manifest), validating each exists.
478
+ INSTALLED_RECIPES=""
479
+ if [ -n "$RECIPES" ]; then
480
+ IFS=',' read -ra _RECIPE_LIST <<< "$RECIPES"
481
+ for r in "${_RECIPE_LIST[@]}"; do
482
+ r="$(printf '%s' "$r" | /usr/bin/sed 's/^ *//; s/ *$//')"
483
+ [ -z "$r" ] && continue
484
+ if [ ! -f "$CORE_ROOT/recipes/$r.md" ]; then
485
+ echo "Warning: recipe '$r' not found at $CORE_ROOT/recipes/$r.md; skipping" >&2
486
+ continue
487
+ fi
488
+ INSTALLED_RECIPES="$INSTALLED_RECIPES $r"
489
+ done
490
+ fi
491
+
492
+ # build_agents_md — writes the full bundle to stdout. Pure assembly; no side effects.
493
+ build_agents_md() {
494
+ # --- header (synthesized inline; no _native/*.tpl exists) ---------------
495
+ /bin/cat <<'HEADER'
496
+ # AGENTS.md — CONDUCTOR workflow rules (Codex adapter)
497
+
498
+ > 이 파일은 CONDUCTOR 프레임워크가 생성한 **프로젝트 규칙 번들**입니다. Codex 는 세션 시작 시
499
+ > 프로젝트 루트의 `AGENTS.md` 를 자동 로드합니다. 아래 규칙은 어떤 코드를 생성하든 항상 적용됩니다.
500
+ >
501
+ > This file is a **project rules bundle** generated by the CONDUCTOR framework. Codex auto-loads
502
+ > `AGENTS.md` from the project root at session start. The rules below apply to every change you make.
503
+
504
+ ## How to use this with Codex (한/영)
505
+
506
+ **한국어** — Codex 는 *한 방(one-shot) 셸 작업* 에 강합니다. 스크립트 작성, 파일 일괄 변환, git 작업,
507
+ "이 명령 실행하고 결과 보고" 류 작업이 최적입니다. 멀티 스텝 오케스트레이션(서브에이전트/훅)은
508
+ Codex 의 강점이 아니므로, 그런 작업은 사람이 순차 프롬프트로 분해하거나 Claude/Cursor 를 쓰세요.
509
+ 이 번들은 Codex 가 *인라인으로 생성하는 코드* 가 프로젝트 컨벤션을 따르도록 충분한 맥락을 줍니다.
510
+
511
+ **English** — Codex shines at *one-shot shell tasks*: writing scripts, batch file transforms, git
512
+ operations, and "run this command and report the output" work. Multi-step orchestration
513
+ (sub-agents / hooks) is not Codex's strength — decompose such work into sequential prompts, or
514
+ reach for Claude/Cursor. This bundle gives Codex enough context that the code it generates inline
515
+ follows your project conventions.
516
+
517
+ > **Enforcement note (Codex)**: Codex has **no sub-agents, no hooks, and no per-pattern rule
518
+ > scoping**. Every rule below is loaded *always* and is **self-policed** — there is no automated
519
+ > gate. Claude-only enforcement mechanisms cited in the rule text (Stop hooks, agent routing) do
520
+ > NOT run on Codex; treat them as reminders. Pair this with a git pre-commit hook if you want a hard gate.
521
+
522
+ ## ABSOLUTE rules (always-on summary)
523
+
524
+ These five bundles are **ABSOLUTE severity** — they are the universal floor, never skipped regardless
525
+ of task size. Full text of each is in its own section below.
526
+
527
+ | Rule | What it guarantees |
528
+ |---|---|
529
+ | **Workflow** | Plan-first / docs-first / process-first ordering; never skip phases by scope. |
530
+ | **Spec-as-you-go** | Documentation updated in the *same turn* as the code it describes. |
531
+ | **Quality Gates** | Two-stage review (pre-commit + pre-merge), test sync, verify-after-change. |
532
+ | **Operations** | Session continuity, completed-task hygiene, dev/prod parity. |
533
+ | **Meta-Discipline** | Originality, ambiguity policy, token economy, model routing, flat-with-leader. |
534
+
535
+ > Before any **non-trivial** task: **Read `docs/CURRENT_WORK.md`** for current project state, then act.
536
+
537
+ HEADER
538
+
539
+ # --- universal rules (each as "## <title>", body sans frontmatter) ------
540
+ if [ "$WIZARD_APPLY_RULES" = "true" ]; then
541
+ for rule in $UNIVERSAL_RULES; do
542
+ src="$CORE_ROOT/universal-rules/$rule.md"
543
+ [ -f "$src" ] || { echo "Warning: $src not found; skipping" >&2; continue; }
544
+ title="$(derive_title "$src")"
545
+ echo "---"
546
+ echo ""
547
+ echo "## $title"
548
+ echo ""
549
+ strip_frontmatter "$src"
550
+ echo ""
551
+ done
552
+ fi
553
+
554
+ # --- compressed workflow from PHASES.md --------------------------------
555
+ echo "---"
556
+ echo ""
557
+ /bin/cat <<'WORKFLOW'
558
+ ## Workflow phases (compressed)
559
+
560
+ The 6-phase model scales with scope. **Codex's typical one-shot use cases skip Plan / Architecture
561
+ more often than other tools** — but the gates that remain (Implementation → Review → Spec) still hold.
562
+
563
+ | Scope | Phases entered | Skip |
564
+ |---|---|---|
565
+ | Trivial | Implementation → Review → Spec | Plan, Architecture, Tasks |
566
+ | Simple | Tasks → Implementation → Review → Spec | Plan, Architecture |
567
+ | Medium | Plan → Tasks → Implementation → Review → Spec | Architecture |
568
+ | Large | Plan → Architecture → Tasks → Implementation → Review → Spec | — |
569
+
570
+ - **Plan** — for medium+ scope: write the approach, files affected, risks, stop condition.
571
+ - **Architecture** — for large/system-shaping work: record decision(s) under `docs/architecture/`.
572
+ - **Tasks** — enumerate work with objective, file paths, constraints, output paths, stop condition.
573
+ - **Implementation** — code + test updates per task. Keep changes scoped to the task.
574
+ - **Review** — Stage A on the diff (correctness), Stage B before merge (block on HIGH-confidence issues).
575
+ - **Spec** — update `docs/specs/<area>.md` to reflect actually-shipped behavior (spec-as-you-go).
576
+
577
+ > On Codex, phase enforcement is **self-policed** (no Stop hooks). The rule text above is the reminder.
578
+
579
+ WORKFLOW
580
+
581
+ # --- recipes (opt-in), each as "## Recipe — <name>" --------------------
582
+ if [ -n "$INSTALLED_RECIPES" ]; then
583
+ for r in $INSTALLED_RECIPES; do
584
+ src="$CORE_ROOT/recipes/$r.md"
585
+ [ -f "$src" ] || continue
586
+ echo "---"
587
+ echo ""
588
+ echo "## Recipe — $r"
589
+ echo ""
590
+ strip_frontmatter "$src"
591
+ echo ""
592
+ done
593
+ fi
594
+
595
+ # --- memory note (DIY .memory/) ----------------------------------------
596
+ /bin/cat <<'MEMORY'
597
+ ---
598
+
599
+ ## Memory (DIY `.memory/`)
600
+
601
+ Codex has **no built-in memory directory**. To persist cross-session context (user role/preferences,
602
+ corrections you should not repeat, ongoing project goals, pointers to external systems), create a
603
+ `.memory/` directory at the project root and add it to `.gitignore` so personal entries don't leak
604
+ into the repo.
605
+
606
+ Suggested layout (one file per entry + an always-read index):
607
+
608
+ ```
609
+ .memory/
610
+ ├── MEMORY.md # index, ≤ 200 lines — paste relevant entries into your prompt
611
+ ├── user_*.md # role, preferences, knowledge level
612
+ ├── feedback_*.md # corrections + validated approaches (lead with the rule, then Why / How)
613
+ ├── project_*.md # ongoing work, goals, deadlines (use absolute dates)
614
+ └── reference_*.md # pointers to external systems (issue trackers, dashboards)
615
+ ```
616
+
617
+ Do NOT store in memory: code patterns / conventions / file paths (read the code), git history
618
+ (use `git log`), debugging fix recipes (the fix is in the commit), or anything already in this
619
+ AGENTS.md. Before relying on a memory entry, **verify it's still true** (the path/flag/claim may be stale).
620
+ MEMORY
621
+ }
622
+
623
+ if [ "$DRY_RUN" = "true" ]; then
624
+ log "would write $AGENTS_DEST (intro + $( [ "$WIZARD_APPLY_RULES" = "true" ] && echo 5 || echo 0 ) universal rules + compressed workflow + recipes:${INSTALLED_RECIPES:- none})"
625
+ else
626
+ build_agents_md > "$AGENTS_DEST"
627
+ record_emit "AGENTS.md" "<synthesized>" "$MANIFEST_LAST_BACKUP"
628
+ log " wrote $AGENTS_DEST"
629
+ fi
630
+
631
+ # ----- opt-in: self-improvement (Reflector) --------------------------------
632
+
633
+ case ",$RECIPES," in
634
+ *",self-improvement,"*)
635
+ log "Step: self-improvement (Reflector) → .codex hook/skill/agent"
636
+ if [ "$DRY_RUN" != "true" ]; then
637
+ /bin/mkdir -p "$TARGET_ABS/.conductor/reflect" "$TARGET_ABS/.codex" "$TARGET_ABS/.codex/agents" "$TARGET_ABS/.agents/skills/reflect"
638
+ gi="$TARGET_ABS/.gitignore"
639
+ grep -qxF '.conductor/' "$gi" 2>/dev/null || printf '\n# CONDUCTOR runtime (local trajectories/lessons)\n.conductor/\n' >> "$gi"
640
+ for s in trajectory-log prune-lessons run-weekly; do
641
+ d="$TARGET_ABS/.conductor/reflect/$s.sh"
642
+ backup_and_remember "$d"; /bin/cp "$CORE_ROOT/reflector/$s.sh" "$d"; /bin/chmod +x "$d"
643
+ record_emit ".conductor/reflect/$s.sh" "core/reflector/$s.sh" "$MANIFEST_LAST_BACKUP"
644
+ done
645
+ # scheduling assets: run-weekly.sh needs the brief; SCHEDULING.md documents registration
646
+ for m in reflect-brief SCHEDULING; do
647
+ d="$TARGET_ABS/.conductor/reflect/$m.md"
648
+ backup_and_remember "$d"; /bin/cp "$CORE_ROOT/reflector/$m.md" "$d"
649
+ record_emit ".conductor/reflect/$m.md" "core/reflector/$m.md" "$MANIFEST_LAST_BACKUP"
650
+ done
651
+ hc="$TARGET_ABS/.codex/hooks.json"
652
+ if [ ! -f "$hc" ]; then
653
+ backup_and_remember "$hc"
654
+ /bin/cat > "$hc" <<'HOOK'
655
+ {
656
+ "hooks": {
657
+ "Stop": [
658
+ { "matcher": "*", "hooks": [ { "type": "command", "command": "bash ./.conductor/reflect/trajectory-log.sh", "timeout": 30 } ] }
659
+ ]
660
+ }
661
+ }
662
+ HOOK
663
+ record_emit ".codex/hooks.json" "<synthesized>" "$MANIFEST_LAST_BACKUP"
664
+ else
665
+ log " .codex/hooks.json exists — add a Stop hook calling ./.conductor/reflect/trajectory-log.sh manually"
666
+ fi
667
+ sk="$TARGET_ABS/.agents/skills/reflect/SKILL.md"
668
+ backup_and_remember "$sk"
669
+ { printf -- '---\nname: reflect\ndescription: Run the CONDUCTOR Reflector — propose lessons from recent sessions (propose-only). Use when wrapping up work.\n---\n\n'; /bin/cat "$CORE_ROOT/reflector/reflect-brief.md"; } > "$sk"
670
+ record_emit ".agents/skills/reflect/SKILL.md" "core/reflector/reflect-brief.md" "$MANIFEST_LAST_BACKUP"
671
+ ag="$TARGET_ABS/.codex/agents/reflector.toml"
672
+ backup_and_remember "$ag"
673
+ { printf 'name = "reflector"\ndescription = "Reads session trajectories and proposes atomic lesson deltas. Propose-only; never applies."\ndeveloper_instructions = """\n'; strip_frontmatter "$CORE_ROOT/roles/reflector.md"; printf '\n"""\n'; } > "$ag"
674
+ record_emit ".codex/agents/reflector.toml" "core/roles/reflector.md" "$MANIFEST_LAST_BACKUP"
675
+ fi
676
+ ;;
677
+ esac
678
+
679
+ # ----- step 2: docs templates --------------------------------------------
680
+
681
+ log "Step 2/2: docs templates → docs/"
682
+ mkdir_if_real "$TARGET_ABS/docs"
683
+ mkdir_if_real "$TARGET_ABS/docs/specs"
684
+
685
+ for tpl in CURRENT_WORK REMAINING_TASKS PLANS TASKS INDEX; do
686
+ src="$CORE_ROOT/docs-templates/$tpl.md"
687
+ dest="$TARGET_ABS/docs/$tpl.md"
688
+ [ -f "$src" ] || continue
689
+ if [ -f "$dest" ]; then
690
+ log " $dest exists — leaving in place"
691
+ continue
692
+ fi
693
+ if [ "$DRY_RUN" = "true" ]; then
694
+ log "would copy $src -> $dest"
695
+ else
696
+ /bin/cp "$src" "$dest"
697
+ record_emit "docs/$tpl.md" "core/docs-templates/$tpl.md" ""
698
+ fi
699
+ done
700
+
701
+ if [ -f "$CORE_ROOT/docs-templates/specs/_example.md" ]; then
702
+ src="$CORE_ROOT/docs-templates/specs/_example.md"
703
+ dest="$TARGET_ABS/docs/specs/_example.md"
704
+ if [ ! -f "$dest" ]; then
705
+ if [ "$DRY_RUN" = "true" ]; then
706
+ log "would copy $src -> $dest"
707
+ else
708
+ /bin/cp "$src" "$dest"
709
+ record_emit "docs/specs/_example.md" "core/docs-templates/specs/_example.md" ""
710
+ fi
711
+ fi
712
+ fi
713
+
714
+ # Finalize manifest after all emits.
715
+ finalize_manifest
716
+
717
+ # ----- completion summary -------------------------------------------------
718
+
719
+ echo ""
720
+ echo "========================================================"
721
+ if [ "$DRY_RUN" = "true" ]; then
722
+ echo " Dry-run preview complete (no files written)."
723
+ else
724
+ echo " Done."
725
+ fi
726
+ echo " Target: $TARGET_ABS"
727
+ echo " Adapter: codex"
728
+ if [ "$WIZARD_APPLY_RULES" = "true" ]; then
729
+ echo " AGENTS.md: intro + 5 universal rules + compressed workflow + memory note"
730
+ else
731
+ echo " AGENTS.md: intro + compressed workflow + memory note (universal rules skipped)"
732
+ fi
733
+ echo " Recipes appended:${INSTALLED_RECIPES:- (none)}"
734
+ echo ""
735
+ echo " Skipped (per ADR-004 honesty):"
736
+ echo " - Hooks: CONDUCTOR emits the Reflector hook when --recipes=self-improvement (ADR-032); other guards remain Claude-only (ADR-034)."
737
+ echo " - Sub-agent personas: Codex has no sub-agent dispatch — single session per task."
738
+ echo " - Per-pattern scoping: Codex loads AGENTS.md whole — all rules are always-on."
739
+ echo " - Hookify rule templates: Claude-only plugin."
740
+ echo ""
741
+ echo " Activation: AGENTS.md auto-loads on Codex session start (project root)."
742
+ echo "========================================================"
743
+ echo ""
744
+ echo "Next steps for the project:"
745
+ echo " 1. Open $TARGET_ABS with Codex."
746
+ echo " 2. Edit docs/CURRENT_WORK.md with your project's current state."
747
+ echo " 3. (optional) Create .memory/ and add it to .gitignore — see the Memory section in AGENTS.md."
748
+ echo " 4. Verify Codex cites project conventions when generating code (confirms AGENTS.md loaded)."