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,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* omniconductor — thin dispatcher to the per-tool adapter transform scripts.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* omniconductor init --target=<tool> [target-dir] [--recipes=a,b] [--dry-run] [--no-prompt]
|
|
9
|
+
* omniconductor init --target=<tool> [target-dir] --uninstall [--force]
|
|
10
|
+
* omniconductor list
|
|
11
|
+
* omniconductor --help | --version
|
|
12
|
+
*
|
|
13
|
+
* It does NOT reimplement any install logic. It locates this repo's
|
|
14
|
+
* adapters/<tool>/transform.sh and runs it with `bash`, forwarding all flags
|
|
15
|
+
* and inheriting stdio. The shell adapters remain the single source of truth
|
|
16
|
+
* (ADR-018 / the bash adapters are the validated implementation).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const path = require('path');
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
const { spawnSync } = require('child_process');
|
|
22
|
+
|
|
23
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
24
|
+
const TOOLS = ['claude', 'cursor', 'copilot', 'gemini', 'codex', 'windsurf'];
|
|
25
|
+
|
|
26
|
+
function readVersion() {
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8')).version || 'unknown';
|
|
29
|
+
} catch {
|
|
30
|
+
return 'unknown';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function usage() {
|
|
35
|
+
return `omniconductor ${readVersion()} — install CONDUCTOR's workflow into an AI coding tool
|
|
36
|
+
|
|
37
|
+
Usage:
|
|
38
|
+
omniconductor init --target=<tool> [target-dir] [options] Install into target-dir (default: .)
|
|
39
|
+
omniconductor list List available tool adapters
|
|
40
|
+
omniconductor --help | --version
|
|
41
|
+
|
|
42
|
+
Tools: ${TOOLS.join(', ')}
|
|
43
|
+
|
|
44
|
+
Common options (forwarded to the adapter):
|
|
45
|
+
--recipes=a,b,c Opt-in recipes to install
|
|
46
|
+
--dry-run Preview only — write nothing
|
|
47
|
+
--no-prompt Skip interactive prompts (CI-safe)
|
|
48
|
+
--uninstall Revert a previous install (manifest-based)
|
|
49
|
+
--force Bypass uninstall safety checks
|
|
50
|
+
|
|
51
|
+
Examples:
|
|
52
|
+
omniconductor init --target=claude ./my-app --recipes=tdd,debugging
|
|
53
|
+
omniconductor init --target=cursor ./my-app --dry-run
|
|
54
|
+
omniconductor init --target=codex . --uninstall
|
|
55
|
+
|
|
56
|
+
Run: npx omniconductor init --target=<tool> <dir>`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function fail(msg) {
|
|
60
|
+
process.stderr.write(`omniconductor: ${msg}\n\n`);
|
|
61
|
+
process.stderr.write(usage() + '\n');
|
|
62
|
+
process.exit(2);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function main(argv) {
|
|
66
|
+
const args = argv.slice(2);
|
|
67
|
+
|
|
68
|
+
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
69
|
+
process.stdout.write(usage() + '\n');
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
73
|
+
process.stdout.write(readVersion() + '\n');
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const cmd = args[0];
|
|
78
|
+
|
|
79
|
+
if (cmd === 'list') {
|
|
80
|
+
process.stdout.write('Available adapters:\n');
|
|
81
|
+
for (const t of TOOLS) {
|
|
82
|
+
const present = fs.existsSync(path.join(ROOT, 'adapters', t, 'transform.sh'));
|
|
83
|
+
process.stdout.write(` ${t.padEnd(9)} ${present ? '✅ transform.sh' : '⏳ not implemented'}\n`);
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (cmd !== 'init') {
|
|
89
|
+
fail(`unknown command '${cmd}'. Expected 'init' or 'list'.`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Parse `init` args: extract --target, the positional target-dir, forward the rest.
|
|
93
|
+
let target = null;
|
|
94
|
+
let targetDir = null;
|
|
95
|
+
const passthrough = [];
|
|
96
|
+
for (const a of args.slice(1)) {
|
|
97
|
+
if (a.startsWith('--target=')) {
|
|
98
|
+
target = a.slice('--target='.length);
|
|
99
|
+
} else if (a === '--target') {
|
|
100
|
+
fail('use --target=<tool> (with =), e.g. --target=claude');
|
|
101
|
+
} else if (a.startsWith('-')) {
|
|
102
|
+
passthrough.push(a);
|
|
103
|
+
} else if (targetDir === null) {
|
|
104
|
+
targetDir = a;
|
|
105
|
+
} else {
|
|
106
|
+
passthrough.push(a);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!target) fail('missing --target=<tool>');
|
|
111
|
+
if (!TOOLS.includes(target)) fail(`unknown target '${target}'. One of: ${TOOLS.join(', ')}`);
|
|
112
|
+
|
|
113
|
+
const transform = path.join(ROOT, 'adapters', target, 'transform.sh');
|
|
114
|
+
if (!fs.existsSync(transform)) {
|
|
115
|
+
fail(`the '${target}' adapter has no transform.sh yet (manual install — see docs/MANUAL-INSTALL.md).`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const dir = targetDir || '.';
|
|
119
|
+
const cmdline = ['bash', transform, dir, ...passthrough];
|
|
120
|
+
process.stderr.write(`omniconductor → ${cmdline.slice(1).join(' ')}\n`);
|
|
121
|
+
|
|
122
|
+
const res = spawnSync('bash', [transform, dir, ...passthrough], { stdio: 'inherit' });
|
|
123
|
+
if (res.error) {
|
|
124
|
+
process.stderr.write(`omniconductor: failed to run adapter: ${res.error.message}\n`);
|
|
125
|
+
return 1;
|
|
126
|
+
}
|
|
127
|
+
return res.status === null ? 1 : res.status;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
process.exit(main(process.argv));
|
package/core/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# `core/` — Layer 1, Universal source-of-truth
|
|
2
|
+
|
|
3
|
+
Anything in this directory MUST work for every supported tool. No tool-specific syntax, no `.claude/` references, no Cursor `.mdc` directives, no Copilot `applyTo:` annotations.
|
|
4
|
+
|
|
5
|
+
## What lives here
|
|
6
|
+
|
|
7
|
+
| Subdirectory | Purpose |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `workflow/` | The Plan → Architecture → Tasks → Implementation → Review → Spec phase definitions. Tool-agnostic phase boundaries. |
|
|
10
|
+
| `universal-rules/` | The 5 universal rules (operations, coding-conventions, token-economy, spec-as-you-go, model-routing). Each is plain markdown. |
|
|
11
|
+
| `docs-templates/` | The doc skeletons every project gets (`CURRENT_WORK.md`, `REMAINING_TASKS.md`, `PLANS.md`, `TASKS.md`, `INDEX.md`, `specs/_example.md`). |
|
|
12
|
+
| `memory-pattern/` | Documentation of the 4-type memory pattern (user / feedback / project / reference). NOT actual memory data. |
|
|
13
|
+
|
|
14
|
+
## Authoring conventions
|
|
15
|
+
|
|
16
|
+
### Plain markdown only
|
|
17
|
+
|
|
18
|
+
ATX headings, tables for comparisons, fenced code blocks with language hint. No HTML. No tool-specific syntax.
|
|
19
|
+
|
|
20
|
+
### Front-matter is OPTIONAL and routing-only
|
|
21
|
+
|
|
22
|
+
If a rule needs adapter routing hints (e.g., "this rule applies only to TypeScript files"), use minimal YAML front-matter that adapters can transform:
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
---
|
|
26
|
+
applies_to:
|
|
27
|
+
- "**/*.ts"
|
|
28
|
+
- "**/*.tsx"
|
|
29
|
+
tier: T1 # informational; how prominent in always-loaded baseline
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Rule body in plain markdown
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Adapters translate `applies_to:` to:
|
|
36
|
+
- Claude: `paths:` in the rule's front-matter
|
|
37
|
+
- Cursor: `globs:` in `.mdc`
|
|
38
|
+
- Copilot: `applyTo:` in `.instructions.md`
|
|
39
|
+
- Gemini / Codex / Windsurf: bundled (no per-pattern routing)
|
|
40
|
+
|
|
41
|
+
### No tool-specific examples
|
|
42
|
+
|
|
43
|
+
If you cite an example, make it generic. ❌ "use `Agent` tool to dispatch". ✅ "delegate to a specialized agent persona".
|
|
44
|
+
|
|
45
|
+
If a rule HAS to reference a Claude-only mechanism, put the example under a clearly-labeled tool-native callout that adapters can show or hide:
|
|
46
|
+
|
|
47
|
+
```markdown
|
|
48
|
+
> **Claude-only mechanism**: enforced via Stop hook (`stop-session-log-check.sh`).
|
|
49
|
+
> Other tools: rely on rule reminder + manual discipline.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Status (P0 foundation)
|
|
53
|
+
|
|
54
|
+
All files in subdirectories are PLACEHOLDERS describing intent. P1 fills them with real content sanitized from the reference adopter.
|
|
55
|
+
|
|
56
|
+
## Adapter contract (referenced, not implemented here)
|
|
57
|
+
|
|
58
|
+
Each adapter MUST:
|
|
59
|
+
- Read every file under `core/`.
|
|
60
|
+
- Translate front-matter to the target tool's format.
|
|
61
|
+
- Emit at the conventional path for that tool (see `docs/HOW-IT-WORKS-PER-TOOL.md`).
|
|
62
|
+
- Never modify files in `core/`.
|
|
63
|
+
|
|
64
|
+
See `adapters/README.md` for the full adapter contract.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
catalog_id: anti-patterns
|
|
3
|
+
description: "Token-economy anti-pattern catalog — diagnostic reference for adopters losing cache hit rate, paying for tool spam, or carrying bloated prefixes."
|
|
4
|
+
type: catalog
|
|
5
|
+
applies_to: ["all-tools"]
|
|
6
|
+
linked_rules:
|
|
7
|
+
- meta-discipline (token economy section)
|
|
8
|
+
- workflow (W2 docs-first, W4 7-step)
|
|
9
|
+
linked_docs:
|
|
10
|
+
- docs/PROMPT-CACHING-GUIDE.md
|
|
11
|
+
- docs/KPI.md
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# `core/anti-patterns/` — Token-economy anti-pattern catalog
|
|
15
|
+
|
|
16
|
+
> What goes wrong when CONDUCTOR is installed without discipline. Each entry is grounded in the Anthropic prompt-caching cost model and the P1.5 baseline measurements (`docs/KPI.md`, 2026-05-07).
|
|
17
|
+
|
|
18
|
+
CONDUCTOR's universal rules describe the *correct* patterns. This catalog describes the **wrong** ones — what they look like, why they damage token efficiency, how to detect them, and the fix. Adopters who follow the universal rules avoid these by construction; the catalog exists for diagnostic use when efficiency drops.
|
|
19
|
+
|
|
20
|
+
## Index
|
|
21
|
+
|
|
22
|
+
| # | Anti-Pattern | Severity | Hit-rate impact | Detection signal |
|
|
23
|
+
|---|---|---|---|---|
|
|
24
|
+
| 01 | [Dynamic system prompt](dynamic-system-prompt.md) | HIGH | -50% to -90% | hit rate < 30% with stable prefix size |
|
|
25
|
+
| 02 | [Large-file Read without range](large-file-read-no-range.md) | HIGH | indirect bloat | full-file Read on > 200-line files |
|
|
26
|
+
| 03 | [Single monolithic rule file](single-monolithic-rule-file.md) | HIGH | direct cache-write bloat | rule file > 500 lines, no path scoping |
|
|
27
|
+
| 04 | [No sub-agent dispatch](no-sub-agent-dispatch.md) | MEDIUM | indirect main-thread bloat | dispatches/session = 0 on multi-feature work |
|
|
28
|
+
| 05 | [Frequent rule-file edits](frequent-rule-file-edit.md) | MEDIUM | -20% to -40% / week | > 3 rule-file commits per week |
|
|
29
|
+
| 06 | [Tool-call spam](tool-call-spam.md) | MEDIUM | latency + output spike | tool calls / turn > 1.5 |
|
|
30
|
+
| 07 | [Skill / MCP eager-load](skill-eager-load.md) | MEDIUM | prefix bloat, hidden multipliers | 30+ eager skills or broad path triggers |
|
|
31
|
+
|
|
32
|
+
Severity legend (estimated impact on cache hit rate, derived from Anthropic prompt-caching cost model + P1.5 baseline):
|
|
33
|
+
- **HIGH** ≈ -50% or more
|
|
34
|
+
- **MEDIUM** ≈ -20%
|
|
35
|
+
- **LOW** ≈ -10% (none in the current catalog; reserved for future entries)
|
|
36
|
+
|
|
37
|
+
## Diagnostic workflow
|
|
38
|
+
|
|
39
|
+
When efficiency feels off — costs creeping up, latency climbing, sessions getting bloated — run the catalog end-to-end:
|
|
40
|
+
|
|
41
|
+
1. **Measure the current state.**
|
|
42
|
+
```bash
|
|
43
|
+
cd <conductor-repo>
|
|
44
|
+
bash tools/measure-tokens.sh --latest
|
|
45
|
+
```
|
|
46
|
+
Note the four numbers: cache hit rate, tool calls/turn, output tokens/turn, cache-write/session.
|
|
47
|
+
|
|
48
|
+
2. **Compare to baseline** (`docs/KPI.md` P1.5):
|
|
49
|
+
|
|
50
|
+
| Metric | Healthy | Investigate when |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| Cache hit rate | ≥ 95% | < 90% — start at Anti-Pattern 01 |
|
|
53
|
+
| Tool calls / turn | ≤ 0.8 | > 1.2 — start at Anti-Pattern 06 |
|
|
54
|
+
| Output tokens / turn | ≤ 800 | > 1200 — Anti-Pattern 04 + 06 likely |
|
|
55
|
+
| Cache-write / session | ≤ 30M | > 50M — Anti-Pattern 02 + 03 + 07 likely |
|
|
56
|
+
| Dispatches / session | 30-150 | 0 on a multi-feature session — Anti-Pattern 04 |
|
|
57
|
+
|
|
58
|
+
3. **Match the symptom → catalog entry**.
|
|
59
|
+
|
|
60
|
+
| Symptom | Suspected anti-pattern(s) |
|
|
61
|
+
|---|---|
|
|
62
|
+
| Cache hit rate dropped this week, no other change | 01, 05 |
|
|
63
|
+
| Session JSONL ballooning past 100MB | 02, 04, 07 |
|
|
64
|
+
| Latency creeping per turn over the session | 02, 04 |
|
|
65
|
+
| High output cost on apparently simple tasks | 04, 06 |
|
|
66
|
+
| First-turn cost (before user types anything) is large | 03, 07 |
|
|
67
|
+
| Cache hit rate fine inside session but resets each new session | 05 |
|
|
68
|
+
|
|
69
|
+
4. **Read the matching catalog entry's §3 Detection + §4 Fix.** Apply the fix; re-measure after one full session.
|
|
70
|
+
|
|
71
|
+
5. **If multiple anti-patterns apply**, address them in severity order (HIGH → MEDIUM). The HIGH entries are usually 80% of the cost.
|
|
72
|
+
|
|
73
|
+
## Reference points cited across this catalog
|
|
74
|
+
|
|
75
|
+
- **Anthropic prompt caching docs** — cost model (cache-write 1.25× / 2×, cache-read 0.1×, prefix-match-only).
|
|
76
|
+
- **CONDUCTOR P1.5 baseline** (`docs/KPI.md`, 2026-05-07) — 8 sessions on a single active project, 100% cache hit rate ceiling, avg 0.61 tool calls / turn, avg 27.4M cache-write / session.
|
|
77
|
+
- **`core/universal-rules/meta-discipline.md` §5** — token economy rules (Read discipline, hidden injection, dispatch budget, cache-friendly prompt order, tool description compression, touched-file rule scoping).
|
|
78
|
+
- **`docs/PROMPT-CACHING-GUIDE.md`** — full Claude-adapter caching guide.
|
|
79
|
+
|
|
80
|
+
The reference project measured in `KPI.md` is one specific monorepo (the originating workspace). Numbers in catalog entries are *estimates anchored to that baseline*. Other projects will see different absolute numbers but the same *direction* — the anti-patterns degrade efficiency on every codebase.
|
|
81
|
+
|
|
82
|
+
## What is NOT in this catalog
|
|
83
|
+
|
|
84
|
+
- **Code-correctness anti-patterns** (silent failures, type-design issues) — those live in role-specific reviewer guidance, not in token-economy rules.
|
|
85
|
+
- **Workflow anti-patterns** (skipping reviews, batching unsafe edits) — those are in `core/universal-rules/workflow.md` and `quality-gates.md`.
|
|
86
|
+
- **Tool-specific quirks** (Cursor-only, Copilot-only) — those live in `adapters/<tool>/`.
|
|
87
|
+
|
|
88
|
+
This catalog is exclusively about how an installation degrades the **token economy** layer of CONDUCTOR.
|
|
89
|
+
|
|
90
|
+
## Contributing new entries
|
|
91
|
+
|
|
92
|
+
A new catalog entry is justified when:
|
|
93
|
+
|
|
94
|
+
1. The pattern has been observed in production (cite the session / project).
|
|
95
|
+
2. The cost model is quantifiable (Anthropic pricing or measure-tokens output).
|
|
96
|
+
3. The fix references an existing universal-rule or recipe — not a new ad-hoc rule.
|
|
97
|
+
4. Severity is honestly assessed against the rubric in this README.
|
|
98
|
+
|
|
99
|
+
File template: copy any existing entry; preserve the frontmatter schema; keep the file ≤ 200 lines.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
# `core/anti-patterns/` — 토큰 경제 안티패턴 카탈로그 (한글 요약)
|
|
104
|
+
|
|
105
|
+
CONDUCTOR universal rules가 *옳은* 패턴을 기술한다면, 이 카탈로그는 **그 반대** — 무엇이 잘못되는가, 왜 토큰 효율을 망가뜨리는가, 어떻게 감지하고 어떻게 고치는가 — 를 기록한다. universal-rules 를 따르면 이 안티패턴들은 자연스럽게 회피된다. 이 카탈로그는 효율이 떨어졌을 때 *진단용* 으로 사용한다.
|
|
106
|
+
|
|
107
|
+
## 카탈로그 인덱스
|
|
108
|
+
|
|
109
|
+
| # | 안티패턴 | 심각도 | hit-rate 영향 | 감지 시그널 |
|
|
110
|
+
|---|---|---|---|---|
|
|
111
|
+
| 01 | [동적 system prompt](dynamic-system-prompt.md) | HIGH | -50% ~ -90% | prefix 크기는 안정인데 hit rate < 30% |
|
|
112
|
+
| 02 | [범위 없는 대형 파일 Read](large-file-read-no-range.md) | HIGH | 간접 bloat | 200줄 이상 파일 전체 Read |
|
|
113
|
+
| 03 | [단일 거대 룰 파일](single-monolithic-rule-file.md) | HIGH | 직접적인 cache-write 폭증 | 룰 파일 500줄 초과 + path 스코프 미사용 |
|
|
114
|
+
| 04 | [sub-agent dispatch 미사용](no-sub-agent-dispatch.md) | MEDIUM | main thread 누적 bloat | 멀티-피처 세션인데 dispatch = 0 |
|
|
115
|
+
| 05 | [잦은 룰 파일 수정](frequent-rule-file-edit.md) | MEDIUM | 주당 -20% ~ -40% | 주 3회 이상 룰 파일 commit |
|
|
116
|
+
| 06 | [tool-call 스팸](tool-call-spam.md) | MEDIUM | latency + output 폭증 | tool calls / turn > 1.5 |
|
|
117
|
+
| 07 | [Skill / MCP eager-load](skill-eager-load.md) | MEDIUM | prefix bloat, 숨은 multiplier | eager skill 30개 초과 또는 광범위 path trigger |
|
|
118
|
+
|
|
119
|
+
## 진단 워크플로 (요약)
|
|
120
|
+
|
|
121
|
+
1. `bash tools/measure-tokens.sh --latest` 실행 → cache hit rate / tool calls per turn / output tokens per turn / cache-write per session 4개 수치 확인.
|
|
122
|
+
2. `docs/KPI.md` P1.5 baseline 과 비교 — 어느 수치가 빠졌는지 파악.
|
|
123
|
+
3. 위 인덱스의 "감지 시그널" 컬럼으로 의심 안티패턴 매칭.
|
|
124
|
+
4. 해당 카탈로그 항목의 §3 (Detection) + §4 (Fix / Alternative) 읽고 적용.
|
|
125
|
+
5. 한 세션 분량 작업 후 다시 측정. HIGH 부터 처리하면 보통 비용의 80% 가 잡힌다.
|
|
126
|
+
|
|
127
|
+
## 카탈로그에 포함되지 *않는* 것
|
|
128
|
+
|
|
129
|
+
- 코드 정확성 안티패턴 (silent failure, type design 문제) — reviewer role guidance 영역.
|
|
130
|
+
- 워크플로 안티패턴 (review skip, 위험한 batch edit) — `core/universal-rules/workflow.md`, `quality-gates.md` 영역.
|
|
131
|
+
- Tool 별 quirk — `adapters/<tool>/` 영역.
|
|
132
|
+
|
|
133
|
+
이 카탈로그는 오직 **토큰 경제** 레이어에서 일어나는 효율 저하만 다룬다.
|
|
134
|
+
|
|
135
|
+
## 새 항목 추가 기준
|
|
136
|
+
|
|
137
|
+
1. 실제 운영 중 관찰된 패턴 (세션 / 프로젝트 인용).
|
|
138
|
+
2. 비용이 정량화 가능 (Anthropic pricing 또는 measure-tokens 출력 기반).
|
|
139
|
+
3. 해결책이 기존 universal-rule / recipe 를 참조 — 새 ad-hoc 룰 만들지 않을 것.
|
|
140
|
+
4. 심각도는 README 의 기준표에 솔직하게 평가.
|
|
141
|
+
|
|
142
|
+
파일 템플릿: 기존 항목 복사. frontmatter 스키마 유지. 200줄 이하 유지.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
anti_pattern_id: dynamic-system-prompt
|
|
3
|
+
name: "Dynamic system prompt — per-turn injection of volatile state"
|
|
4
|
+
type: anti-pattern
|
|
5
|
+
severity: HIGH
|
|
6
|
+
hit_rate_impact: "-50% to -90%"
|
|
7
|
+
detection_method:
|
|
8
|
+
- measure-tokens (cache hit rate < 30% with stable prefix size)
|
|
9
|
+
- grep for `Date.now()` / timestamp templating in system-prompt builder
|
|
10
|
+
applies_to: ["all-tools-with-prompt-caching"]
|
|
11
|
+
linked_rules:
|
|
12
|
+
- meta-discipline (5.4 cache-friendly prompt order)
|
|
13
|
+
- reference: docs/PROMPT-CACHING-GUIDE.md
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Anti-Pattern 01 — Dynamic System Prompt
|
|
17
|
+
|
|
18
|
+
## 1. What it is
|
|
19
|
+
|
|
20
|
+
The orchestrator builds the system prompt fresh on every turn, with volatile content (current timestamp, session ID, last-edit time, transient state) interleaved with the stable rule body.
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
# WRONG — invalidates cache every single turn
|
|
24
|
+
system = f"""
|
|
25
|
+
Today is {datetime.now().isoformat()}.
|
|
26
|
+
You have {get_unread_messages()} unread messages.
|
|
27
|
+
Last edited file: {last_edited_path}.
|
|
28
|
+
|
|
29
|
+
[universal rules ...]
|
|
30
|
+
[CLAUDE.md ...]
|
|
31
|
+
"""
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Anything before the cache_control marker is part of the prefix that Anthropic prefix-matches from byte 0. A single character that changes per turn invalidates everything after it.
|
|
35
|
+
|
|
36
|
+
## 2. Why it kills cache
|
|
37
|
+
|
|
38
|
+
Anthropic prompt caching is **prefix-match-only**. The first byte that differs between two turns is the cache miss point. Everything after — even if textually identical — must be re-written.
|
|
39
|
+
|
|
40
|
+
Cost model (Anthropic prompt caching docs):
|
|
41
|
+
- Cache write = 1.25× input cost (5-min) or 2× (1-hr)
|
|
42
|
+
- Cache read = 0.1× input cost
|
|
43
|
+
- Break-even after 2-3 reads
|
|
44
|
+
|
|
45
|
+
If a 12K-token prefix is invalidated every turn:
|
|
46
|
+
- Per-turn billed input = 12K × 1.25 = 15K cache-write equivalent
|
|
47
|
+
- Vs cached: 12K × 0.1 = 1.2K cache-read
|
|
48
|
+
- **Cost multiplier: ~12.5× per turn**
|
|
49
|
+
|
|
50
|
+
For a 100-turn session: 1.5M extra input tokens vs the cached baseline.
|
|
51
|
+
|
|
52
|
+
## 3. Detection
|
|
53
|
+
|
|
54
|
+
**Quantitative signal** (`tools/measure-tokens.sh`):
|
|
55
|
+
- Cache hit rate < 30% despite a large stable rule body
|
|
56
|
+
- Cache-write tokens roughly equal to cache-read tokens (write-heavy session)
|
|
57
|
+
|
|
58
|
+
**Code-level signal** (grep over orchestrator harness):
|
|
59
|
+
```bash
|
|
60
|
+
grep -RIE 'Date|now\(\)|timestamp|uuid|random|process\.uptime' \
|
|
61
|
+
--include='*.{ts,js,py}' src/orchestrator/
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Reference baseline**: Conductor's measured baseline (P1.5, 2026-05-07) shows 100% hit rate across 8 sessions of an active dev project, because the system prompt is stable. Any drop from that ceiling deserves investigation.
|
|
65
|
+
|
|
66
|
+
## 4. Fix / Alternative
|
|
67
|
+
|
|
68
|
+
**Move volatile state below the cache_control boundary.** The cacheable prefix only contains low-frequency content; per-turn state goes into the user message section.
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
# RIGHT
|
|
72
|
+
system = [
|
|
73
|
+
{
|
|
74
|
+
"type": "text",
|
|
75
|
+
"text": load_universal_rules() + load_project_md() + load_recipes(),
|
|
76
|
+
"cache_control": {"type": "ephemeral"}
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
messages = [
|
|
80
|
+
{
|
|
81
|
+
"role": "user",
|
|
82
|
+
"content": (
|
|
83
|
+
f"Current time: {datetime.now().isoformat()}\n"
|
|
84
|
+
f"Last edited: {last_edited_path}\n"
|
|
85
|
+
f"---\n{user_message}"
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Per `core/universal-rules/meta-discipline.md` §5.4, the order is:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
[1] Universal rules (lowest change rate)
|
|
95
|
+
[2] Project rules
|
|
96
|
+
[3] Selected recipes
|
|
97
|
+
[4] Memory index
|
|
98
|
+
══ cache_control: ephemeral ══
|
|
99
|
+
[5] Per-turn state, tool results, user message
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The Conductor reference project keeps `currentDate` as a system-reminder tag injected by the harness AFTER the cache boundary — not inside the rule body — which is the correct pattern.
|
|
103
|
+
|
|
104
|
+
## 5. Severity rating
|
|
105
|
+
|
|
106
|
+
**HIGH** — single biggest cache-invalidator. A 5-minute investigation usually reveals one or two volatile fields that, once moved below the boundary, restore hit rate from <30% to >80%.
|
|
107
|
+
|
|
108
|
+
| Symptom | Hit-rate hit | Detection difficulty |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| Timestamp at top of system | -90% | trivial (grep) |
|
|
111
|
+
| User-name template variable | -50% | medium |
|
|
112
|
+
| Hash of last commit | -90% | medium |
|
|
113
|
+
| Memory index regenerated each turn | -40% | medium |
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
anti_pattern_id: frequent-rule-file-edit
|
|
3
|
+
name: "Frequent rule-file edits — invalidating the cache prefix every session"
|
|
4
|
+
type: anti-pattern
|
|
5
|
+
severity: MEDIUM
|
|
6
|
+
hit_rate_impact: "-20% to -40% over a working week"
|
|
7
|
+
detection_method:
|
|
8
|
+
- git log on rule files (commits per week to CLAUDE.md / universal rules)
|
|
9
|
+
- measure-tokens cache-write delta across consecutive sessions
|
|
10
|
+
applies_to: ["all-tools-with-prompt-caching"]
|
|
11
|
+
linked_rules:
|
|
12
|
+
- workflow (W2 docs-first)
|
|
13
|
+
- meta-discipline (5.4 cache-friendly prompt order)
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Anti-Pattern 05 — Frequent rule-file edits
|
|
17
|
+
|
|
18
|
+
## 1. What it is
|
|
19
|
+
|
|
20
|
+
The project's main rule file (CLAUDE.md / AGENT.md / GEMINI.md / equivalent) — i.e. the file at the **top of the cache prefix** — is edited multiple times per week. Every edit, no matter how small, invalidates the cache for the next session that reloads it.
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
# WRONG — every other day:
|
|
24
|
+
git log --oneline -- CLAUDE.md
|
|
25
|
+
ab12cd3 docs(claude): tweak workflow phrasing
|
|
26
|
+
de45f67 docs(claude): add new helper agent description
|
|
27
|
+
89ab012 docs(claude): fix typo in section 4
|
|
28
|
+
3456cde docs(claude): inline new troubleshooting tip
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Each commit produces a different prefix bytes-wise, so the next session that loads the rule file pays the full cache-write again.
|
|
32
|
+
|
|
33
|
+
## 2. Why it kills cache
|
|
34
|
+
|
|
35
|
+
Anthropic prompt caching is **prefix-match**. The cache key is the byte sequence of the prefix. A single typo fix changes the byte sequence and the cache must be re-written.
|
|
36
|
+
|
|
37
|
+
Cost model:
|
|
38
|
+
- 5-min cache TTL → applies within a single session, robust to rule edits inside that session
|
|
39
|
+
- Cross-session cache reuse depends on prefix byte-identity from the previous session
|
|
40
|
+
|
|
41
|
+
Edit frequency vs hit rate (estimated, derived from Anthropic prompt caching docs cost model):
|
|
42
|
+
|
|
43
|
+
| Edits/week to top-of-prefix file | Cross-session prefix reuse | Estimated hit-rate hit |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| 0 (stable) | full | 0% |
|
|
46
|
+
| 1 | mostly, occasional miss | -10% |
|
|
47
|
+
| 3 | partial, frequent miss | -25% |
|
|
48
|
+
| 5+ | nearly always missed | -40% |
|
|
49
|
+
|
|
50
|
+
If the rule file is edited daily, every session starts with a fresh cache write — a 30K-token write for the prefix alone, costing 1.25× input baseline.
|
|
51
|
+
|
|
52
|
+
## 3. Detection
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Edits per week to top-of-prefix files
|
|
56
|
+
git log --since='1 week ago' --pretty=format:'%h %s' -- \
|
|
57
|
+
CLAUDE.md AGENT.md GEMINI.md .codex/codex.md \
|
|
58
|
+
.claude/rules/*.md .cursor/rules/*.mdc 2>/dev/null | wc -l
|
|
59
|
+
|
|
60
|
+
# Anything > 3 in a week is suspect
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Symptom in measure-tokens output**: cache-write tokens / session stays high across multiple sessions even when conversation length is short. A stable rule file shows declining cache-write/turn as the session ages; an edited rule file resets that decline every session.
|
|
64
|
+
|
|
65
|
+
## 4. Fix / Alternative
|
|
66
|
+
|
|
67
|
+
**Three disciplines** (compounding):
|
|
68
|
+
|
|
69
|
+
1. **Batch edits.** Accumulate rule changes over a few days, then commit one consolidated update. Reference project policy: docs-only changes wait until the next code-bearing push (per `feedback_push_timing` in the originating project's memory).
|
|
70
|
+
|
|
71
|
+
2. **Move volatile content downward.** New ad-hoc reminders, post-mortems, "watch out for X" notes belong in `CURRENT_WORK.md` (per-turn area, BELOW the cache boundary), not in the rule file.
|
|
72
|
+
|
|
73
|
+
3. **Split paths-scoped from always-loaded.** When new content is path-relevant (e.g. "billing pitfalls"), put it in a path-scoped rule file (Anti-Pattern 03 fix), not the always-loaded floor.
|
|
74
|
+
|
|
75
|
+
**Conductor's own policy** (per `core/universal-rules/README.md`): the 5 universal-rule bundles change "rarely (one CONDUCTOR upgrade per quarter)". Project-specific rules go in `core/recipes/` (opt-in). The recipe layer is intentionally below the universal-rule layer in the cache prefix order, so recipe edits invalidate less.
|
|
76
|
+
|
|
77
|
+
**Reference**: `docs/PROMPT-CACHING-GUIDE.md` "Common cache misses" table lists "Prefix order changes per turn" — same root cause as frequent edits.
|
|
78
|
+
|
|
79
|
+
## 5. Severity rating
|
|
80
|
+
|
|
81
|
+
**MEDIUM** — the harm is gradual rather than per-turn catastrophic. A team that edits the rule file once a week loses ~10% hit rate; a team that edits it daily loses 30-40%. The cumulative cost over a quarter is significant but rarely visible in any single session.
|
|
82
|
+
|
|
83
|
+
The fix is cheap: discipline + batch.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
anti_pattern_id: large-file-read-no-range
|
|
3
|
+
name: "Whole-file Read on large files — no offset / limit"
|
|
4
|
+
type: anti-pattern
|
|
5
|
+
severity: HIGH
|
|
6
|
+
hit_rate_impact: "indirect: cache-write inflation, output-token spike"
|
|
7
|
+
detection_method:
|
|
8
|
+
- measure-tokens (cache-write tokens / session > 30M)
|
|
9
|
+
- session JSONL inspection (Read tool calls without offset/limit on files > 200 lines)
|
|
10
|
+
applies_to: ["all-tools-with-file-Read"]
|
|
11
|
+
linked_rules:
|
|
12
|
+
- meta-discipline (5.1 read discipline)
|
|
13
|
+
- reference: token-economy Read rule
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Anti-Pattern 02 — Large-file Read without range
|
|
17
|
+
|
|
18
|
+
## 1. What it is
|
|
19
|
+
|
|
20
|
+
The orchestrator (or a role agent) calls `Read` on a multi-hundred-line file without `offset` / `limit` parameters, pulling the entire file into context when only a small section is relevant.
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
# WRONG — pulls 2K+ lines into context to find one constant
|
|
24
|
+
Read(file_path="<web-app>/lib/i18n/translations.ts") # 2,400 lines
|
|
25
|
+
|
|
26
|
+
# WRONG — re-Read the same large file in a later turn for a different key
|
|
27
|
+
Read(file_path="<web-app>/lib/i18n/translations.ts") # again
|
|
28
|
+
|
|
29
|
+
# WRONG — scanning a long config to confirm a single value exists
|
|
30
|
+
Read(file_path=".env.example") # 180 lines, then again, then again
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
A single 2K-line Read can dump 20K-40K tokens into the context. Across a session of 50 such Reads, that is 1-2M tokens of cache-write churn.
|
|
34
|
+
|
|
35
|
+
## 2. Why it kills cache
|
|
36
|
+
|
|
37
|
+
The file content itself enters the conversation history. Once it is in the history, it sits inside the cache prefix for subsequent turns until the conversation rolls over. This means:
|
|
38
|
+
|
|
39
|
+
- **Cache-write inflation**: every Read multiplies the size of the per-turn cacheable suffix.
|
|
40
|
+
- **Hidden-skill amplifier**: certain paths auto-inject companion skills (next-cache-components, react-best-practices, framework docs) — 200-600 tokens hidden cost per Read. See `meta-discipline.md` §5.2.
|
|
41
|
+
- **Output-token spike**: when the model summarizes or quotes the file, output cost rises proportionally to file size.
|
|
42
|
+
|
|
43
|
+
Cost estimate (Anthropic pricing reference):
|
|
44
|
+
- 50 full-file Reads × 30K tokens = 1.5M tokens of context bloat
|
|
45
|
+
- At Sonnet output rate (~$15/M) the *response* tokens about that file alone can hit $20+ over a session.
|
|
46
|
+
|
|
47
|
+
**Reference-adopter P1.5 measurement**: average tool calls per turn = 0.61. The two largest sessions had 7K-8K tool calls. If even 10% were full-file Reads on files > 500 lines, that is the root cause of multi-MB session JSONLs.
|
|
48
|
+
|
|
49
|
+
## 3. Detection
|
|
50
|
+
|
|
51
|
+
**Session-level**:
|
|
52
|
+
```bash
|
|
53
|
+
# Find Read tool calls without offset/limit on files known to be > 200 lines
|
|
54
|
+
grep -E '"name":"Read".*"file_path":"[^"]+\.(ts|tsx|md|sql|json)"' \
|
|
55
|
+
~/.claude/projects/<project>/<session>.jsonl | \
|
|
56
|
+
grep -v '"offset"' | wc -l
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Symptom**: cache-write tokens / session climb over 30M (Conductor baseline avg = 27.4M; sessions over that ceiling often have a Read-discipline gap).
|
|
60
|
+
|
|
61
|
+
**Self-check (LLM)**: before any Read, ask "do I need 50+ contiguous lines, or am I after one symbol?" If the latter, Grep wins.
|
|
62
|
+
|
|
63
|
+
## 4. Fix / Alternative
|
|
64
|
+
|
|
65
|
+
**Two-step pattern: Grep first, then range-Read** (per `meta-discipline.md` §5.1):
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
# RIGHT
|
|
69
|
+
Grep(pattern="MAX_RETRIES", path="<web-app>/lib/", output_mode="content", -n=true, -C=3)
|
|
70
|
+
|
|
71
|
+
# Then, only if Grep showed the symbol exists and you need surrounding context:
|
|
72
|
+
Read(file_path="<web-app>/lib/config.ts", offset=120, limit=50)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Range-read defaults**:
|
|
76
|
+
- For files > 200 lines: `offset` + `limit: 100` is mandatory.
|
|
77
|
+
- Read more only if the first range proved insufficient.
|
|
78
|
+
|
|
79
|
+
**Reference project pattern**: the originating workspace's `token-economy.md` rule explicitly forbids `cat` on a whole spec/CLAUDE.md/translations file. The framework version of that rule lives in `core/universal-rules/meta-discipline.md` §5.1.
|
|
80
|
+
|
|
81
|
+
## 5. Severity rating
|
|
82
|
+
|
|
83
|
+
**HIGH** — the largest single contributor to context bloat in production sessions. Combined with auto-injected skills (Anti-Pattern 07), a single careless Read can cost 1K+ tokens.
|
|
84
|
+
|
|
85
|
+
| Pattern | Per-Read token cost | Per-session impact |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| Grep first, no Read needed | ~50 (Grep result) | minimal |
|
|
88
|
+
| Range Read (limit=100) | ~1.5K | acceptable |
|
|
89
|
+
| Full file Read on 500-line file | ~6K + auto-inject 600 | bloat |
|
|
90
|
+
| Full file Read on 2K-line file | ~25K + auto-inject 600 | severe |
|