tlc-claude-code 2.4.8 → 2.4.10
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,248 @@ 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
|
+
|
|
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)
|
|
130
130
|
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
|
-
####
|
|
244
|
-
```bash
|
|
245
|
-
#
|
|
246
|
-
|
|
247
|
-
#
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
#
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
#
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
#
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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
|
+
#### Silent Failure Check (CRITICAL — run first)
|
|
244
|
+
```bash
|
|
245
|
+
# Empty catch blocks
|
|
246
|
+
grep -n 'catch.*{[[:space:]]*}' <file>
|
|
247
|
+
# catch with only return null/undefined/false and no logging
|
|
248
|
+
grep -n 'catch.*{' <file> # then inspect: does the block log before returning?
|
|
249
|
+
# External calls without try/catch (fetch, pool.query, exec, spawn, readFile, writeFile)
|
|
250
|
+
grep -n 'fetch\|\.query\|execSync\|spawn\|readFile\|writeFile' <file>
|
|
251
|
+
# Each must be wrapped in try/catch with error logging
|
|
252
|
+
# Empty catch = ERROR, silent return = ERROR, unwrapped external call = ERROR
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### Connection State Logging Check
|
|
256
|
+
```bash
|
|
257
|
+
# DB, Redis, WebSocket, Docker, HTTP client connections
|
|
258
|
+
# Must have: connect log, disconnect log, error log
|
|
259
|
+
grep -n 'connect\|createPool\|createClient\|new WebSocket\|new Docker' <file>
|
|
260
|
+
# Each connection point should have associated logging for state changes
|
|
261
|
+
# Missing connection logging = WARNING
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### File Size Check
|
|
265
|
+
```bash
|
|
266
|
+
# For each changed implementation file
|
|
267
|
+
wc -l <file>
|
|
268
|
+
# >1000 lines = ERROR, 500-1000 = WARNING
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### Folder Size Check
|
|
272
|
+
```bash
|
|
273
|
+
# For each folder containing changed files
|
|
274
|
+
ls <folder> | wc -l
|
|
275
|
+
# >15 files = ERROR, 8-15 = WARNING
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
#### Strict Typing Check
|
|
279
|
+
```bash
|
|
280
|
+
# Scan changed .ts/.tsx files for `any` type
|
|
281
|
+
grep -n ': any' <file>
|
|
282
|
+
grep -n 'as any' <file>
|
|
283
|
+
grep -n '<any>' <file>
|
|
284
|
+
# Any match = ERROR
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### Return Type Check
|
|
288
|
+
```bash
|
|
289
|
+
# Scan changed .ts/.tsx files for exported functions missing return types
|
|
290
|
+
# Pattern: export function name(params) { (no : ReturnType before {)
|
|
291
|
+
grep -n 'export function.*)[[:space:]]*{' <file>
|
|
292
|
+
grep -n 'export const.*=.*=>.*{' <file>
|
|
293
|
+
# Missing return type on exported function = WARNING
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### Module Structure Check
|
|
297
|
+
```
|
|
298
|
+
# Flag flat folder anti-patterns in changed files:
|
|
299
|
+
# - src/services/ with >5 unrelated services → should be modules/{entity}/
|
|
300
|
+
# - src/controllers/ with >5 controllers → should be modules/{entity}/
|
|
301
|
+
# - src/interfaces/ at project root → should be per-module interfaces/
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Standards results in report:**
|
|
305
|
+
```
|
|
306
|
+
Coding Standards:
|
|
307
|
+
File Sizes: ✅ All under 1000 lines
|
|
308
|
+
Folder Sizes: ✅ All under 15 files
|
|
309
|
+
Strict Typing: ❌ 3 `any` types found
|
|
310
|
+
├── src/api/users.controller.ts:45
|
|
311
|
+
├── src/api/users.controller.ts:89
|
|
312
|
+
└── src/services/email.ts:12
|
|
313
|
+
Return Types: ⚠️ 2 missing on exports
|
|
314
|
+
Module Structure: ✅ Domain-grouped
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Fail if:** Any `any` types in new code, or files >1000 lines.
|
|
318
|
+
|
|
298
319
|
### 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
|
-
|
|
320
|
+
|
|
321
|
+
**CRITICAL: This step runs automatically when providers are configured.**
|
|
322
|
+
|
|
323
|
+
For each provider in `reviewProviders` (except `claude` which is the current session):
|
|
324
|
+
|
|
304
325
|
**How to invoke:**
|
|
305
326
|
|
|
306
327
|
**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 +396,343 @@ Review the full diff against main but do not re-check every local edit. Focus on
|
|
|
375
396
|
```
|
|
376
397
|
|
|
377
398
|
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
|
|
399
|
+
|
|
400
|
+
**Gemini** — no built-in review command, so save diff and invoke:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
# Save diff for Gemini
|
|
404
|
+
git diff main...HEAD > /tmp/review-diff.patch
|
|
405
|
+
line_count=$(wc -l < /tmp/review-diff.patch)
|
|
406
|
+
|
|
407
|
+
# Truncate if too large
|
|
408
|
+
if [ "$line_count" -gt 500 ]; then
|
|
409
|
+
head -500 /tmp/review-diff.patch > /tmp/review-diff-truncated.patch
|
|
410
|
+
echo "... truncated (showing first 500 of $line_count lines)" >> /tmp/review-diff-truncated.patch
|
|
411
|
+
mv /tmp/review-diff-truncated.patch /tmp/review-diff.patch
|
|
412
|
+
fi
|
|
413
|
+
|
|
414
|
+
gemini --print "Review this code diff as a senior engineer. Provide:
|
|
415
|
+
- Specific line-by-line feedback
|
|
416
|
+
- Security vulnerabilities with file:line references
|
|
417
|
+
- Performance concerns
|
|
418
|
+
- Code quality issues
|
|
419
|
+
- Missing test coverage
|
|
420
|
+
|
|
421
|
+
Be thorough and specific. End with APPROVED or CHANGES_REQUESTED.
|
|
422
|
+
|
|
423
|
+
$(cat /tmp/review-diff.patch)"
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**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.
|
|
427
|
+
|
|
428
|
+
**Example output:**
|
|
429
|
+
|
|
430
|
+
```
|
|
431
|
+
Invoking Codex (GPT-5.2) for review...
|
|
432
|
+
┌─────────────────────────────────────────┐
|
|
433
|
+
│ Codex Review Result │
|
|
434
|
+
├─────────────────────────────────────────┤
|
|
435
|
+
│ Verdict: APPROVED │
|
|
436
|
+
│ │
|
|
437
|
+
│ Comments: │
|
|
438
|
+
│ - Clean implementation │
|
|
439
|
+
│ - Tests cover main paths │
|
|
440
|
+
│ - No security issues detected │
|
|
441
|
+
└─────────────────────────────────────────┘
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**Consensus Mode:**
|
|
445
|
+
- If multiple providers are configured, ALL must approve
|
|
446
|
+
- Any CHANGES_REQUESTED = overall CHANGES_REQUESTED
|
|
447
|
+
- Issues from all providers are combined in the report
|
|
448
|
+
|
|
449
|
+
### Step 7: Fix-and-Recheck Loop (RL Mode)
|
|
450
|
+
|
|
451
|
+
**This is the core innovation. Reviews are not one-shot — they loop until clean.**
|
|
452
|
+
|
|
453
|
+
After Steps 2-6 complete, if ANY issues were found:
|
|
454
|
+
|
|
455
|
+
```
|
|
456
|
+
┌─────────────────────────────────────────────┐
|
|
457
|
+
│ REVIEW LOOP (runs until clean) │
|
|
458
|
+
│ │
|
|
459
|
+
│ 1. Collect all issues from Claude + Codex │
|
|
460
|
+
│ 2. Fix each issue: │
|
|
461
|
+
│ - Missing tests → write them │
|
|
462
|
+
│ - Security issues → patch the code │
|
|
463
|
+
│ - Coding standards → refactor │
|
|
464
|
+
│ - Codex feedback → apply fixes │
|
|
465
|
+
│ 3. Run tests to verify fixes don't break │
|
|
466
|
+
│ 4. Commit fixes │
|
|
467
|
+
│ 5. Re-run Steps 2-6 (full review again) │
|
|
468
|
+
│ 6. If new issues → loop back to 1 │
|
|
469
|
+
│ 7. If clean → exit loop, generate report │
|
|
470
|
+
└─────────────────────────────────────────────┘
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Iteration rules:**
|
|
474
|
+
|
|
475
|
+
1. **No arbitrary limit** — keep looping until BOTH providers return APPROVED. The code isn't done until it's clean.
|
|
476
|
+
2. **Each iteration runs the FULL check** — don't skip steps. Fresh eyes each time.
|
|
477
|
+
3. **Re-invoke Codex each iteration** — `codex review --base main` sees the latest fixes
|
|
478
|
+
4. **Commit after each fix round** — `git commit -m "fix: address review feedback (round N)"`
|
|
479
|
+
5. **Track what was fixed** — maintain a running list for the final report
|
|
480
|
+
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.
|
|
481
|
+
|
|
482
|
+
**Fix priority order:**
|
|
483
|
+
1. Security issues (HIGH severity) — fix these first, they block everything
|
|
484
|
+
2. Missing tests — write them before touching implementation
|
|
485
|
+
3. Implementation bugs flagged by Codex — apply fixes
|
|
486
|
+
4. Coding standards (file size, `any` types, return types) — refactor
|
|
487
|
+
5. Style/naming/docs — lowest priority, fix if time permits
|
|
488
|
+
|
|
489
|
+
**What gets auto-fixed vs flagged for human:**
|
|
490
|
+
|
|
491
|
+
| Issue Type | Auto-Fix | Human Review |
|
|
492
|
+
|-----------|----------|--------------|
|
|
493
|
+
| Missing test file | Write it | - |
|
|
494
|
+
| Hardcoded secret | Replace with env var | If unclear what var to use |
|
|
495
|
+
| `any` type | Replace with proper interface | If domain type unclear |
|
|
496
|
+
| File >1000 lines | Split into sub-modules | If split strategy unclear |
|
|
497
|
+
| Security vulnerability | Patch it | If fix might break behavior |
|
|
498
|
+
| Missing ownership check | Add guard/check | If ownership model unclear |
|
|
499
|
+
| Secrets in response | Remove or mask fields | If field is needed by client |
|
|
500
|
+
| Direct `process.env` | Move to config module | If config module doesn't exist yet |
|
|
501
|
+
| Unescaped HTML | Add escapeHtml() | If templating engine preferred |
|
|
502
|
+
| Plaintext sensitive data | Add hash step | - |
|
|
503
|
+
| Manual `new Service()` | Convert to DI | If DI container not set up |
|
|
504
|
+
| Codex-flagged bug | Apply suggestion | If suggestion conflicts with Claude |
|
|
505
|
+
| Merge conflict | - | Always human |
|
|
506
|
+
|
|
507
|
+
**Example iteration:**
|
|
508
|
+
|
|
509
|
+
```
|
|
510
|
+
───────────────────────────────────────
|
|
511
|
+
Review Round 1/5
|
|
512
|
+
───────────────────────────────────────
|
|
513
|
+
Claude: CHANGES_REQUESTED
|
|
514
|
+
- Missing test for src/utils.js
|
|
515
|
+
- Hardcoded API key in src/config.js
|
|
516
|
+
Codex: CHANGES_REQUESTED
|
|
517
|
+
- Missing null check in src/parser.js:42
|
|
518
|
+
- No error handling in src/api.js:88
|
|
519
|
+
|
|
520
|
+
Fixing 4 issues...
|
|
521
|
+
✅ Created src/utils.test.js (3 tests)
|
|
522
|
+
✅ Replaced hardcoded key with process.env.API_KEY
|
|
523
|
+
✅ Added null check in parser.js:42
|
|
524
|
+
✅ Added try/catch in api.js:88
|
|
525
|
+
✅ All tests pass
|
|
526
|
+
✅ Committed: fix: address review feedback (round 1)
|
|
527
|
+
|
|
528
|
+
───────────────────────────────────────
|
|
529
|
+
Review Round 2/5
|
|
530
|
+
───────────────────────────────────────
|
|
531
|
+
Claude: CHANGES_REQUESTED
|
|
532
|
+
- src/utils.test.js missing edge case for empty input
|
|
533
|
+
Codex: APPROVED
|
|
534
|
+
|
|
535
|
+
Fixing 1 issue...
|
|
536
|
+
✅ Added empty input edge case test
|
|
537
|
+
✅ All tests pass
|
|
538
|
+
✅ Committed: fix: address review feedback (round 2)
|
|
539
|
+
|
|
540
|
+
───────────────────────────────────────
|
|
541
|
+
Review Round 3/5
|
|
542
|
+
───────────────────────────────────────
|
|
543
|
+
Claude: APPROVED
|
|
544
|
+
Codex: APPROVED
|
|
545
|
+
|
|
546
|
+
✅ All providers agree — exiting loop.
|
|
547
|
+
───────────────────────────────────────
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Stuck detection (only exit besides clean):**
|
|
551
|
+
|
|
552
|
+
```
|
|
553
|
+
───────────────────────────────────────
|
|
554
|
+
Review Round 7
|
|
555
|
+
───────────────────────────────────────
|
|
556
|
+
Claude: APPROVED
|
|
557
|
+
Codex: CHANGES_REQUESTED
|
|
558
|
+
- Complex refactor needed in src/legacy.js ← appeared 3 times
|
|
559
|
+
|
|
560
|
+
⚠️ STUCK: This issue has reappeared 3 times after being fixed.
|
|
561
|
+
Escalating to human review.
|
|
562
|
+
|
|
563
|
+
Attempts made:
|
|
564
|
+
Round 3: Extracted helper function → Codex still flagged
|
|
565
|
+
Round 5: Split into two modules → Codex still flagged
|
|
566
|
+
Round 7: Added interface layer → Codex still flagged
|
|
567
|
+
|
|
568
|
+
This needs human judgment. Run /tlc:review again after manual fix.
|
|
569
|
+
───────────────────────────────────────
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Step 8: Generate Report
|
|
573
|
+
|
|
574
|
+
```markdown
|
|
575
|
+
# Code Review Report
|
|
576
|
+
|
|
577
|
+
**Date:** 2024-01-15T10:30:00Z
|
|
578
|
+
**Base:** main → **Head:** feature/auth
|
|
579
|
+
|
|
580
|
+
## ✅ Verdict: APPROVED
|
|
581
|
+
|
|
582
|
+
## Summary
|
|
583
|
+
|
|
584
|
+
- ✅ All changed files have tests
|
|
585
|
+
- ✅ TDD score: 75%
|
|
586
|
+
- ✅ No security issues detected
|
|
587
|
+
- ✅ All files under 1000 lines
|
|
588
|
+
- ✅ No `any` types
|
|
589
|
+
- ✅ All exports have return types
|
|
590
|
+
|
|
591
|
+
## Statistics
|
|
592
|
+
|
|
593
|
+
- Files changed: 8
|
|
594
|
+
- Implementation files: 5
|
|
595
|
+
- Test files: 3
|
|
596
|
+
- Commits: 4
|
|
597
|
+
- TDD Score: 75%
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Step 9: Return Verdict
|
|
601
|
+
|
|
602
|
+
**APPROVED** - All providers agree after N iterations. Ready to push/merge.
|
|
603
|
+
|
|
604
|
+
**CHANGES_REQUESTED** - Max iterations reached with remaining issues. Needs human review.
|
|
605
|
+
|
|
606
|
+
## Example Output
|
|
607
|
+
|
|
608
|
+
### Passing Review (Multi-Provider)
|
|
609
|
+
|
|
610
|
+
```
|
|
611
|
+
/tlc:review
|
|
612
|
+
|
|
613
|
+
Loading router config from .tlc.json...
|
|
614
|
+
Review providers: claude, codex
|
|
615
|
+
|
|
616
|
+
Reviewing current branch vs main...
|
|
617
|
+
|
|
618
|
+
Changed files: 6
|
|
619
|
+
├── src/auth/login.js (impl)
|
|
620
|
+
├── src/auth/login.test.js (test) ✓
|
|
621
|
+
├── src/auth/session.js (impl)
|
|
622
|
+
├── src/auth/session.test.js (test) ✓
|
|
623
|
+
└── README.md (docs)
|
|
624
|
+
|
|
625
|
+
Test coverage: ✅ All implementation files have tests
|
|
626
|
+
|
|
627
|
+
Commit analysis:
|
|
628
|
+
├── abc1234 test: add login tests
|
|
629
|
+
├── def5678 feat: implement login
|
|
630
|
+
├── ghi9012 test: add session tests
|
|
631
|
+
└── jkl3456 feat: implement session
|
|
632
|
+
|
|
633
|
+
TDD Score: 50% ✅
|
|
634
|
+
|
|
635
|
+
Security scan: ✅ No issues found
|
|
636
|
+
|
|
637
|
+
───────────────────────────────────────
|
|
638
|
+
Invoking Codex (GPT-5.2) for review...
|
|
639
|
+
───────────────────────────────────────
|
|
640
|
+
Codex verdict: ✅ APPROVED
|
|
641
|
+
- Clean implementation
|
|
642
|
+
- Good separation of concerns
|
|
643
|
+
- Tests are comprehensive
|
|
644
|
+
───────────────────────────────────────
|
|
645
|
+
|
|
646
|
+
Provider Results:
|
|
647
|
+
✅ Claude: APPROVED
|
|
648
|
+
✅ Codex: APPROVED
|
|
649
|
+
|
|
650
|
+
─────────────────────────────────────────────
|
|
651
|
+
✅ APPROVED - Ready to push (2/2 agree)
|
|
652
|
+
─────────────────────────────────────────────
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
### Failing Review (Multi-Provider Disagreement)
|
|
656
|
+
|
|
657
|
+
```
|
|
658
|
+
/tlc:review
|
|
659
|
+
|
|
660
|
+
Loading router config from .tlc.json...
|
|
661
|
+
Review providers: claude, codex
|
|
662
|
+
|
|
663
|
+
Reviewing current branch vs main...
|
|
664
|
+
|
|
665
|
+
Changed files: 4
|
|
666
|
+
├── src/api/users.js (impl)
|
|
667
|
+
├── src/api/auth.js (impl)
|
|
668
|
+
└── src/utils.js (impl)
|
|
669
|
+
|
|
670
|
+
Test coverage: ❌ 3 files missing tests
|
|
671
|
+
├── src/api/users.js → needs src/api/users.test.js
|
|
672
|
+
├── src/api/auth.js → needs src/api/auth.test.js
|
|
673
|
+
└── src/utils.js → needs src/utils.test.js
|
|
674
|
+
|
|
675
|
+
Commit analysis:
|
|
676
|
+
└── abc1234 feat: add all features
|
|
677
|
+
|
|
678
|
+
TDD Score: 0% ❌ (target: 50%+)
|
|
679
|
+
|
|
680
|
+
Security scan: ❌ 1 high severity issue
|
|
681
|
+
└── src/api/auth.js: password = "admin123"
|
|
682
|
+
|
|
683
|
+
───────────────────────────────────────
|
|
684
|
+
Invoking Codex (GPT-5.2) for review...
|
|
685
|
+
───────────────────────────────────────
|
|
686
|
+
Codex verdict: ❌ CHANGES_REQUESTED
|
|
687
|
+
- Missing input validation in users.js
|
|
688
|
+
- SQL injection risk in auth.js line 45
|
|
689
|
+
- No error handling for network failures
|
|
690
|
+
───────────────────────────────────────
|
|
691
|
+
|
|
692
|
+
Provider Results:
|
|
693
|
+
❌ Claude: CHANGES_REQUESTED
|
|
694
|
+
❌ Codex: CHANGES_REQUESTED
|
|
695
|
+
|
|
696
|
+
Combined Issues:
|
|
697
|
+
[Claude] Missing tests for 3 files
|
|
698
|
+
[Claude] Hardcoded password
|
|
699
|
+
[Codex] Missing input validation
|
|
700
|
+
[Codex] SQL injection risk
|
|
701
|
+
[Codex] No error handling
|
|
702
|
+
|
|
703
|
+
───────────────────────────────────────────
|
|
704
|
+
❌ CHANGES_REQUESTED (0/2 approved)
|
|
705
|
+
|
|
706
|
+
Action required:
|
|
707
|
+
1. Add tests for 3 implementation files
|
|
708
|
+
2. Fix hardcoded password in src/api/auth.js
|
|
709
|
+
3. Add input validation (Codex)
|
|
710
|
+
4. Fix SQL injection risk (Codex)
|
|
711
|
+
5. Consider splitting into test-first commits
|
|
712
|
+
───────────────────────────────────────────
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
## Flags
|
|
716
|
+
|
|
717
|
+
| Flag | Description |
|
|
718
|
+
|------|-------------|
|
|
719
|
+
| `--base <branch>` | Compare against different base (default: main) |
|
|
720
|
+
| `--strict` | Fail on any TDD violation |
|
|
721
|
+
| `--no-security` | Skip security scan |
|
|
722
|
+
| `--providers <list>` | Override providers (e.g., `--providers codex,gemini`) |
|
|
723
|
+
| `--codex-only` | Use only Codex for review |
|
|
724
|
+
| `--no-external` | Skip external providers, use Claude only |
|
|
725
|
+
| `--stuck-threshold <N>` | How many times the same issue reappears before escalating to human (default: 3) |
|
|
726
|
+
| `--no-fix` | Single-pass review only — report issues but don't auto-fix |
|
|
727
|
+
| `--fix-all` | Fix even low-priority style issues (default: skip style) |
|
|
728
|
+
|
|
729
|
+
## Integration
|
|
730
|
+
|
|
731
|
+
This review runs automatically:
|
|
732
|
+
- At the end of `/tlc:build` (blocks completion if fails)
|
|
733
|
+
- Before `/tlc:verify` (informational)
|
|
734
|
+
- Can be run manually anytime
|
|
735
|
+
|
|
736
|
+
## ARGUMENTS
|
|
737
|
+
|
|
738
|
+
$ARGUMENTS
|