@educa-corp/sdd-framework 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/build.js +113 -19
- package/bin/gate-trace.js +464 -0
- package/bin/index.js +418 -146
- package/bin/lint-trace.js +602 -0
- package/bin/self-check.js +499 -6
- package/bin/trace-schema.json +1449 -692
- package/commands/debug.md +123 -510
- package/commands/debug.tmpl +3 -0
- package/commands/define-product.md +86 -509
- package/commands/dev-gen-test.md +120 -516
- package/commands/dev-run-test.md +120 -516
- package/commands/dev-smoke-test.md +86 -509
- package/commands/extend-prd.md +486 -0
- package/commands/extend-prd.tmpl +273 -0
- package/commands/fix-bug.md +152 -515
- package/commands/generate-architecture.md +94 -514
- package/commands/generate-architecture.tmpl +3 -0
- package/commands/generate-bdd.md +138 -519
- package/commands/generate-bdd.tmpl +18 -3
- package/commands/generate-code.md +156 -523
- package/commands/generate-code.tmpl +36 -7
- package/commands/generate-design-spec.md +86 -509
- package/commands/generate-prd.md +114 -509
- package/commands/generate-prd.tmpl +28 -0
- package/commands/generate-spec-manifest.md +86 -509
- package/commands/generate-tech-docs.md +86 -509
- package/commands/learn.md +172 -495
- package/commands/learn.tmpl +70 -3
- package/commands/map-testids.md +86 -509
- package/commands/propose-scenario.md +136 -508
- package/commands/propose-scenario.tmpl +52 -1
- package/commands/qc-analyze.md +86 -509
- package/commands/qc-design-test.md +87 -509
- package/commands/qc-design-test.tmpl +1 -0
- package/commands/qc-plan.md +86 -509
- package/commands/qc-report.md +86 -509
- package/commands/qc-review.md +86 -509
- package/commands/qc-run-test.md +133 -517
- package/commands/qc-run-test.tmpl +13 -1
- package/commands/refine-prd.md +99 -519
- package/commands/refine-prd.tmpl +3 -0
- package/commands/report-bug.md +86 -509
- package/commands/review-code.md +127 -513
- package/commands/review-code.tmpl +7 -3
- package/commands/review-context.md +96 -515
- package/commands/review-context.tmpl +6 -2
- package/commands/review-tech-docs.md +90 -510
- package/commands/review-tech-docs.tmpl +3 -0
- package/commands/setup-ai-first.md +166 -137
- package/commands/setup-ai-first.tmpl +72 -0
- package/commands/sync.md +86 -118
- package/commands/sync.tmpl +84 -16
- package/commands/update-framework.md +16 -102
- package/commands/update-framework.tmpl +14 -0
- package/commands/validate-traces.md +458 -531
- package/commands/validate-traces.tmpl +381 -31
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/README.md +20 -0
- package/core/commands/debug.md +123 -510
- package/core/commands/define-product.md +86 -509
- package/core/commands/dev-gen-test.md +120 -516
- package/core/commands/dev-run-test.md +120 -516
- package/core/commands/dev-smoke-test.md +86 -509
- package/core/commands/extend-prd.md +486 -0
- package/core/commands/fix-bug.md +152 -515
- package/core/commands/generate-architecture.md +94 -514
- package/core/commands/generate-bdd.md +138 -519
- package/core/commands/generate-code.md +156 -523
- package/core/commands/generate-design-spec.md +86 -509
- package/core/commands/generate-prd.md +114 -509
- package/core/commands/generate-spec-manifest.md +86 -509
- package/core/commands/generate-tech-docs.md +86 -509
- package/core/commands/learn.md +172 -495
- package/core/commands/map-testids.md +86 -509
- package/core/commands/propose-scenario.md +136 -508
- package/core/commands/qc-analyze.md +86 -509
- package/core/commands/qc-design-test.md +87 -509
- package/core/commands/qc-plan.md +86 -509
- package/core/commands/qc-report.md +86 -509
- package/core/commands/qc-review.md +86 -509
- package/core/commands/qc-run-test.md +133 -517
- package/core/commands/refine-prd.md +99 -519
- package/core/commands/report-bug.md +86 -509
- package/core/commands/review-code.md +127 -513
- package/core/commands/review-context.md +96 -515
- package/core/commands/review-tech-docs.md +90 -510
- package/core/commands/setup-ai-first.md +166 -137
- package/core/commands/sync.md +86 -118
- package/core/commands/update-framework.md +16 -102
- package/core/commands/validate-traces.md +458 -531
- package/core/hooks/data-guard.js +174 -83
- package/core/hooks/settings.json +2 -1
- package/core/rules/workflow.md +48 -4
- package/core/steps/capture-lesson.md +34 -1
- package/core/steps/context-loader.md +24 -3
- package/core/steps/gate.md +92 -35
- package/core/steps/report-footer.md +26 -2
- package/core/steps/trace-mirror.md +34 -7
- package/core/templates/README.md +24 -1
- package/core/templates/ci/trace-gate.yml +146 -0
- package/core/templates/feature.template +1 -1
- package/core/templates/hooks/pre-push +61 -0
- package/docs/01-getting-started/installation.md +18 -1
- package/docs/01-getting-started/what-is-sdd.md +4 -2
- package/docs/02-concepts/architecture.md +48 -5
- package/docs/02-concepts/pipeline-steps/02-specification.md +39 -3
- package/docs/02-concepts/pipeline-steps/04-bdd.md +24 -2
- package/docs/02-concepts/pipeline-steps/05-tech-docs.md +18 -1
- package/docs/02-concepts/pipeline-steps/06-code.md +35 -4
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +137 -12
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +59 -3
- package/docs/02-concepts/roles-and-hitl.md +1 -1
- package/docs/02-concepts/traceability.md +183 -117
- package/docs/03-guides/architect.md +63 -0
- package/docs/03-guides/developer.md +20 -4
- package/docs/03-guides/product-owner.md +72 -68
- package/docs/03-guides/tester-qa.md +81 -70
- package/docs/04-reference/commands.md +134 -105
- package/docs/04-reference/configuration.md +146 -94
- package/docs/04-reference/model-selection.md +32 -19
- package/docs/04-reference/trace-schema.md +26 -9
- package/docs/explain/02-generate-prd.md +80 -78
- package/docs/explain/02b-extend-prd.md +125 -0
- package/docs/explain/03-refine-prd.md +86 -86
- package/docs/explain/04-review-context.md +18 -1
- package/docs/explain/06-generate-bdd.md +23 -0
- package/docs/explain/08-review-tech-docs.md +20 -5
- package/docs/explain/10-review-code.md +36 -2
- package/docs/explain/19-qc-run-test.md +87 -67
- package/docs/explain/21-validate-traces.md +75 -68
- package/docs/explain/23-fix-bug.md +19 -3
- package/docs/explain/26-propose-scenario.md +70 -63
- package/docs/explain/27-learn.md +5 -3
- package/docs/explain/README.md +135 -134
- package/hooks/data-guard.js +174 -83
- package/hooks/settings.json +2 -1
- package/package.json +53 -50
- package/rules/workflow.md +48 -4
- package/steps/capture-lesson.md +34 -1
- package/steps/context-loader.md +24 -3
- package/steps/gate.md +92 -35
- package/steps/report-footer.md +26 -2
- package/steps/trace-mirror.md +34 -7
- package/templates/README.md +24 -1
- package/templates/ci/trace-gate.yml +146 -0
- package/templates/feature.template +1 -1
- package/templates/hooks/pre-push +61 -0
- package/scripts/init.sh +0 -49
- package/scripts/upgrade.sh +0 -94
package/bin/trace-schema.json
CHANGED
|
@@ -1,692 +1,1449 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$comment": [
|
|
3
|
-
"NGUỒN-SỰ-THẬT MÁY ĐỌC cho contract trace của framework. bin/self-check.js đối chiếu",
|
|
4
|
-
"file này với commands/*.tmpl + steps/*.md mỗi lần `npm run build`, và FAIL build khi lệch.",
|
|
5
|
-
"",
|
|
6
|
-
"Vì sao tồn tại: 19/23 GAP trong GAPS.md là cùng một lỗi — contract được phát biểu lại",
|
|
7
|
-
"bằng prose ở nhiều lệnh rồi lệch nhau qua từng lần sửa. Ca thuần khiết nhất là",
|
|
8
|
-
"@trace.sc_version: 3 consumer, 0 producer, tồn tại qua nhiều version mà không lệnh nào,",
|
|
9
|
-
"không cổng nào, không test nào phát hiện. Rule R1 dưới đây bắt đúng lớp lỗi đó.",
|
|
10
|
-
"",
|
|
11
|
-
"ĐỔI CONTRACT: sửa file này TRƯỚC, rồi mới sửa lệnh. Build fail nếu lệnh lệch schema.",
|
|
12
|
-
"Bản dành cho người đọc: docs/04-reference/trace-schema.md (giữ đồng bộ với file này).",
|
|
13
|
-
"",
|
|
14
|
-
"Định dạng JSON chứ không YAML vì package.json có ZERO dependency (npx chạy không cần",
|
|
15
|
-
"install) — thêm js-yaml chỉ để đọc một file cấu hình build-time là không đáng."
|
|
16
|
-
],
|
|
17
|
-
"actors": {
|
|
18
|
-
"$comment": "Tên logic → file nguồn. self-check tìm chuỗi field trong các file này.",
|
|
19
|
-
"generate-bdd": "commands/generate-bdd.tmpl",
|
|
20
|
-
"generate-code": "commands/generate-code.tmpl",
|
|
21
|
-
"generate-tech-docs": "commands/generate-tech-docs.tmpl",
|
|
22
|
-
"generate-prd": "commands/generate-prd.tmpl",
|
|
23
|
-
"generate-design-spec": "commands/generate-design-spec.tmpl",
|
|
24
|
-
"review-context": "commands/review-context.tmpl",
|
|
25
|
-
"review-tech-docs": "commands/review-tech-docs.tmpl",
|
|
26
|
-
"review-code": "commands/review-code.tmpl",
|
|
27
|
-
"validate-traces": "commands/validate-traces.tmpl",
|
|
28
|
-
"dev-gen-test": "commands/dev-gen-test.tmpl",
|
|
29
|
-
"dev-run-test": "commands/dev-run-test.tmpl",
|
|
30
|
-
"dev-smoke-test": "commands/dev-smoke-test.tmpl",
|
|
31
|
-
"qc-run-test": "commands/qc-run-test.tmpl",
|
|
32
|
-
"report-bug": "commands/report-bug.tmpl",
|
|
33
|
-
"propose-scenario": "commands/propose-scenario.tmpl",
|
|
34
|
-
"fix-bug": "commands/fix-bug.tmpl",
|
|
35
|
-
"refine-prd": "commands/refine-prd.tmpl",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"
|
|
84
|
-
"review-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
"
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
"
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
"
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
"
|
|
153
|
-
"
|
|
154
|
-
],
|
|
155
|
-
"
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
"
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
"
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
"
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
"
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
"
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
"
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
"
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
"
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
"dev-
|
|
197
|
-
"qc-run-test"
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
"
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
"
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
"
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
"
|
|
230
|
-
"
|
|
231
|
-
"
|
|
232
|
-
"review-tech-docs"
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
"
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
"
|
|
300
|
-
"
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
"
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
"
|
|
317
|
-
|
|
318
|
-
]
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
"
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
"
|
|
327
|
-
"
|
|
328
|
-
]
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
"
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
"name": "
|
|
346
|
-
"
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
"name": "
|
|
357
|
-
"
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
"
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
"
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
"
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
"
|
|
397
|
-
],
|
|
398
|
-
"read_by": [
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
"
|
|
405
|
-
"
|
|
406
|
-
"
|
|
407
|
-
|
|
408
|
-
"generate-
|
|
409
|
-
"
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
"
|
|
414
|
-
]
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
"
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
"
|
|
423
|
-
|
|
424
|
-
"
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
"
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
"
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
"
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
"
|
|
440
|
-
]
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
"
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
"
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
"
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
"
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
"
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
"
|
|
466
|
-
]
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
"
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
"
|
|
475
|
-
|
|
476
|
-
"
|
|
477
|
-
]
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
"
|
|
499
|
-
"generate-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
"
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
"
|
|
509
|
-
|
|
510
|
-
"
|
|
511
|
-
"
|
|
512
|
-
]
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
"
|
|
531
|
-
"
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
"
|
|
540
|
-
"
|
|
541
|
-
"written_by": [
|
|
542
|
-
"generate-
|
|
543
|
-
"
|
|
544
|
-
],
|
|
545
|
-
"read_by": [
|
|
546
|
-
"
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
"
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
"
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
},
|
|
563
|
-
{
|
|
564
|
-
"
|
|
565
|
-
"
|
|
566
|
-
"
|
|
567
|
-
|
|
568
|
-
"generate-code"
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
"
|
|
572
|
-
"review-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
"
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
"
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
"
|
|
598
|
-
]
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
"
|
|
609
|
-
"
|
|
610
|
-
"
|
|
611
|
-
],
|
|
612
|
-
"
|
|
613
|
-
},
|
|
614
|
-
|
|
615
|
-
"
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
"
|
|
623
|
-
"
|
|
624
|
-
"
|
|
625
|
-
"
|
|
626
|
-
"
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
"
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
"
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
"
|
|
651
|
-
"
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
"
|
|
657
|
-
"
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
},
|
|
671
|
-
{
|
|
672
|
-
"
|
|
673
|
-
"
|
|
674
|
-
"
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
"
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
},
|
|
681
|
-
{
|
|
682
|
-
"
|
|
683
|
-
"
|
|
684
|
-
"
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
"
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
1
|
+
{
|
|
2
|
+
"$comment": [
|
|
3
|
+
"NGUỒN-SỰ-THẬT MÁY ĐỌC cho contract trace của framework. bin/self-check.js đối chiếu",
|
|
4
|
+
"file này với commands/*.tmpl + steps/*.md mỗi lần `npm run build`, và FAIL build khi lệch.",
|
|
5
|
+
"",
|
|
6
|
+
"Vì sao tồn tại: 19/23 GAP trong GAPS.md là cùng một lỗi — contract được phát biểu lại",
|
|
7
|
+
"bằng prose ở nhiều lệnh rồi lệch nhau qua từng lần sửa. Ca thuần khiết nhất là",
|
|
8
|
+
"@trace.sc_version: 3 consumer, 0 producer, tồn tại qua nhiều version mà không lệnh nào,",
|
|
9
|
+
"không cổng nào, không test nào phát hiện. Rule R1 dưới đây bắt đúng lớp lỗi đó.",
|
|
10
|
+
"",
|
|
11
|
+
"ĐỔI CONTRACT: sửa file này TRƯỚC, rồi mới sửa lệnh. Build fail nếu lệnh lệch schema.",
|
|
12
|
+
"Bản dành cho người đọc: docs/04-reference/trace-schema.md (giữ đồng bộ với file này).",
|
|
13
|
+
"",
|
|
14
|
+
"Định dạng JSON chứ không YAML vì package.json có ZERO dependency (npx chạy không cần",
|
|
15
|
+
"install) — thêm js-yaml chỉ để đọc một file cấu hình build-time là không đáng."
|
|
16
|
+
],
|
|
17
|
+
"actors": {
|
|
18
|
+
"$comment": "Tên logic → file nguồn. self-check tìm chuỗi field trong các file này.",
|
|
19
|
+
"generate-bdd": "commands/generate-bdd.tmpl",
|
|
20
|
+
"generate-code": "commands/generate-code.tmpl",
|
|
21
|
+
"generate-tech-docs": "commands/generate-tech-docs.tmpl",
|
|
22
|
+
"generate-prd": "commands/generate-prd.tmpl",
|
|
23
|
+
"generate-design-spec": "commands/generate-design-spec.tmpl",
|
|
24
|
+
"review-context": "commands/review-context.tmpl",
|
|
25
|
+
"review-tech-docs": "commands/review-tech-docs.tmpl",
|
|
26
|
+
"review-code": "commands/review-code.tmpl",
|
|
27
|
+
"validate-traces": "commands/validate-traces.tmpl",
|
|
28
|
+
"dev-gen-test": "commands/dev-gen-test.tmpl",
|
|
29
|
+
"dev-run-test": "commands/dev-run-test.tmpl",
|
|
30
|
+
"dev-smoke-test": "commands/dev-smoke-test.tmpl",
|
|
31
|
+
"qc-run-test": "commands/qc-run-test.tmpl",
|
|
32
|
+
"report-bug": "commands/report-bug.tmpl",
|
|
33
|
+
"propose-scenario": "commands/propose-scenario.tmpl",
|
|
34
|
+
"fix-bug": "commands/fix-bug.tmpl",
|
|
35
|
+
"refine-prd": "commands/refine-prd.tmpl",
|
|
36
|
+
"extend-prd": "commands/extend-prd.tmpl",
|
|
37
|
+
"sync": "commands/sync.tmpl",
|
|
38
|
+
"setup-ai-first": "commands/setup-ai-first.tmpl",
|
|
39
|
+
"generate-spec-manifest": "commands/generate-spec-manifest.tmpl",
|
|
40
|
+
"qc-analyze": "commands/qc-analyze.tmpl",
|
|
41
|
+
"qc-design-test": "commands/qc-design-test.tmpl",
|
|
42
|
+
"map-testids": "commands/map-testids.tmpl",
|
|
43
|
+
"debug": "commands/debug.tmpl",
|
|
44
|
+
"design-spec-template": "templates/design-spec.template.md",
|
|
45
|
+
"context-loader": "steps/context-loader.md",
|
|
46
|
+
"gate": "steps/gate.md",
|
|
47
|
+
"report-footer": "steps/report-footer.md",
|
|
48
|
+
"feature-template": "templates/feature.template",
|
|
49
|
+
"prd-template": "templates/prd.template.md",
|
|
50
|
+
"tech-design-template": "templates/tech-design.template.md"
|
|
51
|
+
},
|
|
52
|
+
"tags": [
|
|
53
|
+
{
|
|
54
|
+
"name": "@trace.sc_version",
|
|
55
|
+
"artifact": ".feature",
|
|
56
|
+
"scope": "scenario",
|
|
57
|
+
"shape": "semver-lite (1.0, 1.1)",
|
|
58
|
+
"written_by": [
|
|
59
|
+
"generate-bdd",
|
|
60
|
+
"feature-template"
|
|
61
|
+
],
|
|
62
|
+
"bumped_by": [
|
|
63
|
+
"generate-bdd",
|
|
64
|
+
"review-context"
|
|
65
|
+
],
|
|
66
|
+
"read_by": [
|
|
67
|
+
"generate-bdd",
|
|
68
|
+
"validate-traces",
|
|
69
|
+
"review-context"
|
|
70
|
+
],
|
|
71
|
+
"why": "Tín hiệu DUY NHẤT cho DRIFT (spec_ver != gen_ver). Không có producer = DRIFT chết."
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "@trace.bdd_version",
|
|
75
|
+
"artifact": ".feature",
|
|
76
|
+
"scope": "file",
|
|
77
|
+
"shape": "semver-lite scalar",
|
|
78
|
+
"written_by": [
|
|
79
|
+
"generate-bdd",
|
|
80
|
+
"feature-template"
|
|
81
|
+
],
|
|
82
|
+
"bumped_by": [
|
|
83
|
+
"generate-bdd",
|
|
84
|
+
"review-context"
|
|
85
|
+
],
|
|
86
|
+
"read_by": [
|
|
87
|
+
"generate-bdd",
|
|
88
|
+
"generate-code",
|
|
89
|
+
"generate-tech-docs",
|
|
90
|
+
"validate-traces",
|
|
91
|
+
"review-tech-docs",
|
|
92
|
+
"review-context"
|
|
93
|
+
],
|
|
94
|
+
"why": "Drift cấp file (Background/dataset/business-definition) mà sc_version không thấy."
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "@trace.bdd_versions",
|
|
98
|
+
"artifact": "tech-design.md",
|
|
99
|
+
"scope": "file",
|
|
100
|
+
"shape": "map theo platform (system=1.5, web=1.9)",
|
|
101
|
+
"written_by": [
|
|
102
|
+
"generate-tech-docs",
|
|
103
|
+
"tech-design-template"
|
|
104
|
+
],
|
|
105
|
+
"read_by": [
|
|
106
|
+
"generate-code",
|
|
107
|
+
"validate-traces",
|
|
108
|
+
"review-tech-docs"
|
|
109
|
+
],
|
|
110
|
+
"why": "Số NHIỀU, cố ý khác @trace.bdd_version (scalar) — cùng tên cho hai kiểu dữ liệu làm vỡ parser generic."
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"name": "@trace.platform",
|
|
114
|
+
"artifact": ".feature",
|
|
115
|
+
"scope": "file",
|
|
116
|
+
"required": "always",
|
|
117
|
+
"values_from": "platform",
|
|
118
|
+
"written_by": [
|
|
119
|
+
"generate-bdd",
|
|
120
|
+
"feature-template"
|
|
121
|
+
],
|
|
122
|
+
"read_by": [
|
|
123
|
+
"generate-code",
|
|
124
|
+
"generate-tech-docs",
|
|
125
|
+
"review-context",
|
|
126
|
+
"context-loader"
|
|
127
|
+
],
|
|
128
|
+
"why": "Quyết BE/FE ở generate-code (cấm fallback platform_type) + tên sổ trace + lookup design-spec. Lưu ý: validate-traces và report-bug KHÔNG đọc tag này — chúng suy platform từ TÊN FILE .tsv ({UC-ID}-{platform}.tsv), nên không phải consumer của tag."
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "@trace.prd_version",
|
|
132
|
+
"artifact": ".feature + code",
|
|
133
|
+
"scope": "file + method",
|
|
134
|
+
"written_by": [
|
|
135
|
+
"generate-bdd",
|
|
136
|
+
"generate-code",
|
|
137
|
+
"feature-template"
|
|
138
|
+
],
|
|
139
|
+
"read_by": [
|
|
140
|
+
"generate-bdd",
|
|
141
|
+
"validate-traces",
|
|
142
|
+
"review-context"
|
|
143
|
+
],
|
|
144
|
+
"why": "Nguồn của PRD_DRIFT (validate-traces Step 4 so 3 tầng: PRD file, TSV, tag trong code)."
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"name": "@trace.implements",
|
|
148
|
+
"artifact": "code",
|
|
149
|
+
"scope": "method",
|
|
150
|
+
"shape": "{UC-ID}-SC{N}",
|
|
151
|
+
"written_by": [
|
|
152
|
+
"generate-code",
|
|
153
|
+
"setup-ai-first"
|
|
154
|
+
],
|
|
155
|
+
"read_by": [
|
|
156
|
+
"validate-traces",
|
|
157
|
+
"review-code",
|
|
158
|
+
"dev-gen-test",
|
|
159
|
+
"dev-smoke-test",
|
|
160
|
+
"fix-bug"
|
|
161
|
+
],
|
|
162
|
+
"why": "Khoá chính của trace ở tầng code. Tra bằng khớp chuỗi CHÍNH XÁC → cấm trỏ thư mục."
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"name": "@trace.source",
|
|
166
|
+
"artifact": "code",
|
|
167
|
+
"scope": "method",
|
|
168
|
+
"shape": "{specs_dir}/{domain}/{prd-slug}/bdd/{platform}/{UC-ID}-{slug}.feature",
|
|
169
|
+
"written_by": [
|
|
170
|
+
"generate-code",
|
|
171
|
+
"setup-ai-first"
|
|
172
|
+
],
|
|
173
|
+
"read_by": [
|
|
174
|
+
"review-code"
|
|
175
|
+
],
|
|
176
|
+
"why": "Con trỏ ngược về spec. PHẢI gồm segment {platform}."
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "@trace.tech_doc_revision",
|
|
180
|
+
"artifact": "code",
|
|
181
|
+
"scope": "method",
|
|
182
|
+
"written_by": [
|
|
183
|
+
"generate-code"
|
|
184
|
+
],
|
|
185
|
+
"read_by": [
|
|
186
|
+
"review-code"
|
|
187
|
+
],
|
|
188
|
+
"why": "Ghi revision tech-doc mà method này được sinh theo. BẤT ĐỐI XỨNG ĐÃ BIẾT: validate-traces Step 5 tính TECHDOC_DRIFT từ cột TSV tech_doc_revision chứ không từ tag này (khác Step 4, có so tag @trace.prd_version trong code). Nên hiện chỉ review-code kiểm sự CÓ MẶT của nó. Muốn đối xứng thì Step 5 phải đọc thêm tag trong code."
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"name": "@trace.verifies",
|
|
192
|
+
"artifact": "test",
|
|
193
|
+
"scope": "method",
|
|
194
|
+
"shape": "{UC-ID}-SC{N}",
|
|
195
|
+
"written_by": [
|
|
196
|
+
"dev-gen-test",
|
|
197
|
+
"qc-run-test",
|
|
198
|
+
"fix-bug"
|
|
199
|
+
],
|
|
200
|
+
"read_by": [
|
|
201
|
+
"validate-traces",
|
|
202
|
+
"review-code",
|
|
203
|
+
"dev-run-test",
|
|
204
|
+
"qc-run-test"
|
|
205
|
+
],
|
|
206
|
+
"why": "Khớp test → sc_id khi ghi test_count/dev_selftest/qc_status."
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"name": "@trace.scenario",
|
|
210
|
+
"artifact": ".feature",
|
|
211
|
+
"scope": "scenario",
|
|
212
|
+
"shape": "{UC-ID}-SC{N}",
|
|
213
|
+
"written_by": [
|
|
214
|
+
"generate-bdd",
|
|
215
|
+
"propose-scenario",
|
|
216
|
+
"feature-template"
|
|
217
|
+
],
|
|
218
|
+
"read_by": [
|
|
219
|
+
"generate-bdd",
|
|
220
|
+
"review-context"
|
|
221
|
+
],
|
|
222
|
+
"why": "Sinh sc_id cho row TSV. Thiếu nó = scenario vô hình với toàn bộ coverage."
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"name": "@trace.status",
|
|
226
|
+
"artifact": ".feature + tech-design.md",
|
|
227
|
+
"scope": "file",
|
|
228
|
+
"values_from": "approval_status",
|
|
229
|
+
"written_by": [
|
|
230
|
+
"feature-template",
|
|
231
|
+
"review-context",
|
|
232
|
+
"review-tech-docs",
|
|
233
|
+
"generate-tech-docs",
|
|
234
|
+
"tech-design-template"
|
|
235
|
+
],
|
|
236
|
+
"read_by": [
|
|
237
|
+
"generate-code",
|
|
238
|
+
"validate-traces",
|
|
239
|
+
"review-tech-docs"
|
|
240
|
+
],
|
|
241
|
+
"why": "Cổng duyệt: DS1 của generate-code, và uc_status sync từ đây."
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"name": "@trace.revision",
|
|
245
|
+
"artifact": "tech-design.md",
|
|
246
|
+
"scope": "file",
|
|
247
|
+
"shape": "integer",
|
|
248
|
+
"written_by": [
|
|
249
|
+
"generate-tech-docs",
|
|
250
|
+
"review-tech-docs",
|
|
251
|
+
"tech-design-template"
|
|
252
|
+
],
|
|
253
|
+
"read_by": [
|
|
254
|
+
"generate-code",
|
|
255
|
+
"validate-traces"
|
|
256
|
+
],
|
|
257
|
+
"why": "Nguồn của tech_doc_revision + TECHDOC_DRIFT."
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"name": "@trace.api_source",
|
|
261
|
+
"artifact": ".feature + tech-design.md",
|
|
262
|
+
"scope": "file",
|
|
263
|
+
"written_by": [
|
|
264
|
+
"generate-bdd",
|
|
265
|
+
"tech-design-template"
|
|
266
|
+
],
|
|
267
|
+
"read_by": [
|
|
268
|
+
"review-tech-docs",
|
|
269
|
+
"review-context"
|
|
270
|
+
],
|
|
271
|
+
"why": "existing → bỏ cổng T7 + skip System BDD Synthesis S1-S3."
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"name": "@trace.stub",
|
|
275
|
+
"artifact": "code",
|
|
276
|
+
"scope": "method",
|
|
277
|
+
"written_by": [
|
|
278
|
+
"generate-code"
|
|
279
|
+
],
|
|
280
|
+
"read_by": [
|
|
281
|
+
"validate-traces",
|
|
282
|
+
"review-code"
|
|
283
|
+
],
|
|
284
|
+
"why": "Method trắng nội-feature. Nguồn của STUB_UNRESOLVED."
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"name": "@trace.mock_for",
|
|
288
|
+
"artifact": "code",
|
|
289
|
+
"scope": "class",
|
|
290
|
+
"written_by": [
|
|
291
|
+
"generate-code"
|
|
292
|
+
],
|
|
293
|
+
"read_by": [
|
|
294
|
+
"generate-code"
|
|
295
|
+
],
|
|
296
|
+
"why": "Đánh dấu layer mock của FE `--phase=ui` thuộc UC nào. `--phase=integration` dò lại chính tag này để biết mock nào phải thay bằng adapter thật — vừa ghi vừa đọc bởi cùng lệnh ở HAI phase khác nhau, đó là đúng."
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"name": "@trace.mock_source",
|
|
300
|
+
"artifact": "code",
|
|
301
|
+
"scope": "class",
|
|
302
|
+
"values": "contract | system-bdd",
|
|
303
|
+
"written_by": [
|
|
304
|
+
"generate-code"
|
|
305
|
+
],
|
|
306
|
+
"read_by": [
|
|
307
|
+
"generate-code"
|
|
308
|
+
],
|
|
309
|
+
"why": "Shape của mock suy từ đâu. `system-bdd` = infer từ behavior (KHÔNG phải full request/response shape) → phase integration phải dự kiến điều chỉnh; `contract` = lấy từ §4 tech-doc, khớp sẵn."
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"name": "@trace.system_bdd",
|
|
313
|
+
"artifact": "code",
|
|
314
|
+
"scope": "class",
|
|
315
|
+
"written_by": [
|
|
316
|
+
"generate-code"
|
|
317
|
+
],
|
|
318
|
+
"read_by": [],
|
|
319
|
+
"allow_no_reader": "Con trỏ tới System BDD mà mock được dựng theo. Nhãn truy vết cho người đọc + reviewer; không có consumer tự động (phase integration route bằng @trace.mock_for/@trace.mock_source).",
|
|
320
|
+
"why": "Ghi mock này dựng theo file System BDD nào."
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"name": "@trace.be_contract",
|
|
324
|
+
"artifact": "code",
|
|
325
|
+
"scope": "class",
|
|
326
|
+
"written_by": [
|
|
327
|
+
"generate-code"
|
|
328
|
+
],
|
|
329
|
+
"read_by": [],
|
|
330
|
+
"allow_no_reader": "CHỈ có khi mock_source=contract — ghi tech-doc nào cấp shape. Nhãn truy vết, không có consumer tự động.",
|
|
331
|
+
"why": "Con trỏ tới tech-doc cấp shape cho mock."
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"name": "@trace.root_cause",
|
|
335
|
+
"artifact": "code",
|
|
336
|
+
"scope": "method",
|
|
337
|
+
"written_by": [
|
|
338
|
+
"fix-bug"
|
|
339
|
+
],
|
|
340
|
+
"read_by": [],
|
|
341
|
+
"allow_no_reader": "Nhãn cho người đọc code — mô tả ngắn nguyên nhân gốc của bug đã fix. Cùng nhóm với @trace.fixes.",
|
|
342
|
+
"why": "Ghi lại nguyên nhân gốc tại chỗ sửa."
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"name": "@trace.regression",
|
|
346
|
+
"artifact": "test",
|
|
347
|
+
"scope": "method",
|
|
348
|
+
"written_by": [
|
|
349
|
+
"fix-bug"
|
|
350
|
+
],
|
|
351
|
+
"read_by": [],
|
|
352
|
+
"allow_no_reader": "Đánh dấu test hồi quy sinh kèm bản fix. Nhãn cho người đọc; test_count/test_classes trong TSV mới là đường máy đọc (G7).",
|
|
353
|
+
"why": "Nhận diện test hồi quy của một ticket."
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"name": "@trace.title",
|
|
357
|
+
"artifact": ".feature",
|
|
358
|
+
"scope": "file",
|
|
359
|
+
"written_by": [
|
|
360
|
+
"feature-template"
|
|
361
|
+
],
|
|
362
|
+
"read_by": [
|
|
363
|
+
"review-context"
|
|
364
|
+
],
|
|
365
|
+
"why": "Tên feature dạng người đọc. review-context B5 Nhóm B chỉ kiểm CÓ MẶT, không kiểm giá trị."
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"name": "@trace.author",
|
|
369
|
+
"artifact": ".feature",
|
|
370
|
+
"scope": "file",
|
|
371
|
+
"written_by": [
|
|
372
|
+
"feature-template"
|
|
373
|
+
],
|
|
374
|
+
"read_by": [
|
|
375
|
+
"review-context"
|
|
376
|
+
],
|
|
377
|
+
"why": "Nguồn gốc file (`AI-generated`). Chỉ kiểm có mặt — xem @trace.title."
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"name": "@trace.created_at",
|
|
381
|
+
"artifact": ".feature",
|
|
382
|
+
"scope": "file",
|
|
383
|
+
"written_by": [
|
|
384
|
+
"feature-template"
|
|
385
|
+
],
|
|
386
|
+
"read_by": [
|
|
387
|
+
"review-context"
|
|
388
|
+
],
|
|
389
|
+
"why": "Ngày tạo file. Chỉ kiểm có mặt — xem @trace.title. KHÁC last_updated của TSV (cái đó là trạng thái, cái này là gốc)."
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
"name": "@trace.generated_at",
|
|
393
|
+
"artifact": "tech-design.md",
|
|
394
|
+
"scope": "file",
|
|
395
|
+
"written_by": [
|
|
396
|
+
"tech-design-template"
|
|
397
|
+
],
|
|
398
|
+
"read_by": [],
|
|
399
|
+
"allow_no_reader": "Ngày sinh tech-doc. Drift của tech-doc đo bằng @trace.revision (integer), KHÔNG bằng ngày — nên field này thuần thông tin cho người đọc.",
|
|
400
|
+
"why": "Ngày sinh tech-doc, dạng người đọc."
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"name": "@trace.business_rules",
|
|
404
|
+
"artifact": ".feature",
|
|
405
|
+
"scope": "scenario",
|
|
406
|
+
"shape": "{TICKET-ID}-UC{N}-BR{m}, …",
|
|
407
|
+
"written_by": [
|
|
408
|
+
"generate-bdd",
|
|
409
|
+
"feature-template",
|
|
410
|
+
"propose-scenario"
|
|
411
|
+
],
|
|
412
|
+
"read_by": [
|
|
413
|
+
"review-context"
|
|
414
|
+
],
|
|
415
|
+
"$reader_note": "generate-tech-docs đọc BR ID từ THÂN scenario (`BR{m}`), không đọc tag này — nên nó không phải consumer.",
|
|
416
|
+
"why": "Link scenario ↔ Business Rule của PRD. BR đánh số LIÊN TỤC toàn PRD (không reset theo UC — G14), nên ID ở đây phải lấy NGUYÊN từ PRD §3. Mở cột bảng BR trên PRD đã có BDD sẽ làm churn ID và phá link này."
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
"name": "@trace.dataset",
|
|
420
|
+
"artifact": ".feature",
|
|
421
|
+
"scope": "file",
|
|
422
|
+
"$producer_note": "CHỈ feature-template — nó được {{include}} nướng cứng vào generate-bdd lúc build, nên generate-bdd không nhắc tên field này ở prose của chính nó. Khai thêm generate-bdd sẽ làm R3 fail.",
|
|
423
|
+
"written_by": [
|
|
424
|
+
"feature-template"
|
|
425
|
+
],
|
|
426
|
+
"read_by": [
|
|
427
|
+
"review-context",
|
|
428
|
+
"validate-traces"
|
|
429
|
+
],
|
|
430
|
+
"why": "File testdata dùng chung của feature. Đổi nó là thay đổi CẤP FILE mà sc_version không thấy — chính vì vậy Step 5c liệt nó vào nguồn của BDD_DRIFT."
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"name": "@trace.prd",
|
|
434
|
+
"artifact": ".feature",
|
|
435
|
+
"scope": "file",
|
|
436
|
+
"shape": "{TICKET-ID}",
|
|
437
|
+
"$producer_note": "CHỈ feature-template — xem @trace.dataset.",
|
|
438
|
+
"written_by": [
|
|
439
|
+
"feature-template"
|
|
440
|
+
],
|
|
441
|
+
"read_by": [
|
|
442
|
+
"review-context"
|
|
443
|
+
],
|
|
444
|
+
"why": "Con trỏ ngược .feature → PRD. Mang TICKET-ID chứ không phải path, vì tech-doc và trace cũng khoá theo TICKET-ID."
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"name": "@trace.platforms",
|
|
448
|
+
"artifact": "tech-design.md",
|
|
449
|
+
"scope": "file",
|
|
450
|
+
"shape": "danh sách platform",
|
|
451
|
+
"written_by": [
|
|
452
|
+
"generate-tech-docs",
|
|
453
|
+
"tech-design-template"
|
|
454
|
+
],
|
|
455
|
+
"read_by": [
|
|
456
|
+
"review-tech-docs"
|
|
457
|
+
],
|
|
458
|
+
"why": "Số NHIỀU, cố ý khác @trace.platform (scalar, ở .feature) — cùng lý do như bdd_version vs bdd_versions (G15): tech-doc là doc GỘP phủ nhiều platform."
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
"name": "@trace.test_type",
|
|
462
|
+
"artifact": "test",
|
|
463
|
+
"scope": "method",
|
|
464
|
+
"written_by": [
|
|
465
|
+
"dev-gen-test"
|
|
466
|
+
],
|
|
467
|
+
"read_by": [],
|
|
468
|
+
"allow_no_reader": "NHÃN CHẾT — phát hiện khi khai schema (G30 lô 3). /dev-gen-test dán nó lên mọi test class nhưng KHÔNG lệnh nào đọc: dev-run-test chạy theo test_command của project, qc-* dùng stack riêng. Giữ vì nó là nhãn hữu ích cho người đọc code và là chỗ móc sẵn nếu sau này muốn chạy test theo loại (vd chỉ chạy unit ở pre-commit). Nếu 6 tháng nữa vẫn không consumer nào → bỏ hẳn thay vì để nợ.",
|
|
469
|
+
"why": "Phân loại test (unit/integration/e2e…). Hiện chỉ là nhãn cho người đọc."
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"name": "@trace.testid_attr",
|
|
473
|
+
"artifact": "tech-design.md",
|
|
474
|
+
"scope": "file",
|
|
475
|
+
"written_by": [
|
|
476
|
+
"map-testids"
|
|
477
|
+
],
|
|
478
|
+
"read_by": [
|
|
479
|
+
"generate-code",
|
|
480
|
+
"qc-run-test",
|
|
481
|
+
"qc-design-test"
|
|
482
|
+
],
|
|
483
|
+
"$history_note": "G30 lô 3 phát hiện field này TỰ MÔ TẢ là contract FE↔QC nhưng chỉ nửa FE (generate-code) đọc — QC tự suy tên thuộc tính từ platform. G37 nối nửa QC: qc-run-test đọc để CẤU HÌNH test-id attribute (Playwright get_by_test_id mặc định dò `data-testid`; dự án dùng `data-test`/`data-qa` sẽ trượt 100% locator nếu không set), qc-design-test ghi lại vào metadata .Test.md để reviewer đối chiếu.",
|
|
484
|
+
"why": "Tên thuộc tính test-id của stack — contract FE↔QC. FE emit theo nó (generate-code), QC cấu hình locator theo nó (qc-run-test). Suy từ platform thay vì đọc field = phát biểu lại sự thật đã ghi ở nơi khác, và hỏng IM LẶNG: test fail 'element not found' trông y hệt bug sản phẩm."
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"name": "@trace.domain",
|
|
488
|
+
"artifact": ".feature + tech-design.md",
|
|
489
|
+
"scope": "file",
|
|
490
|
+
"written_by": [
|
|
491
|
+
"generate-bdd",
|
|
492
|
+
"feature-template",
|
|
493
|
+
"tech-design-template"
|
|
494
|
+
],
|
|
495
|
+
"read_by": [
|
|
496
|
+
"context-loader",
|
|
497
|
+
"review-context",
|
|
498
|
+
"review-tech-docs",
|
|
499
|
+
"generate-spec-manifest",
|
|
500
|
+
"setup-ai-first"
|
|
501
|
+
],
|
|
502
|
+
"why": "Khoá ĐỊNH TUYẾN. context-loader Bước 1.5 đọc nó từ frontmatter target để chọn service submodule — sai là ghi code/trace nhầm repo mà không báo gì."
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
"name": "@trace.id",
|
|
506
|
+
"artifact": ".feature + tech-design.md",
|
|
507
|
+
"scope": "file",
|
|
508
|
+
"shape": "{TICKET-ID}-UC{N}",
|
|
509
|
+
"written_by": [
|
|
510
|
+
"feature-template",
|
|
511
|
+
"tech-design-template"
|
|
512
|
+
],
|
|
513
|
+
"read_by": [
|
|
514
|
+
"generate-code",
|
|
515
|
+
"generate-tech-docs",
|
|
516
|
+
"qc-analyze",
|
|
517
|
+
"review-context"
|
|
518
|
+
],
|
|
519
|
+
"why": "UC-ID của file. generate-code đọc nó để chốt Scope Lock (implement ĐÚNG UC này, không lan sang .feature khác)."
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
"name": "@trace.module",
|
|
523
|
+
"artifact": ".feature + tech-design.md",
|
|
524
|
+
"scope": "file",
|
|
525
|
+
"written_by": [
|
|
526
|
+
"feature-template",
|
|
527
|
+
"tech-design-template"
|
|
528
|
+
],
|
|
529
|
+
"read_by": [
|
|
530
|
+
"dev-gen-test",
|
|
531
|
+
"generate-tech-docs",
|
|
532
|
+
"review-context"
|
|
533
|
+
],
|
|
534
|
+
"why": "Stack module của service sở hữu. dev-gen-test dùng để chọn test pattern. Giá trị `unknown` ở spec repo mode là HỢP LỆ — review-context không được flag."
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"name": "@trace.ucs",
|
|
538
|
+
"artifact": "tech-design.md",
|
|
539
|
+
"scope": "file",
|
|
540
|
+
"shape": "danh sách UC-ID",
|
|
541
|
+
"written_by": [
|
|
542
|
+
"generate-tech-docs",
|
|
543
|
+
"tech-design-template"
|
|
544
|
+
],
|
|
545
|
+
"read_by": [
|
|
546
|
+
"review-tech-docs",
|
|
547
|
+
"gate"
|
|
548
|
+
],
|
|
549
|
+
"why": "Tech-doc là doc GỘP cấp PRD — đây là danh sách UC nó phủ. Cần vì tên file mang {TICKET-ID} chứ không mang {UC-ID} (G10): gate phải tách TICKET-ID rồi glob, và dùng field này để biết doc có phủ UC đang hỏi không."
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
"name": "@trace.seam_port",
|
|
553
|
+
"artifact": "code",
|
|
554
|
+
"scope": "class",
|
|
555
|
+
"written_by": [
|
|
556
|
+
"generate-code"
|
|
557
|
+
],
|
|
558
|
+
"read_by": [
|
|
559
|
+
"review-code"
|
|
560
|
+
],
|
|
561
|
+
"why": "Tên port mà class stub đang giả lập. Đi CẶP với @trace.seam_pending — review-code kiểm cả hai phải có mặt cùng dòng `PENDING` trong _seams.tsv. validate-traces Step 5b nhận diện seam qua @trace.seam_pending + cột `name` của sổ, KHÔNG đọc tag này."
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
"name": "@trace.stub_owner",
|
|
565
|
+
"artifact": "code",
|
|
566
|
+
"scope": "method",
|
|
567
|
+
"written_by": [
|
|
568
|
+
"generate-code"
|
|
569
|
+
],
|
|
570
|
+
"read_by": [
|
|
571
|
+
"validate-traces",
|
|
572
|
+
"review-code"
|
|
573
|
+
],
|
|
574
|
+
"why": "UC lẽ ra phải lấp method trắng này. Step 5b hỏi 'owner đã gen chưa' để quyết STUB_PENDING (ⓘ) vs STUB_UNRESOLVED (🔴 chặn PR). Mất tag = mất luôn phép phân biệt đó → hoặc báo động oan mọi stub, hoặc bỏ sót hàm trắng mồ côi."
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
"name": "@trace.stub_for",
|
|
578
|
+
"artifact": "code",
|
|
579
|
+
"scope": "method",
|
|
580
|
+
"written_by": [
|
|
581
|
+
"generate-code"
|
|
582
|
+
],
|
|
583
|
+
"read_by": [
|
|
584
|
+
"validate-traces",
|
|
585
|
+
"review-code"
|
|
586
|
+
],
|
|
587
|
+
"why": "Trách nhiệm mà method trắng này đang giữ chỗ. Step 5b dùng nó để dò 'có hàm THẬT song song cùng trách nhiệm không' — dấu hiệu Fill-before-create đã trượt (BDD owner đẻ hàm mới thay vì lấp hàm cũ)."
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
"name": "@trace.sign_off",
|
|
591
|
+
"artifact": "tech-design.md",
|
|
592
|
+
"scope": "file",
|
|
593
|
+
"written_by": [
|
|
594
|
+
"review-tech-docs"
|
|
595
|
+
],
|
|
596
|
+
"read_by": [
|
|
597
|
+
"review-tech-docs"
|
|
598
|
+
],
|
|
599
|
+
"why": "Cổng T7 — xác nhận cross-team của tech-doc system BDD. Vừa ghi vừa đọc bởi cùng một lệnh là ĐÚNG (nó là sổ trạng thái nội bộ của cổng đó, không phải contract liên lệnh). LƯU Ý: tech-design.template.md KHÔNG phát ra field này — review-tech-docs tự thêm khi thiếu, nên template không phải producer."
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
"name": "@trace.seam_pending",
|
|
603
|
+
"artifact": "code",
|
|
604
|
+
"scope": "class",
|
|
605
|
+
"written_by": [
|
|
606
|
+
"generate-code"
|
|
607
|
+
],
|
|
608
|
+
"read_by": [
|
|
609
|
+
"validate-traces",
|
|
610
|
+
"review-code"
|
|
611
|
+
],
|
|
612
|
+
"why": "Port cross-UC chưa có hàng thật. Nguồn của SEAM_UNWIRED."
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
"name": "@trace.service",
|
|
616
|
+
"artifact": ".feature",
|
|
617
|
+
"scope": "file",
|
|
618
|
+
"written_by": [
|
|
619
|
+
"generate-bdd",
|
|
620
|
+
"feature-template"
|
|
621
|
+
],
|
|
622
|
+
"read_by": [
|
|
623
|
+
"generate-bdd",
|
|
624
|
+
"dev-gen-test",
|
|
625
|
+
"generate-tech-docs",
|
|
626
|
+
"review-context"
|
|
627
|
+
],
|
|
628
|
+
"why": "Nguồn DUY NHẤT của cột TSV `service` (cột 23) — trace gộp không tách theo service nên thiếu tag này là mất hẳn thông tin sở hữu ở cấp row. BẮT BUỘC mọi mode từ v0.4.3 (trước đó feature.template chủ động bỏ ở spec repo mode, và review-context xếp nó vào Nhóm C có-điều-kiện)."
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
"name": "@trace.design_spec_version",
|
|
632
|
+
"artifact": "code",
|
|
633
|
+
"scope": "method",
|
|
634
|
+
"written_by": [
|
|
635
|
+
"generate-code"
|
|
636
|
+
],
|
|
637
|
+
"read_by": [
|
|
638
|
+
"validate-traces",
|
|
639
|
+
"review-code"
|
|
640
|
+
],
|
|
641
|
+
"why": "Nguồn của DESIGNSPEC_DRIFT (Step 5d). CHỈ FE/App — bỏ hẳn dòng tag với system/backend."
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
"name": "@trace.fixes",
|
|
645
|
+
"artifact": "code",
|
|
646
|
+
"scope": "method",
|
|
647
|
+
"written_by": [
|
|
648
|
+
"fix-bug"
|
|
649
|
+
],
|
|
650
|
+
"read_by": [],
|
|
651
|
+
"allow_no_reader": "Nhãn cho người đọc code, không có consumer tự động."
|
|
652
|
+
}
|
|
653
|
+
],
|
|
654
|
+
"tsv_columns": [
|
|
655
|
+
{
|
|
656
|
+
"n": 1,
|
|
657
|
+
"name": "sc_id",
|
|
658
|
+
"written_by": [
|
|
659
|
+
"generate-bdd"
|
|
660
|
+
],
|
|
661
|
+
"read_by": [
|
|
662
|
+
"validate-traces",
|
|
663
|
+
"generate-code",
|
|
664
|
+
"dev-gen-test",
|
|
665
|
+
"dev-run-test",
|
|
666
|
+
"qc-run-test",
|
|
667
|
+
"report-bug",
|
|
668
|
+
"fix-bug"
|
|
669
|
+
]
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
"n": 2,
|
|
673
|
+
"name": "sc_title",
|
|
674
|
+
"written_by": [
|
|
675
|
+
"generate-bdd"
|
|
676
|
+
],
|
|
677
|
+
"read_by": [
|
|
678
|
+
"validate-traces"
|
|
679
|
+
]
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
"n": 3,
|
|
683
|
+
"name": "spec_ver",
|
|
684
|
+
"written_by": [
|
|
685
|
+
"generate-bdd",
|
|
686
|
+
"validate-traces",
|
|
687
|
+
"review-context"
|
|
688
|
+
],
|
|
689
|
+
"read_by": [
|
|
690
|
+
"validate-traces",
|
|
691
|
+
"generate-code"
|
|
692
|
+
]
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
"n": 4,
|
|
696
|
+
"name": "gen_ver",
|
|
697
|
+
"written_by": [
|
|
698
|
+
"generate-code"
|
|
699
|
+
],
|
|
700
|
+
"read_by": [
|
|
701
|
+
"validate-traces",
|
|
702
|
+
"generate-bdd"
|
|
703
|
+
]
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"n": 5,
|
|
707
|
+
"name": "implemented_by",
|
|
708
|
+
"written_by": [
|
|
709
|
+
"generate-code"
|
|
710
|
+
],
|
|
711
|
+
"read_by": [
|
|
712
|
+
"validate-traces",
|
|
713
|
+
"generate-bdd"
|
|
714
|
+
]
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
"n": 6,
|
|
718
|
+
"name": "test_count",
|
|
719
|
+
"written_by": [
|
|
720
|
+
"dev-gen-test",
|
|
721
|
+
"fix-bug"
|
|
722
|
+
],
|
|
723
|
+
"read_by": [
|
|
724
|
+
"validate-traces",
|
|
725
|
+
"generate-bdd"
|
|
726
|
+
]
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
"n": 7,
|
|
730
|
+
"name": "test_classes",
|
|
731
|
+
"written_by": [
|
|
732
|
+
"dev-gen-test",
|
|
733
|
+
"fix-bug"
|
|
734
|
+
],
|
|
735
|
+
"read_by": [
|
|
736
|
+
"validate-traces",
|
|
737
|
+
"generate-bdd"
|
|
738
|
+
]
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
"n": 8,
|
|
742
|
+
"name": "dev_selftest",
|
|
743
|
+
"$invalidated_by_comment": [
|
|
744
|
+
"PRODUCER vs INVALIDATOR — hai vai khác nhau, cùng nằm trong written_by.",
|
|
745
|
+
"Chủ sở hữu (ghi giá trị KHẲNG ĐỊNH pass/fail): dev-run-test.",
|
|
746
|
+
"Invalidator (chỉ được hạ về not_run/— khi giá trị cũ HẾT ĐÚNG): generate-bdd (spec đổi),",
|
|
747
|
+
"generate-code (lấp stub hoặc sửa method do DRIFT), fix-bug (code đổi), dev-gen-test (test mới).",
|
|
748
|
+
"Luật đầy đủ: rules/workflow.md §Trace Contract — 'Làm mất hiệu lực ≠ ghi đè'.",
|
|
749
|
+
"Vì sao cần: giữ một 'pass' sinh ra từ spec đã bị sửa là BÁO CÁO SAI. Trước G28 chỉ",
|
|
750
|
+
"nhánh lấp-stub hạ cờ, nên chuỗi spec-đổi → DRIFT → regen → OK kết thúc bằng dashboard",
|
|
751
|
+
"xanh hoàn toàn trên một hành vi chưa từng được test."
|
|
752
|
+
],
|
|
753
|
+
"written_by": [
|
|
754
|
+
"dev-run-test",
|
|
755
|
+
"dev-gen-test",
|
|
756
|
+
"generate-code",
|
|
757
|
+
"generate-bdd",
|
|
758
|
+
"fix-bug"
|
|
759
|
+
],
|
|
760
|
+
"read_by": [
|
|
761
|
+
"validate-traces",
|
|
762
|
+
"qc-run-test"
|
|
763
|
+
]
|
|
764
|
+
},
|
|
765
|
+
{
|
|
766
|
+
"n": 9,
|
|
767
|
+
"name": "dev_selftest_at",
|
|
768
|
+
"$comment": "Chủ: dev-run-test. Invalidator (hạ về —): generate-bdd · generate-code · fix-bug. Xem dev_selftest.",
|
|
769
|
+
"written_by": [
|
|
770
|
+
"dev-run-test",
|
|
771
|
+
"generate-code",
|
|
772
|
+
"generate-bdd",
|
|
773
|
+
"fix-bug"
|
|
774
|
+
],
|
|
775
|
+
"read_by": [
|
|
776
|
+
"validate-traces",
|
|
777
|
+
"qc-run-test"
|
|
778
|
+
]
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
"n": 10,
|
|
782
|
+
"name": "qc_status",
|
|
783
|
+
"$comment": "Chủ (ghi pass/fail/skip): qc-run-test — DUY NHẤT. Invalidator (chỉ hạ về not_run khi spec/code vừa đổi): generate-bdd · generate-code. Xem dev_selftest + rules/workflow.md 'Làm mất hiệu lực ≠ ghi đè'.",
|
|
784
|
+
"written_by": [
|
|
785
|
+
"qc-run-test",
|
|
786
|
+
"generate-bdd",
|
|
787
|
+
"generate-code"
|
|
788
|
+
],
|
|
789
|
+
"read_by": [
|
|
790
|
+
"validate-traces",
|
|
791
|
+
"dev-run-test",
|
|
792
|
+
"generate-code",
|
|
793
|
+
"report-bug",
|
|
794
|
+
"fix-bug"
|
|
795
|
+
]
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
"n": 11,
|
|
799
|
+
"name": "qc_run_at",
|
|
800
|
+
"$comment": "Chủ: qc-run-test. Invalidator (hạ về —): generate-bdd · generate-code. Xem qc_status.",
|
|
801
|
+
"written_by": [
|
|
802
|
+
"qc-run-test",
|
|
803
|
+
"generate-bdd",
|
|
804
|
+
"generate-code"
|
|
805
|
+
],
|
|
806
|
+
"read_by": [
|
|
807
|
+
"validate-traces",
|
|
808
|
+
"dev-run-test",
|
|
809
|
+
"generate-code"
|
|
810
|
+
]
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
"n": 12,
|
|
814
|
+
"name": "qc_owner",
|
|
815
|
+
"written_by": [
|
|
816
|
+
"qc-run-test",
|
|
817
|
+
"report-bug"
|
|
818
|
+
],
|
|
819
|
+
"read_by": [
|
|
820
|
+
"validate-traces",
|
|
821
|
+
"generate-code",
|
|
822
|
+
"fix-bug"
|
|
823
|
+
]
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"n": 13,
|
|
827
|
+
"name": "qc_blocked_by",
|
|
828
|
+
"written_by": [
|
|
829
|
+
"qc-run-test",
|
|
830
|
+
"report-bug"
|
|
831
|
+
],
|
|
832
|
+
"read_by": [
|
|
833
|
+
"validate-traces",
|
|
834
|
+
"generate-code",
|
|
835
|
+
"qc-run-test"
|
|
836
|
+
]
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
"n": 14,
|
|
840
|
+
"name": "prd_version",
|
|
841
|
+
"written_by": [
|
|
842
|
+
"generate-bdd"
|
|
843
|
+
],
|
|
844
|
+
"read_by": [
|
|
845
|
+
"validate-traces",
|
|
846
|
+
"generate-code"
|
|
847
|
+
]
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
"n": 15,
|
|
851
|
+
"name": "bdd_version",
|
|
852
|
+
"written_by": [
|
|
853
|
+
"generate-bdd",
|
|
854
|
+
"review-context"
|
|
855
|
+
],
|
|
856
|
+
"read_by": [
|
|
857
|
+
"validate-traces"
|
|
858
|
+
]
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
"n": 16,
|
|
862
|
+
"name": "tech_doc_revision",
|
|
863
|
+
"written_by": [
|
|
864
|
+
"generate-code",
|
|
865
|
+
"review-tech-docs"
|
|
866
|
+
],
|
|
867
|
+
"read_by": [
|
|
868
|
+
"validate-traces",
|
|
869
|
+
"generate-bdd"
|
|
870
|
+
]
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
"n": 17,
|
|
874
|
+
"name": "fe_tech_doc_revision",
|
|
875
|
+
"written_by": [
|
|
876
|
+
"generate-code"
|
|
877
|
+
],
|
|
878
|
+
"read_by": [
|
|
879
|
+
"validate-traces",
|
|
880
|
+
"generate-bdd",
|
|
881
|
+
"review-tech-docs"
|
|
882
|
+
]
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
"n": 18,
|
|
886
|
+
"name": "prd_status",
|
|
887
|
+
"written_by": [
|
|
888
|
+
"generate-bdd",
|
|
889
|
+
"validate-traces"
|
|
890
|
+
],
|
|
891
|
+
"read_by": [
|
|
892
|
+
"validate-traces"
|
|
893
|
+
]
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
"n": 19,
|
|
897
|
+
"name": "uc_status",
|
|
898
|
+
"written_by": [
|
|
899
|
+
"generate-bdd",
|
|
900
|
+
"validate-traces",
|
|
901
|
+
"review-context"
|
|
902
|
+
],
|
|
903
|
+
"read_by": [
|
|
904
|
+
"validate-traces",
|
|
905
|
+
"generate-code"
|
|
906
|
+
]
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
"n": 20,
|
|
910
|
+
"name": "fe_phase",
|
|
911
|
+
"written_by": [
|
|
912
|
+
"generate-code",
|
|
913
|
+
"generate-bdd"
|
|
914
|
+
],
|
|
915
|
+
"read_by": [
|
|
916
|
+
"validate-traces"
|
|
917
|
+
]
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
"n": 21,
|
|
921
|
+
"name": "status",
|
|
922
|
+
"written_by": [
|
|
923
|
+
"validate-traces",
|
|
924
|
+
"generate-bdd"
|
|
925
|
+
],
|
|
926
|
+
"read_by": [
|
|
927
|
+
"validate-traces",
|
|
928
|
+
"generate-code",
|
|
929
|
+
"dev-run-test",
|
|
930
|
+
"qc-run-test"
|
|
931
|
+
]
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
"n": 23,
|
|
935
|
+
"name": "service",
|
|
936
|
+
"$comment": [
|
|
937
|
+
"Đội/submodule sở hữu scenario. Nguồn: @trace.service của header .feature.",
|
|
938
|
+
"VÌ SAO TỒN TẠI (G31): validate-traces Step 0 và trace-mirror.md đều khẳng định trace gộp",
|
|
939
|
+
"'không cần tách theo service vì mỗi row mang @trace.service' — nhưng TSV KHÔNG có cột nào",
|
|
940
|
+
"cho nó và JSON report cũng không. Ở đúng chế độ phổ biến nhất (umbrella + spec_source),",
|
|
941
|
+
"trace hoàn toàn không trả lời được 'scenario này thuộc đội nào' — câu hỏi số MỘT của một",
|
|
942
|
+
"dự án nhiều đội. Nghịch lý: nhánh LEGACY (trace tách theo service) thì CÓ gắn field service",
|
|
943
|
+
"vào JSON; nhánh 'phổ biến' thì không. Cột này làm lời khẳng định kia thành sự thật.",
|
|
944
|
+
"Giá trị: path service | 'multi' (chưa chốt) | 'unresolved' (routing sai) | '—' (single-service)."
|
|
945
|
+
],
|
|
946
|
+
"written_by": [
|
|
947
|
+
"generate-bdd"
|
|
948
|
+
],
|
|
949
|
+
"read_by": [
|
|
950
|
+
"validate-traces"
|
|
951
|
+
]
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
"n": 24,
|
|
955
|
+
"name": "design_spec_version",
|
|
956
|
+
"$comment": [
|
|
957
|
+
"Version design-spec tại thời điểm sinh BDD. Nguồn: | **Version** | của design-spec.",
|
|
958
|
+
"VÌ SAO TỒN TẠI (G32): design-spec điều khiển CẢ BDD FE/App (Screen States + AC-UI) LẪN code",
|
|
959
|
+
"FE (màn hình, component inventory, Figma frame) — nhưng là artifact upstream DUY NHẤT không",
|
|
960
|
+
"có cột TSV, không có tag trong code, không có cờ drift. Nó tự bảo vệ một chiều (reset draft",
|
|
961
|
+
"khi PRD đổi), còn chiều 'designer sửa design-spec SAU KHI BDD/code đã sinh' thì không gì bắt.",
|
|
962
|
+
"GAPS.md G2 mở đầu bằng 'tầng BDD là tầng DUY NHẤT không có cờ drift' — câu đó đúng lúc viết,",
|
|
963
|
+
"vì bảng kiểm kê chỉ tính PRD/BDD/tech-doc/code. Design-spec không nằm trong bảng nên không ai đếm.",
|
|
964
|
+
"'—' cho system/backend và khi sinh BDD mà không có design-spec."
|
|
965
|
+
],
|
|
966
|
+
"written_by": [
|
|
967
|
+
"generate-bdd"
|
|
968
|
+
],
|
|
969
|
+
"read_by": [
|
|
970
|
+
"validate-traces"
|
|
971
|
+
]
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
"n": 22,
|
|
975
|
+
"name": "last_updated",
|
|
976
|
+
"written_by": [
|
|
977
|
+
"generate-bdd",
|
|
978
|
+
"generate-code",
|
|
979
|
+
"dev-gen-test",
|
|
980
|
+
"dev-run-test",
|
|
981
|
+
"qc-run-test",
|
|
982
|
+
"review-context",
|
|
983
|
+
"review-tech-docs",
|
|
984
|
+
"fix-bug"
|
|
985
|
+
],
|
|
986
|
+
"read_by": [
|
|
987
|
+
"validate-traces"
|
|
988
|
+
]
|
|
989
|
+
}
|
|
990
|
+
],
|
|
991
|
+
"aux_tables": [
|
|
992
|
+
{
|
|
993
|
+
"$comment": [
|
|
994
|
+
"Bảng phụ ngoài TSV chính. Nằm ngoài SoT cho tới G30 — dù nó là NGUỒN của hai cờ 🔴",
|
|
995
|
+
"chặn PR (SEAM_UNWIRED, STUB_UNRESOLVED). Đổi tên/thứ tự cột mà không ai bắt được."
|
|
996
|
+
],
|
|
997
|
+
"name": "_seams.tsv",
|
|
998
|
+
"path": "{trace_dir}/{domain}/{prd-slug}/_seams.tsv",
|
|
999
|
+
"columns": [
|
|
1000
|
+
"kind",
|
|
1001
|
+
"name",
|
|
1002
|
+
"consumer_uc",
|
|
1003
|
+
"owner_uc",
|
|
1004
|
+
"artifact",
|
|
1005
|
+
"binding",
|
|
1006
|
+
"status",
|
|
1007
|
+
"last_updated"
|
|
1008
|
+
],
|
|
1009
|
+
"written_by": [
|
|
1010
|
+
"generate-code",
|
|
1011
|
+
"validate-traces"
|
|
1012
|
+
],
|
|
1013
|
+
"read_by": [
|
|
1014
|
+
"validate-traces",
|
|
1015
|
+
"review-code"
|
|
1016
|
+
],
|
|
1017
|
+
"column_actors": [
|
|
1018
|
+
"generate-code",
|
|
1019
|
+
"validate-traces"
|
|
1020
|
+
],
|
|
1021
|
+
"$column_actors_note": "Chỉ hai lệnh này thao tác ở MỨC CỘT (ghi/parse từng field). review-code là consumer ở MỨC BẢNG — nó chỉ kiểm 'có dòng PENDING tương ứng trong sổ không', không đọc tên cột. Tách ra để R3 đừng đòi review-code nhắc đủ 8 tên cột."
|
|
1022
|
+
}
|
|
1023
|
+
],
|
|
1024
|
+
"queues": [
|
|
1025
|
+
{
|
|
1026
|
+
"$comment": [
|
|
1027
|
+
"Hàng đợi feedback từ tester/QC. Khai ở đây để R1 bắt được ca 'hàng đợi mất consumer'",
|
|
1028
|
+
"y như nó bắt field mất producer — đó chính là hình dạng của G26."
|
|
1029
|
+
],
|
|
1030
|
+
"name": "bug-reports",
|
|
1031
|
+
"path_key": "bug_reports_dir",
|
|
1032
|
+
"written_by": [
|
|
1033
|
+
"report-bug"
|
|
1034
|
+
],
|
|
1035
|
+
"read_by": [
|
|
1036
|
+
"fix-bug",
|
|
1037
|
+
"qc-run-test"
|
|
1038
|
+
]
|
|
1039
|
+
},
|
|
1040
|
+
{
|
|
1041
|
+
"name": "bdd-proposals",
|
|
1042
|
+
"path_key": "bdd_proposals_dir",
|
|
1043
|
+
"written_by": [
|
|
1044
|
+
"propose-scenario"
|
|
1045
|
+
],
|
|
1046
|
+
"read_by": [
|
|
1047
|
+
"generate-bdd"
|
|
1048
|
+
]
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
"name": "prd-change-requests",
|
|
1052
|
+
"path_key": "prd_change_requests_dir",
|
|
1053
|
+
"written_by": [
|
|
1054
|
+
"propose-scenario",
|
|
1055
|
+
"extend-prd"
|
|
1056
|
+
],
|
|
1057
|
+
"read_by": [
|
|
1058
|
+
"extend-prd",
|
|
1059
|
+
"validate-traces"
|
|
1060
|
+
],
|
|
1061
|
+
"$roles_note": "extend-prd là consumer DRAIN thật (Bước 2 đọc request accepted làm nguyên liệu; Bước 6.5 đóng dấu incorporated + chuyển sang archived/ + commit) — nên nó vừa read vừa write. validate-traces Step 7b chỉ ĐẾM và nhắc (không drain). G26 đóng đủ 3 phần từ đây."
|
|
1062
|
+
}
|
|
1063
|
+
],
|
|
1064
|
+
"vocabularies": {
|
|
1065
|
+
"$comment": "Mọi giá trị phải xuất hiện ở ít nhất một actor — giá trị chết là dấu hiệu contract lệch.",
|
|
1066
|
+
"$lint_binding_comment": [
|
|
1067
|
+
"BINDING CHO lint-trace (G38). R6 canh 'giá trị có được actor nào DÙNG không' — đó là",
|
|
1068
|
+
"câu hỏi về contract. Nhưng nó không trả lời được 'file .tsv THẬT có tuân enum này không',",
|
|
1069
|
+
"vì không rule nào mở sổ thật ra xem. bin/lint-trace.js làm việc đó, và nó cần biết mỗi",
|
|
1070
|
+
"vocabulary neo vào ĐÂU. Mỗi vocabulary PHẢI khai đúng một trong:",
|
|
1071
|
+
" column → một cột của TSV chính",
|
|
1072
|
+
" columns → nhiều cột của TSV chính",
|
|
1073
|
+
" aux_table + aux_column → một cột của bảng phụ trong aux_tables",
|
|
1074
|
+
" filename_segment → một đoạn trong tên file sổ",
|
|
1075
|
+
" $lint → cố ý ngoài phạm vi lint, PHẢI nêu lý do",
|
|
1076
|
+
"Thiếu tất cả → self-check.js R8a fail build. Đây là van chống lặp lại chính G38:",
|
|
1077
|
+
"thêm vocabulary mới mà quên dạy checker thì build đỏ, không phải 6 tháng sau mới biết."
|
|
1078
|
+
],
|
|
1079
|
+
"trace_status": {
|
|
1080
|
+
"values": [
|
|
1081
|
+
"OK",
|
|
1082
|
+
"DRIFT",
|
|
1083
|
+
"GAP",
|
|
1084
|
+
"UNTRACKED",
|
|
1085
|
+
"ORPHANED"
|
|
1086
|
+
],
|
|
1087
|
+
"column": "status"
|
|
1088
|
+
},
|
|
1089
|
+
"platform": {
|
|
1090
|
+
"values": [
|
|
1091
|
+
"web",
|
|
1092
|
+
"app",
|
|
1093
|
+
"system"
|
|
1094
|
+
],
|
|
1095
|
+
"filename_segment": "{UC-ID}-{platform}.tsv",
|
|
1096
|
+
"$filename_note": "Tên sổ là nơi DUY NHẤT mang platform của row — validate-traces Step 2 lấy platform từ đây để tìm .feature đúng thư mục con. Sổ thiếu đoạn này thì cả sổ vô hình (đúng hình dạng G3/G8)."
|
|
1097
|
+
},
|
|
1098
|
+
"approval_status": {
|
|
1099
|
+
"values": [
|
|
1100
|
+
"draft",
|
|
1101
|
+
"in-review",
|
|
1102
|
+
"approved"
|
|
1103
|
+
],
|
|
1104
|
+
"columns": [
|
|
1105
|
+
"prd_status",
|
|
1106
|
+
"uc_status"
|
|
1107
|
+
]
|
|
1108
|
+
},
|
|
1109
|
+
"fe_phase": {
|
|
1110
|
+
"values": [
|
|
1111
|
+
"ui",
|
|
1112
|
+
"integrated"
|
|
1113
|
+
],
|
|
1114
|
+
"column": "fe_phase"
|
|
1115
|
+
},
|
|
1116
|
+
"dev_selftest_status": {
|
|
1117
|
+
"$comment": [
|
|
1118
|
+
"G49 — hai cột này mang enum nhưng trước đó KHÔNG có vocabulary, nên lint T3 không canh:",
|
|
1119
|
+
"`dev_selftest = passed`, `qc_status = OK`, `qc_status = pending` đều đi qua sạch.",
|
|
1120
|
+
"Mà đây là hai cột của G28 ('cờ nói dối') và là hai cột có NHIỀU NGƯỜI GHI NHẤT trong",
|
|
1121
|
+
"schema — 5 lệnh và 3 lệnh, mỗi lệnh ở một nhánh điều kiện khác nhau, tất cả bằng prose.",
|
|
1122
|
+
"Cột dễ lệch giá trị nhất trong sổ, và là cột duy nhất mang enum mà không được canh.",
|
|
1123
|
+
"",
|
|
1124
|
+
"VÌ SAO SỐNG ĐƯỢC QUA G30: G30 mở phạm vi schema cho TAG (@trace.*). Hai cột này không",
|
|
1125
|
+
"có tag tương ứng — chúng chỉ sống trong TSV. Nên chúng nằm ngoài lăng kính của G30, và",
|
|
1126
|
+
"trước G38 thì không có lăng kính nào soi cột-không-có-tag."
|
|
1127
|
+
],
|
|
1128
|
+
"values": [
|
|
1129
|
+
"pass",
|
|
1130
|
+
"fail",
|
|
1131
|
+
"not_run"
|
|
1132
|
+
],
|
|
1133
|
+
"column": "dev_selftest"
|
|
1134
|
+
},
|
|
1135
|
+
"qc_run_status": {
|
|
1136
|
+
"$comment": "Xem dev_selftest_status. Có thêm `skip` — QC chủ động bỏ qua scenario (khác not_run: chưa chạy).",
|
|
1137
|
+
"values": [
|
|
1138
|
+
"pass",
|
|
1139
|
+
"fail",
|
|
1140
|
+
"skip",
|
|
1141
|
+
"not_run"
|
|
1142
|
+
],
|
|
1143
|
+
"column": "qc_status"
|
|
1144
|
+
},
|
|
1145
|
+
"seam_status": {
|
|
1146
|
+
"values": [
|
|
1147
|
+
"PENDING",
|
|
1148
|
+
"READY",
|
|
1149
|
+
"RESOLVED"
|
|
1150
|
+
],
|
|
1151
|
+
"aux_table": "_seams.tsv",
|
|
1152
|
+
"aux_column": "status"
|
|
1153
|
+
},
|
|
1154
|
+
"audit_flags": {
|
|
1155
|
+
"$lint": "n/a — không sống trong TSV. Cờ audit được tính lúc chạy và sống trong trace-report.json (issues + summary counter); R7 canh đủ ba tầng của chúng. lint-trace chỉ kiểm file trên đĩa, nên không có gì để neo.",
|
|
1156
|
+
"values": [
|
|
1157
|
+
"PRD_DRIFT",
|
|
1158
|
+
"PRD_STALE_REF",
|
|
1159
|
+
"BDD_DRIFT",
|
|
1160
|
+
"TECHDOC_DRIFT",
|
|
1161
|
+
"TECHDOC_STALE_REF",
|
|
1162
|
+
"FE_TECHDOC_DRIFT",
|
|
1163
|
+
"TECHDOC_STALE_VS_BDD",
|
|
1164
|
+
"DESIGNSPEC_DRIFT",
|
|
1165
|
+
"DESIGNSPEC_STALE_VS_BDD",
|
|
1166
|
+
"TRACE_ORPHAN",
|
|
1167
|
+
"SEAM_UNWIRED",
|
|
1168
|
+
"STUB_UNRESOLVED",
|
|
1169
|
+
"SEAM_PENDING",
|
|
1170
|
+
"STUB_PENDING"
|
|
1171
|
+
]
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
"gate": {
|
|
1175
|
+
"$comment": [
|
|
1176
|
+
"CỔNG CHẶN PR (G39). README khai bằng chữ in đậm rằng 4 cờ này 'chặn PR', kèm câu",
|
|
1177
|
+
"'build xanh + test từng-UC xanh KHÔNG phát hiện được' — đó là điểm bán hàng cốt lõi.",
|
|
1178
|
+
"Nhưng trước G39 không có gì chặn: 0 CI, 0 git hook, 0 exit code. /validate-traces in",
|
|
1179
|
+
"một report vào terminal Claude Code, nơi không CI nào đọc được. Kỷ luật là honor-system,",
|
|
1180
|
+
"và cái gì không chặn thì sau sprint thứ ba không ai làm.",
|
|
1181
|
+
"",
|
|
1182
|
+
"bin/gate-trace.js đọc khối này để biết ĐẾM CỜ NÀO — không hard-code. Vì sao quan trọng:",
|
|
1183
|
+
"gate đọc summary[counter]. Nếu counter bị đổi tên mà gate không biết, `undefined > 0`",
|
|
1184
|
+
"là false ⇒ GATE PASS TRÊN CODE HỎNG. Đó là false-green im lặng, đúng hình dạng G1.",
|
|
1185
|
+
"Nên gate PHẢI fail khi counter nó chờ không có mặt trong report, và self-check R9 canh",
|
|
1186
|
+
"cả hai đầu (counter có trong summary của validate-traces · issues_key có trong issues).",
|
|
1187
|
+
"",
|
|
1188
|
+
"Cờ 🟠 (PRD_DRIFT, BDD_DRIFT, TECHDOC_DRIFT, …) CỐ Ý không nằm đây — chúng là 'code chưa",
|
|
1189
|
+
"theo kịp spec', một loại nợ khác, không làm hỏng luồng đang chạy. Chặn PR vì nợ là làm",
|
|
1190
|
+
"cổng bị tắt. Xem README §Traceability."
|
|
1191
|
+
],
|
|
1192
|
+
"report_path": "{trace_dir}/trace-report.json",
|
|
1193
|
+
"config_preconditions": {
|
|
1194
|
+
"$comment": [
|
|
1195
|
+
"TẦNG G0 — 'sổ có ĐƯỢC BẢO VỆ không?', hỏi TRƯỚC cả ba tầng kia.",
|
|
1196
|
+
"",
|
|
1197
|
+
"Vì sao tách khỏi `blocking`: `blocking` có nghĩa hẹp là CODE ĐANG HỎNG (4 cờ 🔴), và",
|
|
1198
|
+
"R9(e) tồn tại để giữ đúng ranh giới đó — nó fail build nếu ai nhét một cờ NỢ (🟠) vào.",
|
|
1199
|
+
"Hai điều kiện dưới đây thuộc loại THỨ BA: chưa có gì sai, nhưng LƯỚI AN TOÀN ĐANG TẮT.",
|
|
1200
|
+
"Ví như: động cơ hỏng (🔴) · đến hạn thay dầu (🟠) · CHƯA CÀI DÂY AN TOÀN (G0).",
|
|
1201
|
+
"Trộn chúng vào `blocking` là làm mờ chính ranh giới R9(e) bảo vệ.",
|
|
1202
|
+
"",
|
|
1203
|
+
"Vì sao hỏi TRƯỚC: G1 kiểm rất kỹ cấu trúc của một quyển sổ mà có thể KHÔNG NẰM TRONG",
|
|
1204
|
+
"GIT. Kiểm cấu trúc của thứ sắp mất thì vô nghĩa.",
|
|
1205
|
+
"",
|
|
1206
|
+
"Cách hoạt động: cả hai điều kiện đã được `bin/lint-trace.js` phát hiện dưới dạng WARN.",
|
|
1207
|
+
"gate NÂNG chúng thành lỗi chặn. Một implementation, hai mức nghiêm trọng — cố ý:",
|
|
1208
|
+
" pre-push (lint) → NHẮC. Chặn push vì một dòng cấu hình sẽ dạy dev gõ --no-verify,",
|
|
1209
|
+
" và mất luôn phần lint THẬT (sổ hỏng cấu trúc).",
|
|
1210
|
+
" CI (gate) → CHẶN. Đây là chỗ đúng để chặn.",
|
|
1211
|
+
"Cùng cách phân vai G39 đã chọn cho pre-push vs CI."
|
|
1212
|
+
],
|
|
1213
|
+
"promote_lint_rules": [
|
|
1214
|
+
{
|
|
1215
|
+
"rule": "T11",
|
|
1216
|
+
"why": "sổ trace đang bị gitignore — nó KHÔNG được lưu vào git, mất là mất toàn bộ (G29)"
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
"rule": "T10",
|
|
1220
|
+
"why": "sổ thiếu luật merge — hai nhánh cùng ghi sẽ mất row của nhau, im lặng (G40)"
|
|
1221
|
+
}
|
|
1222
|
+
]
|
|
1223
|
+
},
|
|
1224
|
+
"checkpoint_levels": {
|
|
1225
|
+
"$comment": [
|
|
1226
|
+
"MỨC CHẶN CHECKPOINT CỦA TỪNG LỆNH (nợ 'nhãn chặn cứng' sau G41).",
|
|
1227
|
+
"",
|
|
1228
|
+
"G41 viết ba mức vào steps/gate.md Bước 3a — nhưng KHÔNG lệnh nào tự khai mình thuộc",
|
|
1229
|
+
"mức nào. Nên agent phải TỰ SUY từ bảng đó mỗi lần đọc: '/extend-prd sửa một PRD đã",
|
|
1230
|
+
"duyệt — có tính là ghi đè file đã có không?'. Suy đúng thì không sao; suy sai một lần",
|
|
1231
|
+
"theo hướng nhẹ hơn thì `--yes` bỏ qua được một cổng đáng ra KHÔNG BAO GIỜ được bỏ.",
|
|
1232
|
+
"",
|
|
1233
|
+
"Đây là hình dạng đã gặp bốn lần trong loạt GAP này: luật ĐÚNG, viết RÕ, và KHÔNG AI",
|
|
1234
|
+
"CANH. G1 ('phải bump sc_version') · G28 ('đổi spec thì hạ qc_status') · G41 ('read-only",
|
|
1235
|
+
"được miễn CHECKPOINT' — gate không thi hành) · và cái này. Ba lần trước đều chữa bằng",
|
|
1236
|
+
"cùng một cách: khai tường minh + để máy canh. R11 là phần 'máy canh'.",
|
|
1237
|
+
"",
|
|
1238
|
+
"KHÔNG liệt kê `normal`: nó là mặc định, và liệt kê ra là tạo một danh sách phải bảo",
|
|
1239
|
+
"trì mãi mãi — thêm lệnh mới mà quên thêm vào đó thì lại sai lần nữa.",
|
|
1240
|
+
"",
|
|
1241
|
+
"PHẠM VI: `hard` là 'ghi đè thứ NGƯỜI DÙNG ĐÃ DUYỆT'. /generate-code · /generate-bdd ·",
|
|
1242
|
+
"/generate-tech-docs · /map-testids CỐ Ý không nằm đây — chúng ghi thứ SINH RA ĐƯỢC từ",
|
|
1243
|
+
"spec, không phải thứ người dùng đã duyệt bằng tay. Ba script migrate cũng không: chúng",
|
|
1244
|
+
"là CLI, dry-run mặc định, không đi qua gate."
|
|
1245
|
+
],
|
|
1246
|
+
"label_marker": "Checkpoint:",
|
|
1247
|
+
"hard": [
|
|
1248
|
+
{ "cmd": "generate-prd", "why": "ghi đè PRD đã có → mất changelog, ĐÁNH SỐ LẠI BR, phá @trace.business_rules trong mọi .feature đã sinh" },
|
|
1249
|
+
{ "cmd": "extend-prd", "why": "sửa PRD đã DUYỆT" },
|
|
1250
|
+
{ "cmd": "refine-prd", "why": "--resume áp findings trực tiếp vào PRD" },
|
|
1251
|
+
{ "cmd": "generate-architecture", "why": "ghi đè architecture.md đã verified_by một người thật" }
|
|
1252
|
+
],
|
|
1253
|
+
"none": [
|
|
1254
|
+
{ "cmd": "review-code", "why": "read-only" },
|
|
1255
|
+
{ "cmd": "validate-traces", "why": "read-only (ghi trace-report.json + TSV status, không đụng spec/code)" },
|
|
1256
|
+
{ "cmd": "debug", "why": "read-only" },
|
|
1257
|
+
{ "cmd": "review-context", "why": "read-only (ghi findings vào .agent/review/)" },
|
|
1258
|
+
{ "cmd": "review-tech-docs", "why": "read-only (ghi findings vào .agent/review/)" }
|
|
1259
|
+
]
|
|
1260
|
+
},
|
|
1261
|
+
"audit_invalidating_tags": {
|
|
1262
|
+
"$comment": [
|
|
1263
|
+
"TAG NÀO TRONG CODE, KHI ĐỔI, LÀM AUDIT HẾT TƯƠI (nợ #4 sau Wave 1).",
|
|
1264
|
+
"",
|
|
1265
|
+
"gate chứng minh 'report khớp SỔ', không chứng minh 'sổ khớp CODE' — việc đó cần",
|
|
1266
|
+
"/validate-traces, một lệnh LLM không chạy được trong CI thường. Nên có lỗ: dev sửa",
|
|
1267
|
+
"code mà không audit lại thì sổ+report vẫn khớp nhau, gate vẫn PASS, và mọi cờ 🔴 nói",
|
|
1268
|
+
"về trạng thái TRƯỚC khi sửa. Job `require-fresh-audit` trong templates/ci/ bịt lỗ đó",
|
|
1269
|
+
"bằng một PROXY: không verify được thì ĐÒI BẰNG CHỨNG có người vừa verify.",
|
|
1270
|
+
"",
|
|
1271
|
+
"VÌ SAO LÀ TAG CHỨ KHÔNG PHẢI `^src/`: bản đầu của job hỏi 'PR có sửa src/ không?' và",
|
|
1272
|
+
"vì thế phải để TẮT mặc định — nó ĐO SAI THỨ. Framework có luật boundary-only tagging",
|
|
1273
|
+
"(docs/02-concepts/traceability.md): chỉ Controller/Handler/Middleware/Steps mang tag;",
|
|
1274
|
+
"Entity/Repository/DTO/Interface/Base KHÔNG. Nên `^src/` chặn PR chỉ sửa một DTO — một",
|
|
1275
|
+
"file không mang lời khẳng định trace nào. Cái gì báo oan thì bị tắt, rồi mất luôn phần",
|
|
1276
|
+
"thật sự cần chặn.",
|
|
1277
|
+
"Câu hỏi đúng không phải 'PR có sửa src/?' mà 'PR có sửa thứ mà report đang KHẲNG ĐỊNH?'",
|
|
1278
|
+
"— và report khẳng định qua tag, tag thì nhìn thấy trong diff.",
|
|
1279
|
+
"",
|
|
1280
|
+
"PHẠM VI: chỉ 7 tag là NGUỒN của 4 cờ chặn PR. Tag version (@trace.prd_version,",
|
|
1281
|
+
"tech_doc_revision, design_spec_version) sinh ra cờ 🟠 — cờ đó cố ý không chặn, nên đổi",
|
|
1282
|
+
"chúng không cần đòi audit lại.",
|
|
1283
|
+
"",
|
|
1284
|
+
"GIỚI HẠN ĐÃ BIẾT: đổi tên class (AuthService → AuthenticationService) không chạm dòng",
|
|
1285
|
+
"tag ⇒ tag-diff bỏ lọt, dù cột `implemented_by` giờ trỏ vào tên không còn. Chấp nhận có",
|
|
1286
|
+
"chủ ý: ca đó ít gặp hơn hẳn ca sửa-code-thường, và nó KHÔNG im lặng (lần /validate-traces",
|
|
1287
|
+
"kế tiếp báo ngay). Còn báo oan thì xảy ra mỗi ngày và hậu quả là CỔNG BỊ TẮT — mất tất cả.",
|
|
1288
|
+
"Biến thể chặt hơn ('PR chạm file nào CÓ chứa tag') ghi trong comment của template.",
|
|
1289
|
+
"",
|
|
1290
|
+
"self-check R10 canh templates/ci/trace-gate.yml có nhắc đủ 7 tag này. Tag đổi tên mà",
|
|
1291
|
+
"file CI không biết ⇒ grep không khớp gì ⇒ job LUÔN XANH ⇒ cổng mù im lặng."
|
|
1292
|
+
],
|
|
1293
|
+
"ci_template": "templates/ci/trace-gate.yml",
|
|
1294
|
+
"tags": [
|
|
1295
|
+
{ "tag": "@trace.implements", "flags": ["ORPHANED", "TRACE_ORPHAN"] },
|
|
1296
|
+
{ "tag": "@trace.verifies", "flags": ["ORPHANED", "TRACE_ORPHAN"] },
|
|
1297
|
+
{ "tag": "@trace.seam_port", "flags": ["SEAM_UNWIRED"] },
|
|
1298
|
+
{ "tag": "@trace.seam_pending", "flags": ["SEAM_UNWIRED"] },
|
|
1299
|
+
{ "tag": "@trace.stub", "flags": ["STUB_UNRESOLVED"] },
|
|
1300
|
+
{ "tag": "@trace.stub_owner", "flags": ["STUB_UNRESOLVED"] },
|
|
1301
|
+
{ "tag": "@trace.stub_for", "flags": ["STUB_UNRESOLVED"] }
|
|
1302
|
+
]
|
|
1303
|
+
},
|
|
1304
|
+
"blocking": [
|
|
1305
|
+
{
|
|
1306
|
+
"counter": "orphaned_count",
|
|
1307
|
+
"issues_key": "orphaned",
|
|
1308
|
+
"label_fields": ["sc_id", "platform"],
|
|
1309
|
+
"why": "code + test còn trỏ vào scenario đã bị xoá khỏi .feature"
|
|
1310
|
+
},
|
|
1311
|
+
{
|
|
1312
|
+
"counter": "trace_orphan_count",
|
|
1313
|
+
"issues_key": "trace_orphan",
|
|
1314
|
+
"label_fields": ["sc_id", "file"],
|
|
1315
|
+
"why": "tag trong code trỏ vào SC-ID không tồn tại — không chỗ nào khác bắt được"
|
|
1316
|
+
},
|
|
1317
|
+
{
|
|
1318
|
+
"counter": "seam_unwired_count",
|
|
1319
|
+
"issues_key": "seam_unwired",
|
|
1320
|
+
"label_fields": ["port", "consumer_uc"],
|
|
1321
|
+
"why": "luồng ghép đang chạy vào stub thay vì hàng thật"
|
|
1322
|
+
},
|
|
1323
|
+
{
|
|
1324
|
+
"counter": "stub_unresolved_count",
|
|
1325
|
+
"issues_key": "stub_unresolved",
|
|
1326
|
+
"label_fields": ["artifact", "consumer_uc"],
|
|
1327
|
+
"why": "hàm rỗng chưa được lấp, nhưng caller đã gọi"
|
|
1328
|
+
}
|
|
1329
|
+
],
|
|
1330
|
+
"reconcile": {
|
|
1331
|
+
"$comment": [
|
|
1332
|
+
"Gate đọc trace-report.json — một file CÓ THỂ CŨ. Không kiểm tươi thì gate là sân khấu:",
|
|
1333
|
+
"chạy /validate-traces một lần, commit report, rồi sửa spec/code tuỳ ý — CI đọc report cũ",
|
|
1334
|
+
"và cho qua mãi. So sánh theo thời gian commit KHÔNG dùng được (report và code thường nằm",
|
|
1335
|
+
"trong CÙNG một commit, nên mốc thời gian luôn 'cũ hơn'). Cách dùng được: đối chiếu report",
|
|
1336
|
+
"với chính sổ TSV mà nó khai là đang mô tả. Bất biến dựa vào: /validate-traces Step 6 ghi",
|
|
1337
|
+
"`status` trở lại TSV, nên NGAY SAU một lần chạy, TSV và report phải khớp.",
|
|
1338
|
+
"hard = lệch thì FAIL (đếm số row là tuyệt đối, không nhập nhằng).",
|
|
1339
|
+
"soft = lệch thì WARN (phụ thuộc quy ước đếm — vd ORPHANED được report biểu diễn bằng",
|
|
1340
|
+
"boolean `orphaned` chứ không phải giá trị `status`, nên không ép cứng)."
|
|
1341
|
+
],
|
|
1342
|
+
"hard": { "total_scs": "số row dữ liệu trong mọi TSV thuộc phạm vi report" },
|
|
1343
|
+
"soft": {
|
|
1344
|
+
"drift_count": "DRIFT",
|
|
1345
|
+
"gap_count": "GAP",
|
|
1346
|
+
"untracked_count": "UNTRACKED",
|
|
1347
|
+
"orphaned_count": "ORPHANED"
|
|
1348
|
+
},
|
|
1349
|
+
"per_sc": {
|
|
1350
|
+
"$comment": [
|
|
1351
|
+
"G48 — đối chiếu TỪNG scenario thay vì chỉ tổng số. So tổng bỏ lọt ca thường gặp nhất",
|
|
1352
|
+
"khi spec tiến hoá: một SC bị xoá + một SC được thêm trong cùng một lần → tổng KHÔNG",
|
|
1353
|
+
"đổi → report cũ vẫn được coi là tươi. Khoá phải gồm platform: sc_id một mình không",
|
|
1354
|
+
"định danh được scenario ('sc_id trùng số giữa các platform là 2 scenario khác nhau').",
|
|
1355
|
+
"",
|
|
1356
|
+
"Chuẩn hoá ORPHANED: JSON CỐ Ý chỉ có 4 giá trị status, và row ORPHANED xuất ra là",
|
|
1357
|
+
"`status: DRIFT` + `orphaned: true` (validate-traces §Rules — để VS Code extension",
|
|
1358
|
+
"switch trên status không rơi vào nhánh không khớp). Nên khi so với cột `status` của",
|
|
1359
|
+
"TSV, phải quy đổi `orphaned:true` → ORPHANED TRƯỚC. Quy ước này ĐƯỢC GHI RÕ nên",
|
|
1360
|
+
"status so được ở mức `hard`; nếu nó chỉ là suy đoán thì phải để `soft`.",
|
|
1361
|
+
"",
|
|
1362
|
+
"BACKWARD-COMPAT: report sinh bởi version trước G48 không có `platform`. Gate rơi về",
|
|
1363
|
+
"so tổng số + in ⚠️ 'kiểm độ tươi đang ở mức yếu', KHÔNG fail — người dùng chưa chạy",
|
|
1364
|
+
"lại /validate-traces không phải là lỗi của họ."
|
|
1365
|
+
],
|
|
1366
|
+
"key_fields": ["sc_id", "platform"],
|
|
1367
|
+
"compare": "status",
|
|
1368
|
+
"orphaned_flag": "orphaned",
|
|
1369
|
+
"orphaned_status": "ORPHANED"
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
},
|
|
1373
|
+
"path_keys": {
|
|
1374
|
+
"$comment": "Key phải có trong templates/project-context.yaml VÀ được dùng bởi ít nhất một actor. Key khai mà không ai dùng = key chết (GAPS.md G17).",
|
|
1375
|
+
"config_file": "templates/project-context.yaml",
|
|
1376
|
+
"ignore_unused": [
|
|
1377
|
+
"specs_dir",
|
|
1378
|
+
"src_dir",
|
|
1379
|
+
"trace_dir",
|
|
1380
|
+
"tech_docs_dir",
|
|
1381
|
+
"lessons_file"
|
|
1382
|
+
]
|
|
1383
|
+
},
|
|
1384
|
+
"forbidden_patterns": [
|
|
1385
|
+
{
|
|
1386
|
+
"pattern": "bdd/{UC-ID}.feature",
|
|
1387
|
+
"reason": "@trace.source thiếu segment {platform}. Layout thật: bdd/{platform}/{UC-ID}-{slug}.feature",
|
|
1388
|
+
"gap": "G8"
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
"pattern": "{UC-ID}*-tech-design",
|
|
1392
|
+
"reason": "Glob không bao giờ khớp: tech-doc là doc GỘP cấp PRD, tên mang {TICKET-ID} chứ không mang {UC-ID}",
|
|
1393
|
+
"gap": "G10",
|
|
1394
|
+
"except": {
|
|
1395
|
+
"steps/gate.md": "Trích dẫn pattern trong cảnh báo tại chỗ: \"Đừng glob {UC-ID}*-tech-design*.md — nó nở thành ... và không bao giờ khớp\""
|
|
1396
|
+
}
|
|
1397
|
+
},
|
|
1398
|
+
{
|
|
1399
|
+
"pattern": "{prd-slug}/{UC-ID}.tsv",
|
|
1400
|
+
"reason": "Tên sổ trace thiếu -{platform}. Một sổ cho mỗi UC × platform",
|
|
1401
|
+
"gap": "G18"
|
|
1402
|
+
},
|
|
1403
|
+
{
|
|
1404
|
+
"pattern": "@trace.uc=",
|
|
1405
|
+
"reason": "Từ vựng ĐÃ KHAI TỬ (G11). Số UC đã nằm trong `sc_id` (`{UC-ID}-SC{N}`) nên tag riêng là thừa và gây nhập nhằng với `@trace.ucs` (danh sách UC của tech-doc). Ba file dưới được phép chứa vì chúng đang MAP NGƯỢC nó sang canonical rồi strip — không phải phát ra nó.",
|
|
1406
|
+
"gap": "G11/G30",
|
|
1407
|
+
"except": {
|
|
1408
|
+
"commands/generate-bdd.tmpl": "Đường backward-compat khi nhặt proposal cũ từ feedback/bdd-proposals/",
|
|
1409
|
+
"commands/propose-scenario.tmpl": "Ghi chú cho tester đừng dùng lại format cũ",
|
|
1410
|
+
"commands/review-context.tmpl": "B5 auto-fix: map tag lạc sang canonical rồi strip"
|
|
1411
|
+
}
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
"pattern": "@trace.ac=",
|
|
1415
|
+
"reason": "Từ vựng ĐÃ KHAI TỬ (G11) — thay bằng dòng `# Covers: AC{N}`. Xem @trace.uc=.",
|
|
1416
|
+
"gap": "G11/G30",
|
|
1417
|
+
"except": {
|
|
1418
|
+
"commands/generate-bdd.tmpl": "Đường backward-compat cho proposal cũ",
|
|
1419
|
+
"commands/propose-scenario.tmpl": "Ghi chú format cũ",
|
|
1420
|
+
"commands/review-context.tmpl": "B5 auto-fix map sang `# Covers:`"
|
|
1421
|
+
}
|
|
1422
|
+
},
|
|
1423
|
+
{
|
|
1424
|
+
"pattern": "claude-opus-4",
|
|
1425
|
+
"reason": "Hardcode version model — dùng \"model Opus mới nhất\" để không phải sửa framework mỗi lần lên model",
|
|
1426
|
+
"gap": "G21"
|
|
1427
|
+
},
|
|
1428
|
+
{
|
|
1429
|
+
"pattern": "{paths.feature_template}",
|
|
1430
|
+
"reason": "Key chết: template được {{include}} nướng cứng lúc build, lệnh không đọc path template lúc chạy",
|
|
1431
|
+
"gap": "G17"
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
"pattern": "{paths.prd_template}",
|
|
1435
|
+
"reason": "Key chết — xem G9/G17",
|
|
1436
|
+
"gap": "G17"
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
"pattern": "{paths.trace_report}",
|
|
1440
|
+
"reason": "Key chết và trỏ sai: report thật là {trace_dir}/trace-report.json",
|
|
1441
|
+
"gap": "G17"
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
"pattern": "{paths.templates_dir}",
|
|
1445
|
+
"reason": "Key chết — xem G17",
|
|
1446
|
+
"gap": "G17"
|
|
1447
|
+
}
|
|
1448
|
+
]
|
|
1449
|
+
}
|