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.
- package/CHANGELOG.md +64 -0
- package/LICENSE +219 -0
- package/NOTICE +11 -0
- package/README.md +526 -0
- package/THIRD_PARTY_NOTICES.md +31 -0
- package/TRADEMARKS.md +26 -0
- package/VISION.md +106 -0
- package/adapters/README.md +121 -0
- package/adapters/claude/README.md +102 -0
- package/adapters/claude/SUPPORTED-FEATURES.md +66 -0
- package/adapters/claude/hookify-templates/.recipe-scoped +9 -0
- package/adapters/claude/hookify-templates/README.md +93 -0
- package/adapters/claude/hookify-templates/block-completion-claim-without-push.local.md.template +56 -0
- package/adapters/claude/hookify-templates/block-direct-push-protected-branch.local.md.template +18 -0
- package/adapters/claude/hookify-templates/block-force-push-protected-branch.local.md.template +42 -0
- package/adapters/claude/hookify-templates/block-server-secret-in-client.local.md.template +36 -0
- package/adapters/claude/hookify-templates/warn-any-type-added.local.md.template +44 -0
- package/adapters/claude/hookify-templates/warn-commit-without-pre-commit-review.local.md.template +52 -0
- package/adapters/claude/hookify-templates/warn-console-direct.local.md.template +55 -0
- package/adapters/claude/hookify-templates/warn-create-table-without-access-control.local.md.template +35 -0
- package/adapters/claude/hookify-templates/warn-current-work-without-remaining-tasks.local.md.template +36 -0
- package/adapters/claude/hookify-templates/warn-gh-pr-create-without-pre-merge-review.local.md.template +38 -0
- package/adapters/claude/hookify-templates/warn-hardcoded-text-without-i18n-key.local.md.template +21 -0
- package/adapters/claude/hookify-templates/warn-on-gh-pr-merge.local.md.template +33 -0
- package/adapters/claude/hookify-templates/warn-plan-spec-without-remaining-tasks.local.md.template +44 -0
- package/adapters/claude/hookify-templates/warn-raw-hex-instead-of-token.local.md.template +21 -0
- package/adapters/claude/hookify-templates/warn-security-definer-without-search-path.local.md.template +30 -0
- package/adapters/claude/hookify-templates/warn-stop-commit-without-current-work.local.md.template +47 -0
- package/adapters/claude/hookify-templates/warn-user-manual-completion.local.md.template +40 -0
- package/adapters/claude/transform-spec.md +140 -0
- package/adapters/claude/transform.sh +1169 -0
- package/adapters/codex/README.md +87 -0
- package/adapters/codex/SUPPORTED-FEATURES.md +66 -0
- package/adapters/codex/transform-spec.md +90 -0
- package/adapters/codex/transform.sh +748 -0
- package/adapters/copilot/README.md +88 -0
- package/adapters/copilot/SUPPORTED-FEATURES.md +73 -0
- package/adapters/copilot/transform-spec.md +111 -0
- package/adapters/copilot/transform.sh +757 -0
- package/adapters/cursor/README.md +87 -0
- package/adapters/cursor/SUPPORTED-FEATURES.md +90 -0
- package/adapters/cursor/transform-spec.md +124 -0
- package/adapters/cursor/transform.sh +731 -0
- package/adapters/gemini/README.md +93 -0
- package/adapters/gemini/SUPPORTED-FEATURES.md +80 -0
- package/adapters/gemini/transform-spec.md +102 -0
- package/adapters/gemini/transform.sh +844 -0
- package/adapters/windsurf/README.md +93 -0
- package/adapters/windsurf/SUPPORTED-FEATURES.md +67 -0
- package/adapters/windsurf/transform-spec.md +99 -0
- package/adapters/windsurf/transform.sh +727 -0
- package/bin/omniconductor.js +130 -0
- package/core/README.md +64 -0
- package/core/anti-patterns/README.md +142 -0
- package/core/anti-patterns/dynamic-system-prompt.md +113 -0
- package/core/anti-patterns/frequent-rule-file-edit.md +83 -0
- package/core/anti-patterns/large-file-read-no-range.md +90 -0
- package/core/anti-patterns/no-sub-agent-dispatch.md +89 -0
- package/core/anti-patterns/single-monolithic-rule-file.md +99 -0
- package/core/anti-patterns/skill-eager-load.md +83 -0
- package/core/anti-patterns/tool-call-spam.md +93 -0
- package/core/docs-templates/CURRENT_WORK.md +64 -0
- package/core/docs-templates/INDEX.md +57 -0
- package/core/docs-templates/PLANS.md +44 -0
- package/core/docs-templates/README.md +40 -0
- package/core/docs-templates/REMAINING_TASKS.md +43 -0
- package/core/docs-templates/TASKS.md +51 -0
- package/core/docs-templates/specs/_example.md +121 -0
- package/core/hooks/README.md +62 -0
- package/core/hooks/pretool-agent-routing.sh.template +97 -0
- package/core/hooks/pretool-commit-current-work-check.sh.template +103 -0
- package/core/hooks/pretool-commit-test-coverage-check.sh.template +116 -0
- package/core/hooks/pretool-large-file-read-guard.sh.template +117 -0
- package/core/hooks/stop-cache-hit-baseline-check.sh.template +133 -0
- package/core/hooks/stop-r6-review-check.sh.template +80 -0
- package/core/hooks/stop-session-log-check.sh.template +101 -0
- package/core/hooks/stop-trajectory-log.sh.template +96 -0
- package/core/memory-pattern/EXAMPLES.md +114 -0
- package/core/memory-pattern/README.md +133 -0
- package/core/recipes/README.md +46 -0
- package/core/recipes/auto-mock-data.md +82 -0
- package/core/recipes/branch-strategy.md +100 -0
- package/core/recipes/coding-conventions.md +123 -0
- package/core/recipes/database-discipline.md +65 -0
- package/core/recipes/debugging.md +143 -0
- package/core/recipes/design-system.md +30 -0
- package/core/recipes/i18n.md +118 -0
- package/core/recipes/monorepo.md +101 -0
- package/core/recipes/self-improvement.md +61 -0
- package/core/recipes/tdd.md +128 -0
- package/core/recipes/web-mobile-parity.md +87 -0
- package/core/reflector/SCHEDULING.md +83 -0
- package/core/reflector/prune-lessons.sh +105 -0
- package/core/reflector/reflect-brief.md +11 -0
- package/core/reflector/reflect.command.md +13 -0
- package/core/reflector/run-weekly.sh +54 -0
- package/core/reflector/trajectory-log.sh +55 -0
- package/core/roles/README.md +61 -0
- package/core/roles/builder.md +75 -0
- package/core/roles/designer.md +93 -0
- package/core/roles/helper.md +70 -0
- package/core/roles/planner.md +123 -0
- package/core/roles/reflector.md +72 -0
- package/core/roles/reviewer.md +104 -0
- package/core/roles/scribe.md +89 -0
- package/core/universal-rules/README.md +71 -0
- package/core/universal-rules/meta-discipline.md +292 -0
- package/core/universal-rules/operations.md +162 -0
- package/core/universal-rules/quality-gates.md +191 -0
- package/core/universal-rules/spec-as-you-go.md +123 -0
- package/core/universal-rules/workflow.md +153 -0
- package/core/workflow/PHASES.md +134 -0
- package/core/workflow/README.md +56 -0
- package/docs/MANUAL-INSTALL.md +456 -0
- package/package.json +52 -0
- package/tools/check-framework-purity.sh +91 -0
- package/tools/measure-tokens.sh +169 -0
- package/tools/validate-adapter-output.sh +611 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe_id: i18n
|
|
3
|
+
recipe_name: "Multi-locale translation key sync"
|
|
4
|
+
applies_when: "project supports 2+ locales for user-facing text"
|
|
5
|
+
severity: ABSOLUTE (when installed)
|
|
6
|
+
linked_rules:
|
|
7
|
+
- quality-gates
|
|
8
|
+
- spec-as-you-go
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Recipe — i18n Multi-Locale Sync
|
|
12
|
+
|
|
13
|
+
> Opt-in recipe. Install when the project supports 2+ locales. The originating project supports 8 locales (en, ko, ja, zh, es, fr, de, pt); the rule generalizes to N.
|
|
14
|
+
|
|
15
|
+
## 1. The N-locale rule
|
|
16
|
+
|
|
17
|
+
When new user-facing text is added to ANY surface, translation keys for ALL supported locales MUST be added in the same PR. Partial coverage (e.g., en + ko added, others left empty) is treated as INCOMPLETE.
|
|
18
|
+
|
|
19
|
+
### 1.1 Why all-locales-or-none
|
|
20
|
+
|
|
21
|
+
Partial coverage produces UI fallback chaos: some locales render the new text, others render the key string or fall back to en, the user thinks the feature is broken in their language. The rule eliminates the partial state entirely.
|
|
22
|
+
|
|
23
|
+
### 1.2 Locale list (project-specific)
|
|
24
|
+
|
|
25
|
+
The project's rule index lists the supported locales explicitly. The originating project's list:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
en, ko, ja, zh, es, fr, de, pt
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The recipe is the rule; the locale list is the parameter.
|
|
32
|
+
|
|
33
|
+
## 2. Source-of-truth + per-app copies
|
|
34
|
+
|
|
35
|
+
The originating project's organization (used as a reference pattern):
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
packages/shared/src/i18n/translations.ts ← source of truth
|
|
39
|
+
<web-app>/lib/i18n/translations.ts ← web local copy (always synced)
|
|
40
|
+
<mobile-app>/... ← mobile imports from shared package directly
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2.1 Why a web local copy
|
|
44
|
+
|
|
45
|
+
Web build does not always resolve shared package imports at runtime in the same way as mobile. The local copy is the runtime artifact for web. The build process MAY automate the copy, but the copy still needs to land in source control and be auditable.
|
|
46
|
+
|
|
47
|
+
### 2.2 Sync verification
|
|
48
|
+
|
|
49
|
+
A pre-build script verifies the two files are byte-identical (or otherwise structurally consistent). Production project example: `scripts/check-i18n-sync.mjs` runs sha256 byte-diff on the source-of-truth and the local copy, blocking the build if they diverge.
|
|
50
|
+
|
|
51
|
+
### 2.3 Why pre-build (not pre-commit)
|
|
52
|
+
|
|
53
|
+
Pre-commit catches local divergence but not divergence introduced by an external PR or merge conflict resolution. Pre-build catches both. The cost is one fast file read on every build.
|
|
54
|
+
|
|
55
|
+
## 3. The "empty key" anti-pattern
|
|
56
|
+
|
|
57
|
+
Adding `helpFaq.q1: ""` (empty string) for some locales is NOT acceptable. The user sees a blank UI. Either:
|
|
58
|
+
|
|
59
|
+
- Provide a real translation (preferred — use AI translation as draft, human-review later if needed).
|
|
60
|
+
- Fall back to en explicitly via the i18n library's fallback chain (so the user sees English text, not blank).
|
|
61
|
+
- Don't ship the key until all locales have content.
|
|
62
|
+
|
|
63
|
+
## 4. Component contract
|
|
64
|
+
|
|
65
|
+
Every user-facing string MUST go through the i18n hook (e.g., `useTranslation()`). Hardcoded strings are forbidden by `coding-conventions.md` (recipe). The pattern:
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
// WRONG
|
|
69
|
+
<Button>Save plan</Button>
|
|
70
|
+
|
|
71
|
+
// RIGHT
|
|
72
|
+
const { t } = useTranslation();
|
|
73
|
+
<Button>{t("plan.save")}</Button>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This applies to every visible string, including:
|
|
77
|
+
|
|
78
|
+
- Button labels.
|
|
79
|
+
- Page titles.
|
|
80
|
+
- Form placeholders.
|
|
81
|
+
- Error messages (the i18n key, NOT the raw error from a service).
|
|
82
|
+
- Toast messages.
|
|
83
|
+
- ARIA labels (translated, not hardcoded).
|
|
84
|
+
|
|
85
|
+
## 5. Adding a new translation key — checklist
|
|
86
|
+
|
|
87
|
+
For every new key:
|
|
88
|
+
|
|
89
|
+
- [ ] Added to source-of-truth file with all N locales populated.
|
|
90
|
+
- [ ] Local copies (per-app) synced.
|
|
91
|
+
- [ ] Sync-check script (if installed) passes.
|
|
92
|
+
- [ ] Component uses the key via `t()`.
|
|
93
|
+
- [ ] No hardcoded English string remains as a placeholder.
|
|
94
|
+
|
|
95
|
+
## 6. Adding a new locale
|
|
96
|
+
|
|
97
|
+
Adding a new locale (e.g., the project decides to support `it`):
|
|
98
|
+
|
|
99
|
+
- [ ] Add the locale code to the locale list in the rule index.
|
|
100
|
+
- [ ] Add `it` keys to every existing translation key in the source-of-truth.
|
|
101
|
+
- [ ] Update fallback chain configuration.
|
|
102
|
+
- [ ] Update language-picker UI (if user-selectable).
|
|
103
|
+
- [ ] Update any locale-specific assets (date format, number format, RTL handling if applicable).
|
|
104
|
+
|
|
105
|
+
## 7. Cross-tool enforcement
|
|
106
|
+
|
|
107
|
+
| Mechanism | Where |
|
|
108
|
+
|---|---|
|
|
109
|
+
| Pre-build sync check | `scripts/check-i18n-sync.mjs` (or equivalent) — blocks build on divergence |
|
|
110
|
+
| Pre-commit review | Reviewer checklist item: "all locales added?" |
|
|
111
|
+
| TypeScript | Strongly-typed key set (translation hook returns errors for unknown keys) |
|
|
112
|
+
| Rule text | This recipe text, loaded into the tool's rule context |
|
|
113
|
+
|
|
114
|
+
## 8. Production failure example
|
|
115
|
+
|
|
116
|
+
Documented failure: a PR added 96 keys to the source-of-truth for one locale, but the web local copy was missing those 96 keys. Pre-build sync check caught it before the PR merged. Without the sync check, the prod build would have failed at runtime in that locale only — likely undetected for hours.
|
|
117
|
+
|
|
118
|
+
The pre-build sync check is the single most cost-effective i18n investment a multi-locale project can make.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe_id: monorepo
|
|
3
|
+
recipe_name: "Monorepo structure with shared package"
|
|
4
|
+
applies_when: "project uses npm workspaces (or equivalent) with shared code between apps"
|
|
5
|
+
severity: STRONG (when installed)
|
|
6
|
+
linked_rules:
|
|
7
|
+
- workflow
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Recipe — Monorepo Structure
|
|
11
|
+
|
|
12
|
+
> Opt-in recipe. Install when the project uses npm workspaces (or pnpm / yarn workspaces / turborepo) with shared code between multiple deployable apps. Do NOT install on single-app projects.
|
|
13
|
+
|
|
14
|
+
## 1. The frozen folder structure rule
|
|
15
|
+
|
|
16
|
+
Once the monorepo's top-level structure is set (apps + packages + root config), DO NOT change it without explicit authorization.
|
|
17
|
+
|
|
18
|
+
### 1.1 Why "frozen"
|
|
19
|
+
|
|
20
|
+
Folder restructures invalidate every cached path: TypeScript paths, IDE workspaces, deploy pipelines, test selectors, documentation references. The cost of a restructure is high enough that "let's clean this up" is not a sufficient justification.
|
|
21
|
+
|
|
22
|
+
The originating project recorded this as an explicit user instruction: "do not change current monorepo folder structure". The rule generalizes.
|
|
23
|
+
|
|
24
|
+
## 2. Reference structure (originating project)
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
project-root/
|
|
28
|
+
├── apps/
|
|
29
|
+
│ ├── web/ ← Next.js app (or equivalent)
|
|
30
|
+
│ └── mobile/ ← React Native / Expo app (or equivalent)
|
|
31
|
+
├── packages/
|
|
32
|
+
│ └── shared/ ← Shared business logic, types, constants, i18n source-of-truth
|
|
33
|
+
├── docs/ ← All project documentation
|
|
34
|
+
├── .claude/ (or .cursor/ / .github/instructions/ / .windsurf/)
|
|
35
|
+
├── package.json ← root with `workspaces` config
|
|
36
|
+
└── ...
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This is the reference, not the mandate. Adopters with different conventions (e.g., turborepo with `packages/web`, `packages/mobile`) follow the same principle: freeze the top-level layout once decided.
|
|
40
|
+
|
|
41
|
+
## 3. Shared package contract
|
|
42
|
+
|
|
43
|
+
Code that goes in `packages/shared`:
|
|
44
|
+
|
|
45
|
+
- Business logic that runs identically on both surfaces.
|
|
46
|
+
- Type definitions consumed by both surfaces.
|
|
47
|
+
- Constants (rate limits, feature names, error codes).
|
|
48
|
+
- i18n source-of-truth (per `recipes/i18n.md`).
|
|
49
|
+
|
|
50
|
+
Code that does NOT go in `packages/shared`:
|
|
51
|
+
|
|
52
|
+
- Surface-specific UI components (web: `<web-app>/components/`; mobile: `<mobile-app>/src/components/`).
|
|
53
|
+
- Surface-specific hooks that depend on platform APIs.
|
|
54
|
+
- Build / deploy configuration.
|
|
55
|
+
|
|
56
|
+
## 4. Import direction
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
<web-app>/ → imports from packages/shared (one-way)
|
|
60
|
+
<mobile-app>/ → imports from packages/shared (one-way)
|
|
61
|
+
packages/shared/ → imports nothing from apps/ (HARD RULE)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Reverse imports (shared importing from apps/) create build-order cycles and defeat the purpose of the shared package.
|
|
65
|
+
|
|
66
|
+
### 4.1 Web's "imports from shared" caveat
|
|
67
|
+
|
|
68
|
+
On some build setups, the web app does NOT import from `packages/shared` directly at runtime — instead it consumes a local copy (this is the i18n recipe's pattern). Whether direct import or local copy is the right pattern depends on the deploy target's module resolution semantics. The recipe documents the convention; the project's own tooling makes it work.
|
|
69
|
+
|
|
70
|
+
## 5. Code duplication between apps
|
|
71
|
+
|
|
72
|
+
Duplicated business logic between the web and mobile surfaces is FORBIDDEN. If two surfaces have the same logic, it belongs in `packages/shared`.
|
|
73
|
+
|
|
74
|
+
The reviewer role's checklist (`roles/reviewer.md`) includes a "no duplicated business logic" check. The check is performed by reading the diffs for both surfaces and looking for parallel logic.
|
|
75
|
+
|
|
76
|
+
## 6. Test organization
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
<web-app>/e2e/
|
|
80
|
+
├── functional/ ← E2E functional specs
|
|
81
|
+
├── visual/ ← Visual smoke specs
|
|
82
|
+
└── pages.ts ← Page catalog for visual smoke
|
|
83
|
+
|
|
84
|
+
<mobile-app>/__tests__/ ← Mobile-specific
|
|
85
|
+
packages/shared/__tests__/ ← Unit tests for shared logic
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Test execution is per-app (each `package.json` has its own test script). Root `package.json` has aggregate scripts that run all apps.
|
|
89
|
+
|
|
90
|
+
## 7. Deploy pipeline implications
|
|
91
|
+
|
|
92
|
+
Each app deploys independently. Changes to `packages/shared` trigger redeploys of every app that imports it. CI configuration MUST handle this — typically by running every app's build when shared changes.
|
|
93
|
+
|
|
94
|
+
## 8. Cross-tool enforcement
|
|
95
|
+
|
|
96
|
+
| Mechanism | Where |
|
|
97
|
+
|---|---|
|
|
98
|
+
| Folder structure freeze | Rule text + reviewer checklist |
|
|
99
|
+
| Import direction | TypeScript compiler (with `paths` config) + lint rule (e.g., `import/no-internal-modules`) |
|
|
100
|
+
| Duplication check | Reviewer role manual check |
|
|
101
|
+
| Build coupling | CI configuration (per-app build matrix) |
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe_id: self-improvement
|
|
3
|
+
recipe_name: "Self-Improvement (Reflector, propose-only)"
|
|
4
|
+
applies_when: "a project wants periodic, human-approved distillation of session lessons into its memory/rules"
|
|
5
|
+
severity: STRONG (when installed)
|
|
6
|
+
linked_rules:
|
|
7
|
+
- meta-discipline
|
|
8
|
+
- operations
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Recipe — Self-Improvement (Reflector)
|
|
12
|
+
|
|
13
|
+
> Opt-in recipe. Install when you want CONDUCTOR to periodically read your recent sessions and PROPOSE lessons for your memory/rules. It never applies anything automatically. Do NOT install if you do not want a retrospective step — there is no silent learning here by design.
|
|
14
|
+
|
|
15
|
+
## The loop
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Observe → Reflect → Propose → (human GO) → Apply
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
- **Observe** — a stop-hook logs a trajectory pointer each session (Claude adapter); git history and `docs/CURRENT_WORK.md` are always-available fallbacks.
|
|
22
|
+
- **Reflect** — the `reflector` role reads the period's trajectories (success AND failure) and distils atomic lessons.
|
|
23
|
+
- **Propose** — the reflector appends `ADD/UPDATE/STALE` deltas to `docs/REFLECTION-PROPOSALS.md`. This is the ONLY output. Nothing is written to memory or rules.
|
|
24
|
+
- **Apply** — a human reviews the proposals like a diff and accepts/edits/rejects. On acceptance, the lesson becomes a `feedback_lesson-*.md` memory entry (see `core/memory-pattern/README.md`).
|
|
25
|
+
|
|
26
|
+
## Safety contract (read first)
|
|
27
|
+
|
|
28
|
+
- **Propose-only.** The reflector must never edit rules, memory, or code. Applying is a human decision.
|
|
29
|
+
- **Grounded-or-dropped.** Every proposed lesson cites a trajectory; un-cited lessons are discarded.
|
|
30
|
+
- **Delta, never rewrite.** Lessons are atomic items merged/pruned by a deterministic script, never by rewriting a whole file. This prevents "context collapse" (accumulated detail eroded by repeated full rewrites).
|
|
31
|
+
|
|
32
|
+
## Cadence
|
|
33
|
+
|
|
34
|
+
Run weekly (batch), or on demand via `/reflect`. To automate the weekly run, register the emitted `.conductor/reflect/run-weekly.sh` with a scheduler — see `.conductor/reflect/SCHEDULING.md` for per-tool instructions (OS cron/launchd is the universal local path). Reflection must not exceed the rule-file-edit budget in `core/anti-patterns/frequent-rule-file-edit.md` (more than 3 rule-file commits/week is itself a smell) — batch proposals, do not drip per-session edits.
|
|
35
|
+
|
|
36
|
+
## Trajectory sources (precedence)
|
|
37
|
+
|
|
38
|
+
1. Session transcript (richest) — via `.conductor/trajectories/index.jsonl`.
|
|
39
|
+
2. git history — universal.
|
|
40
|
+
3. Retro artifact — `docs/CURRENT_WORK.md`, `docs/sessions/*`.
|
|
41
|
+
|
|
42
|
+
## Per-tool automation
|
|
43
|
+
|
|
44
|
+
- **Claude**: the `stop-trajectory-log` hook records pointers; a scheduled run (Routines / Desktop Scheduled Task / cron → `claude -p`) invokes the reflector weekly; `.conductor/reflect/prune-lessons.sh` keeps the store bounded; `/reflect` runs it on demand.
|
|
45
|
+
- **Other tools**: the WHAT above is identical. Each adapter emits the trajectory hook, the native `/reflect` command, the reflector agent/rule, `.conductor/reflect/prune-lessons.sh`, and `.conductor/reflect/run-weekly.sh` + `reflect-brief.md` + `SCHEDULING.md`. Register `run-weekly.sh` with OS cron/launchd (or a native local scheduler where available) per `SCHEDULING.md`; the universal floor is running `/reflect` manually.
|
|
46
|
+
|
|
47
|
+
## Bounded store (deterministic prune)
|
|
48
|
+
|
|
49
|
+
`.conductor/reflect/prune-lessons.sh` (non-LLM) decays lessons unused for K weeks to `status: stale`, and marks-stale lessons whose provenance path no longer exists. It never deletes a lesson — only exact byte-duplicate files are removed (no information is lost). It is idempotent. This is the anti-collapse guarantee. (Non-destructive marking matches the propose-only philosophy: an unattended script must not destroy user memory.)
|
|
50
|
+
|
|
51
|
+
## Conductor Integration
|
|
52
|
+
|
|
53
|
+
**meta-discipline (M1 originality / M2 token economy)**: the reflector reads with ranges and map-then-reduce; proposals are original, grounded distillations, not copied text.
|
|
54
|
+
|
|
55
|
+
**operations (O1 real-time docs sync)**: accepted lessons and the proposals file are part of the project's documentation state.
|
|
56
|
+
|
|
57
|
+
## Cross-References
|
|
58
|
+
|
|
59
|
+
- `core/roles/reflector.md` — the actor this recipe drives.
|
|
60
|
+
- `core/memory-pattern/README.md` — the `feedback_lesson-*` file format proposals target.
|
|
61
|
+
- `core/anti-patterns/frequent-rule-file-edit.md` — the edit-budget guardrail.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe_id: tdd
|
|
3
|
+
recipe_name: "Test-Driven Development (Red-Green-Refactor)"
|
|
4
|
+
applies_when: "project has a test framework (vitest / jest / pytest / etc.) and wants TDD methodology enforced across feature work, bug fixes, and refactors"
|
|
5
|
+
severity: STRONG (when installed)
|
|
6
|
+
linked_rules:
|
|
7
|
+
- spec-as-you-go
|
|
8
|
+
- quality-gates
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Recipe — Test-Driven Development
|
|
12
|
+
|
|
13
|
+
> Opt-in recipe. Install on projects with an established test framework where TDD discipline is a team standard. Do NOT install on throwaway prototypes or projects with no testing infrastructure — adopt the test framework first.
|
|
14
|
+
|
|
15
|
+
## When to Apply
|
|
16
|
+
|
|
17
|
+
Every development activity that changes behavior:
|
|
18
|
+
|
|
19
|
+
- **New feature** — write the test before writing production code
|
|
20
|
+
- **Bug fix** — write a failing test that reproduces the bug; then fix it
|
|
21
|
+
- **Refactor** — green test suite is the safety net; refactor to keep it green
|
|
22
|
+
- **Behavior change** — update the test first to reflect the new expected behavior
|
|
23
|
+
|
|
24
|
+
Exceptions (discuss with your human partner before skipping):
|
|
25
|
+
|
|
26
|
+
- Throwaway exploration / spike — throw away the spike code; start fresh with TDD
|
|
27
|
+
- Generated / scaffolded code — add behavior tests before modifying generated output
|
|
28
|
+
- Configuration files with no testable behavior
|
|
29
|
+
|
|
30
|
+
## Pattern — Red-Green-Refactor
|
|
31
|
+
|
|
32
|
+
The TDD cycle has three phases. Each phase has an explicit STOP-AND-VERIFY step that cannot be skipped.
|
|
33
|
+
|
|
34
|
+
### RED — Write One Failing Test
|
|
35
|
+
|
|
36
|
+
Write the smallest test that describes a single desired behavior. Run the suite and confirm the test fails for the right reason (missing feature, not a syntax error).
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# vitest
|
|
40
|
+
npx vitest run path/to/file.test.ts
|
|
41
|
+
|
|
42
|
+
# jest
|
|
43
|
+
npx jest path/to/file.test.ts
|
|
44
|
+
|
|
45
|
+
# pytest
|
|
46
|
+
pytest tests/test_feature.py::test_specific_case -v
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
A test that passes immediately proves nothing — it was either testing existing behavior or testing the wrong thing. If it passes on first run, fix the test.
|
|
50
|
+
|
|
51
|
+
### GREEN — Minimal Implementation
|
|
52
|
+
|
|
53
|
+
Write the simplest code that makes the failing test pass. "Simplest" means: no speculative features, no generalization the test does not require, no YAGNI extensions. If the test passes with three lines, ship three lines.
|
|
54
|
+
|
|
55
|
+
Do not refactor during Green. Refactoring while Red is still on the board is how the cycle breaks.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Watch mode for rapid Red → Green iteration
|
|
59
|
+
npx vitest --watch path/to/file.test.ts
|
|
60
|
+
pytest-watch tests/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
After the test passes, run the full suite to confirm no regression.
|
|
64
|
+
|
|
65
|
+
### REFACTOR — Clean Up, Stay Green
|
|
66
|
+
|
|
67
|
+
With Green confirmed, remove duplication, improve names, extract helpers. Every refactor step must keep the suite green. Refactoring does not mean adding new behavior — that starts a new Red phase.
|
|
68
|
+
|
|
69
|
+
Commit discipline: keep Red, Green, and Refactor as separate commits when the history is audited. This is an option, not a hard requirement — but it makes rollback and review significantly cleaner.
|
|
70
|
+
|
|
71
|
+
## Canonical Cycle for a Bug Fix
|
|
72
|
+
|
|
73
|
+
1. Reproduce the bug with a deterministic, minimal failing test
|
|
74
|
+
2. Confirm the test fails with the exact error message the bug produces
|
|
75
|
+
3. Write the minimal fix
|
|
76
|
+
4. Confirm the test passes; run the full suite
|
|
77
|
+
5. Refactor the fix if the implementation is rough
|
|
78
|
+
|
|
79
|
+
Never fix a bug without a test. A fix without a test is a guess that happened to work today.
|
|
80
|
+
|
|
81
|
+
## Sub-Agent Dispatch Ordering
|
|
82
|
+
|
|
83
|
+
When delegating implementation via sub-agents, the brief MUST specify this sequence:
|
|
84
|
+
|
|
85
|
+
1. Write the failing test(s) first
|
|
86
|
+
2. Implement until the tests pass
|
|
87
|
+
3. Run the full suite and confirm green
|
|
88
|
+
4. Report test output as proof of completion
|
|
89
|
+
|
|
90
|
+
A sub-agent that returns "implemented X" without test output has not completed the task.
|
|
91
|
+
|
|
92
|
+
## Conductor Integration
|
|
93
|
+
|
|
94
|
+
**spec-as-you-go (W3)**: Tests are executable specs. When a feature's behavior changes, the test changes first. The spec doc and the test should describe the same invariants.
|
|
95
|
+
|
|
96
|
+
**quality-gates (Q1 pre-commit)**: Test passage is a pre-commit gate. The gate is not "tests exist" — it is "tests run green." Both conditions are required.
|
|
97
|
+
|
|
98
|
+
**workflow.md W2 (build phase)**: Every W2 implementation task applies this recipe's Red-Green-Refactor cycle. The plan should include an explicit "write failing tests first" step in the W2 brief.
|
|
99
|
+
|
|
100
|
+
## Anti-Patterns
|
|
101
|
+
|
|
102
|
+
| Anti-pattern | Why it breaks TDD |
|
|
103
|
+
|---|---|
|
|
104
|
+
| Write implementation first, tests after | Tests-after answer "what does this do?" Tests-first answer "what should this do?" Tests-after are biased by the implementation you just wrote. |
|
|
105
|
+
| Write 10+ failing tests in one Red phase | Massive Red phases extend the feedback loop and make root cause diagnosis harder when Green fails. Write one test at a time. |
|
|
106
|
+
| Mock-heavy tests that never touch real code | Tests that exercise only mock return values give false confidence. Use real code paths; mock only unavoidable I/O boundaries (network, filesystem, clock). |
|
|
107
|
+
| "Too simple to test" rationalization | Simple code breaks in context. The test costs 30 seconds. |
|
|
108
|
+
| Refactoring during the Red phase | You cannot safely refactor against a failing test. Always refactor from Green. |
|
|
109
|
+
| Keeping unverified "reference" implementation | Once you have reference code, you will adapt it instead of deriving from the test. Delete it. Start from the test. |
|
|
110
|
+
|
|
111
|
+
## Verification Checklist
|
|
112
|
+
|
|
113
|
+
Before marking any task complete:
|
|
114
|
+
|
|
115
|
+
- [ ] Every new function or method has a test that was written first
|
|
116
|
+
- [ ] Watched each test fail before implementing
|
|
117
|
+
- [ ] Each test failed for the expected reason (feature absent, not typo)
|
|
118
|
+
- [ ] Wrote minimal code to pass each test
|
|
119
|
+
- [ ] All tests pass
|
|
120
|
+
- [ ] No warnings or errors in test output
|
|
121
|
+
- [ ] Tests cover edge cases and error paths (not just happy path)
|
|
122
|
+
|
|
123
|
+
## Cross-References
|
|
124
|
+
|
|
125
|
+
- `core/universal-rules/spec-as-you-go.md` — tests as executable specs; same-turn update rule
|
|
126
|
+
- `core/universal-rules/quality-gates.md` — Q1 pre-commit: test green is a hard gate
|
|
127
|
+
- `core/recipes/debugging.md` — when a test fails during investigation, this recipe owns the fix cycle
|
|
128
|
+
- Red-Green-Refactor is Kent Beck's method; this recipe is independently written. Its structure was informed in part by the **Superpowers** project (idea-level; no text reproduced) — see `THIRD_PARTY_NOTICES.md`.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
recipe_id: web-mobile-parity
|
|
3
|
+
recipe_name: "Web ↔ Mobile feature and bug parity"
|
|
4
|
+
applies_when: "project has both web and mobile surfaces sharing user-facing features or business logic"
|
|
5
|
+
severity: ABSOLUTE (when installed)
|
|
6
|
+
linked_rules:
|
|
7
|
+
- workflow
|
|
8
|
+
- quality-gates
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Recipe — Web ↔ Mobile Parity
|
|
12
|
+
|
|
13
|
+
> Opt-in recipe. Install when the project has both web and mobile surfaces. Do NOT install on web-only or mobile-only projects.
|
|
14
|
+
|
|
15
|
+
## 1. Feature parity (P1)
|
|
16
|
+
|
|
17
|
+
Every user-facing feature MUST be developed for both web and mobile in the same iteration. Pair-development is the default; one-surface-only is an explicit exception that requires a written justification (a one-line note in CURRENT_WORK.md is sufficient).
|
|
18
|
+
|
|
19
|
+
### 1.1 Why pair-development
|
|
20
|
+
|
|
21
|
+
If web ships first, mobile parity gets deprioritized indefinitely. The originating project tracked this and found that "mobile follow-up" tasks aged out at a 60% rate within 3 months. Pairing eliminates the queue entirely.
|
|
22
|
+
|
|
23
|
+
### 1.2 Acceptable single-surface exceptions
|
|
24
|
+
|
|
25
|
+
- Admin features (web-only by policy — admins don't operate from mobile).
|
|
26
|
+
- Experimental features behind a feature flag (mobile waits for the flag to flip).
|
|
27
|
+
- Surface-specific hardware integrations (camera, biometrics — mobile only).
|
|
28
|
+
- Marketing pages (web only).
|
|
29
|
+
|
|
30
|
+
### 1.3 Pair-development workflow
|
|
31
|
+
|
|
32
|
+
For a feature touching user-facing flow:
|
|
33
|
+
|
|
34
|
+
1. Planner produces design with explicit web + mobile section.
|
|
35
|
+
2. Builder dispatch implements both surfaces in same logical task. (Mechanically may be 2 sub-tasks, but they share a single task ID.)
|
|
36
|
+
3. Tests cover both surfaces (web E2E + mobile E2E or equivalent).
|
|
37
|
+
4. Pre-commit review covers both diffs.
|
|
38
|
+
5. Spec update mentions both surfaces.
|
|
39
|
+
|
|
40
|
+
## 2. Bug-fix parity (P2 — ABSOLUTE)
|
|
41
|
+
|
|
42
|
+
When a bug is found on one surface, the orchestrator MUST verify whether the same bug exists on the other surface and fix BOTH in the same PR.
|
|
43
|
+
|
|
44
|
+
### 2.1 The half-fix anti-pattern
|
|
45
|
+
|
|
46
|
+
The single most-violated rule in the originating project's history. A bug was reported on web; the orchestrator fixed web; the user found the same bug on mobile two days later. This pattern repeated until the rule was promoted to ABSOLUTE.
|
|
47
|
+
|
|
48
|
+
### 2.2 Verification protocol
|
|
49
|
+
|
|
50
|
+
When a bug is reported:
|
|
51
|
+
|
|
52
|
+
1. Reproduce on the reported surface.
|
|
53
|
+
2. **Before fixing**: check whether the same bug exists on the other surface. (`grep` for the same logic, run the same scenario.)
|
|
54
|
+
3. If yes: fix both in the same PR.
|
|
55
|
+
4. If no: state explicitly in the commit message that the other surface was checked and found unaffected.
|
|
56
|
+
|
|
57
|
+
### 2.3 Why "before fixing"
|
|
58
|
+
|
|
59
|
+
Fixing on one surface first means the orchestrator's mental model is loaded with that surface's code. Switching contexts to the other surface afterward is harder; the rule treats both surfaces as the same diagnostic context.
|
|
60
|
+
|
|
61
|
+
## 3. Code organization to support parity
|
|
62
|
+
|
|
63
|
+
| Pattern | Rationale |
|
|
64
|
+
|---|---|
|
|
65
|
+
| Shared business logic in a shared package (e.g., `packages/shared`) | Single source of truth → no drift. |
|
|
66
|
+
| Shared types and constants in shared package | Type drift between surfaces is the worst kind. |
|
|
67
|
+
| Surface-specific UI in `<web-app>/` and `<mobile-app>/` | Surfaces have different UI primitives; that's correct. |
|
|
68
|
+
| Translation source-of-truth in shared package, with per-app local copies kept in sync | Web build doesn't depend on shared package import resolution at runtime; the local copy is the runtime artifact. |
|
|
69
|
+
|
|
70
|
+
The `recipes/monorepo.md` recipe describes the npm-workspaces structure that makes this organization practical.
|
|
71
|
+
|
|
72
|
+
## 4. Test coverage parity
|
|
73
|
+
|
|
74
|
+
If a flow has a web E2E test, the mobile equivalent flow MUST have a mobile E2E test (or documented reason why not — typically "mobile uses native components that web E2E doesn't exercise").
|
|
75
|
+
|
|
76
|
+
The `recipes/i18n.md` recipe handles the translation-key parity concern (8-locale or N-locale sync between web and mobile).
|
|
77
|
+
|
|
78
|
+
## 5. Cross-tool enforcement
|
|
79
|
+
|
|
80
|
+
| Mechanism | Enforcement |
|
|
81
|
+
|---|---|
|
|
82
|
+
| Shared package import structure | TypeScript compiler at build time |
|
|
83
|
+
| E2E test coverage | CI test runner |
|
|
84
|
+
| Bug-fix parity | Rule text + pre-commit review (Q1) prompts |
|
|
85
|
+
| Pair-development | Planner gate + reviewer checklist |
|
|
86
|
+
|
|
87
|
+
This recipe has no automated cross-surface check beyond rule text. The reviewer role is the final gate that catches single-surface PRs that should have been pair-developed.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Scheduling the weekly Reflector
|
|
2
|
+
|
|
3
|
+
The Reflector is **propose-only** — a scheduled run reads `.conductor/trajectories/index.jsonl`
|
|
4
|
+
+ git history and appends proposals to `docs/REFLECTION-PROPOSALS.md`. It applies nothing.
|
|
5
|
+
Nothing here auto-registers a schedule (that is a machine/user-level action a repo installer
|
|
6
|
+
cannot do for you); this documents how to register the runner CONDUCTOR emitted:
|
|
7
|
+
|
|
8
|
+
.conductor/reflect/run-weekly.sh
|
|
9
|
+
|
|
10
|
+
It auto-detects the first supported CLI on `PATH`
|
|
11
|
+
(`claude` → `codex` → `gemini` → `cursor-agent` → `copilot` → `devin`).
|
|
12
|
+
Force one with `CONDUCTOR_REFLECT_CLI=<cli>`; preview with `CONDUCTOR_REFLECT_DRYRUN=1`.
|
|
13
|
+
|
|
14
|
+
> **Local vs cloud — the one rule that matters.** The trajectory log lives locally under
|
|
15
|
+
> `.conductor/` (typically git-ignored). A **cloud** scheduler runs on a fresh clone and
|
|
16
|
+
> **cannot see it**. So for local-trajectory reflection, use a **local** scheduler:
|
|
17
|
+
> OS cron / launchd, Claude Desktop scheduled tasks, or Codex app automations.
|
|
18
|
+
> Cloud schedulers (Cursor Automations, Copilot cloud automations, Devin Scheduled Sessions)
|
|
19
|
+
> only work if you commit `.conductor/trajectories/` — not recommended.
|
|
20
|
+
|
|
21
|
+
## Universal: OS cron / launchd (works on every tool, local files)
|
|
22
|
+
|
|
23
|
+
`cron` — weekly, Mondays 09:00 (edit `crontab -e`), using an absolute project path:
|
|
24
|
+
|
|
25
|
+
0 9 * * 1 cd /abs/path/to/project && ./.conductor/reflect/run-weekly.sh >> .conductor/reflect-weekly.log 2>&1
|
|
26
|
+
|
|
27
|
+
macOS `launchd` — a `~/Library/LaunchAgents/conductor-reflect.plist` `StartCalendarInterval`
|
|
28
|
+
entry (Weekday 1, Hour 9) invoking the same script. Dry-run first:
|
|
29
|
+
|
|
30
|
+
CONDUCTOR_REFLECT_DRYRUN=1 ./.conductor/reflect/run-weekly.sh
|
|
31
|
+
|
|
32
|
+
## Native local schedulers (best where available)
|
|
33
|
+
|
|
34
|
+
- **Claude Code — Desktop Scheduled Tasks** (local; sees uncommitted files; weekly picker).
|
|
35
|
+
Create a task whose prompt is `/reflect` (Desktop app must be open, machine awake). The
|
|
36
|
+
cloud "Routines" run on a fresh clone → they will NOT see local trajectories.
|
|
37
|
+
- **Codex — app Automations** (local project, `cron` syntax, invokes saved skills). Create a
|
|
38
|
+
weekly automation running the `$reflect` skill against the local project (Codex app must be
|
|
39
|
+
running, project present on disk).
|
|
40
|
+
|
|
41
|
+
## Cloud schedulers — trajectory-blind (avoid for local reflection)
|
|
42
|
+
|
|
43
|
+
Cursor **Automations**, Copilot **cloud** automations, and Devin **Scheduled Sessions** run in a
|
|
44
|
+
cloud clone and cannot read un-committed `.conductor/`. Use OS cron locally instead. (Copilot's
|
|
45
|
+
desktop app also has *local* automations, which can work like the OS-cron path.)
|
|
46
|
+
|
|
47
|
+
## CI: GitHub Actions (cron) — only if trajectories are committed
|
|
48
|
+
|
|
49
|
+
A workflow runs on a fresh checkout, so `.conductor/trajectories/index.jsonl` must be committed
|
|
50
|
+
(or restored from an artifact), and the resulting `docs/REFLECTION-PROPOSALS.md` committed/PR'd
|
|
51
|
+
back. Per-tool official actions + `on: schedule`:
|
|
52
|
+
|
|
53
|
+
# Claude
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- uses: anthropics/claude-code-action@v1
|
|
56
|
+
with: { prompt: "/reflect", anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} }
|
|
57
|
+
|
|
58
|
+
# Gemini
|
|
59
|
+
- uses: google-github-actions/run-gemini-cli@v0
|
|
60
|
+
with: { prompt: "/reflect", gemini_api_key: ${{ secrets.GEMINI_API_KEY }} }
|
|
61
|
+
|
|
62
|
+
# Codex
|
|
63
|
+
- uses: openai/codex-action@v1
|
|
64
|
+
with: { prompt: "Run the $reflect skill", openai-api-key: ${{ secrets.OPENAI_API_KEY }} }
|
|
65
|
+
|
|
66
|
+
# Copilot
|
|
67
|
+
- run: npm i -g @github/copilot && copilot -p "$(cat .conductor/reflect/reflect-brief.md)" --allow-tool=write --no-ask-user
|
|
68
|
+
env: { COPILOT_GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} }
|
|
69
|
+
|
|
70
|
+
(Trigger with `on: { schedule: [{ cron: "0 9 * * 1" }] }`.)
|
|
71
|
+
|
|
72
|
+
## After a run
|
|
73
|
+
|
|
74
|
+
Review `docs/REFLECTION-PROPOSALS.md`; for accepted deltas, add them as `feedback_lesson-*.md`
|
|
75
|
+
memory entries, then run `.conductor/reflect/prune-lessons.sh <memory-dir>` to keep the set bounded.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
*Headless flags + scheduler local/cloud behavior verified against first-party docs 2026-07-05.
|
|
80
|
+
Some details (Cursor custom-command in `-p`, exact approval-flag names, Copilot-app local file
|
|
81
|
+
scope, the Copilot CI token env var `COPILOT_GITHUB_TOKEN`) were not first-party-confirmable —
|
|
82
|
+
the runner inlines the brief text rather than relying on unverified `/reflect` resolution, and
|
|
83
|
+
you may need to add your tool's write-approval flag / confirm its CI secret name.*
|