tlc-claude-code 2.4.9 → 2.5.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.
@@ -1,15 +1,15 @@
1
- # /tlc:review - Review Current Branch
2
-
3
- Review changes on current branch before pushing. **Runs in a loop until clean.**
4
-
5
- ## Routing
6
-
7
- This command supports multi-model routing via `~/.tlc/config.json`.
8
-
9
- **Before executing this command:**
10
-
11
- 1. Read routing config:
12
- ```bash
1
+ # /tlc:review - Review Current Branch
2
+
3
+ Review changes on current branch before pushing. **Runs in a loop until clean.**
4
+
5
+ ## Routing
6
+
7
+ This command supports multi-model routing via `~/.tlc/config.json`.
8
+
9
+ **Before executing this command:**
10
+
11
+ 1. Read routing config:
12
+ ```bash
13
13
  node -e "const fs = require('fs');
14
14
  const path = require('path');
15
15
  const os = require('os');
@@ -80,227 +80,252 @@ function resolveRouting(options) {
80
80
  }
81
81
  const result = resolveRouting({ command: \"review\", flagModel: process.argv[1], projectDir: process.cwd(), homeDir: process.env.HOME || os.homedir(), fs });
82
82
  process.stdout.write(JSON.stringify(result));" 2>/dev/null
83
- ```
84
-
85
- 2. If `models[0]` is NOT `claude` (i.e., routed to external model):
86
- - Read PROJECT.md, current phase PLAN.md, CODING-STANDARDS.md
87
- - Package the agent prompt below with project context using `prompt-packager`
88
- - Dispatch to the target CLI using `cli-dispatcher`
89
- - Display the CLI output and stop — do NOT execute the agent prompt below
90
-
91
- 3. If `models[0]` IS `claude` (or no routing config exists):
92
- - Execute the agent prompt below as normal (current behavior)
93
-
94
- 4. If `strategy` is `parallel`:
95
- - Execute inline (Claude) AND dispatch to CLI models simultaneously
96
- - Collect and merge results
97
-
98
- **Override:** Pass `--model <name>` to route this specific run to a different model.
99
-
100
- ## What This Does
101
-
102
- 1. Compares current branch to main/master
103
- 2. **Invokes configured review providers** (Claude, Codex, Gemini)
104
- 3. Checks test coverage for all changed files
105
- 4. Analyzes commit order for TDD compliance
106
- 5. Scans for security issues
107
- 6. If issues found **fix them automatically, then re-review**
108
- 7. **Repeats until both Claude and Codex approve** — no arbitrary limit, runs until clean
109
-
110
- **This is an iterative review loop, not a single pass.** Think of it as RL-mode: keep fixing and re-checking until the code is foolproof.
111
-
112
- **This runs automatically at the end of `/tlc:build`.**
113
-
114
- ## Multi-Provider Reviews
115
-
116
- TLC automatically uses ALL providers configured for the `review` capability in `.tlc.json`:
117
-
118
- ```json
119
- {
120
- "router": {
121
- "capabilities": {
122
- "review": { "providers": ["claude", "codex"], "fallback": "claude" }
123
- }
124
- }
125
- }
126
- ```
127
-
128
- **With this config, `/tlc:review` will:**
129
- 1. Run Claude's review (current session)
83
+ ```
84
+
85
+ 2. If `models[0]` is NOT `claude` (i.e., routed to external model):
86
+ - Read PROJECT.md, current phase PLAN.md, CODING-STANDARDS.md
87
+ - Package the agent prompt below with project context using `prompt-packager`
88
+ - Dispatch to the target CLI using `cli-dispatcher`
89
+ - Display the CLI output and stop — do NOT execute the agent prompt below
90
+
91
+ 3. If `models[0]` IS `claude` (or no routing config exists):
92
+ - Execute the agent prompt below as normal (current behavior)
93
+
94
+ 4. If `strategy` is `parallel`:
95
+ - Execute inline (Claude) AND dispatch to CLI models simultaneously
96
+ - Collect and merge results
97
+ - **CRITICAL: If a provider fails (wrong model, auth error, CLI missing), do NOT silently fall back to single-provider.** Instead:
98
+ 1. Check `.tlc/.router-state.json` for the provider's actual available model and retry
99
+ 2. If retry fails, ask the user: "[Provider] failed: [reason]. Run with [other provider] only, or fix and retry?"
100
+ 3. Never say "proceeding with X-only" without user consent
101
+
102
+ **Override:** Pass `--model <name>` to route this specific run to a different model.
103
+
104
+ ## What This Does
105
+
106
+ 1. Compares current branch to main/master
107
+ 2. **Invokes configured review providers** (Claude, Codex, Gemini)
108
+ 3. Checks test coverage for all changed files
109
+ 4. Analyzes commit order for TDD compliance
110
+ 5. Scans for security issues
111
+ 6. If issues found → **fix them automatically, then re-review**
112
+ 7. **Repeats until both Claude and Codex approve** — no arbitrary limit, runs until clean
113
+
114
+ **This is an iterative review loop, not a single pass.** Think of it as RL-mode: keep fixing and re-checking until the code is foolproof.
115
+
116
+ **This runs automatically at the end of `/tlc:build`.**
117
+
118
+ ## Multi-Provider Reviews
119
+
120
+ TLC automatically uses ALL providers configured for the `review` capability in `.tlc.json`:
121
+
122
+ ```json
123
+ {
124
+ "router": {
125
+ "capabilities": {
126
+ "review": { "providers": ["claude", "codex"], "fallback": "claude" }
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ **With this config, `/tlc:review` will:**
133
+ 1. Run Claude's review (current session)
130
134
  2. Invoke Codex CLI for second opinion: `codex exec review --base main -m gpt-5.4 --json --ephemeral`
131
- 3. Combine verdicts - both must approve for APPROVED
132
-
133
- ## Usage
134
-
135
- ```
136
- /tlc:review # Review current branch vs main
137
- /tlc:review --base dev # Review vs different base branch
138
- ```
139
-
140
- ## Process
141
-
142
- ### Step 1: Load Router State (Persistent)
143
-
144
- **Always read from the router state file first**, then fall back to config:
145
-
146
- ```javascript
147
- // 1. Read persistent router state (written by session-init hook)
148
- const routerState = JSON.parse(fs.readFileSync('.tlc/.router-state.json', 'utf-8'));
149
-
150
- // 2. Read config for capability mappings
151
- const config = JSON.parse(fs.readFileSync('.tlc.json', 'utf-8'));
152
- const reviewProviders = config.router?.capabilities?.review?.providers || ['claude'];
153
- const providers = config.router?.providers || {};
154
-
155
- // 3. Filter to only AVAILABLE providers (from state file)
156
- const availableReviewers = reviewProviders.filter(p =>
157
- routerState.providers[p]?.available === true
158
- );
159
- ```
160
-
161
- **The state file (`.tlc/.router-state.json`) is authoritative for availability.** It's written by the `SessionStart` hook, re-probed every hour, and persists across skill invocations. Never run `which codex` yourself — read the state file.
162
-
163
- If the state file is missing or stale (>1 hour), probe manually and write a fresh one.
164
-
165
- **Default providers for review:** `['claude', 'codex']` — but only invoked if the state file confirms they're available.
166
-
167
- If Codex is configured AND available in state, it WILL be invoked automatically.
168
-
169
- ### Step 2: Identify Changes
170
-
171
- ```bash
172
- git diff --name-status main...HEAD
173
- ```
174
-
175
- Categorize files:
176
- - Implementation files (`.js`, `.ts`, `.py`, etc.)
177
- - Test files (`*.test.*`, `test_*`, `*_test.*`)
178
- - Other files (docs, config, etc.)
179
-
180
- ### Step 3: Check Test Coverage
181
-
182
- For each implementation file, verify a corresponding test exists:
183
-
184
- | Implementation | Expected Test |
185
- |---------------|---------------|
186
- | `src/auth.js` | `src/auth.test.js` or `test/auth.test.js` |
187
- | `lib/utils.ts` | `lib/utils.test.ts` or `tests/utils.test.ts` |
188
- | `pkg/main.go` | `pkg/main_test.go` |
189
- | `src/login.py` | `tests/test_login.py` |
190
-
191
- **Fail if:** Implementation files have no corresponding test (in changeset or on disk).
192
-
193
- ### Step 4: Analyze TDD Compliance
194
-
195
- Check commit order to verify tests were written first:
196
-
197
- ```bash
198
- git log --oneline --name-status main..HEAD
199
- ```
200
-
201
- **Score calculation:**
202
- - Test-only commits → +1 TDD point
203
- - Implementation-only commits → -1 TDD point (except fix/refactor/chore)
204
- - Mixed commits → neutral
205
-
206
- **TDD Score = (test-first commits / total commits) × 100**
207
-
208
- **Fail if:** TDD score < 50% with more than 2 commits.
209
-
210
- ### Step 5: Security Scan
211
-
212
- Scan diff for common security issues:
213
-
214
- **Pattern-Based Checks:**
215
-
216
- | Pattern | Issue | Severity |
217
- |---------|-------|----------|
218
- | `password = "..."` | Hardcoded password | HIGH |
219
- | `api_key = "..."` | Hardcoded API key | HIGH |
220
- | `eval(...)` | Code injection risk | MEDIUM |
221
- | `innerHTML =` | XSS risk | MEDIUM |
222
- | `dangerouslySetInnerHTML` | React XSS risk | MEDIUM |
223
- | `exec("..." + var)` | Command injection | HIGH |
224
- | `SELECT...WHERE...+` | SQL injection | HIGH |
225
-
226
- **Semantic Security Checks (read the code, not just grep):**
227
-
228
- | Check | What to Look For | Severity |
229
- |-------|-----------------|----------|
230
- | **Ownership/IDOR** | Controller methods that take an ID param (`req.params.id`, `@Param('id')`) and query data without checking the requesting user owns the resource. Every data-access endpoint MUST verify ownership, not just authentication. | HIGH |
231
- | **Secrets in responses** | Response objects, DTOs, or `res.json()`/`res.send()` calls that include fields like `apiKey`, `secret`, `token`, `password`, `webhookSecret`. Secrets are write-only — never return them. | HIGH |
232
- | **Direct `process.env`** | `process.env.` usage in service, controller, or middleware files. All env access MUST go through a validated config module. Grep: `process\.env\.` in non-config files. | MEDIUM |
233
- | **Unescaped HTML** | Template literals that build HTML with `${...}` interpolation of variables (e.g., `` `<h1>${user.name}</h1>` ``). All dynamic values in HTML MUST be escaped. | HIGH |
234
- | **Plaintext sensitive data** | OTP codes, reset tokens, or session secrets stored without hashing. Look for database inserts/updates of these values without a hash step. | HIGH |
235
- | **Manual instantiation** | `new SomeProvider(...)` or `new SomeService(...)` in application code instead of using DI. | MEDIUM |
236
-
237
- **Fail if:** Any HIGH severity issues found.
238
-
239
- ### Step 5b: Coding Standards Check
240
-
241
- Scan all changed/added files for coding standards violations:
242
-
243
- #### File Size Check
244
- ```bash
245
- # For each changed implementation file
246
- wc -l <file>
247
- # >1000 lines = ERROR, 500-1000 = WARNING
248
- ```
249
-
250
- #### Folder Size Check
251
- ```bash
252
- # For each folder containing changed files
253
- ls <folder> | wc -l
254
- # >15 files = ERROR, 8-15 = WARNING
255
- ```
256
-
257
- #### Strict Typing Check
258
- ```bash
259
- # Scan changed .ts/.tsx files for `any` type
260
- grep -n ': any' <file>
261
- grep -n 'as any' <file>
262
- grep -n '<any>' <file>
263
- # Any match = ERROR
264
- ```
265
-
266
- #### Return Type Check
267
- ```bash
268
- # Scan changed .ts/.tsx files for exported functions missing return types
269
- # Pattern: export function name(params) { (no : ReturnType before {)
270
- grep -n 'export function.*)[[:space:]]*{' <file>
271
- grep -n 'export const.*=.*=>.*{' <file>
272
- # Missing return type on exported function = WARNING
273
- ```
274
-
275
- #### Module Structure Check
276
- ```
277
- # Flag flat folder anti-patterns in changed files:
278
- # - src/services/ with >5 unrelated services → should be modules/{entity}/
279
- # - src/controllers/ with >5 controllers → should be modules/{entity}/
280
- # - src/interfaces/ at project root should be per-module interfaces/
281
- ```
282
-
283
- **Standards results in report:**
284
- ```
285
- Coding Standards:
286
- File Sizes: ✅ All under 1000 lines
287
- Folder Sizes: All under 15 files
288
- Strict Typing: ❌ 3 `any` types found
289
- ├── src/api/users.controller.ts:45
290
- ├── src/api/users.controller.ts:89
291
- └── src/services/email.ts:12
292
- Return Types: ⚠️ 2 missing on exports
293
- Module Structure: Domain-grouped
294
- ```
295
-
296
- **Fail if:** Any `any` types in new code, or files >1000 lines.
297
-
135
+ 3. Combine verdicts - both must approve for APPROVED
136
+
137
+ ## Usage
138
+
139
+ ```
140
+ /tlc:review # Review current branch vs main
141
+ /tlc:review --base dev # Review vs different base branch
142
+ ```
143
+
144
+ ## Process
145
+
146
+ ### Step 1: Load Router State (Persistent)
147
+
148
+ **Always read from the router state file first**, then fall back to config:
149
+
150
+ ```javascript
151
+ // 1. Read persistent router state (written by session-init hook)
152
+ const routerState = JSON.parse(fs.readFileSync('.tlc/.router-state.json', 'utf-8'));
153
+
154
+ // 2. Read config for capability mappings
155
+ const config = JSON.parse(fs.readFileSync('.tlc.json', 'utf-8'));
156
+ const reviewProviders = config.router?.capabilities?.review?.providers || ['claude'];
157
+ const providers = config.router?.providers || {};
158
+
159
+ // 3. Filter to only AVAILABLE providers (from state file)
160
+ const availableReviewers = reviewProviders.filter(p =>
161
+ routerState.providers[p]?.available === true
162
+ );
163
+ ```
164
+
165
+ **The state file (`.tlc/.router-state.json`) is authoritative for availability.** It's written by the `SessionStart` hook, re-probed every hour, and persists across skill invocations. Never run `which codex` yourself — read the state file.
166
+
167
+ If the state file is missing or stale (>1 hour), probe manually and write a fresh one.
168
+
169
+ **Default providers for review:** `['claude', 'codex']` — but only invoked if the state file confirms they're available.
170
+
171
+ If Codex is configured AND available in state, it WILL be invoked automatically.
172
+
173
+ ### Step 2: Identify Changes
174
+
175
+ ```bash
176
+ git diff --name-status main...HEAD
177
+ ```
178
+
179
+ Categorize files:
180
+ - Implementation files (`.js`, `.ts`, `.py`, etc.)
181
+ - Test files (`*.test.*`, `test_*`, `*_test.*`)
182
+ - Other files (docs, config, etc.)
183
+
184
+ ### Step 3: Check Test Coverage
185
+
186
+ For each implementation file, verify a corresponding test exists:
187
+
188
+ | Implementation | Expected Test |
189
+ |---------------|---------------|
190
+ | `src/auth.js` | `src/auth.test.js` or `test/auth.test.js` |
191
+ | `lib/utils.ts` | `lib/utils.test.ts` or `tests/utils.test.ts` |
192
+ | `pkg/main.go` | `pkg/main_test.go` |
193
+ | `src/login.py` | `tests/test_login.py` |
194
+
195
+ **Fail if:** Implementation files have no corresponding test (in changeset or on disk).
196
+
197
+ ### Step 4: Analyze TDD Compliance
198
+
199
+ Check commit order to verify tests were written first:
200
+
201
+ ```bash
202
+ git log --oneline --name-status main..HEAD
203
+ ```
204
+
205
+ **Score calculation:**
206
+ - Test-only commits → +1 TDD point
207
+ - Implementation-only commits → -1 TDD point (except fix/refactor/chore)
208
+ - Mixed commits → neutral
209
+
210
+ **TDD Score = (test-first commits / total commits) × 100**
211
+
212
+ **Fail if:** TDD score < 50% with more than 2 commits.
213
+
214
+ ### Step 5: Security Scan
215
+
216
+ Scan diff for common security issues:
217
+
218
+ **Pattern-Based Checks:**
219
+
220
+ | Pattern | Issue | Severity |
221
+ |---------|-------|----------|
222
+ | `password = "..."` | Hardcoded password | HIGH |
223
+ | `api_key = "..."` | Hardcoded API key | HIGH |
224
+ | `eval(...)` | Code injection risk | MEDIUM |
225
+ | `innerHTML =` | XSS risk | MEDIUM |
226
+ | `dangerouslySetInnerHTML` | React XSS risk | MEDIUM |
227
+ | `exec("..." + var)` | Command injection | HIGH |
228
+ | `SELECT...WHERE...+` | SQL injection | HIGH |
229
+
230
+ **Semantic Security Checks (read the code, not just grep):**
231
+
232
+ | Check | What to Look For | Severity |
233
+ |-------|-----------------|----------|
234
+ | **Ownership/IDOR** | Controller methods that take an ID param (`req.params.id`, `@Param('id')`) and query data without checking the requesting user owns the resource. Every data-access endpoint MUST verify ownership, not just authentication. | HIGH |
235
+ | **Secrets in responses** | Response objects, DTOs, or `res.json()`/`res.send()` calls that include fields like `apiKey`, `secret`, `token`, `password`, `webhookSecret`. Secrets are write-only — never return them. | HIGH |
236
+ | **Direct `process.env`** | `process.env.` usage in service, controller, or middleware files. All env access MUST go through a validated config module. Grep: `process\.env\.` in non-config files. | MEDIUM |
237
+ | **Unescaped HTML** | Template literals that build HTML with `${...}` interpolation of variables (e.g., `` `<h1>${user.name}</h1>` ``). All dynamic values in HTML MUST be escaped. | HIGH |
238
+ | **Plaintext sensitive data** | OTP codes, reset tokens, or session secrets stored without hashing. Look for database inserts/updates of these values without a hash step. | HIGH |
239
+ | **Manual instantiation** | `new SomeProvider(...)` or `new SomeService(...)` in application code instead of using DI. | MEDIUM |
240
+
241
+ **Fail if:** Any HIGH severity issues found.
242
+
243
+ ### Step 5b: Coding Standards Check
244
+
245
+ Scan all changed/added files for coding standards violations:
246
+
247
+ #### Silent Failure Check (CRITICAL — run first)
248
+ ```bash
249
+ # Empty catch blocks
250
+ grep -n 'catch.*{[[:space:]]*}' <file>
251
+ # catch with only return null/undefined/false and no logging
252
+ grep -n 'catch.*{' <file> # then inspect: does the block log before returning?
253
+ # External calls without try/catch (fetch, pool.query, exec, spawn, readFile, writeFile)
254
+ grep -n 'fetch\|\.query\|execSync\|spawn\|readFile\|writeFile' <file>
255
+ # Each must be wrapped in try/catch with error logging
256
+ # Empty catch = ERROR, silent return = ERROR, unwrapped external call = ERROR
257
+ ```
258
+
259
+ #### Connection State Logging Check
260
+ ```bash
261
+ # DB, Redis, WebSocket, Docker, HTTP client connections
262
+ # Must have: connect log, disconnect log, error log
263
+ grep -n 'connect\|createPool\|createClient\|new WebSocket\|new Docker' <file>
264
+ # Each connection point should have associated logging for state changes
265
+ # Missing connection logging = WARNING
266
+ ```
267
+
268
+ #### File Size Check
269
+ ```bash
270
+ # For each changed implementation file
271
+ wc -l <file>
272
+ # >1000 lines = ERROR, 500-1000 = WARNING
273
+ ```
274
+
275
+ #### Folder Size Check
276
+ ```bash
277
+ # For each folder containing changed files
278
+ ls <folder> | wc -l
279
+ # >15 files = ERROR, 8-15 = WARNING
280
+ ```
281
+
282
+ #### Strict Typing Check
283
+ ```bash
284
+ # Scan changed .ts/.tsx files for `any` type
285
+ grep -n ': any' <file>
286
+ grep -n 'as any' <file>
287
+ grep -n '<any>' <file>
288
+ # Any match = ERROR
289
+ ```
290
+
291
+ #### Return Type Check
292
+ ```bash
293
+ # Scan changed .ts/.tsx files for exported functions missing return types
294
+ # Pattern: export function name(params) { (no : ReturnType before {)
295
+ grep -n 'export function.*)[[:space:]]*{' <file>
296
+ grep -n 'export const.*=.*=>.*{' <file>
297
+ # Missing return type on exported function = WARNING
298
+ ```
299
+
300
+ #### Module Structure Check
301
+ ```
302
+ # Flag flat folder anti-patterns in changed files:
303
+ # - src/services/ with >5 unrelated services → should be modules/{entity}/
304
+ # - src/controllers/ with >5 controllers → should be modules/{entity}/
305
+ # - src/interfaces/ at project root → should be per-module interfaces/
306
+ ```
307
+
308
+ **Standards results in report:**
309
+ ```
310
+ Coding Standards:
311
+ File Sizes: ✅ All under 1000 lines
312
+ Folder Sizes: ✅ All under 15 files
313
+ Strict Typing: ❌ 3 `any` types found
314
+ ├── src/api/users.controller.ts:45
315
+ ├── src/api/users.controller.ts:89
316
+ └── src/services/email.ts:12
317
+ Return Types: ⚠️ 2 missing on exports
318
+ Module Structure: ✅ Domain-grouped
319
+ ```
320
+
321
+ **Fail if:** Any `any` types in new code, or files >1000 lines.
322
+
298
323
  ### Step 6: Invoke External Providers (Codex, Gemini)
299
-
300
- **CRITICAL: This step runs automatically when providers are configured.**
301
-
302
- For each provider in `reviewProviders` (except `claude` which is the current session):
303
-
324
+
325
+ **CRITICAL: This step runs automatically when providers are configured.**
326
+
327
+ For each provider in `reviewProviders` (except `claude` which is the current session):
328
+
304
329
  **How to invoke:**
305
330
 
306
331
  **Codex** — use `codex exec review` with explicit model selection, JSON output, and `--ephemeral` for CI-style stateless runs. It reads the git diff natively, no need to pipe files.
@@ -375,343 +400,343 @@ Review the full diff against main but do not re-check every local edit. Focus on
375
400
  ```
376
401
 
377
402
  Use `codex exec review`, not plain `codex review`, for better automation controls. Always include `-m gpt-5.4`, `--json`, and `--ephemeral` in automated runs.
378
-
379
- **Gemini** — no built-in review command, so save diff and invoke:
380
-
381
- ```bash
382
- # Save diff for Gemini
383
- git diff main...HEAD > /tmp/review-diff.patch
384
- line_count=$(wc -l < /tmp/review-diff.patch)
385
-
386
- # Truncate if too large
387
- if [ "$line_count" -gt 500 ]; then
388
- head -500 /tmp/review-diff.patch > /tmp/review-diff-truncated.patch
389
- echo "... truncated (showing first 500 of $line_count lines)" >> /tmp/review-diff-truncated.patch
390
- mv /tmp/review-diff-truncated.patch /tmp/review-diff.patch
391
- fi
392
-
393
- gemini --print "Review this code diff as a senior engineer. Provide:
394
- - Specific line-by-line feedback
395
- - Security vulnerabilities with file:line references
396
- - Performance concerns
397
- - Code quality issues
398
- - Missing test coverage
399
-
400
- Be thorough and specific. End with APPROVED or CHANGES_REQUESTED.
401
-
402
- $(cat /tmp/review-diff.patch)"
403
- ```
404
-
405
- **Note:** Each CLI has its own syntax. Check `codex --help` and `gemini --help` for exact flags. The `--print` flag outputs the response without interactive mode.
406
-
407
- **Example output:**
408
-
409
- ```
410
- Invoking Codex (GPT-5.2) for review...
411
- ┌─────────────────────────────────────────┐
412
- │ Codex Review Result │
413
- ├─────────────────────────────────────────┤
414
- │ Verdict: APPROVED │
415
- │ │
416
- │ Comments: │
417
- │ - Clean implementation │
418
- │ - Tests cover main paths │
419
- │ - No security issues detected │
420
- └─────────────────────────────────────────┘
421
- ```
422
-
423
- **Consensus Mode:**
424
- - If multiple providers are configured, ALL must approve
425
- - Any CHANGES_REQUESTED = overall CHANGES_REQUESTED
426
- - Issues from all providers are combined in the report
427
-
428
- ### Step 7: Fix-and-Recheck Loop (RL Mode)
429
-
430
- **This is the core innovation. Reviews are not one-shot — they loop until clean.**
431
-
432
- After Steps 2-6 complete, if ANY issues were found:
433
-
434
- ```
435
- ┌─────────────────────────────────────────────┐
436
- │ REVIEW LOOP (runs until clean) │
437
- │ │
438
- │ 1. Collect all issues from Claude + Codex │
439
- │ 2. Fix each issue: │
440
- │ - Missing tests → write them │
441
- │ - Security issues → patch the code │
442
- │ - Coding standards → refactor │
443
- │ - Codex feedback → apply fixes │
444
- │ 3. Run tests to verify fixes don't break │
445
- │ 4. Commit fixes │
446
- │ 5. Re-run Steps 2-6 (full review again) │
447
- │ 6. If new issues → loop back to 1 │
448
- │ 7. If clean → exit loop, generate report │
449
- └─────────────────────────────────────────────┘
450
- ```
451
-
452
- **Iteration rules:**
453
-
454
- 1. **No arbitrary limit** — keep looping until BOTH providers return APPROVED. The code isn't done until it's clean.
455
- 2. **Each iteration runs the FULL check** — don't skip steps. Fresh eyes each time.
456
- 3. **Re-invoke Codex each iteration** — `codex review --base main` sees the latest fixes
457
- 4. **Commit after each fix round** — `git commit -m "fix: address review feedback (round N)"`
458
- 5. **Track what was fixed** — maintain a running list for the final report
459
- 6. **Stuck detection** — if the SAME issue appears 3 times after being "fixed", stop and escalate to the user with context on what was tried. This is the only exit condition besides clean.
460
-
461
- **Fix priority order:**
462
- 1. Security issues (HIGH severity) — fix these first, they block everything
463
- 2. Missing tests — write them before touching implementation
464
- 3. Implementation bugs flagged by Codex — apply fixes
465
- 4. Coding standards (file size, `any` types, return types) — refactor
466
- 5. Style/naming/docs — lowest priority, fix if time permits
467
-
468
- **What gets auto-fixed vs flagged for human:**
469
-
470
- | Issue Type | Auto-Fix | Human Review |
471
- |-----------|----------|--------------|
472
- | Missing test file | Write it | - |
473
- | Hardcoded secret | Replace with env var | If unclear what var to use |
474
- | `any` type | Replace with proper interface | If domain type unclear |
475
- | File >1000 lines | Split into sub-modules | If split strategy unclear |
476
- | Security vulnerability | Patch it | If fix might break behavior |
477
- | Missing ownership check | Add guard/check | If ownership model unclear |
478
- | Secrets in response | Remove or mask fields | If field is needed by client |
479
- | Direct `process.env` | Move to config module | If config module doesn't exist yet |
480
- | Unescaped HTML | Add escapeHtml() | If templating engine preferred |
481
- | Plaintext sensitive data | Add hash step | - |
482
- | Manual `new Service()` | Convert to DI | If DI container not set up |
483
- | Codex-flagged bug | Apply suggestion | If suggestion conflicts with Claude |
484
- | Merge conflict | - | Always human |
485
-
486
- **Example iteration:**
487
-
488
- ```
489
- ───────────────────────────────────────
490
- Review Round 1/5
491
- ───────────────────────────────────────
492
- Claude: CHANGES_REQUESTED
493
- - Missing test for src/utils.js
494
- - Hardcoded API key in src/config.js
495
- Codex: CHANGES_REQUESTED
496
- - Missing null check in src/parser.js:42
497
- - No error handling in src/api.js:88
498
-
499
- Fixing 4 issues...
500
- ✅ Created src/utils.test.js (3 tests)
501
- ✅ Replaced hardcoded key with process.env.API_KEY
502
- ✅ Added null check in parser.js:42
503
- ✅ Added try/catch in api.js:88
504
- ✅ All tests pass
505
- ✅ Committed: fix: address review feedback (round 1)
506
-
507
- ───────────────────────────────────────
508
- Review Round 2/5
509
- ───────────────────────────────────────
510
- Claude: CHANGES_REQUESTED
511
- - src/utils.test.js missing edge case for empty input
512
- Codex: APPROVED
513
-
514
- Fixing 1 issue...
515
- ✅ Added empty input edge case test
516
- ✅ All tests pass
517
- ✅ Committed: fix: address review feedback (round 2)
518
-
519
- ───────────────────────────────────────
520
- Review Round 3/5
521
- ───────────────────────────────────────
522
- Claude: APPROVED
523
- Codex: APPROVED
524
-
525
- ✅ All providers agree — exiting loop.
526
- ───────────────────────────────────────
527
- ```
528
-
529
- **Stuck detection (only exit besides clean):**
530
-
531
- ```
532
- ───────────────────────────────────────
533
- Review Round 7
534
- ───────────────────────────────────────
535
- Claude: APPROVED
536
- Codex: CHANGES_REQUESTED
537
- - Complex refactor needed in src/legacy.js ← appeared 3 times
538
-
539
- ⚠️ STUCK: This issue has reappeared 3 times after being fixed.
540
- Escalating to human review.
541
-
542
- Attempts made:
543
- Round 3: Extracted helper function → Codex still flagged
544
- Round 5: Split into two modules → Codex still flagged
545
- Round 7: Added interface layer → Codex still flagged
546
-
547
- This needs human judgment. Run /tlc:review again after manual fix.
548
- ───────────────────────────────────────
549
- ```
550
-
551
- ### Step 8: Generate Report
552
-
553
- ```markdown
554
- # Code Review Report
555
-
556
- **Date:** 2024-01-15T10:30:00Z
557
- **Base:** main → **Head:** feature/auth
558
-
559
- ## ✅ Verdict: APPROVED
560
-
561
- ## Summary
562
-
563
- - ✅ All changed files have tests
564
- - ✅ TDD score: 75%
565
- - ✅ No security issues detected
566
- - ✅ All files under 1000 lines
567
- - ✅ No `any` types
568
- - ✅ All exports have return types
569
-
570
- ## Statistics
571
-
572
- - Files changed: 8
573
- - Implementation files: 5
574
- - Test files: 3
575
- - Commits: 4
576
- - TDD Score: 75%
577
- ```
578
-
579
- ### Step 9: Return Verdict
580
-
581
- **APPROVED** - All providers agree after N iterations. Ready to push/merge.
582
-
583
- **CHANGES_REQUESTED** - Max iterations reached with remaining issues. Needs human review.
584
-
585
- ## Example Output
586
-
587
- ### Passing Review (Multi-Provider)
588
-
589
- ```
590
- /tlc:review
591
-
592
- Loading router config from .tlc.json...
593
- Review providers: claude, codex
594
-
595
- Reviewing current branch vs main...
596
-
597
- Changed files: 6
598
- ├── src/auth/login.js (impl)
599
- ├── src/auth/login.test.js (test) ✓
600
- ├── src/auth/session.js (impl)
601
- ├── src/auth/session.test.js (test) ✓
602
- └── README.md (docs)
603
-
604
- Test coverage: ✅ All implementation files have tests
605
-
606
- Commit analysis:
607
- ├── abc1234 test: add login tests
608
- ├── def5678 feat: implement login
609
- ├── ghi9012 test: add session tests
610
- └── jkl3456 feat: implement session
611
-
612
- TDD Score: 50% ✅
613
-
614
- Security scan: ✅ No issues found
615
-
616
- ───────────────────────────────────────
617
- Invoking Codex (GPT-5.2) for review...
618
- ───────────────────────────────────────
619
- Codex verdict: ✅ APPROVED
620
- - Clean implementation
621
- - Good separation of concerns
622
- - Tests are comprehensive
623
- ───────────────────────────────────────
624
-
625
- Provider Results:
626
- ✅ Claude: APPROVED
627
- ✅ Codex: APPROVED
628
-
629
- ─────────────────────────────────────────────
630
- ✅ APPROVED - Ready to push (2/2 agree)
631
- ─────────────────────────────────────────────
632
- ```
633
-
634
- ### Failing Review (Multi-Provider Disagreement)
635
-
636
- ```
637
- /tlc:review
638
-
639
- Loading router config from .tlc.json...
640
- Review providers: claude, codex
641
-
642
- Reviewing current branch vs main...
643
-
644
- Changed files: 4
645
- ├── src/api/users.js (impl)
646
- ├── src/api/auth.js (impl)
647
- └── src/utils.js (impl)
648
-
649
- Test coverage: ❌ 3 files missing tests
650
- ├── src/api/users.js → needs src/api/users.test.js
651
- ├── src/api/auth.js → needs src/api/auth.test.js
652
- └── src/utils.js → needs src/utils.test.js
653
-
654
- Commit analysis:
655
- └── abc1234 feat: add all features
656
-
657
- TDD Score: 0% ❌ (target: 50%+)
658
-
659
- Security scan: ❌ 1 high severity issue
660
- └── src/api/auth.js: password = "admin123"
661
-
662
- ───────────────────────────────────────
663
- Invoking Codex (GPT-5.2) for review...
664
- ───────────────────────────────────────
665
- Codex verdict: ❌ CHANGES_REQUESTED
666
- - Missing input validation in users.js
667
- - SQL injection risk in auth.js line 45
668
- - No error handling for network failures
669
- ───────────────────────────────────────
670
-
671
- Provider Results:
672
- ❌ Claude: CHANGES_REQUESTED
673
- ❌ Codex: CHANGES_REQUESTED
674
-
675
- Combined Issues:
676
- [Claude] Missing tests for 3 files
677
- [Claude] Hardcoded password
678
- [Codex] Missing input validation
679
- [Codex] SQL injection risk
680
- [Codex] No error handling
681
-
682
- ───────────────────────────────────────────
683
- ❌ CHANGES_REQUESTED (0/2 approved)
684
-
685
- Action required:
686
- 1. Add tests for 3 implementation files
687
- 2. Fix hardcoded password in src/api/auth.js
688
- 3. Add input validation (Codex)
689
- 4. Fix SQL injection risk (Codex)
690
- 5. Consider splitting into test-first commits
691
- ───────────────────────────────────────────
692
- ```
693
-
694
- ## Flags
695
-
696
- | Flag | Description |
697
- |------|-------------|
698
- | `--base <branch>` | Compare against different base (default: main) |
699
- | `--strict` | Fail on any TDD violation |
700
- | `--no-security` | Skip security scan |
701
- | `--providers <list>` | Override providers (e.g., `--providers codex,gemini`) |
702
- | `--codex-only` | Use only Codex for review |
703
- | `--no-external` | Skip external providers, use Claude only |
704
- | `--stuck-threshold <N>` | How many times the same issue reappears before escalating to human (default: 3) |
705
- | `--no-fix` | Single-pass review only — report issues but don't auto-fix |
706
- | `--fix-all` | Fix even low-priority style issues (default: skip style) |
707
-
708
- ## Integration
709
-
710
- This review runs automatically:
711
- - At the end of `/tlc:build` (blocks completion if fails)
712
- - Before `/tlc:verify` (informational)
713
- - Can be run manually anytime
714
-
715
- ## ARGUMENTS
716
-
717
- $ARGUMENTS
403
+
404
+ **Gemini** — no built-in review command, so save diff and invoke:
405
+
406
+ ```bash
407
+ # Save diff for Gemini
408
+ git diff main...HEAD > /tmp/review-diff.patch
409
+ line_count=$(wc -l < /tmp/review-diff.patch)
410
+
411
+ # Truncate if too large
412
+ if [ "$line_count" -gt 500 ]; then
413
+ head -500 /tmp/review-diff.patch > /tmp/review-diff-truncated.patch
414
+ echo "... truncated (showing first 500 of $line_count lines)" >> /tmp/review-diff-truncated.patch
415
+ mv /tmp/review-diff-truncated.patch /tmp/review-diff.patch
416
+ fi
417
+
418
+ gemini --print "Review this code diff as a senior engineer. Provide:
419
+ - Specific line-by-line feedback
420
+ - Security vulnerabilities with file:line references
421
+ - Performance concerns
422
+ - Code quality issues
423
+ - Missing test coverage
424
+
425
+ Be thorough and specific. End with APPROVED or CHANGES_REQUESTED.
426
+
427
+ $(cat /tmp/review-diff.patch)"
428
+ ```
429
+
430
+ **Note:** Each CLI has its own syntax. Check `codex --help` and `gemini --help` for exact flags. The `--print` flag outputs the response without interactive mode.
431
+
432
+ **Example output:**
433
+
434
+ ```
435
+ Invoking Codex (GPT-5.2) for review...
436
+ ┌─────────────────────────────────────────┐
437
+ │ Codex Review Result │
438
+ ├─────────────────────────────────────────┤
439
+ │ Verdict: APPROVED │
440
+ │ │
441
+ │ Comments: │
442
+ │ - Clean implementation │
443
+ │ - Tests cover main paths │
444
+ │ - No security issues detected │
445
+ └─────────────────────────────────────────┘
446
+ ```
447
+
448
+ **Consensus Mode:**
449
+ - If multiple providers are configured, ALL must approve
450
+ - Any CHANGES_REQUESTED = overall CHANGES_REQUESTED
451
+ - Issues from all providers are combined in the report
452
+
453
+ ### Step 7: Fix-and-Recheck Loop (RL Mode)
454
+
455
+ **This is the core innovation. Reviews are not one-shot — they loop until clean.**
456
+
457
+ After Steps 2-6 complete, if ANY issues were found:
458
+
459
+ ```
460
+ ┌─────────────────────────────────────────────┐
461
+ │ REVIEW LOOP (runs until clean) │
462
+ │ │
463
+ │ 1. Collect all issues from Claude + Codex │
464
+ │ 2. Fix each issue: │
465
+ │ - Missing tests → write them │
466
+ │ - Security issues → patch the code │
467
+ │ - Coding standards → refactor │
468
+ │ - Codex feedback → apply fixes │
469
+ │ 3. Run tests to verify fixes don't break │
470
+ │ 4. Commit fixes │
471
+ │ 5. Re-run Steps 2-6 (full review again) │
472
+ │ 6. If new issues → loop back to 1 │
473
+ │ 7. If clean → exit loop, generate report │
474
+ └─────────────────────────────────────────────┘
475
+ ```
476
+
477
+ **Iteration rules:**
478
+
479
+ 1. **No arbitrary limit** — keep looping until BOTH providers return APPROVED. The code isn't done until it's clean.
480
+ 2. **Each iteration runs the FULL check** — don't skip steps. Fresh eyes each time.
481
+ 3. **Re-invoke Codex each iteration** — `codex review --base main` sees the latest fixes
482
+ 4. **Commit after each fix round** — `git commit -m "fix: address review feedback (round N)"`
483
+ 5. **Track what was fixed** — maintain a running list for the final report
484
+ 6. **Stuck detection** — if the SAME issue appears 3 times after being "fixed", stop and escalate to the user with context on what was tried. This is the only exit condition besides clean.
485
+
486
+ **Fix priority order:**
487
+ 1. Security issues (HIGH severity) — fix these first, they block everything
488
+ 2. Missing tests — write them before touching implementation
489
+ 3. Implementation bugs flagged by Codex — apply fixes
490
+ 4. Coding standards (file size, `any` types, return types) — refactor
491
+ 5. Style/naming/docs — lowest priority, fix if time permits
492
+
493
+ **What gets auto-fixed vs flagged for human:**
494
+
495
+ | Issue Type | Auto-Fix | Human Review |
496
+ |-----------|----------|--------------|
497
+ | Missing test file | Write it | - |
498
+ | Hardcoded secret | Replace with env var | If unclear what var to use |
499
+ | `any` type | Replace with proper interface | If domain type unclear |
500
+ | File >1000 lines | Split into sub-modules | If split strategy unclear |
501
+ | Security vulnerability | Patch it | If fix might break behavior |
502
+ | Missing ownership check | Add guard/check | If ownership model unclear |
503
+ | Secrets in response | Remove or mask fields | If field is needed by client |
504
+ | Direct `process.env` | Move to config module | If config module doesn't exist yet |
505
+ | Unescaped HTML | Add escapeHtml() | If templating engine preferred |
506
+ | Plaintext sensitive data | Add hash step | - |
507
+ | Manual `new Service()` | Convert to DI | If DI container not set up |
508
+ | Codex-flagged bug | Apply suggestion | If suggestion conflicts with Claude |
509
+ | Merge conflict | - | Always human |
510
+
511
+ **Example iteration:**
512
+
513
+ ```
514
+ ───────────────────────────────────────
515
+ Review Round 1/5
516
+ ───────────────────────────────────────
517
+ Claude: CHANGES_REQUESTED
518
+ - Missing test for src/utils.js
519
+ - Hardcoded API key in src/config.js
520
+ Codex: CHANGES_REQUESTED
521
+ - Missing null check in src/parser.js:42
522
+ - No error handling in src/api.js:88
523
+
524
+ Fixing 4 issues...
525
+ ✅ Created src/utils.test.js (3 tests)
526
+ ✅ Replaced hardcoded key with process.env.API_KEY
527
+ ✅ Added null check in parser.js:42
528
+ ✅ Added try/catch in api.js:88
529
+ ✅ All tests pass
530
+ ✅ Committed: fix: address review feedback (round 1)
531
+
532
+ ───────────────────────────────────────
533
+ Review Round 2/5
534
+ ───────────────────────────────────────
535
+ Claude: CHANGES_REQUESTED
536
+ - src/utils.test.js missing edge case for empty input
537
+ Codex: APPROVED
538
+
539
+ Fixing 1 issue...
540
+ ✅ Added empty input edge case test
541
+ ✅ All tests pass
542
+ ✅ Committed: fix: address review feedback (round 2)
543
+
544
+ ───────────────────────────────────────
545
+ Review Round 3/5
546
+ ───────────────────────────────────────
547
+ Claude: APPROVED
548
+ Codex: APPROVED
549
+
550
+ ✅ All providers agree — exiting loop.
551
+ ───────────────────────────────────────
552
+ ```
553
+
554
+ **Stuck detection (only exit besides clean):**
555
+
556
+ ```
557
+ ───────────────────────────────────────
558
+ Review Round 7
559
+ ───────────────────────────────────────
560
+ Claude: APPROVED
561
+ Codex: CHANGES_REQUESTED
562
+ - Complex refactor needed in src/legacy.js ← appeared 3 times
563
+
564
+ ⚠️ STUCK: This issue has reappeared 3 times after being fixed.
565
+ Escalating to human review.
566
+
567
+ Attempts made:
568
+ Round 3: Extracted helper function → Codex still flagged
569
+ Round 5: Split into two modules → Codex still flagged
570
+ Round 7: Added interface layer → Codex still flagged
571
+
572
+ This needs human judgment. Run /tlc:review again after manual fix.
573
+ ───────────────────────────────────────
574
+ ```
575
+
576
+ ### Step 8: Generate Report
577
+
578
+ ```markdown
579
+ # Code Review Report
580
+
581
+ **Date:** 2024-01-15T10:30:00Z
582
+ **Base:** main → **Head:** feature/auth
583
+
584
+ ## ✅ Verdict: APPROVED
585
+
586
+ ## Summary
587
+
588
+ - ✅ All changed files have tests
589
+ - ✅ TDD score: 75%
590
+ - ✅ No security issues detected
591
+ - ✅ All files under 1000 lines
592
+ - ✅ No `any` types
593
+ - ✅ All exports have return types
594
+
595
+ ## Statistics
596
+
597
+ - Files changed: 8
598
+ - Implementation files: 5
599
+ - Test files: 3
600
+ - Commits: 4
601
+ - TDD Score: 75%
602
+ ```
603
+
604
+ ### Step 9: Return Verdict
605
+
606
+ **APPROVED** - All providers agree after N iterations. Ready to push/merge.
607
+
608
+ **CHANGES_REQUESTED** - Max iterations reached with remaining issues. Needs human review.
609
+
610
+ ## Example Output
611
+
612
+ ### Passing Review (Multi-Provider)
613
+
614
+ ```
615
+ /tlc:review
616
+
617
+ Loading router config from .tlc.json...
618
+ Review providers: claude, codex
619
+
620
+ Reviewing current branch vs main...
621
+
622
+ Changed files: 6
623
+ ├── src/auth/login.js (impl)
624
+ ├── src/auth/login.test.js (test) ✓
625
+ ├── src/auth/session.js (impl)
626
+ ├── src/auth/session.test.js (test) ✓
627
+ └── README.md (docs)
628
+
629
+ Test coverage: ✅ All implementation files have tests
630
+
631
+ Commit analysis:
632
+ ├── abc1234 test: add login tests
633
+ ├── def5678 feat: implement login
634
+ ├── ghi9012 test: add session tests
635
+ └── jkl3456 feat: implement session
636
+
637
+ TDD Score: 50% ✅
638
+
639
+ Security scan: ✅ No issues found
640
+
641
+ ───────────────────────────────────────
642
+ Invoking Codex (GPT-5.2) for review...
643
+ ───────────────────────────────────────
644
+ Codex verdict: ✅ APPROVED
645
+ - Clean implementation
646
+ - Good separation of concerns
647
+ - Tests are comprehensive
648
+ ───────────────────────────────────────
649
+
650
+ Provider Results:
651
+ ✅ Claude: APPROVED
652
+ ✅ Codex: APPROVED
653
+
654
+ ─────────────────────────────────────────────
655
+ ✅ APPROVED - Ready to push (2/2 agree)
656
+ ─────────────────────────────────────────────
657
+ ```
658
+
659
+ ### Failing Review (Multi-Provider Disagreement)
660
+
661
+ ```
662
+ /tlc:review
663
+
664
+ Loading router config from .tlc.json...
665
+ Review providers: claude, codex
666
+
667
+ Reviewing current branch vs main...
668
+
669
+ Changed files: 4
670
+ ├── src/api/users.js (impl)
671
+ ├── src/api/auth.js (impl)
672
+ └── src/utils.js (impl)
673
+
674
+ Test coverage: ❌ 3 files missing tests
675
+ ├── src/api/users.js → needs src/api/users.test.js
676
+ ├── src/api/auth.js → needs src/api/auth.test.js
677
+ └── src/utils.js → needs src/utils.test.js
678
+
679
+ Commit analysis:
680
+ └── abc1234 feat: add all features
681
+
682
+ TDD Score: 0% ❌ (target: 50%+)
683
+
684
+ Security scan: ❌ 1 high severity issue
685
+ └── src/api/auth.js: password = "admin123"
686
+
687
+ ───────────────────────────────────────
688
+ Invoking Codex (GPT-5.2) for review...
689
+ ───────────────────────────────────────
690
+ Codex verdict: ❌ CHANGES_REQUESTED
691
+ - Missing input validation in users.js
692
+ - SQL injection risk in auth.js line 45
693
+ - No error handling for network failures
694
+ ───────────────────────────────────────
695
+
696
+ Provider Results:
697
+ ❌ Claude: CHANGES_REQUESTED
698
+ ❌ Codex: CHANGES_REQUESTED
699
+
700
+ Combined Issues:
701
+ [Claude] Missing tests for 3 files
702
+ [Claude] Hardcoded password
703
+ [Codex] Missing input validation
704
+ [Codex] SQL injection risk
705
+ [Codex] No error handling
706
+
707
+ ───────────────────────────────────────────
708
+ ❌ CHANGES_REQUESTED (0/2 approved)
709
+
710
+ Action required:
711
+ 1. Add tests for 3 implementation files
712
+ 2. Fix hardcoded password in src/api/auth.js
713
+ 3. Add input validation (Codex)
714
+ 4. Fix SQL injection risk (Codex)
715
+ 5. Consider splitting into test-first commits
716
+ ───────────────────────────────────────────
717
+ ```
718
+
719
+ ## Flags
720
+
721
+ | Flag | Description |
722
+ |------|-------------|
723
+ | `--base <branch>` | Compare against different base (default: main) |
724
+ | `--strict` | Fail on any TDD violation |
725
+ | `--no-security` | Skip security scan |
726
+ | `--providers <list>` | Override providers (e.g., `--providers codex,gemini`) |
727
+ | `--codex-only` | Use only Codex for review |
728
+ | `--no-external` | Skip external providers, use Claude only |
729
+ | `--stuck-threshold <N>` | How many times the same issue reappears before escalating to human (default: 3) |
730
+ | `--no-fix` | Single-pass review only — report issues but don't auto-fix |
731
+ | `--fix-all` | Fix even low-priority style issues (default: skip style) |
732
+
733
+ ## Integration
734
+
735
+ This review runs automatically:
736
+ - At the end of `/tlc:build` (blocks completion if fails)
737
+ - Before `/tlc:verify` (informational)
738
+ - Can be run manually anytime
739
+
740
+ ## ARGUMENTS
741
+
742
+ $ARGUMENTS