omniconductor 0.4.1 → 0.6.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ Format follows [Keep a Changelog](https://keepachangelog.com/); versioning is [S
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.6.0] — 2026-07-07
9
+
10
+ ### Added
11
+ - **`loop-engineering` recipe + `pretool-loop-guard` PreToolUse hook** — opt-in discipline for bounded, externally-verified agent loops (G1–G6): explicit done-criterion, iteration+token budget, require-progress, escalate-on-stall, **verify externally never by self-judgment**, oscillation/infinite-loop guard. Grounded in a 5-source verification pass (Huang/DeepMind "Cannot Self-Correct Yet", CRITIC, Reflexion, "When Agents Do Not Stop", Anthropic *Building Effective Agents* — verify hierarchy rules/tests > visual > LLM-judge). The Claude hook is a non-blocking `permissionDecision: ask` soft-warn that self-gates on the recipe, detects same-action-repeat / runaway tool-call budget, is fail-open, and honors `CONDUCTOR_SKIP_LOOP_GUARD` / `CONDUCTOR_LOOP_REPEAT_MAX` / `CONDUCTOR_LOOP_BUDGET` / `CONDUCTOR_LOOP_COOLDOWN_SECONDS`. Recipe count **12 → 13**, hook templates **9 → 10**. Hook is Claude-only (ADR-034); other tools use the rule text. — **ADR-038**.
12
+
13
+ ## [0.5.0] — 2026-07-07
14
+
15
+ ### Added
16
+ - **`git-hygiene` recipe + `stop-git-hygiene-guard` Stop hook** — opt-in shared-repo discipline (G1–G7): no unrequested worktrees, push-don't-hoard, merge=delete-branch, backup≠applied (verify by real code), no reckless force/rebase on shared repos, bundle PRs for CI, session-end hygiene check. Prevents the failure where merged work *looks* lost (orphan worktrees / local-only commit hoarding / stale merged branches) and burns reconciliation time. Recipe body installs on all six tools; the Stop-hook reminder is Claude-only (ADR-034), non-blocking, self-gated on the recipe. Recipe count **11 → 12**, hook templates **7 → 9** (the 0.3.0 `stop-trajectory-log` count was also un-synced). — **ADR-037**.
17
+
8
18
  ## [0.4.1] — 2026-07-06
9
19
 
10
20
  ### Fixed (docs)
package/README.md CHANGED
@@ -6,11 +6,11 @@ Write your project's rules, workflow, and discipline ONCE. Install into any AI c
6
6
 
7
7
  > Born from one year of production iteration at LFamily Labs — the rules, agents, hooks, and memory patterns that survived real shipping pressure.
8
8
 
9
- > **Status (v0.4.0 — 2026-07-05)**: All 6 adapters ship a working `transform.sh` — **Claude Code** (full: rules + hooks + sub-agents + per-call model routing), **Cursor**, **GitHub Copilot** (one install covers 5 IDEs), **Gemini CLI** (`GEMINI.md` + `.gemini/styleguide.md`), **Codex** (`AGENTS.md`), **Windsurf / Devin Desktop** (`.windsurfrules` + `.devin/rules/*.md`). Published to npm as [`omniconductor`](https://www.npmjs.com/package/omniconductor) (v0.4.0). Output is emit-verified (format-validator + CI on all 6); live runtime consumption by Gemini / Codex / Windsurf is adopter-pending — see [`docs/ADAPTER-LIVE-VERIFICATION.md`](./docs/ADAPTER-LIVE-VERIFICATION.md). Manual install ([`docs/MANUAL-INSTALL.md`](./docs/MANUAL-INSTALL.md)) remains a fallback.
9
+ > **Status (v0.6.0 — 2026-07-07)**: All 6 adapters ship a working `transform.sh` — **Claude Code** (full: rules + hooks + sub-agents + per-call model routing), **Cursor**, **GitHub Copilot** (one install covers 5 IDEs), **Gemini CLI** (`GEMINI.md` + `.gemini/styleguide.md`), **Codex** (`AGENTS.md`), **Windsurf / Devin Desktop** (`.windsurfrules` + `.devin/rules/*.md`). Published to npm as [`omniconductor`](https://www.npmjs.com/package/omniconductor) (v0.6.0). Output is emit-verified (format-validator + CI on all 6); live runtime consumption by Gemini / Codex / Windsurf is adopter-pending — see [`docs/ADAPTER-LIVE-VERIFICATION.md`](./docs/ADAPTER-LIVE-VERIFICATION.md). Manual install ([`docs/MANUAL-INSTALL.md`](./docs/MANUAL-INSTALL.md)) remains a fallback.
10
10
  >
11
- > **New in 0.4.0**: instruction-fidelity-first **token economy** reduce tokens without distorting your instructions: lossless context editing before lossy compaction, an output-brevity discipline, and a new "verbose output" anti-pattern (ADR-035/036; [`docs/CONTEXT-EDITING-GUIDE.md`](./docs/CONTEXT-EDITING-GUIDE.md)). **In 0.3.0**: an opt-in **self-improvement / Reflector loop** (reads session trajectories + git and *proposes* lessons — propose-only — on all six tools; `--recipes=self-improvement`, ADR-030/032/033) + a first-party-verified **compatibility-matrix correction** (all six tools ship hooks / sub-agents / per-task model routing, retiring the old "Claude-only" view; ADR-031). Full history: [`CHANGELOG.md`](./CHANGELOG.md).
11
+ > **New in 0.6.0**: an opt-in **`loop-engineering` recipe** — bounded, externally-verified agent loops (explicit done-criterion, iteration+token budget, require-progress, escalate-on-stall, **verify externally never by self-judgment**, oscillation guard), grounded in a 5-source research pass; Claude adds a non-blocking PreToolUse loop-guard, other tools use the rule text (ADR-038). **In 0.5.0**: **`git-hygiene`** shared-repo discipline (ADR-037). **In 0.4.0**: instruction-fidelity **token economy** (ADR-035/036). **In 0.3.0**: **self-improvement / Reflector loop** (ADR-030/032/033) + compatibility-matrix correction (ADR-031). Full history: [`CHANGELOG.md`](./CHANGELOG.md).
12
12
  >
13
- > Marketplace listing (VSCode Marketplace + Open VSX) remains **Phase 2** (post-0.4) — see ADR-023.
13
+ > Marketplace listing (VSCode Marketplace + Open VSX) remains **Phase 2** (post-0.6) — see ADR-023.
14
14
 
15
15
  ---
16
16
 
@@ -21,7 +21,7 @@ Write your project's rules, workflow, and discipline ONCE. Install into any AI c
21
21
  - [Tool coverage matrix](#tool-coverage-matrix)
22
22
  - [Install paths (3 options)](#install-paths)
23
23
  - [Cross-platform: Mac and Windows](#cross-platform-mac-and-windows)
24
- - [Recipes catalog (11)](#recipes-catalog)
24
+ - [Recipes catalog (13)](#recipes-catalog)
25
25
  - [`transform.sh` options reference](#transformsh-options-reference)
26
26
  - [Update / Maintenance / Uninstall](#update--maintenance--uninstall)
27
27
  - [Token measurement & KPI baseline](#token-measurement--kpi-baseline)
@@ -74,7 +74,41 @@ bash ~/conductor/adapters/claude/transform.sh . \
74
74
  # 5. Claude Code 재시작 → /agents 로 6 에이전트 확인
75
75
  ```
76
76
 
77
- 다른 도구는 [Install paths](#install-paths) 참조. Windows 는 [Cross-platform](#cross-platform-mac-and-windows) 참조.
77
+ ### 설치 방법 (3가지)
78
+
79
+ - **Path A — `npx` (권장, 클론 불필요)**: `npx omniconductor init --target=<tool> <dir>` — `<tool>` = `claude` / `cursor` / `copilot` / `gemini` / `codex` / `windsurf`. `list` · `--dry-run` · `--recipes=A,B` · `--uninstall` 지원.
80
+ - **Path B — bash 어댑터**: CONDUCTOR 클론 후 `bash adapters/<tool>/transform.sh <dir> [--recipes=...] [--dry-run]`.
81
+ - **Path C — 수동 복사**: 스크립트 없이 `cp`/`cat` 으로. [`docs/MANUAL-INSTALL.md`](./docs/MANUAL-INSTALL.md) 참조.
82
+ - **Windows**: Git Bash 또는 WSL2 — [Cross-platform](#cross-platform-mac-and-windows) 참조.
83
+
84
+ ### Recipe 카탈로그 (13개, opt-in)
85
+
86
+ 5개 universal rule 은 항상 설치되고, recipe 는 프로젝트에 맞게 골라 담습니다 (`--recipes=`).
87
+
88
+ | Recipe | 설치 시점 |
89
+ |---|---|
90
+ | `coding-conventions` | TypeScript/TSX — 네이밍·Result 패턴·에러 처리 규약 |
91
+ | `monorepo` | npm/pnpm workspaces (apps + packages) |
92
+ | `i18n` | 2개 이상 로케일 — 새 텍스트는 모든 로케일 동시 |
93
+ | `branch-strategy` | main/develop/release 3-브랜치 모델 |
94
+ | `web-mobile-parity` | 웹+모바일 로직 공유 — 버그·기능 양쪽 반영 |
95
+ | `auto-mock-data` | DB 스키마 변경 시 mock seed 자동생성 |
96
+ | `tdd` | 테스트 프레임워크 + Red-Green-Refactor |
97
+ | `debugging` | 재현→원인→수정→회귀테스트 (증상 패치 금지) |
98
+ | `database-discipline` | 관계형 DB — 마이그레이션 우선·접근제어·dev/prod 패리티 |
99
+ | `design-system` | 디자인 토큰 시스템 — 토큰 우선·컴포넌트 재사용·접근성 |
100
+ | `self-improvement` | 세션 회고 Reflector (propose-only, 사람이 승인) |
101
+ | `git-hygiene` | git 프로젝트 (특히 멀티세션/공유 repo) — worktree·push·브랜치 위생 |
102
+ | `loop-engineering` | 에이전트 루프 (fix→verify 반복) — 종료조건·예산·**외부검증** |
103
+
104
+ ### 업데이트 / 제거
105
+
106
+ - **업데이트**: CONDUCTOR 클론을 `git pull` 후 어댑터 재실행 (또는 `npx omniconductor` 최신 버전).
107
+ - **제거**: `bash adapters/<tool>/transform.sh <dir> --uninstall` — manifest 기반으로 CONDUCTOR 가 넣은 파일만 복원/삭제 (직접 커스터마이즈한 건 보존).
108
+
109
+ ### 상세 레퍼런스 (영문)
110
+
111
+ 도구별 지원 매트릭스, `transform.sh` 전체 옵션, 토큰 측정, 트러블슈팅, FAQ 는 아래 영문 섹션을 참조하세요: [Tool coverage matrix](#tool-coverage-matrix) · [transform.sh options](#transformsh-options-reference) · [Troubleshooting](#troubleshooting) · [FAQ](#faq).
78
112
 
79
113
  ---
80
114
 
@@ -248,7 +282,7 @@ For tools without an adapter (Gemini / Codex / Windsurf), or for adopters in con
248
282
 
249
283
  ## Recipes catalog
250
284
 
251
- 11 opt-in recipes layer project-specific discipline on top of the 5 universal rule bundles. Universal rules always install; recipes are pick-and-mix.
285
+ 13 opt-in recipes layer project-specific discipline on top of the 5 universal rule bundles. Universal rules always install; recipes are pick-and-mix.
252
286
 
253
287
  | Recipe | Install when | Adds |
254
288
  |---|---|---|
@@ -263,6 +297,8 @@ For tools without an adapter (Gemini / Codex / Windsurf), or for adopters in con
263
297
  | `database-discipline` | Relational store + migrations + dev/prod split | Migration-first schema changes, access-control on new tables, dev/prod parity |
264
298
  | `design-system` | Design-token system in use | Tokens over raw hex, component reuse, accessibility + spacing scale adherence |
265
299
  | `self-improvement` | Want periodic, human-approved review of your sessions | A **Reflector** reads recent session trajectories + git and **proposes** lessons-learned to `docs/REFLECTION-PROPOSALS.md` (propose-only; you apply). Emits a session-end trajectory hook, a `/reflect` command, a reflector agent, a deterministic prune, and a weekly runner + scheduling guide — on all six tools. See ADR-030/032/033. |
300
+ | `git-hygiene` | Any git project — esp. multi-session/agent repos or protected branches | Shared-repo discipline (G1–G7): no unrequested worktrees, push-don't-hoard, merge=delete-branch, backup≠applied (verify by real code), no reckless force/rebase on shared repos, bundle PRs for CI, session-end hygiene check. Claude adds a non-blocking Stop-hook reminder; other tools use the rule text. See ADR-037. |
301
+ | `loop-engineering` | Any agentic loop (generate→verify→fix→re-verify, test-fix, multi-step) | Bounded, externally-verified loops (G1–G6): explicit done-criterion, iteration+token budget, require-progress, escalate-on-stall, **verify externally never by self-judgment**, oscillation guard. Grounded in the research that self-correction without an external check is unreliable. Claude adds a non-blocking PreToolUse loop-guard (repeat/runaway detection); other tools use the rule text. See ADR-038. |
266
302
 
267
303
  #### Decision tree
268
304
 
@@ -278,6 +314,8 @@ Want root-cause debugging? YES → debugging
278
314
  Relational DB + migrations? YES → database-discipline
279
315
  Design-token system? YES → design-system
280
316
  Want weekly session self-review? YES → self-improvement
317
+ Use git (esp. shared/multi-session)? YES → git-hygiene
318
+ Agent loops / iterative fix-verify? YES → loop-engineering
281
319
  ```
282
320
 
283
321
  #### Recommended combos
@@ -302,7 +340,7 @@ Usage: bash adapters/<tool>/transform.sh <target-project> [options]
302
340
  | Option | Description |
303
341
  |---|---|
304
342
  | `<target-project>` | Project directory to install into (required). `.` for current dir. |
305
- | `--recipes=A,B,C` | Comma-separated recipes from the 11 in `core/recipes/`. |
343
+ | `--recipes=A,B,C` | Comma-separated recipes from the 13 in `core/recipes/`. |
306
344
  | `--dry-run` | Preview only — no files written. |
307
345
  | `--measure-baseline` | Run `tools/measure-tokens.sh --latest` after install; save CSV; auto-show anti-patterns if cache hit < 95%. |
308
346
  | `--no-prompt` | Skip wizard, apply defaults (CI-safe). Combine with `--recipes` and `--measure-baseline` as needed. |
@@ -311,7 +349,7 @@ Usage: bash adapters/<tool>/transform.sh <target-project> [options]
311
349
  | `--force` | Bypass uninstall safety gates (active rebase/merge, missing manifest). |
312
350
  | `-h` `--help` | Print usage. |
313
351
 
314
- **Recipe names** (11): `web-mobile-parity`, `i18n`, `monorepo`, `branch-strategy`, `auto-mock-data`, `coding-conventions`, `tdd`, `debugging`, `database-discipline`, `design-system`, `self-improvement`.
352
+ **Recipe names** (13): `web-mobile-parity`, `i18n`, `monorepo`, `branch-strategy`, `auto-mock-data`, `coding-conventions`, `tdd`, `debugging`, `database-discipline`, `design-system`, `self-improvement`, `git-hygiene`, `loop-engineering`.
315
353
 
316
354
  #### File overwrite behavior
317
355
 
@@ -410,7 +448,7 @@ diff CLAUDE.md.conductor-backup-* CLAUDE.md
410
448
 
411
449
  #### "recipe not found" warning
412
450
 
413
- Check recipe name spelling. Available: `web-mobile-parity`, `i18n`, `monorepo`, `branch-strategy`, `auto-mock-data`, `coding-conventions`, `tdd`, `debugging`, `database-discipline`, `design-system`, `self-improvement`.
451
+ Check recipe name spelling. 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`.
414
452
 
415
453
  #### "Tool doesn't recognize the new rules"
416
454
 
@@ -493,7 +531,7 @@ A: Open VSX. Cursor is a VSCode fork but cannot pull from Microsoft's marketplac
493
531
 
494
532
  **Q: My project uses Go / Python / Rust, not TypeScript.**
495
533
 
496
- A: Skip `coding-conventions` (TypeScript-specific). The 5 universal rule bundles and the other 10 recipes are stack-agnostic.
534
+ A: Skip `coding-conventions` (TypeScript-specific). The 5 universal rule bundles and the other 12 recipes are stack-agnostic.
497
535
 
498
536
  **Q: Windows native PowerShell?**
499
537
 
@@ -45,7 +45,7 @@ bash adapters/claude/transform.sh <target> [--dry-run]
45
45
  │ │ ├── quality-gates.md
46
46
  │ │ ├── operations.md
47
47
  │ │ └── meta-discipline.md
48
- │ ├── hooks/ # 7 hook scripts
48
+ │ ├── hooks/ # 10 hook scripts
49
49
  │ │ ├── pretool-agent-routing.sh
50
50
  │ │ ├── pretool-commit-current-work-check.sh
51
51
  │ │ ├── pretool-commit-test-coverage-check.sh
@@ -32,7 +32,7 @@ CONDUCTOR's universal `meta-discipline.md` rubric (token economy + model routing
32
32
 
33
33
  ## Hook execution model
34
34
 
35
- CONDUCTOR ships 7 hooks, all registered in the generated `.claude/settings.json` (written directly by `transform.sh` — there is no `settings.template.json`):
35
+ CONDUCTOR ships 10 hooks, all registered in the generated `.claude/settings.json` (written directly by `transform.sh` — there is no `settings.template.json`):
36
36
 
37
37
  | Hook | Event | Purpose |
38
38
  |---|---|---|
@@ -58,9 +58,9 @@ The Claude adapter ships a working `transform.sh`. Verified by fresh-target inst
58
58
 
59
59
  | Feature claim | Verified-by-real-install | Verification command / observation |
60
60
  |---|---|---|
61
- | `transform.sh` emits 6 roles, 5 rules, 7 hooks, settings.json, docs | ✅ | `bash adapters/claude/transform.sh <tmp>` then inspect `<tmp>/.claude/` |
61
+ | `transform.sh` emits 6 roles, 5 rules, 10 hooks, settings.json, docs | ✅ | `bash adapters/claude/transform.sh <tmp>` then inspect `<tmp>/.claude/` |
62
62
  | Sub-agent dispatch works | ✅ | `.claude/agents/{planner,builder,reviewer,helper,designer,scribe}.md` recognized by `/help` |
63
63
  | Lazy / always-loaded rules present | ✅ | `.claude/rules/{workflow,spec-as-you-go,quality-gates,operations,meta-discipline}.md` |
64
- | Hooks registered in settings.json | ✅ | `.claude/settings.json` `hooks:` block lists 4 PreToolUse + 3 Stop |
64
+ | Hooks registered in settings.json | ✅ | `.claude/settings.json` `hooks:` block lists 5 PreToolUse + 5 Stop |
65
65
  | Stop hook blocks on missing spec update | ✅ | commit code without spec → `stop-session-log-check.sh` fires |
66
66
  | Idempotent re-run | ✅ | second run reports "SKIP (exists)" for every emitted file |
@@ -31,7 +31,7 @@ core/docs-templates/specs/_example.md
31
31
  core/memory-pattern/README.md
32
32
  core/memory-pattern/EXAMPLES.md
33
33
  core/roles/*.md # 6 role personas → .claude/agents/ (planner/builder/reviewer/helper/designer/scribe)
34
- core/hooks/*.sh.template # 7 hook templates
34
+ core/hooks/*.sh.template # 10 hook templates
35
35
  adapters/claude/_native/CLAUDE.md.tpl # Claude-specific orchestrator manual template
36
36
  ```
37
37
 
@@ -70,7 +70,7 @@ Options:
70
70
  manifest are preserved.
71
71
  --force Bypass uninstall safety checks (active worktrees, missing manifest)
72
72
 
73
- Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement
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, loop-engineering
74
74
  EOF
75
75
  exit 0
76
76
  ;;
@@ -593,7 +593,7 @@ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN"
593
593
  # 3. Select recipes
594
594
  echo ""
595
595
  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"
596
+ 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
597
  printf "Select recipes (comma-separated, or leave blank for none): "
598
598
  read -r _recipe_answer
599
599
  if [ -n "$_recipe_answer" ]; then
@@ -725,7 +725,7 @@ mkdir_if_real "$TARGET_ABS/.claude/hooks"
725
725
  # read guard) emit only if their templates are present in the CONDUCTOR core/ tree, allowing the
726
726
  # adapter to remain forward-compatible with P1.7 work in progress.
727
727
  INSTALLED_HOOKS=()
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; do
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 pretool-loop-guard; do
729
729
  src="$CORE_ROOT/hooks/$hook.sh.template"
730
730
  dest="$TARGET_ABS/.claude/hooks/$hook.sh"
731
731
  if [ ! -f "$src" ]; then
@@ -796,6 +796,12 @@ else
796
796
  "hooks": [
797
797
  { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/pretool-large-file-read-guard.sh" }
798
798
  ]
799
+ },
800
+ {
801
+ "matcher": "*",
802
+ "hooks": [
803
+ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/pretool-loop-guard.sh" }
804
+ ]
799
805
  }
800
806
  ],
801
807
  "Stop": [
@@ -804,14 +810,15 @@ else
804
810
  { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-session-log-check.sh" },
805
811
  { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-r6-review-check.sh" },
806
812
  { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-cache-hit-baseline-check.sh" },
807
- { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-trajectory-log.sh" }
813
+ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-trajectory-log.sh" },
814
+ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-git-hygiene-guard.sh" }
808
815
  ]
809
816
  }
810
817
  ]
811
818
  }
812
819
  }
813
820
  SETTINGS_EOF
814
- 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 8 core hooks: 4 PreToolUse + 4 Stop)"
821
+ 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)"
815
822
  record_emit ".claude/settings.json" "<synthesized>" ""
816
823
  fi
817
824
 
@@ -75,7 +75,7 @@ Output (single-file Codex model):
75
75
  <target>/AGENTS.md Bundled intro + 5 universal rules + compressed workflow + recipes
76
76
  <target>/docs/*.md Universal doc templates (CURRENT_WORK, REMAINING_TASKS, ...)
77
77
 
78
- Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement
78
+ 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
79
79
 
80
80
  What this adapter does NOT install (per ADR-004 honesty):
81
81
  - Hook guards (CONDUCTOR emits the Reflector hook when --recipes=self-improvement, ADR-032; other guards remain Claude-only, ADR-034)
@@ -448,7 +448,7 @@ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN"
448
448
 
449
449
  echo ""
450
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"
451
+ 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"
452
452
  printf "Select recipes (comma-separated, or leave blank for none): "
453
453
  read -r _recipe_answer
454
454
  if [ -n "$_recipe_answer" ]; then
@@ -87,7 +87,7 @@ Options:
87
87
  Conductor-emitted files when none.
88
88
  --force Bypass uninstall safety checks (active worktrees, missing manifest)
89
89
 
90
- Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement
90
+ 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
91
91
 
92
92
  Output (default):
93
93
  <target>/.github/copilot-instructions.md (5 universal rules merged)
@@ -523,7 +523,7 @@ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN"
523
523
 
524
524
  echo ""
525
525
  echo "Available recipes:"
526
- echo " web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement"
526
+ 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"
527
527
  printf "Select recipes (comma-separated, blank for none): "
528
528
  read -r _recipe_answer
529
529
  if [ -n "$_recipe_answer" ]; then
@@ -67,7 +67,7 @@ Options:
67
67
  manifest are preserved.
68
68
  --force Bypass uninstall safety checks (active worktrees, missing manifest)
69
69
 
70
- Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement
70
+ 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
71
71
 
72
72
  What this adapter does NOT install (per ADR-004 honesty + ADR-021):
73
73
  - Hook guards (CONDUCTOR emits the Reflector hook when --recipes=self-improvement, ADR-032; other guards remain Claude-only, ADR-034)
@@ -490,7 +490,7 @@ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN"
490
490
 
491
491
  echo ""
492
492
  echo "Available recipes:"
493
- echo " web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement"
493
+ 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"
494
494
  printf "Select recipes (comma-separated, or leave blank for none): "
495
495
  read -r _recipe_answer
496
496
  if [ -n "$_recipe_answer" ]; then
@@ -71,7 +71,7 @@ Options:
71
71
  manifest are preserved.
72
72
  --force Bypass uninstall safety checks (active worktrees, missing manifest)
73
73
 
74
- Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement
74
+ 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
75
75
 
76
76
  Gemini single-file model:
77
77
  - All 5 universal rules + selected recipes are bundled into one always-loaded GEMINI.md.
@@ -486,7 +486,7 @@ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN"
486
486
 
487
487
  echo ""
488
488
  echo "Available recipes:"
489
- echo " web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement"
489
+ 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"
490
490
  printf "Select recipes (comma-separated, or leave blank for none): "
491
491
  read -r _recipe_answer
492
492
  if [ -n "$_recipe_answer" ]; then
@@ -67,7 +67,7 @@ Options:
67
67
  manifest are preserved.
68
68
  --force Bypass uninstall safety checks (active worktrees, missing manifest)
69
69
 
70
- Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement
70
+ 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
71
71
 
72
72
  What this adapter does NOT install (per ADR-004 honesty + ADR-021):
73
73
  - Hook guards (CONDUCTOR emits the Reflector hook when --recipes=self-improvement, ADR-032; other guards remain Claude-only, ADR-034)
@@ -453,7 +453,7 @@ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN"
453
453
 
454
454
  echo ""
455
455
  echo "Available recipes:"
456
- echo " web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement"
456
+ 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"
457
457
  printf "Select recipes (comma-separated, or leave blank for none): "
458
458
  read -r _recipe_answer
459
459
  if [ -n "$_recipe_answer" ]; then
@@ -14,6 +14,8 @@ CONDUCTOR's universal hook spec. Templates here are compiled into native shell s
14
14
  | `stop-r6-review-check.sh.template` | Session stop event | Remind to run pre-merge review on open PR | Claude `.claude/hooks/stop-r6-review-check.sh` |
15
15
  | `stop-cache-hit-baseline-check.sh.template` | Session stop event | Non-blocking diagnostic — reads the latest session JSONL, computes cache hit rate, reminds when below baseline (token-economy). Fail-open. Override env disables: `CONDUCTOR_SKIP_CACHE_CHECK=1`. | Claude `.claude/hooks/stop-cache-hit-baseline-check.sh` |
16
16
  | `stop-trajectory-log.sh.template` | Session stop event | Non-blocking — reads `transcript_path` + `session_id` from the Stop hook's **stdin** (exact provenance; no `~/.claude/projects` dir-scan) and **upserts** one pointer record per session (session id, transcript path, git HEAD, cwd) into `.conductor/trajectories/index.jsonl` for the Reflector (recipes/self-improvement.md). Same stdin approach as the non-Claude portable logger `core/reflector/trajectory-log.sh`. **Opt-in gated: no-ops unless `.conductor/reflect/` exists** (created only by the self-improvement recipe). Anchors to the project root; fail-open. Override: `CONDUCTOR_SKIP_TRAJLOG=1`. | Claude `.claude/hooks/stop-trajectory-log.sh` |
17
+ | `stop-git-hygiene-guard.sh.template` | Session stop event | Non-blocking — detects git-hygiene collapse (extra worktrees, local-only commits not on any remote, abnormally many local branches) and injects a cleanup reminder per `recipes/git-hygiene.md` (G1/G2/G3/G7). **Opt-in gated: no-ops unless `.claude/rules/git-hygiene.md` exists** (created only by the git-hygiene recipe). Anchors to the project root; 15-min cool-down; fail-open, always exits 0. Overrides: `CONDUCTOR_SKIP_GIT_HYGIENE=1`, `CONDUCTOR_GIT_HYGIENE_BRANCH_MAX` (default 20). | Claude `.claude/hooks/stop-git-hygiene-guard.sh` |
18
+ | `pretool-loop-guard.sh.template` | Before each tool call (PreToolUse, `*` matcher) | Non-blocking soft-warn (`permissionDecision: ask`) — tracks a per-session signature of each tool call and surfaces a reminder when the **same action repeats** ≥ `CONDUCTOR_LOOP_REPEAT_MAX` (default 5; oscillation/no-progress) or the session's **total tool calls** ≥ `CONDUCTOR_LOOP_BUDGET` (default 120; runaway), per `recipes/loop-engineering.md` (G2/G3/G6). **Opt-in gated: no-ops unless `.claude/rules/loop-engineering.md` exists.** Per-session cool-down (`CONDUCTOR_LOOP_COOLDOWN_SECONDS`, default 120); trace in `$TMPDIR`, not the repo; fail-open, always exits 0. Override: `CONDUCTOR_SKIP_LOOP_GUARD=1`. | Claude `.claude/hooks/pretool-loop-guard.sh` |
17
19
 
18
20
  The two `pretool-commit-*` templates are **soft `ask` warns**: they emit
19
21
  `{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":...}}`,
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # CONDUCTOR universal hook template
4
+ # hook_id: pretool-loop-guard
5
+ # trigger: pretool
6
+ # action: Before each tool call, track a per-session signature of the call and
7
+ # soft-warn (non-blocking "ask") when the SAME action repeats too often
8
+ # (oscillation / no-progress loop) or the session's total tool calls
9
+ # exceed a budget (runaway loop). Enforces the loop-engineering recipe.
10
+ # compile_targets: claude
11
+ # fallback: rule-text-reminder
12
+ #
13
+ # Generated by adapters/<tool>/transform.sh.
14
+ #
15
+ # Enforces:
16
+ # - recipes/loop-engineering.md (bound the loop: iteration budget G2, no-progress
17
+ # halt G3, oscillation/infinite-loop guard G6)
18
+ #
19
+ # Behavior (fail-open, non-blocking):
20
+ # 1. No-op unless the loop-engineering recipe is installed (self-gate on
21
+ # .claude/rules/loop-engineering.md).
22
+ # 2. Per session, keep a trace of tool-call signatures in a private tmp file.
23
+ # A "signature" = tool_name + hash(tool_input): identical calls collide.
24
+ # 3. Warn (permissionDecision:ask + reason) when the CURRENT signature has
25
+ # occurred >= REPEAT_MAX times (same action repeated — likely looping without
26
+ # progress), OR the session's total tool calls >= BUDGET (runaway). A per-
27
+ # session cool-down keeps it from firing on every subsequent call.
28
+ # 4. ALWAYS exit 0. Any error, missing input, or missing python3 → allow silently.
29
+ # "ask" surfaces the reason and routes to the permission flow — it does NOT
30
+ # hard-block and does NOT auto-approve (same contract as the other pretool
31
+ # soft-warns).
32
+ #
33
+ # Overrides (runtime env, not compile-time placeholders):
34
+ # CONDUCTOR_SKIP_LOOP_GUARD=1 disable entirely
35
+ # CONDUCTOR_LOOP_REPEAT_MAX same-action repeat threshold (default 5)
36
+ # CONDUCTOR_LOOP_BUDGET total tool-calls-per-session threshold (default 120)
37
+ # CONDUCTOR_LOOP_COOLDOWN_SECONDS min seconds between warns per session (default 120)
38
+
39
+ set -u
40
+
41
+ # Honor opt-out before any work.
42
+ [ "${CONDUCTOR_SKIP_LOOP_GUARD:-}" = "1" ] && exit 0
43
+
44
+ # Anchor to the project root (emitted hook lives at <project>/.claude/hooks/).
45
+ _self_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" || exit 0
46
+ _proj_root="$(cd "$_self_dir/../.." 2>/dev/null && pwd)" || exit 0
47
+ cd "$_proj_root" 2>/dev/null || exit 0
48
+
49
+ # Self-gate: only act when the loop-engineering recipe is installed.
50
+ [ -f ".claude/rules/loop-engineering.md" ] || exit 0
51
+
52
+ # Robust JSON handling needs python3; without it, degrade to silent allow.
53
+ command -v /usr/bin/python3 >/dev/null 2>&1 || exit 0
54
+
55
+ # Read the PreToolUse payload from stdin (no piped stdin → nothing to do).
56
+ export PAYLOAD_RAW="$(/bin/cat 2>/dev/null || true)"
57
+ [ -n "${PAYLOAD_RAW:-}" ] || exit 0
58
+
59
+ # All logic lives in python for safe parsing / hashing / file IO. It prints EITHER
60
+ # the ask-JSON (when a threshold is crossed and not cooling down) or nothing. Any
61
+ # exception prints nothing → the shell falls through to `exit 0` (allow).
62
+ REPEAT_MAX="${CONDUCTOR_LOOP_REPEAT_MAX:-5}" \
63
+ BUDGET="${CONDUCTOR_LOOP_BUDGET:-120}" \
64
+ COOLDOWN="${CONDUCTOR_LOOP_COOLDOWN_SECONDS:-120}" \
65
+ /usr/bin/python3 -c '
66
+ import json, os, sys, hashlib, re, time, tempfile
67
+
68
+ def out_nothing():
69
+ sys.exit(0)
70
+
71
+ try:
72
+ raw = os.environ.get("PAYLOAD_RAW", "") or ""
73
+ d = json.loads(raw)
74
+ if not isinstance(d, dict):
75
+ out_nothing()
76
+
77
+ tool = d.get("tool_name", "") or ""
78
+ if not tool:
79
+ out_nothing() # no identifiable action → nothing to track
80
+
81
+ tool_input = d.get("tool_input", {})
82
+ session = d.get("session_id", "") or d.get("sessionId", "") or "nosession"
83
+
84
+ # Sanitize identifiers used in file paths (defense against path injection).
85
+ session = re.sub(r"[^A-Za-z0-9_-]", "", str(session))[:64] or "nosession"
86
+ user = re.sub(r"[^A-Za-z0-9_-]", "", os.environ.get("USER", "") or "unknown")[:32] or "unknown"
87
+
88
+ # Thresholds (env-tunable, with safe fallbacks on garbage input).
89
+ def envint(name, default):
90
+ try:
91
+ v = int(os.environ.get(name, "") or default)
92
+ return v if v > 0 else default
93
+ except Exception:
94
+ return default
95
+ repeat_max = envint("REPEAT_MAX", 5)
96
+ budget = envint("BUDGET", 120)
97
+ cooldown = envint("COOLDOWN", 120)
98
+
99
+ # Signature = tool + stable hash of its input. Identical calls collide;
100
+ # a canonical (sorted-key) dump makes key order irrelevant.
101
+ try:
102
+ payload = json.dumps(tool_input, sort_keys=True, ensure_ascii=True, default=str)
103
+ except Exception:
104
+ payload = repr(tool_input)
105
+ sig = tool + ":" + hashlib.sha1(payload.encode("utf-8", "replace")).hexdigest()[:16]
106
+
107
+ tmp = tempfile.gettempdir()
108
+ base = os.path.join(tmp, "conductor-loop-%s-%s" % (user, session))
109
+ trace_path = base + ".trace"
110
+ cooldown_path = base + ".cooldown"
111
+
112
+ # Append this signature, then read the (bounded) trace back.
113
+ try:
114
+ with open(trace_path, "a", encoding="utf-8") as f:
115
+ f.write(sig + "\n")
116
+ except Exception:
117
+ out_nothing() # cannot persist → cannot reason about the loop; allow.
118
+
119
+ try:
120
+ with open(trace_path, "r", encoding="utf-8") as f:
121
+ lines = f.read().splitlines()
122
+ except Exception:
123
+ out_nothing()
124
+
125
+ # Bound work: only the last N entries matter for a runaway/oscillation view.
126
+ if len(lines) > 5000:
127
+ lines = lines[-5000:]
128
+
129
+ total = len(lines)
130
+ same = sum(1 for x in lines if x == sig)
131
+
132
+ hit_repeat = same >= repeat_max
133
+ hit_budget = total >= budget
134
+ if not (hit_repeat or hit_budget):
135
+ out_nothing()
136
+
137
+ # Cool-down: at most one warn per `cooldown` seconds per session.
138
+ now = int(time.time())
139
+ try:
140
+ with open(cooldown_path, "r", encoding="utf-8") as f:
141
+ last = int((f.read().strip() or "0"))
142
+ except Exception:
143
+ last = 0
144
+ if now - last < cooldown:
145
+ out_nothing()
146
+ try:
147
+ with open(cooldown_path, "w", encoding="utf-8") as f:
148
+ f.write(str(now))
149
+ except Exception:
150
+ pass # cool-down is best-effort; still warn this once.
151
+
152
+ if hit_repeat:
153
+ reason = ("[loop-guard] The same action (%s) has run %d times this session — "
154
+ "you may be looping without progress (recipe G3/G6). Before repeating: "
155
+ "confirm each iteration changes state, verify with an EXTERNAL check "
156
+ "(tests/rules/tool output — not self-judgment), and if stuck after a few "
157
+ "tries, stop and ask rather than loop (G4). " % (tool, same))
158
+ else:
159
+ reason = ("[loop-guard] %d tool calls this session — approaching a runaway loop "
160
+ "(recipe G2 iteration budget). Confirm you are converging on an explicit "
161
+ "done-criterion, not spinning. " % total)
162
+ reason += "(Silence: CONDUCTOR_SKIP_LOOP_GUARD=1; tune CONDUCTOR_LOOP_REPEAT_MAX / CONDUCTOR_LOOP_BUDGET.)"
163
+
164
+ print(json.dumps({
165
+ "hookSpecificOutput": {
166
+ "hookEventName": "PreToolUse",
167
+ "permissionDecision": "ask",
168
+ "permissionDecisionReason": reason,
169
+ }
170
+ }))
171
+ except SystemExit:
172
+ raise
173
+ except Exception:
174
+ # Absolutely never fail a tool call because of this guard.
175
+ pass
176
+ '
177
+ exit 0
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # CONDUCTOR universal hook template
4
+ # hook_id: stop-git-hygiene-guard
5
+ # trigger: stop
6
+ # action: On session stop, detect git-hygiene-collapse states (orphan worktrees,
7
+ # local-only commits, abnormally many local branches) and inject a
8
+ # non-blocking cleanup reminder per the git-hygiene recipe (G1/G2/G3/G7).
9
+ # compile_targets: claude
10
+ # fallback: rule-text-reminder
11
+ #
12
+ # Generated by adapters/<tool>/transform.sh.
13
+ #
14
+ # Enforces:
15
+ # - recipes/git-hygiene.md (session-end hygiene: G1 worktrees, G2 push, G3 delete)
16
+ #
17
+ # Behavior (fail-open, non-blocking):
18
+ # 1. No-op unless the git-hygiene recipe is installed (self-gate on
19
+ # .claude/rules/git-hygiene.md) — the guard ships with every Claude install
20
+ # but only acts for adopters who opted into the recipe.
21
+ # 2. Reminder only. Emits {"decision":"block","reason":...} to surface the state
22
+ # to Claude; ALWAYS exits 0. Never hard-fails, never blocks session stop.
23
+ # 3. Cools down (one reminder / 15 min) so it does not nag.
24
+ #
25
+ # Detects the states that make merged work look lost and burn reconciliation time:
26
+ # - worktrees beyond the main tree (G1),
27
+ # - local commits not on any remote (`git log --branches --not --remotes`) (G2),
28
+ # - abnormally high local branch count = merged branches never deleted (G3).
29
+ #
30
+ # Overrides (read at runtime, not compile-time placeholders):
31
+ # CONDUCTOR_SKIP_GIT_HYGIENE=1 silence for a deliberate transient state
32
+ # CONDUCTOR_GIT_HYGIENE_BRANCH_MAX local-branch threshold (default 20)
33
+
34
+ set -u
35
+
36
+ [ "${CONDUCTOR_SKIP_GIT_HYGIENE:-}" = "1" ] && exit 0
37
+
38
+ # Anchor to the project root. The emitted hook lives at <project>/.claude/hooks/,
39
+ # so ../.. is the root — resolves the recipe gate + git checks regardless of cwd.
40
+ _self_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" || exit 0
41
+ _proj_root="$(cd "$_self_dir/../.." 2>/dev/null && pwd)" || exit 0
42
+ cd "$_proj_root" || exit 0
43
+
44
+ # Self-gate: only act when the git-hygiene recipe is installed.
45
+ [ -f ".claude/rules/git-hygiene.md" ] || exit 0
46
+
47
+ # Not a git repo → nothing to check.
48
+ git rev-parse --git-dir >/dev/null 2>&1 || exit 0
49
+
50
+ BRANCH_MAX="${CONDUCTOR_GIT_HYGIENE_BRANCH_MAX:-20}"
51
+
52
+ # (1) Worktrees beyond the main tree.
53
+ WT_COUNT="$(git worktree list 2>/dev/null | /usr/bin/grep -c . )"
54
+ [ -n "$WT_COUNT" ] || WT_COUNT=1
55
+ WT_EXTRA=$((WT_COUNT - 1))
56
+
57
+ # (2) Local commits not on any remote (unpushed = at-risk / phantom-lost).
58
+ LOCAL_ONLY="$(git log --branches --not --remotes --oneline 2>/dev/null | /usr/bin/grep -c . )"
59
+ [ -n "$LOCAL_ONLY" ] || LOCAL_ONLY=0
60
+
61
+ # (3) Local branch count (merged branches never deleted accumulate here).
62
+ BRANCHES="$(git for-each-ref --format='%(refname:short)' refs/heads 2>/dev/null | /usr/bin/grep -c . )"
63
+ [ -n "$BRANCHES" ] || BRANCHES=0
64
+
65
+ # Nothing wrong → allow stop silently.
66
+ if [ "$WT_EXTRA" -le 0 ] && [ "$LOCAL_ONLY" -le 0 ] && [ "$BRANCHES" -le "$BRANCH_MAX" ]; then
67
+ exit 0
68
+ fi
69
+
70
+ # Cool-down: at most one reminder per 15 min.
71
+ FLAG="/tmp/conductor-git-hygiene-flag-${USER:-unknown}"
72
+ if [ -f "$FLAG" ]; then
73
+ LAST="$(/bin/cat "$FLAG" 2>/dev/null || echo 0)"
74
+ NOW="$(/bin/date +%s 2>/dev/null || echo 0)"
75
+ if [ "$((NOW - LAST))" -lt 900 ]; then
76
+ exit 0
77
+ fi
78
+ fi
79
+ /bin/date +%s > "$FLAG" 2>/dev/null || true
80
+
81
+ MSGS=""
82
+ [ "$WT_EXTRA" -gt 0 ] && MSGS="${MSGS}${WT_EXTRA} extra git worktree(s) present (G1: remove unless a requested worktree is mid-use). "
83
+ [ "$LOCAL_ONLY" -gt 0 ] && MSGS="${MSGS}${LOCAL_ONLY} local-only commit(s) not on any remote (G2: push them — this is exactly the 'phantom lost/unmerged feature' state). "
84
+ [ "$BRANCHES" -gt "$BRANCH_MAX" ] && MSGS="${MSGS}${BRANCHES} local branches (G3: delete branches whose PRs merged, local+remote). "
85
+
86
+ /bin/cat <<JSON
87
+ {"decision":"block","reason":"[git-hygiene] ${MSGS}Before ending: run 'git worktree list' + 'git log --branches --not --remotes --oneline' and clean up per the git-hygiene recipe (push local-only work, remove orphan worktrees, delete merged branches). Backup != applied: verify features are on the target branch by real code, not by a backup branch. (Set CONDUCTOR_SKIP_GIT_HYGIENE=1 to silence a deliberate transient state.)"}
88
+ JSON
89
+ exit 0
@@ -2,7 +2,7 @@
2
2
 
3
3
  Per ADR-013, CONDUCTOR ships project-specific recipes as OPT-IN. They are not loaded by default. Adopters select the recipes that match their project and the adapter wires them into the appropriate native location.
4
4
 
5
- ## The 11 recipes
5
+ ## The 13 recipes
6
6
 
7
7
  | File | When to install |
8
8
  |---|---|
@@ -17,6 +17,8 @@ Per ADR-013, CONDUCTOR ships project-specific recipes as OPT-IN. They are not lo
17
17
  | `database-discipline.md` | Project has a relational store with migrations + dev/prod split. Ships 2 recipe-scoped hookify rules (SQL access-control + SECURITY DEFINER search_path) — see ADR-028 |
18
18
  | `design-system.md` | Project maintains a design-token system (color/spacing/typography tokens). Ships 1 recipe-scoped hookify rule (raw-hex-instead-of-token) — see ADR-028 |
19
19
  | `self-improvement.md` | Project wants a periodic, human-approved Reflector that distils session lessons into memory/rules. Propose-only; nothing auto-applies. Drives the `reflector` role — see ADR-030 |
20
+ | `git-hygiene.md` | Any git project — esp. repos worked by multiple sessions/agents or with protected branches. Shared-repo discipline (no orphan worktrees, push-don't-hoard, merge=delete-branch, backup≠applied). Ships a Claude-only Stop-hook reminder (`stop-git-hygiene-guard`); other tools use the rule text — see ADR-037 |
21
+ | `loop-engineering.md` | Any agentic loop (generate→verify→fix→re-verify, test-fix, multi-step). Bounded, externally-verified loops: explicit done-criterion, iteration+token budget, require-progress, escalate-on-stall, verify-externally-not-self-judgment, oscillation guard. Ships a Claude-only PreToolUse reminder (`pretool-loop-guard`); other tools use the rule text — see ADR-038 |
20
22
 
21
23
  ## Selection patterns
22
24
 
@@ -27,7 +29,9 @@ Per ADR-013, CONDUCTOR ships project-specific recipes as OPT-IN. They are not lo
27
29
  | Multi-locale SaaS | `i18n` + `coding-conventions` + `tdd` + `debugging` |
28
30
  | Relational-DB-backed SaaS (migrations + dev/prod) | `database-discipline` + `coding-conventions` + `tdd` + `debugging` |
29
31
  | Token-driven design system (theming / dark-mode) | `design-system` + `coding-conventions` + `tdd` + `debugging` |
30
- | Full-stack SaaS with web + mobile + i18n | All 11 |
32
+ | Full-stack SaaS with web + mobile + i18n | All 13 |
33
+ | Any git repo, esp. shared / multi-session | add `git-hygiene` to any of the above |
34
+ | Agentic / iterative loops (fix-verify, test-fix) | add `loop-engineering` to any of the above |
31
35
  | Greenfield experiment | None — universal-rules + roles only is enough |
32
36
 
33
37
  ## How adapters consume these files
@@ -0,0 +1,60 @@
1
+ ---
2
+ recipe_id: git-hygiene
3
+ recipe_name: "Git Hygiene / Shared-Repo Discipline"
4
+ applies_when: "any git project — especially repos worked by multiple sessions/agents or with protected branches"
5
+ severity: STRONG (when installed)
6
+ linked_rules:
7
+ - operations
8
+ - quality-gates
9
+ - meta-discipline
10
+ ---
11
+
12
+ # Recipe — Git Hygiene / Shared-Repo Discipline
13
+
14
+ > Opt-in recipe. Install for any project under git — strongly recommended when more than one session/agent may touch the repo, or when it has protected branches. It codifies the workflow-hygiene habits that stop *completed* work from *looking* lost. Install if you have ever spent time reconciling "where did my feature go" — you likely will again without it.
15
+
16
+ ## Why this exists
17
+
18
+ Left undisciplined, an agent can turn a healthy repo into one where merged work looks stranded: it spins up `git worktree`s nobody asked for and never cleans them up, hoards commits locally instead of pushing, and never deletes branches after their PRs merge. The classic collapse — dozens of stale local branches, a pile of local-only commits, orphan worktrees — loses *nothing* (it's all merged), but it makes finished work read as **unmerged / lost**, triggers a false "it's only backed up, not applied" scramble, and burns large reconciliation time and trust. Prose alone gets forgotten, so this recipe is backed by a Claude Stop hook (below).
19
+
20
+ ## The 7 obligations
21
+
22
+ ### G1 — No worktrees unless explicitly requested
23
+ The default work model is **normal branches in the single working tree**. Reach for `git worktree` only when the user explicitly asks, or a documented isolation need exists. If you create one, **remove it in the same session** (`git worktree remove`) and delete its branch. An orphan worktree's uncommitted/unpushed work reads as a phantom "lost / unmerged feature" to the next actor.
24
+
25
+ ### G2 — Push, never hoard
26
+ The moment a commit is worth keeping, push it to a **named branch on origin**. Do not accumulate local-only commits. Invariant: at session end `git log --branches --not --remotes` is **empty**. Local-only piles are the direct cause of "unpushed/lost feature" panics and the cost of later diffing what is *actually* missing.
27
+
28
+ ### G3 — Merge means delete
29
+ When a PR merges, immediately delete that branch **both local and remote** (`git branch -d/-D` + `git push origin --delete`). Stale pointers — especially a pre-squash local pointer left after a squash-merge — masquerade as an "unmerged feature" and are the #1 source of the illusion.
30
+
31
+ ### G4 — Backup ≠ applied
32
+ Pushing to an isolated/backup branch is **not** integration. "It's backed up" and "the feature is on the target branch / live" are separate claims. Verify a feature is on your integration/target branch by reading the **actual code** there (file / symbol / value grep), never by the existence of a backup branch. This is `quality-gates.md` Q4 (verify-after-changes) applied to git: a backup is a safety net, never a completion verdict.
33
+
34
+ ### G5 — No reckless branch ops on a shared repo
35
+ No force-push / rebase / reset / branch-move / protected-branch rewrite that a concurrent session or another actor might be building on. Minimize branch churn; when a branch operation's scope or reversibility is unclear, ASK (`meta-discipline.md` AMB-3/AMB-4 — non-trivially-reversible ops and protected-branch writes force ASK). **Another session's uncommitted/unpushed work is inviolable** — back it up and surface it, but never merge/delete/rewrite it on your own judgment.
36
+
37
+ ### G6 — Bundle PRs (CI economy)
38
+ Bundle related work into as few PRs as reasonable — CI runs per PR and free-tier minutes are finite. Do not fragment one change into many PRs that each re-consume CI, and do not push docs-only commits mid-review that re-trigger the whole pipeline. Verify locally before the single push so the one CI run passes first try.
39
+
40
+ ### G7 — Session-end hygiene check
41
+ Before finishing a session: **0 orphan worktrees · 0 local-only commits (all on origin) · merged branches deleted · current branch + working-tree state clear.**
42
+
43
+ - [ ] `git worktree list` → only the main tree (unless a requested worktree is still mid-use)?
44
+ - [ ] `git log --branches --not --remotes --oneline` → empty?
45
+ - [ ] Merged PR branches deleted (local + remote)?
46
+ - [ ] Not sitting on a stale/behind branch that hides completed work?
47
+
48
+ ## Conductor Integration
49
+
50
+ - **Claude** — a Stop hook `stop-git-hygiene-guard` (from `core/hooks/`) fires a **non-blocking reminder** when it detects the collapse states: extra worktrees, local-only commits, or an abnormally high local-branch count. It always exits 0 (observation only, never blocks a session), self-gates on this recipe being installed, cools down between reminders, and honors `CONDUCTOR_SKIP_GIT_HYGIENE=1` (silence) and `CONDUCTOR_GIT_HYGIENE_BRANCH_MAX` (branch-count threshold, default 20).
51
+ - **Cursor / Copilot / Gemini / Codex / Windsurf** — the hook is Claude-only (per `docs/DESIGN-DECISIONS.md` ADR-034; Windsurf also lacks Stop-style events). On these tools this recipe's rule text is the enforcement: run the G7 checklist manually at session end.
52
+ - **Target branch** — G2/G3/G4 reference your *integration/target branch* (commonly `main`, or `develop` if you also install the `branch-strategy` recipe). Substitute your project's value.
53
+
54
+ ## Cross-References
55
+
56
+ - `quality-gates.md` §4 (verify-after-changes) — G4's "verify by real code, not by a backup branch."
57
+ - `meta-discipline.md` §3 (AMB-3/AMB-4) — G5's ASK-before-reckless-branch-op gate.
58
+ - `meta-discipline.md` §5.7 (lossless-before-lossy compaction) — the *uncommitted-durability* layer beneath G2's *unpushed-hygiene* layer; complementary.
59
+ - `branch-strategy.md` recipe — defines the target/integration branch model G2–G4 build on.
60
+ - `core/anti-patterns/frequent-rule-file-edit.md` — G6's "don't re-trigger CI with churn" echoes the cost-of-churn principle.
@@ -0,0 +1,73 @@
1
+ ---
2
+ recipe_id: loop-engineering
3
+ recipe_name: "Loop Engineering (bounded, externally-verified agent loops)"
4
+ applies_when: "any agentic coding work that iterates — generate→verify→fix→re-verify, test-fix loops, multi-step tasks"
5
+ severity: STRONG (when installed)
6
+ linked_rules:
7
+ - quality-gates
8
+ - meta-discipline
9
+ - workflow
10
+ ---
11
+
12
+ # Recipe — Loop Engineering
13
+
14
+ > Opt-in recipe. Install for any project where the agent works in a **loop** — "do → check → fix → re-check until done." It codifies how to run that loop so it **terminates correctly, stays bounded, and never declares success without an external check.** Install if you want agent loops that are reliable instead of ones that thrash, run away, or report "done" on unverified work.
15
+
16
+ ## Why this exists
17
+
18
+ An agent that loops "until it's right" fails in a few well-documented ways. The evidence (peer-reviewed + Anthropic primary sources) is blunt:
19
+
20
+ - **Self-correction without an external signal is unreliable and can make things WORSE.** Models asked to fix their own work with no external feedback often flip correct answers to wrong ones (*LLMs Cannot Self-Correct Reasoning Yet*, Huang et al., DeepMind, ICLR'24). The real gains come from loops grounded in **tests/tools** (Reflexion, CRITIC), not self-judgment.
21
+ - **"The model says it's done" is not evidence.** LLM self-assessment is systematically over-confident, and LLM-as-judge carries position/verbosity/self-preference bias (*Judging LLM-as-a-Judge*, Zheng et al., NeurIPS'23). Declaring victory without running the check ("early victory") is the most common fidelity failure.
22
+ - **Unbounded loops run away.** Infinite / oscillation (edit↔revert) loops are a documented structural failure — in one study **95.6% ended in cost exhaustion / model-DoS** (*When Agents Do Not Stop*, 2026). More iterations help only up to a point, then *saturate and hurt*; long trajectories degrade (context rot, error compounding).
23
+
24
+ So a good loop is **bounded, progress-checked, and terminated by an external verifier** — not by the model's opinion. Prose gets forgotten, so on the Claude adapter this recipe is backed by a `pretool-loop-guard` hook.
25
+
26
+ ## The loop shape (well-supported)
27
+
28
+ ```
29
+ Plan → (act → verify) loop → replan on failure → escalate on repeated stall
30
+ ```
31
+
32
+ - **Plan first**, then act (ReAct: interleave reason+act+observe beats act-only).
33
+ - On a failed check, **reflect and replan** using the failure (Reflexion) — not a blind retry.
34
+ - Reserve expensive search/branching (Tree-of-Thoughts) for genuinely exploratory tasks; the default loop stays simple (Anthropic: "the simplest solution possible; add complexity only when it demonstrably improves outcomes").
35
+
36
+ ## The 6 obligations
37
+
38
+ ### G1 — Terminate on an explicit, verified done-criterion
39
+ Before looping, state what "done" IS (a passing test, a matching value, a satisfied spec item). The loop ends when that criterion is **verified true** — never on a vibe or a word-count of effort.
40
+
41
+ ### G2 — Bound the loop (iteration + token budget)
42
+ Set a ceiling before you start: a max number of iterations AND a token/time budget. When the ceiling is hit, **stop and report** (with what's done and what's left) — do not silently keep going. Anthropic ships this as `max_turns` / `max_budget_usd` ("a good default for production agents").
43
+
44
+ ### G3 — Require progress each iteration
45
+ Every pass must change state toward the goal. If an iteration produces no new information or the same result, that is a **no-progress signal** — stop and rethink rather than repeat. (More iterations past the point of progress saturate, then degrade quality.)
46
+
47
+ ### G4 — Escalate on stall, don't loop forever
48
+ After a small number of failed/no-progress iterations (default ~3–5), **hand back to the human** with the state and the blocker, instead of looping. Ties to `meta-discipline.md` AMB — when stuck or the next step is non-trivially reversible, ASK.
49
+
50
+ ### G5 — Verify externally, never by self-judgment (the core rule)
51
+ A loop's exit signal MUST be an **external / ground-truth check** — run the test, execute the code, lint against the rule, diff the value — **not** the model asserting "looks correct." Verify hierarchy (Anthropic, strongest first):
52
+
53
+ 1. **Rules / tests / tool output** — deterministic, best (e.g. run the test suite; lint TS instead of eyeballing).
54
+ 2. **Visual / rendered feedback** — screenshots, output diffs.
55
+ 3. **LLM-as-judge** — weakest, last resort, and never the sole gate.
56
+
57
+ This is `quality-gates.md` Q4 (verify-after-changes) applied inside the loop. "Declared done without running the check" = the early-victory anti-pattern; it is a rule violation here.
58
+
59
+ ### G6 — Guard against oscillation / infinite loops
60
+ Detect and break repetition: the same action repeated, or an edit↔revert cycle, means the loop is spinning. Track what you've already tried; if you're repeating, **change approach or escalate (G4)** — never keep re-issuing the same failing action.
61
+
62
+ ## Conductor Integration
63
+
64
+ - **Claude** — a PreToolUse hook `pretool-loop-guard` (from `core/hooks/`) tracks a per-session signature of each tool call and fires a **non-blocking soft-warn** (`permissionDecision: ask`) when the **same action repeats too often** (G3/G6 — likely looping without progress) or the **session's total tool calls exceed a budget** (G2 — runaway). It self-gates on this recipe being installed, is fail-open (never blocks a tool call on error), and honors `CONDUCTOR_SKIP_LOOP_GUARD=1`, `CONDUCTOR_LOOP_REPEAT_MAX` (default 5), `CONDUCTOR_LOOP_BUDGET` (default 120), `CONDUCTOR_LOOP_COOLDOWN_SECONDS` (default 120).
65
+ - **Cursor / Copilot / Gemini / Codex / Windsurf** — the hook is Claude-only (per `docs/DESIGN-DECISIONS.md` ADR-034/ADR-038). On these tools this recipe's rule text is the enforcement: follow G1–G6 by discipline (the loop shape + external-verify rule are tool-agnostic).
66
+
67
+ ## Cross-References
68
+
69
+ - `quality-gates.md` §4 (verify-after-changes) — G5's external-verify rule is Q4 applied inside the loop.
70
+ - `meta-discipline.md` §3 (AMB) — G4's escalate-on-stall / ASK-when-stuck gate.
71
+ - `meta-discipline.md` §5.9 (output brevity) + §5.7 — G2's token budget shares the token-economy ceiling.
72
+ - `tdd.md` / `debugging.md` recipes — concrete instances of a G1–G6 loop (Red-Green; reproduce→root-cause→fix→regression).
73
+ - `self-improvement.md` recipe — the session-level Reflector loop is itself a G1–G6 instance (propose → human-verify → apply).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniconductor",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "Multi-coding-agent workflow framework. Write your project's rules, workflow, and discipline ONCE — install into Claude Code, Cursor, GitHub Copilot, Gemini CLI, Codex, or Windsurf. Encodes the discipline developers most often skip — spec-before-code, review gates, session continuity — so your AI agents catch what's easy to miss.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "LFamily Labs LLC",