tlc-claude-code 2.4.2 → 2.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/tlc/build.md +75 -5
- package/.claude/commands/tlc/discuss.md +174 -123
- package/.claude/commands/tlc/e2e-verify.md +1 -1
- package/.claude/commands/tlc/plan.md +77 -2
- package/.claude/commands/tlc/recall.md +59 -87
- package/.claude/commands/tlc/remember.md +76 -71
- package/.claude/commands/tlc/review.md +76 -21
- package/.claude/commands/tlc/tlc.md +204 -473
- package/.claude/hooks/tlc-capture-exchange.sh +50 -21
- package/.claude/hooks/tlc-session-init.sh +30 -0
- package/CLAUDE.md +6 -5
- package/bin/init.js +12 -3
- package/package.json +4 -1
- package/scripts/dev-link.sh +29 -0
- package/scripts/test-package.sh +54 -0
- package/scripts/version-sync.js +42 -0
- package/scripts/version-sync.test.js +100 -0
- package/server/lib/capture/classifier.js +71 -0
- package/server/lib/capture/classifier.test.js +71 -0
- package/server/lib/capture/claude-capture.js +140 -0
- package/server/lib/capture/claude-capture.test.js +152 -0
- package/server/lib/capture/codex-capture.js +79 -0
- package/server/lib/capture/codex-capture.test.js +161 -0
- package/server/lib/capture/codex-event-parser.js +76 -0
- package/server/lib/capture/codex-event-parser.test.js +83 -0
- package/server/lib/capture/ensure-ready.js +56 -0
- package/server/lib/capture/ensure-ready.test.js +135 -0
- package/server/lib/capture/envelope.js +77 -0
- package/server/lib/capture/envelope.test.js +169 -0
- package/server/lib/capture/extractor.js +51 -0
- package/server/lib/capture/extractor.test.js +92 -0
- package/server/lib/capture/generic-capture.js +96 -0
- package/server/lib/capture/generic-capture.test.js +171 -0
- package/server/lib/capture/index.js +117 -0
- package/server/lib/capture/index.test.js +263 -0
- package/server/lib/capture/redactor.js +68 -0
- package/server/lib/capture/redactor.test.js +93 -0
- package/server/lib/capture/spool-processor.js +155 -0
- package/server/lib/capture/spool-processor.test.js +278 -0
- package/server/lib/health-check.js +255 -0
- package/server/lib/health-check.test.js +243 -0
- package/server/lib/model-router.js +11 -2
- package/server/lib/model-router.test.js +27 -1
- package/server/lib/orchestration/cli-dispatch.js +200 -0
- package/server/lib/orchestration/cli-dispatch.test.js +242 -0
- package/server/lib/orchestration/codex-orchestrator.js +185 -0
- package/server/lib/orchestration/codex-orchestrator.test.js +221 -0
- package/server/lib/orchestration/dep-linker.js +61 -0
- package/server/lib/orchestration/dep-linker.test.js +174 -0
- package/server/lib/orchestration/prompt-builder.js +118 -0
- package/server/lib/orchestration/prompt-builder.test.js +200 -0
- package/server/lib/orchestration/standalone-compat.js +39 -0
- package/server/lib/orchestration/standalone-compat.test.js +144 -0
- package/server/lib/orchestration/worktree-manager.js +43 -0
- package/server/lib/orchestration/worktree-manager.test.js +50 -0
- package/server/lib/router-config.js +18 -3
- package/server/lib/router-config.test.js +57 -1
- package/server/lib/routing/index.js +34 -0
- package/server/lib/routing/index.test.js +33 -0
- package/server/lib/routing-command.js +11 -2
- package/server/lib/routing-command.test.js +39 -1
- package/server/lib/routing-preamble.integration.test.js +319 -0
- package/server/lib/routing-preamble.js +34 -11
- package/server/lib/routing-preamble.test.js +11 -0
- package/server/lib/task-router-config.js +35 -14
- package/server/lib/task-router-config.test.js +77 -13
|
@@ -83,16 +83,18 @@ process.stdout.write(JSON.stringify(result));" 2>/dev/null
|
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
2. If `models[0]` is NOT `claude` (i.e., routed to external model):
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
- Dispatch
|
|
89
|
-
-
|
|
86
|
+
- Resolve modules with fallback: try `tlc-claude-code/server/lib/...` first, then `$PROJECT_DIR/server/lib/...`
|
|
87
|
+
- Build the full prompt with `buildFullPrompt` from `orchestration/prompt-builder`
|
|
88
|
+
- Dispatch via unified CLI routing with `dispatch` from `orchestration/cli-dispatch`
|
|
89
|
+
- Capture provider output for memory with `captureFromProvider` from `capture`, display the CLI output, and stop — do NOT execute the agent prompt below
|
|
90
90
|
|
|
91
91
|
3. If `models[0]` IS `claude` (or no routing config exists):
|
|
92
92
|
- Execute the agent prompt below as normal (current behavior)
|
|
93
93
|
|
|
94
94
|
4. If `strategy` is `parallel`:
|
|
95
|
-
-
|
|
95
|
+
- Resolve modules with fallback: try `tlc-claude-code/server/lib/...` first, then `$PROJECT_DIR/server/lib/...`
|
|
96
|
+
- Execute inline (Claude) AND dispatch each external provider via `dispatch` from `orchestration/cli-dispatch`
|
|
97
|
+
- After each provider completes, capture its output with `captureFromProvider` from `capture`
|
|
96
98
|
- Collect and merge results
|
|
97
99
|
|
|
98
100
|
**Override:** Pass `--model <name>` to route this specific run to a different model.
|
|
@@ -276,6 +278,34 @@ This is the core TLC command. Tests before code, one task at a time.
|
|
|
276
278
|
|
|
277
279
|
## Process
|
|
278
280
|
|
|
281
|
+
### Step 0: Create Phase Branch (Mandatory)
|
|
282
|
+
|
|
283
|
+
**Never commit directly to the main branch.** Before ANY work begins:
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# Get main branch name from .tlc.json or default to "main"
|
|
287
|
+
mainBranch=$(node -e "try{console.log(require('./.tlc.json').git?.mainBranch||'main')}catch{console.log('main')}" 2>/dev/null)
|
|
288
|
+
|
|
289
|
+
# Check if already on a phase branch
|
|
290
|
+
currentBranch=$(git branch --show-current)
|
|
291
|
+
if [[ "$currentBranch" == phase/* ]]; then
|
|
292
|
+
echo "Already on phase branch: $currentBranch"
|
|
293
|
+
else
|
|
294
|
+
# Create phase branch
|
|
295
|
+
branchName="phase/${phase_number}"
|
|
296
|
+
git checkout -b "$branchName" "$mainBranch" 2>/dev/null || git checkout "$branchName"
|
|
297
|
+
echo "Working on branch: $branchName"
|
|
298
|
+
fi
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**This is not optional.** All commits go to the phase branch. When the phase is complete:
|
|
302
|
+
1. Push the branch: `git push -u origin phase/{N}`
|
|
303
|
+
2. Create PR: `gh pr create --base main --head phase/{N}`
|
|
304
|
+
3. CI validates on the PR
|
|
305
|
+
4. Merge when green
|
|
306
|
+
|
|
307
|
+
**Why:** TLC projects use integration branches. Committing to main bypasses CI, review, and the PR workflow we built. Eat your own soup.
|
|
308
|
+
|
|
279
309
|
### Step 1: Load Plans
|
|
280
310
|
|
|
281
311
|
Read all `.planning/phases/{phase}-*-PLAN.md` files for this phase.
|
|
@@ -916,6 +946,46 @@ Verdict: ❌ CHANGES REQUESTED
|
|
|
916
946
|
|
|
917
947
|
**CRITICAL: Phase is NOT complete until review passes.**
|
|
918
948
|
|
|
949
|
+
### Step 11: Push Branch and Create PR (Mandatory)
|
|
950
|
+
|
|
951
|
+
**After review passes, push the phase branch and create a PR. Ask the user before pushing.**
|
|
952
|
+
|
|
953
|
+
```bash
|
|
954
|
+
# Get current branch
|
|
955
|
+
branchName=$(git branch --show-current)
|
|
956
|
+
mainBranch=$(node -e "try{console.log(require('./.tlc.json').git?.mainBranch||'main')}catch{console.log('main')}" 2>/dev/null)
|
|
957
|
+
|
|
958
|
+
# Confirm with user
|
|
959
|
+
echo "Phase complete. Ready to push $branchName and create PR to $mainBranch?"
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
After user approval:
|
|
963
|
+
|
|
964
|
+
```bash
|
|
965
|
+
# Push branch
|
|
966
|
+
git push -u origin "$branchName"
|
|
967
|
+
|
|
968
|
+
# Create PR with phase summary
|
|
969
|
+
gh pr create \
|
|
970
|
+
--base "$mainBranch" \
|
|
971
|
+
--head "$branchName" \
|
|
972
|
+
--title "Phase {N}: {Phase Name}" \
|
|
973
|
+
--body "## Summary
|
|
974
|
+
- {task count} tasks completed
|
|
975
|
+
- {test count} tests passing
|
|
976
|
+
- Review: APPROVED
|
|
977
|
+
|
|
978
|
+
## Tasks
|
|
979
|
+
{list of completed tasks from PLAN.md}
|
|
980
|
+
|
|
981
|
+
## Test Results
|
|
982
|
+
{test runner summary}"
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
**The PR is the deliverable, not the commits.** CI runs on the PR. Merge when green.
|
|
986
|
+
|
|
987
|
+
**If the user has already been working on main** (e.g., first time using branching): push main directly but note that future phases MUST use branches.
|
|
988
|
+
|
|
919
989
|
## Framework Defaults
|
|
920
990
|
|
|
921
991
|
### TLC Default: Mocha Stack
|
|
@@ -99,7 +99,13 @@ process.stdout.write(JSON.stringify(result));" 2>/dev/null
|
|
|
99
99
|
|
|
100
100
|
## What This Does
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
Runs a short implementation interview for the current phase using a silent expansion workflow:
|
|
103
|
+
- First scan the phase goal, codebase patterns, stack, and recent changes
|
|
104
|
+
- Then propose a concrete implementation approach before asking questions
|
|
105
|
+
- Ask only questions that materially improve the plan
|
|
106
|
+
- Save decisions, trade-offs, and constraints to `.planning/phases/{N}-DISCUSSION.md`
|
|
107
|
+
|
|
108
|
+
This command is not a blank-page brainstorming prompt. The agent should do the initial thinking first, then ask the user to confirm or correct the proposal.
|
|
103
109
|
|
|
104
110
|
## Usage
|
|
105
111
|
|
|
@@ -107,174 +113,219 @@ Gathers your preferences for HOW a phase should be built through adaptive questi
|
|
|
107
113
|
/tlc:discuss [phase_number]
|
|
108
114
|
```
|
|
109
115
|
|
|
110
|
-
If no phase number, auto-detect current phase from ROADMAP.md
|
|
116
|
+
If no phase number, auto-detect current phase from `.planning/ROADMAP.md`.
|
|
111
117
|
|
|
112
118
|
## Process
|
|
113
119
|
|
|
114
|
-
### Step 1:
|
|
120
|
+
### Step 1: Scan Context First
|
|
115
121
|
|
|
116
|
-
|
|
117
|
-
- Phase name and goal
|
|
118
|
-
- What comes before (context)
|
|
119
|
-
- What comes after (constraints)
|
|
122
|
+
Before asking anything, silently inspect the implementation context for the phase.
|
|
120
123
|
|
|
121
|
-
|
|
124
|
+
Read:
|
|
125
|
+
- `.planning/ROADMAP.md` - current phase name, goal, and surrounding phase context
|
|
126
|
+
- `PROJECT.md` - product constraints, stack, architecture, conventions
|
|
127
|
+
- `.planning/phases/{N}-DISCUSSION.md` if it exists - previously made decisions and unresolved gaps
|
|
128
|
+
- Relevant code for the phase area - existing modules, patterns, folder structure, interfaces, tests
|
|
122
129
|
|
|
123
|
-
|
|
130
|
+
Also inspect:
|
|
131
|
+
- Tech stack already in use
|
|
132
|
+
- Existing implementation patterns that should be preserved
|
|
133
|
+
- Recent git changes that affect the phase direction, integration surface, or constraints
|
|
124
134
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
3) Minimal styling (Tailwind only)
|
|
131
|
-
|
|
132
|
-
State management?
|
|
133
|
-
1) React state + context
|
|
134
|
-
2) Zustand / Jotai
|
|
135
|
-
3) Redux
|
|
136
|
-
4) Server state only (React Query)
|
|
137
|
-
|
|
138
|
-
Form handling?
|
|
139
|
-
1) React Hook Form
|
|
140
|
-
2) Formik
|
|
141
|
-
3) Native forms
|
|
142
|
-
```
|
|
135
|
+
The scan should answer:
|
|
136
|
+
- What is this phase trying to accomplish?
|
|
137
|
+
- What implementation shape is most consistent with the current codebase?
|
|
138
|
+
- What decisions are already implied by the stack or recent work?
|
|
139
|
+
- What is still genuinely ambiguous?
|
|
143
140
|
|
|
144
|
-
|
|
145
|
-
```
|
|
146
|
-
API style?
|
|
147
|
-
1) REST
|
|
148
|
-
2) tRPC
|
|
149
|
-
3) GraphQL
|
|
150
|
-
|
|
151
|
-
Validation approach?
|
|
152
|
-
1) Zod schemas
|
|
153
|
-
2) Yup
|
|
154
|
-
3) Manual validation
|
|
155
|
-
|
|
156
|
-
Error handling?
|
|
157
|
-
1) Return error objects
|
|
158
|
-
2) Throw exceptions
|
|
159
|
-
3) Result types (Ok/Err)
|
|
160
|
-
```
|
|
141
|
+
Do not ask the user to restate information that can be learned from the repo.
|
|
161
142
|
|
|
162
|
-
|
|
163
|
-
```
|
|
164
|
-
Query approach?
|
|
165
|
-
1) Raw SQL
|
|
166
|
-
2) Query builder (Kysely, Knex)
|
|
167
|
-
3) ORM (Prisma, Drizzle)
|
|
168
|
-
|
|
169
|
-
Migration strategy?
|
|
170
|
-
1) Schema-first (Prisma migrate)
|
|
171
|
-
2) Code-first
|
|
172
|
-
3) Manual SQL migrations
|
|
173
|
-
```
|
|
143
|
+
### Step 2: Expand Before Asking
|
|
174
144
|
|
|
175
|
-
|
|
176
|
-
```
|
|
177
|
-
Auth provider?
|
|
178
|
-
1) Custom (JWT + bcrypt)
|
|
179
|
-
2) NextAuth / Auth.js
|
|
180
|
-
3) Clerk / Auth0 / Supabase Auth
|
|
181
|
-
|
|
182
|
-
Session storage?
|
|
183
|
-
1) JWT in httpOnly cookie
|
|
184
|
-
2) Database sessions
|
|
185
|
-
3) Redis sessions
|
|
186
|
-
```
|
|
145
|
+
After scanning, propose a full default implementation approach before any questions.
|
|
187
146
|
|
|
188
|
-
|
|
147
|
+
The proposal should be concrete enough that the user can react to it:
|
|
148
|
+
- Architecture and boundaries
|
|
149
|
+
- Main components/modules/files involved
|
|
150
|
+
- Data flow or request flow
|
|
151
|
+
- Key trade-offs
|
|
152
|
+
- Constraints or risks that seem likely
|
|
153
|
+
- Assumptions inferred from the stack and recent code
|
|
189
154
|
|
|
190
|
-
|
|
191
|
-
|
|
155
|
+
The proposal should sound like:
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
Based on the roadmap goal, current patterns, and recent changes, I would implement this as:
|
|
159
|
+
- ...
|
|
160
|
+
- ...
|
|
192
161
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
- Offline behavior?
|
|
197
|
-
- Rate limiting?
|
|
162
|
+
The main open decisions I still need to confirm are:
|
|
163
|
+
1. ...
|
|
164
|
+
2. ...
|
|
198
165
|
```
|
|
199
166
|
|
|
200
|
-
|
|
167
|
+
Do not ask "What do you want?" or "How should we build this?" before giving a recommendation.
|
|
201
168
|
|
|
202
|
-
|
|
203
|
-
|
|
169
|
+
### Step 3: Filter Questions Aggressively
|
|
170
|
+
|
|
171
|
+
Only ask a question if removing it would degrade the resulting `DISCUSSION.md` or weaken the next `/tlc:plan`.
|
|
172
|
+
|
|
173
|
+
Each question must extract substance such as:
|
|
174
|
+
- Architectural decisions
|
|
175
|
+
- Integration boundaries
|
|
176
|
+
- Operational constraints
|
|
177
|
+
- Failure-mode handling
|
|
178
|
+
- Trade-offs that materially change implementation
|
|
179
|
+
|
|
180
|
+
Do not ask about preferences that do not affect the outcome, such as:
|
|
181
|
+
- Naming choices
|
|
182
|
+
- Formatting
|
|
183
|
+
- Minor stylistic conventions
|
|
184
|
+
- Options already dictated by the existing stack unless there is a real conflict
|
|
185
|
+
|
|
186
|
+
Bad:
|
|
187
|
+
- "What database should we use?"
|
|
188
|
+
- "How do you want this named?"
|
|
189
|
+
|
|
190
|
+
Good:
|
|
191
|
+
- "I would keep this on SQLite with WAL mode because the project already uses local-first storage and recent work assumes file-backed state. Any reason to use a different persistence strategy?"
|
|
192
|
+
- "I would model this as a service plus thin CLI adapter to match the existing command architecture. Good, or do you need a different boundary for reuse/testing?"
|
|
204
193
|
|
|
205
|
-
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
-
|
|
194
|
+
### Step 4: Ask Propose-Then-Confirm Questions
|
|
195
|
+
|
|
196
|
+
Every question must include:
|
|
197
|
+
- The recommended answer
|
|
198
|
+
- The evidence behind that recommendation
|
|
199
|
+
- The decision to confirm or correct
|
|
200
|
+
|
|
201
|
+
Question style:
|
|
202
|
+
|
|
203
|
+
```text
|
|
204
|
+
1. Persistence
|
|
205
|
+
I would use SQLite with WAL mode because the current stack is local-first and this phase needs durable state with low operational overhead.
|
|
206
|
+
Good to keep that, or do you need a different storage model for sync/concurrency reasons?
|
|
209
207
|
```
|
|
210
208
|
|
|
211
|
-
|
|
209
|
+
Prefer questions that let the user confirm, reject, or constrain the recommendation.
|
|
210
|
+
|
|
211
|
+
### Step 5: Calibrate Depth
|
|
212
|
+
|
|
213
|
+
Choose question count based on phase complexity.
|
|
212
214
|
|
|
213
|
-
|
|
215
|
+
For simple phases:
|
|
216
|
+
- Ask 2-3 questions maximum
|
|
217
|
+
- Focus on the few decisions that materially change scope or architecture
|
|
218
|
+
|
|
219
|
+
For complex phases:
|
|
220
|
+
- Ask 5-8 questions
|
|
221
|
+
- Cover the major decision surfaces only
|
|
222
|
+
|
|
223
|
+
Complexity signals include:
|
|
224
|
+
- Multiple subsystems or services
|
|
225
|
+
- New infrastructure or persistence
|
|
226
|
+
- Cross-cutting auth/security concerns
|
|
227
|
+
- Large UX flows with state transitions
|
|
228
|
+
- Significant ambiguity in roadmap wording
|
|
229
|
+
|
|
230
|
+
Do not turn straightforward phases into long interviews.
|
|
231
|
+
|
|
232
|
+
### Step 6: Iterate When Answers Reveal New Gaps
|
|
233
|
+
|
|
234
|
+
If the user’s answers expose a new implementation gap, contradiction, or constraint, ask targeted follow-up questions.
|
|
235
|
+
|
|
236
|
+
Follow-up questions must also use the same pattern:
|
|
237
|
+
- explain the inferred implication
|
|
238
|
+
- recommend the likely answer
|
|
239
|
+
- ask for confirmation/correction
|
|
240
|
+
|
|
241
|
+
Stop when the remaining uncertainty no longer meaningfully affects planning.
|
|
242
|
+
|
|
243
|
+
### Step 7: Write Concrete Decisions
|
|
244
|
+
|
|
245
|
+
Create or update `.planning/phases/{N}-DISCUSSION.md`.
|
|
246
|
+
|
|
247
|
+
The file must contain decisions and rationale, not a transcript of the conversation.
|
|
248
|
+
|
|
249
|
+
Use this structure:
|
|
214
250
|
|
|
215
251
|
```markdown
|
|
216
252
|
# Phase {N}: {Name} - Discussion
|
|
217
253
|
|
|
218
|
-
##
|
|
254
|
+
## Proposed Approach
|
|
219
255
|
|
|
220
|
-
|
|
221
|
-
|----------|--------|-------|
|
|
222
|
-
| State management | Zustand | Simple, minimal boilerplate |
|
|
223
|
-
| Form handling | React Hook Form | Good validation support |
|
|
224
|
-
| API style | tRPC | Type-safe, good DX |
|
|
256
|
+
[Short summary of the implementation direction that emerged from the scan and discussion]
|
|
225
257
|
|
|
226
|
-
##
|
|
258
|
+
## Decisions
|
|
227
259
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
260
|
+
| Decision | Recommendation | Confirmed / Adjusted | Why It Matters |
|
|
261
|
+
|----------|----------------|----------------------|----------------|
|
|
262
|
+
| Service boundary | Core service with thin CLI adapter | Confirmed | Matches existing command architecture and keeps logic testable |
|
|
263
|
+
| Persistence | SQLite with WAL mode | Adjusted: in-memory for this phase | Avoids premature persistence until sync arrives |
|
|
231
264
|
|
|
232
265
|
## Constraints
|
|
233
266
|
|
|
234
|
-
- Must
|
|
235
|
-
-
|
|
267
|
+
- Must preserve existing module boundaries
|
|
268
|
+
- Must work with current local-first workflow
|
|
269
|
+
- Must remain compatible with `/tlc:plan`
|
|
236
270
|
|
|
237
|
-
##
|
|
271
|
+
## Risks / Follow-Ups
|
|
238
272
|
|
|
239
|
-
|
|
240
|
-
|
|
273
|
+
- Migration path needed if persistence changes in later phases
|
|
274
|
+
- Error handling contract should be validated in planning
|
|
241
275
|
|
|
242
|
-
|
|
276
|
+
## Planning Notes
|
|
243
277
|
|
|
278
|
+
- Call out concrete file/module areas likely to change
|
|
279
|
+
- Record unresolved items only if they materially affect planning
|
|
244
280
|
```
|
|
245
|
-
Discussion saved to .planning/phases/{N}-DISCUSSION.md
|
|
246
281
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
282
|
+
Guidelines for the output:
|
|
283
|
+
- Prefer concrete decisions over raw notes
|
|
284
|
+
- Capture trade-offs and rationale briefly
|
|
285
|
+
- Record unresolved questions only if they still matter for `/tlc:plan`
|
|
286
|
+
- Do not dump the full interview transcript
|
|
251
287
|
|
|
252
|
-
|
|
288
|
+
### Step 8: Confirm Next Step
|
|
289
|
+
|
|
290
|
+
After writing the file, report:
|
|
291
|
+
|
|
292
|
+
```text
|
|
293
|
+
Discussion saved to .planning/phases/{N}-DISCUSSION.md
|
|
253
294
|
|
|
295
|
+
Ready to continue with /tlc:plan?
|
|
296
|
+
1) Yes
|
|
297
|
+
2) No
|
|
254
298
|
```
|
|
255
|
-
> /tlc:discuss 2
|
|
256
299
|
|
|
257
|
-
|
|
300
|
+
## Interview Rules
|
|
258
301
|
|
|
259
|
-
|
|
302
|
+
- Scan before asking
|
|
303
|
+
- Propose before questioning
|
|
304
|
+
- Ask only high-leverage questions
|
|
305
|
+
- Recommend an answer in every question
|
|
306
|
+
- Prefer substance over preference
|
|
307
|
+
- Adapt question count to phase complexity
|
|
308
|
+
- Add follow-ups only when answers reveal real new gaps
|
|
309
|
+
- Produce a decision document, not a transcript
|
|
260
310
|
|
|
261
|
-
|
|
262
|
-
1) React state + context
|
|
263
|
-
2) Zustand
|
|
264
|
-
3) Server state only (React Query)
|
|
311
|
+
## Example Opening
|
|
265
312
|
|
|
266
|
-
|
|
313
|
+
```text
|
|
314
|
+
> /tlc:discuss 2
|
|
315
|
+
|
|
316
|
+
Phase 2: User Dashboard
|
|
267
317
|
|
|
268
|
-
|
|
269
|
-
1) REST + fetch
|
|
270
|
-
2) tRPC
|
|
271
|
-
3) React Query + REST
|
|
318
|
+
Based on the roadmap goal, the existing React + tRPC patterns, and recent changes in the dashboard data layer, I would implement this as a server-driven dashboard shell with a thin client state layer for filters and optimistic updates.
|
|
272
319
|
|
|
273
|
-
|
|
320
|
+
I would keep data fetching in the existing query pattern, add one aggregation endpoint for summary cards, and keep widget rendering as local components rather than introducing a new layout system.
|
|
274
321
|
|
|
275
|
-
|
|
322
|
+
The main decisions I still need to confirm are:
|
|
276
323
|
|
|
277
|
-
|
|
324
|
+
1. Dashboard state boundary
|
|
325
|
+
I would keep filter/sort state in URL params plus local component state so it stays shareable without introducing a global store.
|
|
326
|
+
Good, or do you need cross-page state that justifies Zustand?
|
|
278
327
|
|
|
279
|
-
|
|
328
|
+
2. Empty/loading/error behavior
|
|
329
|
+
I would standardize on skeleton loading plus inline empty states because that matches current UI behavior and keeps failure modes visible per widget.
|
|
330
|
+
Good, or do you need a page-level loading/error shell?
|
|
280
331
|
```
|
|
@@ -78,7 +78,7 @@ await page.screenshot({ path: '/tmp/tlc-screenshots/login.png', fullPage: true }
|
|
|
78
78
|
|
|
79
79
|
// After login
|
|
80
80
|
await page.fill('[data-testid="email"]', 'user@local.com');
|
|
81
|
-
await page.fill('[data-testid="password"]', '
|
|
81
|
+
await page.fill('[data-testid="password"]', 'REDACTED');
|
|
82
82
|
await page.click('[data-testid="login-btn"]');
|
|
83
83
|
await page.waitForURL('**/dashboard**');
|
|
84
84
|
await page.screenshot({ path: '/tmp/tlc-screenshots/after-login.png', fullPage: true });
|
|
@@ -111,6 +111,7 @@ process.stdout.write(JSON.stringify(result));" 2>/dev/null
|
|
|
111
111
|
- **Extension points**: Where will this need to grow? Plan for it.
|
|
112
112
|
- **Error boundaries**: Where can failures occur? How are they handled?
|
|
113
113
|
- **Data flow**: How does data enter, transform, and exit the system?
|
|
114
|
+
- **Outcome constraints**: Define required behaviors, scale limits, latency targets, and failure handling. Avoid prescribing implementation mechanics unless a constraint is already fixed by the system.
|
|
114
115
|
|
|
115
116
|
### Code Quality Gates
|
|
116
117
|
- **File size limit**: No file should exceed 1000 lines. Plan splits for large modules.
|
|
@@ -122,6 +123,7 @@ process.stdout.write(JSON.stringify(result));" 2>/dev/null
|
|
|
122
123
|
- **Vertical slices**: Each task delivers testable, visible progress
|
|
123
124
|
- **Risk-first**: Tackle unknowns and integrations early
|
|
124
125
|
- **Dependencies explicit**: Mark what blocks what
|
|
126
|
+
- **Strategic purpose clear**: Every task explains why it exists, what risk it retires, or what capability it unlocks
|
|
125
127
|
|
|
126
128
|
## What This Does
|
|
127
129
|
|
|
@@ -163,12 +165,21 @@ Each task should be:
|
|
|
163
165
|
- **Testable** - has clear pass/fail criteria
|
|
164
166
|
- **Independent** - minimal dependencies on other tasks
|
|
165
167
|
- **Standards-compliant** - won't produce files >1000 lines or folders >15 files
|
|
168
|
+
- **Strategically justified** - includes the problem solved and why this task matters now
|
|
166
169
|
|
|
167
170
|
**Before finalizing tasks, check:**
|
|
168
171
|
1. Will any planned file exceed 1000 lines? → Split into sub-modules
|
|
169
172
|
2. Will any folder exceed 15 files? → Plan domain subfolders
|
|
170
173
|
3. Are all interfaces defined? → Add `interfaces/` directory per module
|
|
171
174
|
4. Are types explicit? → Plan typed interfaces, not `any`
|
|
175
|
+
5. Do acceptance criteria describe outcomes instead of implementation? → Rewrite "use X" into "must achieve Y"
|
|
176
|
+
6. Are any files likely to grow past 1000 lines after follow-on tasks? → Add a warning and split plan now, not later
|
|
177
|
+
|
|
178
|
+
**When estimating file and folder impact:**
|
|
179
|
+
- Check existing target files and folders before assigning work
|
|
180
|
+
- Include projected growth from all tasks in the phase, not only the current task
|
|
181
|
+
- Add an explicit warning in the plan if any task is likely to create or expand a file beyond 1000 lines
|
|
182
|
+
- Prefer splitting by domain responsibility before implementation starts
|
|
172
183
|
|
|
173
184
|
#### Task Status Markers (Multi-User)
|
|
174
185
|
|
|
@@ -189,6 +200,8 @@ Use `/tlc:claim` to claim a task, `/tlc:release` to release one.
|
|
|
189
200
|
|
|
190
201
|
**Goal:** Define database schema for users table
|
|
191
202
|
|
|
203
|
+
**Strategic Purpose:** Establish the canonical user data contract early so authentication, profile management, and downstream integrations build on a stable foundation.
|
|
204
|
+
|
|
192
205
|
**Files:**
|
|
193
206
|
- src/modules/user/interfaces/user.interface.ts
|
|
194
207
|
- src/modules/user/user.repository.ts
|
|
@@ -199,6 +212,7 @@ Use `/tlc:claim` to claim a task, `/tlc:release` to release one.
|
|
|
199
212
|
- [ ] Timestamps auto-populate
|
|
200
213
|
- [ ] All types explicit (no `any`)
|
|
201
214
|
- [ ] Exported functions have return types
|
|
215
|
+
- [ ] Criteria describe observable outcomes and constraints, not implementation choices
|
|
202
216
|
|
|
203
217
|
**Test Cases:**
|
|
204
218
|
- Schema validates correct user data
|
|
@@ -221,18 +235,35 @@ Create `.planning/phases/{N}-PLAN.md`:
|
|
|
221
235
|
|
|
222
236
|
- [ ] {Any setup or prior work needed}
|
|
223
237
|
|
|
238
|
+
## Risk Assessment
|
|
239
|
+
|
|
240
|
+
- **Unknowns:** {Unclear requirements, technical unknowns, external dependencies}
|
|
241
|
+
- **Integration Points:** {Systems, modules, APIs, data contracts, migrations}
|
|
242
|
+
- **Potential Failures:** {What could break, degrade, or block delivery}
|
|
243
|
+
- **Mitigations:** {How the plan reduces or contains those risks}
|
|
244
|
+
|
|
245
|
+
## Decision Log
|
|
246
|
+
|
|
247
|
+
| Decision | Rationale | Alternatives Considered | Consequence |
|
|
248
|
+
|----------|-----------|--------------------------|-------------|
|
|
249
|
+
| {Architectural choice} | {Why this is the best fit now} | {What else was considered} | {Tradeoff or follow-on impact} |
|
|
250
|
+
|
|
224
251
|
## Tasks
|
|
225
252
|
|
|
226
253
|
### Task 1: {Title}
|
|
227
254
|
|
|
228
255
|
**Goal:** {What this accomplishes}
|
|
229
256
|
|
|
257
|
+
**Strategic Purpose:** {Why this task matters, what problem it solves, or what later work it unlocks}
|
|
258
|
+
|
|
230
259
|
**Files:**
|
|
231
260
|
- {files to create/modify}
|
|
261
|
+
- {note if any file is at risk of exceeding 1000 lines and how the plan avoids it}
|
|
232
262
|
|
|
233
263
|
**Acceptance Criteria:**
|
|
234
|
-
- [ ] {
|
|
235
|
-
- [ ] {
|
|
264
|
+
- [ ] {Observable behavior or outcome 1}
|
|
265
|
+
- [ ] {Observable behavior, scale constraint, latency target, or failure-handling outcome 2}
|
|
266
|
+
- [ ] {No criterion prescribes implementation details unless already mandated by project constraints}
|
|
236
267
|
|
|
237
268
|
**Test Cases:**
|
|
238
269
|
- {Test description 1}
|
|
@@ -248,11 +279,21 @@ Create `.planning/phases/{N}-PLAN.md`:
|
|
|
248
279
|
|
|
249
280
|
{Task dependencies if any - e.g., Task 3 requires Task 1}
|
|
250
281
|
|
|
282
|
+
## Definition of Done
|
|
283
|
+
|
|
284
|
+
| Dimension | Definition |
|
|
285
|
+
|-----------|------------|
|
|
286
|
+
| Behavior Change | {What users, operators, or dependent systems can now do differently} |
|
|
287
|
+
| Tests | {Unit, integration, end-to-end, contract, or manual checks required} |
|
|
288
|
+
| Failure Modes | {Known failure paths handled and verified} |
|
|
289
|
+
| Rollback | {How the change can be reverted or disabled safely if needed} |
|
|
290
|
+
|
|
251
291
|
## Estimated Scope
|
|
252
292
|
|
|
253
293
|
- Tasks: {N}
|
|
254
294
|
- Files: {N}
|
|
255
295
|
- Tests: ~{N} (estimated)
|
|
296
|
+
- File size warnings: {None / list any files projected to exceed 1000 lines and planned split}
|
|
256
297
|
```
|
|
257
298
|
|
|
258
299
|
### Step 5: Review Plan
|
|
@@ -269,6 +310,9 @@ Tasks: 4
|
|
|
269
310
|
4. Add loading/error states
|
|
270
311
|
|
|
271
312
|
Estimated tests: 12
|
|
313
|
+
Key risks: 2 integration points, 1 unresolved dependency
|
|
314
|
+
Architecture decisions logged: 3
|
|
315
|
+
File size warnings: none
|
|
272
316
|
|
|
273
317
|
Proceed with this plan? (Y/n)
|
|
274
318
|
```
|
|
@@ -294,12 +338,15 @@ Task: Create login API endpoint
|
|
|
294
338
|
- Validates email/password
|
|
295
339
|
- Returns JWT token
|
|
296
340
|
- Handles invalid credentials
|
|
341
|
+
- Explains why login is needed now and what downstream work it unlocks
|
|
342
|
+
- Defines outcomes such as response behavior, error handling, and throughput constraints
|
|
297
343
|
```
|
|
298
344
|
|
|
299
345
|
**Bad tasks:**
|
|
300
346
|
```
|
|
301
347
|
Task: Build auth system <- too big
|
|
302
348
|
Task: Add login <- too vague
|
|
349
|
+
Task: Use Redis cache <- prescribes implementation, not outcome
|
|
303
350
|
```
|
|
304
351
|
|
|
305
352
|
## Example Output
|
|
@@ -311,12 +358,27 @@ Task: Add login <- too vague
|
|
|
311
358
|
|
|
312
359
|
User registration and login with JWT tokens.
|
|
313
360
|
|
|
361
|
+
## Risk Assessment
|
|
362
|
+
|
|
363
|
+
- **Unknowns:** Final session expiry requirements and auth provider migration timeline
|
|
364
|
+
- **Integration Points:** Database schema, password hashing, token issuance, API error contracts
|
|
365
|
+
- **Potential Failures:** Duplicate users, weak validation, token leakage, incompatible response shapes
|
|
366
|
+
- **Mitigations:** Lock contracts early, validate edge cases, test failure paths before wiring UI
|
|
367
|
+
|
|
368
|
+
## Decision Log
|
|
369
|
+
|
|
370
|
+
| Decision | Rationale | Alternatives Considered | Consequence |
|
|
371
|
+
|----------|-----------|--------------------------|-------------|
|
|
372
|
+
| Use separate schema and endpoint tasks | Reduces coupling and surfaces auth contract risks early | Single end-to-end auth task | More handoff points, but lower integration risk |
|
|
373
|
+
|
|
314
374
|
## Tasks
|
|
315
375
|
|
|
316
376
|
### Task 1: Create user schema
|
|
317
377
|
|
|
318
378
|
**Goal:** Database schema for users
|
|
319
379
|
|
|
380
|
+
**Strategic Purpose:** Create the source-of-truth user contract first so registration, login, and profile features depend on one stable model instead of diverging assumptions.
|
|
381
|
+
|
|
320
382
|
**Files:**
|
|
321
383
|
- src/db/schema/users.ts
|
|
322
384
|
- src/db/migrations/001_users.sql
|
|
@@ -325,6 +387,7 @@ User registration and login with JWT tokens.
|
|
|
325
387
|
- [ ] Has id, email, passwordHash, createdAt, updatedAt
|
|
326
388
|
- [ ] Email unique constraint
|
|
327
389
|
- [ ] Password hashed with bcrypt
|
|
390
|
+
- [ ] User creation rules are expressed as observable schema outcomes, not storage implementation notes
|
|
328
391
|
|
|
329
392
|
**Test Cases:**
|
|
330
393
|
- Schema accepts valid user data
|
|
@@ -337,6 +400,8 @@ User registration and login with JWT tokens.
|
|
|
337
400
|
|
|
338
401
|
**Goal:** POST /api/auth/register
|
|
339
402
|
|
|
403
|
+
**Strategic Purpose:** Deliver the first externally usable auth capability and validate that schema, validation, and response contracts work together under real request flows.
|
|
404
|
+
|
|
340
405
|
**Files:**
|
|
341
406
|
- src/api/auth/register.ts
|
|
342
407
|
- src/lib/auth/password.ts
|
|
@@ -346,10 +411,20 @@ User registration and login with JWT tokens.
|
|
|
346
411
|
- [ ] Returns user without password
|
|
347
412
|
- [ ] Rejects existing email with 409
|
|
348
413
|
- [ ] Validates email format
|
|
414
|
+
- [ ] Handles invalid and duplicate registration attempts with stable API behavior under concurrent requests
|
|
349
415
|
|
|
350
416
|
**Test Cases:**
|
|
351
417
|
- Register with valid data returns user
|
|
352
418
|
- Register with existing email returns 409
|
|
353
419
|
- Register with invalid email returns 400
|
|
354
420
|
- Password stored as hash
|
|
421
|
+
|
|
422
|
+
## Definition of Done
|
|
423
|
+
|
|
424
|
+
| Dimension | Definition |
|
|
425
|
+
|-----------|------------|
|
|
426
|
+
| Behavior Change | Users can register and authenticate through stable API contracts |
|
|
427
|
+
| Tests | Schema, endpoint, validation, and concurrency-sensitive duplicate-user paths are covered |
|
|
428
|
+
| Failure Modes | Duplicate email, invalid payloads, and password exposure paths are rejected safely |
|
|
429
|
+
| Rollback | Auth routes can be disabled and schema migration reverted with a documented backout path |
|
|
355
430
|
```
|