@educa-corp/sdd-framework 0.6.0 → 0.7.1
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/gate-trace.js +25 -2
- package/bin/index.js +32 -5
- package/bin/lint-trace.js +41 -0
- package/bin/self-check.js +430 -3
- package/bin/trace-schema.json +418 -31
- package/core/FRAMEWORK_VERSION +1 -1
- package/{commands/extend-prd.md → core/commands/amend-prd.md} +206 -173
- package/core/commands/dev-run-test.md +48 -10
- package/core/commands/extend-prd.md +39 -12
- package/core/commands/generate-bdd.md +52 -10
- package/core/commands/generate-code.md +35 -2
- package/core/commands/generate-tech-docs.md +36 -4
- package/core/commands/map-testids.md +1 -1
- package/core/commands/qc-run-test.md +29 -3
- package/core/commands/refine-prd.md +13 -2
- package/core/commands/review-context.md +43 -8
- package/core/commands/sync.md +105 -1
- package/core/commands/validate-traces.md +289 -16
- package/core/rules/workflow.md +34 -0
- package/core/steps/context-loader.md +27 -6
- package/core/templates/feature.template +1 -1
- package/core/templates/project-context.yaml +3 -3
- package/core/templates/tech-design.template.md +2 -2
- package/docs/02-concepts/architecture.md +37 -1
- package/docs/02-concepts/overview.md +1 -1
- package/docs/02-concepts/pipeline-steps/02-specification.md +13 -7
- package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +2 -0
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +1 -0
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +34 -3
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +10 -1
- package/docs/02-concepts/traceability.md +187 -183
- package/docs/03-guides/architect.md +13 -4
- package/docs/03-guides/developer.md +1 -0
- package/docs/03-guides/product-owner.md +89 -72
- package/docs/03-guides/tester-qa.md +81 -81
- package/docs/04-reference/commands.md +148 -134
- package/docs/04-reference/trace-schema.md +45 -1
- package/docs/explain/02b-extend-prd.md +1 -1
- package/docs/explain/02c-amend-prd.md +152 -0
- package/docs/explain/06-generate-bdd.md +1 -1
- package/docs/explain/13-dev-run-test.md +15 -1
- package/docs/explain/19-qc-run-test.md +91 -87
- package/docs/explain/21-validate-traces.md +79 -75
- package/docs/explain/28-sync.md +25 -0
- package/docs/explain/README.md +136 -135
- package/package.json +1 -8
- package/commands/debug.md +0 -529
- package/commands/debug.tmpl +0 -260
- package/commands/define-product.md +0 -438
- package/commands/define-product.tmpl +0 -225
- package/commands/dev-gen-test.md +0 -700
- package/commands/dev-gen-test.tmpl +0 -490
- package/commands/dev-run-test.md +0 -435
- package/commands/dev-run-test.tmpl +0 -225
- package/commands/dev-smoke-test.md +0 -374
- package/commands/dev-smoke-test.tmpl +0 -217
- package/commands/extend-prd.tmpl +0 -273
- package/commands/fix-bug.md +0 -519
- package/commands/fix-bug.tmpl +0 -197
- package/commands/generate-architecture.md +0 -354
- package/commands/generate-architecture.tmpl +0 -197
- package/commands/generate-bdd.md +0 -923
- package/commands/generate-bdd.tmpl +0 -590
- package/commands/generate-code.md +0 -859
- package/commands/generate-code.tmpl +0 -649
- package/commands/generate-design-spec.md +0 -737
- package/commands/generate-design-spec.tmpl +0 -524
- package/commands/generate-prd.md +0 -722
- package/commands/generate-prd.tmpl +0 -226
- package/commands/generate-spec-manifest.md +0 -321
- package/commands/generate-spec-manifest.tmpl +0 -164
- package/commands/generate-tech-docs.md +0 -920
- package/commands/generate-tech-docs.tmpl +0 -273
- package/commands/learn.md +0 -399
- package/commands/learn.tmpl +0 -130
- package/commands/map-testids.md +0 -238
- package/commands/map-testids.tmpl +0 -81
- package/commands/propose-scenario.md +0 -359
- package/commands/propose-scenario.tmpl +0 -202
- package/commands/qc-analyze.md +0 -269
- package/commands/qc-analyze.tmpl +0 -112
- package/commands/qc-design-test.md +0 -226
- package/commands/qc-design-test.tmpl +0 -69
- package/commands/qc-plan.md +0 -206
- package/commands/qc-plan.tmpl +0 -49
- package/commands/qc-report.md +0 -217
- package/commands/qc-report.tmpl +0 -60
- package/commands/qc-review.md +0 -210
- package/commands/qc-review.tmpl +0 -53
- package/commands/qc-run-test.md +0 -326
- package/commands/qc-run-test.tmpl +0 -116
- package/commands/refine-prd.md +0 -653
- package/commands/refine-prd.tmpl +0 -281
- package/commands/report-bug.md +0 -305
- package/commands/report-bug.tmpl +0 -148
- package/commands/review-code.md +0 -415
- package/commands/review-code.tmpl +0 -146
- package/commands/review-context.md +0 -902
- package/commands/review-context.tmpl +0 -530
- package/commands/review-tech-docs.md +0 -561
- package/commands/review-tech-docs.tmpl +0 -404
- package/commands/setup-ai-first.md +0 -602
- package/commands/setup-ai-first.tmpl +0 -450
- package/commands/sync.md +0 -430
- package/commands/sync.tmpl +0 -429
- package/commands/update-framework.md +0 -203
- package/commands/update-framework.tmpl +0 -202
- package/commands/validate-traces.md +0 -1077
- package/commands/validate-traces.tmpl +0 -920
- package/hooks/data-guard.js +0 -232
- package/hooks/settings.json +0 -19
- package/modules/android-compose/module.yaml +0 -13
- package/modules/android-compose/stack-profile.yaml +0 -57
- package/modules/angular/architecture-snippets/component-patterns.md +0 -187
- package/modules/angular/module.yaml +0 -6
- package/modules/angular/stack-profile.yaml +0 -38
- package/modules/context-engineering/architecture-snippets/context-design.md +0 -119
- package/modules/context-engineering/module.yaml +0 -9
- package/modules/context-engineering/stack-profile.yaml +0 -61
- package/modules/dotnet/architecture-snippets/clean-arch.md +0 -160
- package/modules/dotnet/module.yaml +0 -6
- package/modules/dotnet/stack-profile.yaml +0 -50
- package/modules/flutter/module.yaml +0 -14
- package/modules/flutter/stack-profile.yaml +0 -59
- package/modules/golang/architecture-snippets/domain-layout.md +0 -283
- package/modules/golang/module.yaml +0 -6
- package/modules/golang/stack-profile.yaml +0 -40
- package/modules/ios-swiftui/module.yaml +0 -13
- package/modules/ios-swiftui/stack-profile.yaml +0 -55
- package/modules/java-spring/architecture-snippets/layered-arch.md +0 -201
- package/modules/java-spring/module.yaml +0 -15
- package/modules/java-spring/stack-profile.yaml +0 -28
- package/modules/nextjs/architecture-snippets/app-router-patterns.md +0 -269
- package/modules/nextjs/module.yaml +0 -14
- package/modules/nextjs/stack-profile.yaml +0 -74
- package/modules/nuxt/module.yaml +0 -14
- package/modules/nuxt/stack-profile.yaml +0 -58
- package/modules/phaser-game/architecture-snippets/phaser-scene-patterns.md +0 -646
- package/modules/phaser-game/module.yaml +0 -15
- package/modules/phaser-game/stack-profile.yaml +0 -90
- package/modules/php-laravel/architecture-snippets/service-repository.md +0 -302
- package/modules/php-laravel/module.yaml +0 -15
- package/modules/php-laravel/stack-profile.yaml +0 -56
- package/modules/qc-playwright/stack-profile.yaml +0 -66
- package/modules/react/architecture-snippets/hooks-query-patterns.md +0 -254
- package/modules/react/module.yaml +0 -14
- package/modules/react/stack-profile.yaml +0 -63
- package/modules/react-native/module.yaml +0 -14
- package/modules/react-native/stack-profile.yaml +0 -56
- package/modules/vue/module.yaml +0 -14
- package/modules/vue/stack-profile.yaml +0 -65
- package/rules/data-protection.md +0 -80
- package/rules/workflow.md +0 -99
- package/skills/code/SKILL.md +0 -19
- package/skills/code/SKILL.tmpl +0 -19
- package/skills/debug/SKILL.md +0 -19
- package/skills/debug/SKILL.tmpl +0 -19
- package/skills/design-spec/SKILL.md +0 -11
- package/skills/design-spec/SKILL.tmpl +0 -11
- package/skills/discovery/SKILL.md +0 -14
- package/skills/discovery/SKILL.tmpl +0 -14
- package/skills/prd/SKILL.md +0 -19
- package/skills/prd/SKILL.tmpl +0 -19
- package/skills/qc/qa-analyst/DOC_GAPS.template.md +0 -63
- package/skills/qc/qa-analyst/acceptance-criteria.md +0 -60
- package/skills/qc/qa-analyst/business-rules.md +0 -59
- package/skills/qc/qa-analyst/data-flow.md +0 -64
- package/skills/qc/qa-analyst/spec-breakdown.md +0 -61
- package/skills/qc/qa-designer/e2e/journey.md +0 -41
- package/skills/qc/qa-designer/exploratory/charter.md +0 -68
- package/skills/qc/qa-designer/exploratory/explore-to-functional.md +0 -43
- package/skills/qc/qa-designer/functional/api.md +0 -45
- package/skills/qc/qa-designer/functional/gui-feature.md +0 -46
- package/skills/qc/qa-designer/functional/gui-screen.md +0 -52
- package/skills/qc/qa-designer/integration/api.md +0 -42
- package/skills/qc/qa-designer/integration/db.md +0 -39
- package/skills/qc/qa-designer/integration/gui.md +0 -40
- package/skills/qc/qa-designer/integration/kafka.md +0 -40
- package/skills/qc/qa-designer/non-functional.md +0 -40
- package/skills/qc/qa-planner/test-plan.md +0 -120
- package/skills/qc/qa-reviewer/script/e2e.md +0 -87
- package/skills/qc/qa-reviewer/script/exploratory.md +0 -45
- package/skills/qc/qa-reviewer/script/functional.md +0 -101
- package/skills/qc/qa-reviewer/script/integration.md +0 -91
- package/skills/qc/qa-reviewer/script/non-functional.md +0 -126
- package/skills/qc/qa-reviewer/test-case/e2e.md +0 -73
- package/skills/qc/qa-reviewer/test-case/exploratory.md +0 -43
- package/skills/qc/qa-reviewer/test-case/functional.md +0 -76
- package/skills/qc/qa-reviewer/test-case/integration.md +0 -69
- package/skills/qc/qa-reviewer/test-case/non-functional.md +0 -73
- package/skills/qc/qa-runner/e2e.md +0 -49
- package/skills/qc/qa-runner/exploratory/session.md +0 -36
- package/skills/qc/qa-runner/functional/api.md +0 -35
- package/skills/qc/qa-runner/functional/gui-feature.md +0 -51
- package/skills/qc/qa-runner/functional/gui-screen.md +0 -55
- package/skills/qc/qa-runner/integration.md +0 -47
- package/skills/qc/qa-runner/non-functional.md +0 -49
- package/skills/qc/qa-runner/report/report.md +0 -37
- package/skills/setup-ai-first/SKILL.md +0 -19
- package/skills/setup-ai-first/SKILL.tmpl +0 -19
- package/skills/spec/SKILL.md +0 -19
- package/skills/spec/SKILL.tmpl +0 -19
- package/skills/test/SKILL.md +0 -18
- package/skills/test/SKILL.tmpl +0 -18
- package/steps/business-language.md +0 -56
- package/steps/capture-lesson.md +0 -112
- package/steps/context-loader.md +0 -406
- package/steps/gate.md +0 -151
- package/steps/report-footer.md +0 -125
- package/steps/review-fanout.md +0 -159
- package/steps/spawn-agent.md +0 -129
- package/steps/trace-mirror.md +0 -53
- package/templates/README.md +0 -70
- package/templates/architecture.template.md +0 -394
- package/templates/ci/trace-gate.yml +0 -146
- package/templates/design-spec.template.md +0 -217
- package/templates/feature.template +0 -123
- package/templates/hooks/pre-push +0 -61
- package/templates/platform-guide.template.md +0 -145
- package/templates/prd.template.md +0 -283
- package/templates/product-definition.template.md +0 -188
- package/templates/project-context.yaml +0 -212
- package/templates/tech-design.template.md +0 -490
package/bin/trace-schema.json
CHANGED
|
@@ -937,17 +937,37 @@
|
|
|
937
937
|
"Đội/submodule sở hữu scenario. Nguồn: @trace.service của header .feature.",
|
|
938
938
|
"VÌ SAO TỒN TẠI (G31): validate-traces Step 0 và trace-mirror.md đều khẳng định trace gộp",
|
|
939
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.
|
|
941
|
-
"
|
|
942
|
-
"
|
|
943
|
-
"
|
|
944
|
-
"
|
|
940
|
+
"cho nó và JSON report cũng không. Cột này làm lời khẳng định kia thành sự thật.",
|
|
941
|
+
"",
|
|
942
|
+
"BỐN GIÁ TRỊ — G51 tách hai cái từng bị gộp:",
|
|
943
|
+
" {path} = đã route xong, đây là repo sở hữu",
|
|
944
|
+
" unrouted = CHƯA AI QUYẾT repo. Trạng thái HỢP LỆ và BÌNH THƯỜNG ở feature đầu tiên của",
|
|
945
|
+
" một domain mới. Cờ 🟠 SERVICE_UNROUTED. KHÔNG chặn BDD, KHÔNG chặn PR.",
|
|
946
|
+
" unresolved = CONFIG SAI CẤU TRÚC (một entry vừa có path vừa có by_prd_slug, hoặc",
|
|
947
|
+
" by_prd_slug lồng nhau). Đây là BUG cần sửa file, không phải trạng thái chờ.",
|
|
948
|
+
" '—' = single-service mode, không có khái niệm service",
|
|
949
|
+
"",
|
|
950
|
+
"VÌ SAO PHẢI TÁCH (G51): trước đó 'unresolved' mang CẢ HAI nghĩa nên cả hai chịu chung một",
|
|
951
|
+
"hình phạt — /generate-bdd DỪNG HẲN. Nhưng PRD/BDD là artifact NGHIỆP VỤ: PO biết domain",
|
|
952
|
+
"(auth, payment) và biết platform (web/app — người dùng làm việc đó ở đâu), nhưng KHÔNG biết",
|
|
953
|
+
"code sẽ nằm repo nào, và thường lúc đó CHƯA AI QUYẾT. Nên cổng đặt sai phase: nó chặn phase",
|
|
954
|
+
"KHÔNG CẦN biết, còn generate-code — phase BUỘC PHẢI biết mới ghi được file — thì không kiểm.",
|
|
955
|
+
"Ca bị đánh nặng nhất là feature ĐẦU TIÊN của một domain mới: chưa có mapping ⇒ PO bị chặn",
|
|
956
|
+
"bởi một quyết định thuộc architect, ở phase architect còn chưa vào.",
|
|
957
|
+
"",
|
|
958
|
+
"AI PHÂN GIẢI: validate-traces đọc lại services: mỗi lần chạy và nâng unrouted → path khi",
|
|
959
|
+
"mapping xuất hiện — giống cách nó đã làm với spec_ver. Architect thêm mapping ⇒ sổ TỰ LÀNH,",
|
|
960
|
+
"không sửa tay, KHÔNG phải chạy lại /generate-bdd. Vì thế validate-traces là producer thứ hai",
|
|
961
|
+
"của cột này, và đó là ngoại lệ CÓ CHỦ Ý với luật 'mỗi cột một chủ': nó không ghi giá trị mới,",
|
|
962
|
+
"nó chỉ phân giải một placeholder mà generate-bdd đã cố ý để lại."
|
|
945
963
|
],
|
|
946
964
|
"written_by": [
|
|
947
|
-
"generate-bdd"
|
|
965
|
+
"generate-bdd",
|
|
966
|
+
"validate-traces"
|
|
948
967
|
],
|
|
949
968
|
"read_by": [
|
|
950
|
-
"validate-traces"
|
|
969
|
+
"validate-traces",
|
|
970
|
+
"generate-code"
|
|
951
971
|
]
|
|
952
972
|
},
|
|
953
973
|
{
|
|
@@ -1087,10 +1107,36 @@
|
|
|
1087
1107
|
"column": "status"
|
|
1088
1108
|
},
|
|
1089
1109
|
"platform": {
|
|
1110
|
+
"$comment": [
|
|
1111
|
+
"PLATFORM = DELIVERY SURFACE, không phải tech stack. `webview` là surface thứ tư có thật:",
|
|
1112
|
+
"một bundle web nhúng trong app native — không phải `web` (browser) và không phải `app`",
|
|
1113
|
+
"(native). Nó có BDD riêng (tương tác khác), design-spec riêng, và repo riêng.",
|
|
1114
|
+
"",
|
|
1115
|
+
"VÌ SAO PHẢI THÊM (báo cáo từ project thật, v0.7.0): framework DẠY `webview` ở BỐN chỗ —",
|
|
1116
|
+
" templates/project-context.yaml FORM C lấy webview mini-game làm ví dụ",
|
|
1117
|
+
" steps/context-loader.md 2c ví dụ đầy đủ: bdd/webview/UC1.feature",
|
|
1118
|
+
" commands/setup-ai-first prompt tự đưa ra `learning:webview:dap-chuot:phaser-game`",
|
|
1119
|
+
" modules/phaser-game stack-profile có mục build cho webview",
|
|
1120
|
+
"— rồi TỪ CHỐI nó ở tầng kiểm. lint-trace T5 là `err`, và validate-traces Step 1.0 DỪNG",
|
|
1121
|
+
"NGAY khi lint exit 1 ⇒ project dùng đúng ví dụ của framework mất TOÀN BỘ audit.",
|
|
1122
|
+
"",
|
|
1123
|
+
"Đổi tên sổ KHÔNG phải đường ra: nó phá khoá routing `by_prd_slug`, lệch với",
|
|
1124
|
+
"@trace.platform trong .feature, và gộp hai surface vào một sổ làm sc_id đụng nhau (mỗi",
|
|
1125
|
+
"platform đánh SC từ 1).",
|
|
1126
|
+
"",
|
|
1127
|
+
"NỢ CÒN LẠI — danh sách này vẫn ĐÓNG: project cần `desktop`/`tv`/`mini-program`/`cli` sẽ",
|
|
1128
|
+
"bị chặn y như vậy và phải chờ một bản release. Nguyên nhân gốc là `platform` được xử lý",
|
|
1129
|
+
"như enum ĐÓNG trong contract nhưng MỌI code path sinh ra nó đều MỞ (setup-ai-first nhận",
|
|
1130
|
+
"chuỗi bất kỳ · context-loader 2b đọc sub-key bất kỳ · generate-bdd ghi bdd/{platform}/",
|
|
1131
|
+
"không kiểm gì). Cách sửa đúng là cho project TỰ KHAI thêm platform trong",
|
|
1132
|
+
"project-context.yaml và để lint-trace đọc — giữ được tính năng bắt typo của T5 mà không",
|
|
1133
|
+
"cần release cho từng surface mới. Đang hoãn có chủ ý, làm ở đợt sau."
|
|
1134
|
+
],
|
|
1090
1135
|
"values": [
|
|
1091
1136
|
"web",
|
|
1092
1137
|
"app",
|
|
1093
|
-
"system"
|
|
1138
|
+
"system",
|
|
1139
|
+
"webview"
|
|
1094
1140
|
],
|
|
1095
1141
|
"filename_segment": "{UC-ID}-{platform}.tsv",
|
|
1096
1142
|
"$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)."
|
|
@@ -1154,6 +1200,7 @@
|
|
|
1154
1200
|
"audit_flags": {
|
|
1155
1201
|
"$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
1202
|
"values": [
|
|
1203
|
+
"PRD_UNTRACKED_EDIT",
|
|
1157
1204
|
"PRD_DRIFT",
|
|
1158
1205
|
"PRD_STALE_REF",
|
|
1159
1206
|
"BDD_DRIFT",
|
|
@@ -1167,7 +1214,8 @@
|
|
|
1167
1214
|
"SEAM_UNWIRED",
|
|
1168
1215
|
"STUB_UNRESOLVED",
|
|
1169
1216
|
"SEAM_PENDING",
|
|
1170
|
-
"STUB_PENDING"
|
|
1217
|
+
"STUB_PENDING",
|
|
1218
|
+
"SERVICE_UNROUTED"
|
|
1171
1219
|
]
|
|
1172
1220
|
}
|
|
1173
1221
|
},
|
|
@@ -1245,17 +1293,48 @@
|
|
|
1245
1293
|
],
|
|
1246
1294
|
"label_marker": "Checkpoint:",
|
|
1247
1295
|
"hard": [
|
|
1248
|
-
{
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1296
|
+
{
|
|
1297
|
+
"cmd": "generate-prd",
|
|
1298
|
+
"why": "ghi đè PRD đã có → mất changelog, ĐÁNH SỐ LẠI BR, phá @trace.business_rules trong mọi .feature đã sinh"
|
|
1299
|
+
},
|
|
1300
|
+
{
|
|
1301
|
+
"cmd": "extend-prd",
|
|
1302
|
+
"why": "sửa PRD đã DUYỆT"
|
|
1303
|
+
},
|
|
1304
|
+
{
|
|
1305
|
+
"cmd": "amend-prd",
|
|
1306
|
+
"why": "SỬA TẠI CHỖ một AC/BR/UC đã duyệt — thao tác ghi DUY NHẤT trong framework được phép làm output KHÔNG phải superset của bản cũ"
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
"cmd": "refine-prd",
|
|
1310
|
+
"why": "--resume áp findings trực tiếp vào PRD"
|
|
1311
|
+
},
|
|
1312
|
+
{
|
|
1313
|
+
"cmd": "generate-architecture",
|
|
1314
|
+
"why": "ghi đè architecture.md đã verified_by một người thật"
|
|
1315
|
+
}
|
|
1252
1316
|
],
|
|
1253
1317
|
"none": [
|
|
1254
|
-
{
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
{
|
|
1318
|
+
{
|
|
1319
|
+
"cmd": "review-code",
|
|
1320
|
+
"why": "read-only"
|
|
1321
|
+
},
|
|
1322
|
+
{
|
|
1323
|
+
"cmd": "validate-traces",
|
|
1324
|
+
"why": "read-only (ghi trace-report.json + TSV status, không đụng spec/code)"
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
"cmd": "debug",
|
|
1328
|
+
"why": "read-only"
|
|
1329
|
+
},
|
|
1330
|
+
{
|
|
1331
|
+
"cmd": "review-context",
|
|
1332
|
+
"why": "read-only (ghi findings vào .agent/review/)"
|
|
1333
|
+
},
|
|
1334
|
+
{
|
|
1335
|
+
"cmd": "review-tech-docs",
|
|
1336
|
+
"why": "read-only (ghi findings vào .agent/review/)"
|
|
1337
|
+
}
|
|
1259
1338
|
]
|
|
1260
1339
|
},
|
|
1261
1340
|
"audit_invalidating_tags": {
|
|
@@ -1292,38 +1371,150 @@
|
|
|
1292
1371
|
],
|
|
1293
1372
|
"ci_template": "templates/ci/trace-gate.yml",
|
|
1294
1373
|
"tags": [
|
|
1295
|
-
{
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1374
|
+
{
|
|
1375
|
+
"tag": "@trace.implements",
|
|
1376
|
+
"flags": [
|
|
1377
|
+
"ORPHANED",
|
|
1378
|
+
"TRACE_ORPHAN"
|
|
1379
|
+
]
|
|
1380
|
+
},
|
|
1381
|
+
{
|
|
1382
|
+
"tag": "@trace.verifies",
|
|
1383
|
+
"flags": [
|
|
1384
|
+
"ORPHANED",
|
|
1385
|
+
"TRACE_ORPHAN"
|
|
1386
|
+
]
|
|
1387
|
+
},
|
|
1388
|
+
{
|
|
1389
|
+
"tag": "@trace.seam_port",
|
|
1390
|
+
"flags": [
|
|
1391
|
+
"SEAM_UNWIRED"
|
|
1392
|
+
]
|
|
1393
|
+
},
|
|
1394
|
+
{
|
|
1395
|
+
"tag": "@trace.seam_pending",
|
|
1396
|
+
"flags": [
|
|
1397
|
+
"SEAM_UNWIRED"
|
|
1398
|
+
]
|
|
1399
|
+
},
|
|
1400
|
+
{
|
|
1401
|
+
"tag": "@trace.stub",
|
|
1402
|
+
"flags": [
|
|
1403
|
+
"STUB_UNRESOLVED"
|
|
1404
|
+
]
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
"tag": "@trace.stub_owner",
|
|
1408
|
+
"flags": [
|
|
1409
|
+
"STUB_UNRESOLVED"
|
|
1410
|
+
]
|
|
1411
|
+
},
|
|
1412
|
+
{
|
|
1413
|
+
"tag": "@trace.stub_for",
|
|
1414
|
+
"flags": [
|
|
1415
|
+
"STUB_UNRESOLVED"
|
|
1416
|
+
]
|
|
1417
|
+
}
|
|
1418
|
+
]
|
|
1419
|
+
},
|
|
1420
|
+
"report_root_keys": {
|
|
1421
|
+
"$comment": [
|
|
1422
|
+
"KEY Ở CẤP GỐC CỦA trace-report.json MÀ gate-trace ĐỌC (G57).",
|
|
1423
|
+
"",
|
|
1424
|
+
"VÌ SAO KHỐI NÀY TỒN TẠI: `report.domain` từng có 1 consumer (gate-trace, và nó CHẶN PR nếu",
|
|
1425
|
+
"giá trị khác 'all') và 0 producer — validate-traces không có cờ nào để đặt nó. Năm chỗ trong",
|
|
1426
|
+
"lệnh mô tả một 'domain argument' / 'domain filter' KHÔNG TỒN TẠI: ghi chú Gate ('target là",
|
|
1427
|
+
"một tên domain hoặc UC-ID cụ thể từ $ARGUMENTS') · Step 1 đọc TSV 'khớp domain target' ·",
|
|
1428
|
+
"schema report '<domain argument, or all if no filter>' · Step 8 'nếu có domain filter, chỉ",
|
|
1429
|
+
"gồm các PRD đó trong prds[]' · dòng trace-history mang field domain.",
|
|
1430
|
+
"Nên ô đó LUÔN ghi 'all', và phần kiểm của gate CHƯA BAO GIỜ chạy một lần nào.",
|
|
1431
|
+
"",
|
|
1432
|
+
"Đây ĐÚNG hình dạng R1 fail build vì nó ('field có consumer mà không có producer' — ca",
|
|
1433
|
+
"@trace.sc_version: 3 consumer, 0 producer, sống qua nhiều version không ai bắt được). Nó sống",
|
|
1434
|
+
"được vì R1 chỉ canh field trong SỔ TSV và tag trong CODE — không rule nào canh key ở cấp gốc",
|
|
1435
|
+
"của BIÊN BẢN JSON. Cùng điểm mù mà R13 vừa bịt cho `spec_baseline`.",
|
|
1436
|
+
"",
|
|
1437
|
+
"Và ghi chú Gate còn tệ hơn im lặng: một agent đọc 'target là một tên domain hoặc UC-ID' sẽ",
|
|
1438
|
+
"TIN rằng scoping hoạt động.",
|
|
1439
|
+
"",
|
|
1440
|
+
"R9(h) là phần 'máy canh': mỗi key phải CÓ MẶT trong skeleton JSON của validate-traces VÀ được",
|
|
1441
|
+
"gate-trace đọc qua `report.{key}`. Cả hai đầu, không đầu nào được lửng."
|
|
1442
|
+
],
|
|
1443
|
+
"keys": [
|
|
1444
|
+
{
|
|
1445
|
+
"key": "scope",
|
|
1446
|
+
"shape": "{ kind: all | domain | prd | uc, value: string }",
|
|
1447
|
+
"written_by": "validate-traces",
|
|
1448
|
+
"read_by": "gate-trace",
|
|
1449
|
+
"why": "Gate PHẢI chặn mọi biên bản phiến diện, không chỉ biên bản hẹp-theo-domain — xem $comment của scope_kinds cho ca false-green mà `domain` một mình không bắt được."
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
"key": "domain",
|
|
1453
|
+
"shape": "tên domain, hoặc 'all'",
|
|
1454
|
+
"written_by": "validate-traces",
|
|
1455
|
+
"read_by": "gate-trace",
|
|
1456
|
+
"why": "Giữ cho TƯƠNG THÍCH NGƯỢC: biên bản sinh trước G57 không có `scope`. Gate rơi về logic cũ + in ⚠️ 'kiểm độ phủ đang ở mức yếu' thay vì fail — người dùng chưa chạy lại /validate-traces không phải là lỗi của họ. Cùng khuôn backward-compat G48 đã dùng cho `platform`."
|
|
1457
|
+
}
|
|
1458
|
+
],
|
|
1459
|
+
"scope_kinds": {
|
|
1460
|
+
"$comment": [
|
|
1461
|
+
"BẪY FALSE-GREEN mà bản fix G57 sẽ TỰ TAY MỞ nếu không siết G2 cùng lúc.",
|
|
1462
|
+
"",
|
|
1463
|
+
"gate-trace bản cũ: `if (domain !== 'all') { others = domainsOnDisk().filter(≠domain);",
|
|
1464
|
+
"if (others.length) fail }`. Trong repo MỘT domain, `others` là RỖNG ⇒ KHÔNG fail. Nên một",
|
|
1465
|
+
"biên bản hẹp-theo-PRD (hoặc hẹp-theo-UC) trong repo một domain sẽ được gate nhận là 'toàn",
|
|
1466
|
+
"bộ' — đúng cái 'cấp giấy xanh cho thứ chưa ai xem' mà chú thích của chính nó cảnh báo.",
|
|
1467
|
+
"",
|
|
1468
|
+
"Hiện tại vô hại vì không ai scope được. Nó BẬT NGAY khi scoping thành khả dụng. Nên điều",
|
|
1469
|
+
"kiện đúng là: `scope.kind !== 'all'` ⇒ FAIL, KHÔNG ngoại lệ — không phụ thuộc vào việc trên",
|
|
1470
|
+
"đĩa có bao nhiêu domain.",
|
|
1471
|
+
"",
|
|
1472
|
+
"Thêm cờ scope mà không siết G2 là biến cổng thành SÂN KHẤU — đúng cái G39 dựng lên để chống."
|
|
1473
|
+
],
|
|
1474
|
+
"values": ["all", "domain", "prd", "uc"],
|
|
1475
|
+
"gate_rule": "scope.kind !== 'all' ⇒ FAIL G2, không ngoại lệ",
|
|
1476
|
+
"flags": [
|
|
1477
|
+
{ "flag": "--domain", "kind": "domain", "arg": "{domain}" },
|
|
1478
|
+
{ "flag": "--prd", "kind": "prd", "arg": "{TICKET-ID}" },
|
|
1479
|
+
{ "flag": "--uc", "kind": "uc", "arg": "{UC-ID}" }
|
|
1302
1480
|
]
|
|
1481
|
+
}
|
|
1303
1482
|
},
|
|
1304
1483
|
"blocking": [
|
|
1305
1484
|
{
|
|
1306
1485
|
"counter": "orphaned_count",
|
|
1307
1486
|
"issues_key": "orphaned",
|
|
1308
|
-
"label_fields": [
|
|
1487
|
+
"label_fields": [
|
|
1488
|
+
"sc_id",
|
|
1489
|
+
"platform"
|
|
1490
|
+
],
|
|
1309
1491
|
"why": "code + test còn trỏ vào scenario đã bị xoá khỏi .feature"
|
|
1310
1492
|
},
|
|
1311
1493
|
{
|
|
1312
1494
|
"counter": "trace_orphan_count",
|
|
1313
1495
|
"issues_key": "trace_orphan",
|
|
1314
|
-
"label_fields": [
|
|
1496
|
+
"label_fields": [
|
|
1497
|
+
"sc_id",
|
|
1498
|
+
"file"
|
|
1499
|
+
],
|
|
1315
1500
|
"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
1501
|
},
|
|
1317
1502
|
{
|
|
1318
1503
|
"counter": "seam_unwired_count",
|
|
1319
1504
|
"issues_key": "seam_unwired",
|
|
1320
|
-
"label_fields": [
|
|
1505
|
+
"label_fields": [
|
|
1506
|
+
"port",
|
|
1507
|
+
"consumer_uc"
|
|
1508
|
+
],
|
|
1321
1509
|
"why": "luồng ghép đang chạy vào stub thay vì hàng thật"
|
|
1322
1510
|
},
|
|
1323
1511
|
{
|
|
1324
1512
|
"counter": "stub_unresolved_count",
|
|
1325
1513
|
"issues_key": "stub_unresolved",
|
|
1326
|
-
"label_fields": [
|
|
1514
|
+
"label_fields": [
|
|
1515
|
+
"artifact",
|
|
1516
|
+
"consumer_uc"
|
|
1517
|
+
],
|
|
1327
1518
|
"why": "hàm rỗng chưa được lấp, nhưng caller đã gọi"
|
|
1328
1519
|
}
|
|
1329
1520
|
],
|
|
@@ -1339,7 +1530,9 @@
|
|
|
1339
1530
|
"soft = lệch thì WARN (phụ thuộc quy ước đếm — vd ORPHANED được report biểu diễn bằng",
|
|
1340
1531
|
"boolean `orphaned` chứ không phải giá trị `status`, nên không ép cứng)."
|
|
1341
1532
|
],
|
|
1342
|
-
"hard": {
|
|
1533
|
+
"hard": {
|
|
1534
|
+
"total_scs": "số row dữ liệu trong mọi TSV thuộc phạm vi report"
|
|
1535
|
+
},
|
|
1343
1536
|
"soft": {
|
|
1344
1537
|
"drift_count": "DRIFT",
|
|
1345
1538
|
"gap_count": "GAP",
|
|
@@ -1363,13 +1556,207 @@
|
|
|
1363
1556
|
"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
1557
|
"lại /validate-traces không phải là lỗi của họ."
|
|
1365
1558
|
],
|
|
1366
|
-
"key_fields": [
|
|
1559
|
+
"key_fields": [
|
|
1560
|
+
"sc_id",
|
|
1561
|
+
"platform"
|
|
1562
|
+
],
|
|
1367
1563
|
"compare": "status",
|
|
1368
1564
|
"orphaned_flag": "orphaned",
|
|
1369
1565
|
"orphaned_status": "ORPHANED"
|
|
1370
1566
|
}
|
|
1371
1567
|
}
|
|
1372
1568
|
},
|
|
1569
|
+
"changelog_row_contract": {
|
|
1570
|
+
"$comment": [
|
|
1571
|
+
"DÒNG CHANGELOG LÀ CONTRACT MÁY ĐỌC (G52 · G53 · G58).",
|
|
1572
|
+
"",
|
|
1573
|
+
"PRD phủ nhiều UC nhưng `Version` là MỘT scalar; tech-doc gộp cấp PRD phủ nhiều UC",
|
|
1574
|
+
"nhưng `@trace.revision` cũng là một scalar. Nên sửa một UC làm MỌI UC lệch version.",
|
|
1575
|
+
"Bộ lọc ở validate-traces Step 4/5 chống báo động oan bằng cách đọc dòng changelog để",
|
|
1576
|
+
"biết lần bump đó ĐỤNG UC NÀO — nên dòng đó không phải văn xuôi cho người đọc, nó là",
|
|
1577
|
+
"ĐẦU VÀO của một phép phân loại 🟠-vs-ⓘ.",
|
|
1578
|
+
"",
|
|
1579
|
+
"VÌ SAO CẦN KHỐI NÀY: trước đó contract này là contract DUY NHẤT có consumer ĐƯỢC CANH",
|
|
1580
|
+
"(R1–R11 canh tên cột/field) mà KHÔNG producer nào được canh. Bốn lệnh ghi nó, ba hình",
|
|
1581
|
+
"dạng khác nhau, không ai kiểm — và hỏng theo CẢ HAI hướng:",
|
|
1582
|
+
" G52 /review-context --fix ghi `Auto-fix: applied {N} findings` — 0 scope ⇒ 🟠 cho MỌI",
|
|
1583
|
+
" UC. Lệnh chạy thường xuyên nhất trong lane PO là lệnh gây nhiễu nhất; sau vài",
|
|
1584
|
+
" sprint PRD_DRIFT sáng thường trực và không ai đọc nữa — mất luôn cờ đúng.",
|
|
1585
|
+
" G53 /extend-prd ghi `sửa BR8` — nêu BR mà KHÔNG nêu UC sở hữu ⇒ UC đổi thật bị xếp ⓘ",
|
|
1586
|
+
" ⇒ rào của `--realign-prd-version` (chỉ chặn 🟠) MỞ CỬA ⇒ nhãn version bị dán lại",
|
|
1587
|
+
" trên một BR vừa đổi hành vi. Đây là hướng IM LẶNG, nặng hơn hướng ỒN.",
|
|
1588
|
+
" G58 /generate-tech-docs chỉ nói `thêm một row Changelog` — không format, không ví dụ.",
|
|
1589
|
+
" Chưa nổ vì comment trong template tình cờ đúng. Nợ chờ lệch.",
|
|
1590
|
+
"",
|
|
1591
|
+
"LỜI GIẢI ĐÃ TỒN TẠI TRONG CHÍNH FRAMEWORK: nhánh BDD của review-context Fix Mode",
|
|
1592
|
+
"Phase 3 làm đúng chuẩn — bump `sc_version` theo TỪNG scenario bị đụng, liệt kê check",
|
|
1593
|
+
"nào đổi thân scenario, và nói thẳng lý do (`bump vô cớ tạo DRIFT giả và làm cờ mất giá",
|
|
1594
|
+
"trị`). Nhánh PRD ngay trên nó thì không. Khối này chỉ nâng cách làm đó lên thành",
|
|
1595
|
+
"contract cho cả bốn producer.",
|
|
1596
|
+
"",
|
|
1597
|
+
"self-check R12 là phần `máy canh`: producer phải nhắc `scope_token`, consumer phải",
|
|
1598
|
+
"nhắc `scope_token` + `neutral_marker` + `resolve_to_uc.anchor`. Marker được GHI mà",
|
|
1599
|
+
"consumer không HIỂU thì tệ hơn không có marker — nó bị coi là văn xuôi và lọt im lặng."
|
|
1600
|
+
],
|
|
1601
|
+
"scope_token": "{changelog_scope}",
|
|
1602
|
+
"scope_grammar": "Mỗi mệnh đề mở đầu bằng ĐƠN VỊ SỞ HỮU rồi tới mô tả: `{UC-ID}: {mô tả}`. Nhiều mệnh đề ngăn bằng `;`. Nội dung không thuộc UC nào → `PRD-global: {mô tả}`. BR/AC luôn đi KÈM UC sở hữu (`UC3: sửa BR8`) và KHÔNG BAO GIỜ đứng một mình (`sửa BR8`) — consumer khớp theo UC, nên một BR đứng một mình làm UC sở hữu nó bị xếp ⓘ trong khi nội dung của nó vừa đổi.",
|
|
1603
|
+
"ambiguous_fallback": "Không mệnh đề nào nêu được đơn vị sở hữu → consumer coi row là MƠ HỒ và gắn 🟠 cho MỌI UC (lưới an toàn: không suy đoán được thì quét rộng). Đây là hành vi ĐÚNG khi thiếu thông tin — nhưng là hành vi SAI khi producer CÓ thông tin mà không ghi.",
|
|
1604
|
+
"neutral_marker": "[no-behavior]",
|
|
1605
|
+
"neutral_semantics": "Hậu tố đặt sau một mệnh đề mà producer CHỨNG MINH ĐƯỢC là không đổi hành vi. Consumer: UC nêu trong mệnh đề có marker này KHÔNG bị 🟠 — nó ở lại ⓘ. Chỉ producer nào biết chính xác loại fix mình vừa áp mới được dùng; KHÔNG dùng cho người tự khai.",
|
|
1606
|
+
"neutral_checks": [
|
|
1607
|
+
{ "check": "P4:skeleton", "why": "thêm section/metadata skeleton còn THIẾU — cấu trúc, không có nội dung nghiệp vụ nào mới" },
|
|
1608
|
+
{ "check": "P4:status-row", "why": "thêm `| **Status** | draft |` khi row vắng — giá trị mặc định, không phải quyết định nghiệp vụ" },
|
|
1609
|
+
{ "check": "P4:drop-empty-api-section", "why": "xoá section `Existing API Contract` RỖNG ở greenfield — xoá chỗ trống" }
|
|
1610
|
+
],
|
|
1611
|
+
"not_neutral_checks": [
|
|
1612
|
+
{ "check": "P1:banned-term", "why": "term đó cũng nằm trong .feature đã sinh — BDD lỗi thời THẬT về thuật ngữ (B2/C4 sẽ bắt). Đổi từ trong PRD mà không nêu UC là bỏ sót, không phải trung tính." },
|
|
1613
|
+
{ "check": "P1:tech-jargon", "why": "auto-fix của nó là `diễn đạt lại` / `chuyển Design Spec` / `bỏ về Tech Docs` — VIẾT LẠI câu văn AC/BR, và nhánh 2/3 LẤY nội dung ra khỏi PRD. Không chứng minh được là trung tính." }
|
|
1614
|
+
],
|
|
1615
|
+
"resolve_to_uc": {
|
|
1616
|
+
"required": true,
|
|
1617
|
+
"anchor": "BR/AC → UC sở hữu",
|
|
1618
|
+
"how": "Chuẩn hoá tập bị ảnh hưởng VỀ UC trước khi so: BR → UC có BR đó trong bảng Business Rule (PRD §3); AC → UC có AC đó ở dòng `**AC liên quan:**`. Không có bước này thì phép thử `UC này có trong tập?` luôn FALSE cho một row chỉ nêu BR/AC ⇒ ⓘ sai (G53). Step 4 đã mở file PRD nên không phát sinh I/O.",
|
|
1619
|
+
"fallback": "BR/AC không phân giải được về UC nào (ID đã bị xoá, hoặc PRD lệch cấu trúc) → coi row là MƠ HỒ (🟠 cho mọi UC), KHÔNG bỏ qua mệnh đề đó."
|
|
1620
|
+
},
|
|
1621
|
+
"producers": [
|
|
1622
|
+
{ "cmd": "refine-prd", "artifact": "PRD", "where": "Phase 3", "scope_source": "`uc_id` / `section` của các finding được chấp nhận" },
|
|
1623
|
+
{ "cmd": "extend-prd", "artifact": "PRD", "where": "Bước 6", "scope_source": "UC mới + UC SỞ HỮU mỗi BR/AC bị sửa (kết luận của Bước 3.2)" },
|
|
1624
|
+
{ "cmd": "amend-prd", "artifact": "PRD", "where": "Bước 5", "scope_source": "UC SỞ HỮU của mỗi ID mà PO khai tường minh ở Bước 1 (`amend_targets`)" },
|
|
1625
|
+
{ "cmd": "review-context", "artifact": "PRD", "where": "Fix Mode Phase 3", "scope_source": "`uc_id` của mọi finding `status: applied` (findings YAML — field bắt buộc)", "emits_neutral_marker": true, "why_emits": "nó là producer DUY NHẤT biết chính xác `check_id` của từng fix vừa áp, nên là producer duy nhất chứng minh được tính trung tính" },
|
|
1626
|
+
{ "cmd": "generate-tech-docs", "artifact": "tech-design.md", "where": "Bước 1 (APPEND) + §Sinh", "scope_source": "UC trong `input_features` của batch vừa thêm/sửa" }
|
|
1627
|
+
],
|
|
1628
|
+
"consumers": [
|
|
1629
|
+
{ "cmd": "validate-traces", "where": "Step 4 (PRD) · Step 5 (tech-doc)", "use": "phân loại 🟠 DRIFT vs ⓘ STALE_REF theo từng UC" },
|
|
1630
|
+
{ "cmd": "generate-bdd", "where": "Version Check", "use": "khuyến nghị Y (cập nhật hẹp) vs F (gen lại toàn bộ)" }
|
|
1631
|
+
]
|
|
1632
|
+
},
|
|
1633
|
+
"spec_edit_detection": {
|
|
1634
|
+
"$comment": [
|
|
1635
|
+
"PHÁT HIỆN SỬA TÀI LIỆU NGOÀI ĐƯỜNG CHÍNH THỨC (G54, nửa sau).",
|
|
1636
|
+
"",
|
|
1637
|
+
"TOÀN BỘ lưới an toàn của framework so NHÃN VERSION, không so NỘI DUNG — không có một",
|
|
1638
|
+
"content hash nào ở đâu. Nên một PRD bị sửa tay mà không bump version là điểm mù TUYỆT",
|
|
1639
|
+
"ĐỐI: validate-traces thấy `PRD version == prd_version` ⇒ sạch · gate-trace thấy report",
|
|
1640
|
+
"khớp sổ ⇒ PASS · require-fresh-audit thấy PR không chạm tag ⇒ không đòi audit. Cả ba",
|
|
1641
|
+
"tầng xanh, và cả ba ĐÚNG theo định nghĩa của chính chúng.",
|
|
1642
|
+
"",
|
|
1643
|
+
"Và G54 không chỉ CHO PHÉP sửa tay — nó ĐẨY người dùng về đó: /generate-prd DỪNG HẲN trên",
|
|
1644
|
+
"file đã có (§Guard: 'Tồn tại → DỪNG. KHÔNG ghi, KHÔNG hỏi Y/N') · /extend-prd chỉ",
|
|
1645
|
+
"add-only · /refine-prd chỉ áp được finding do chính nó tìm ra. Trước /amend-prd, hành",
|
|
1646
|
+
"vi hợp lý duy nhất còn lại LÀ mở file .md ra gõ. Thiết kế tự tạo ra con đường nó không",
|
|
1647
|
+
"canh được.",
|
|
1648
|
+
"",
|
|
1649
|
+
"VÌ SAO KHÔNG DÙNG CONTENT HASH: git đã băm nội dung hộ rồi. Thêm một cột hash vào sổ",
|
|
1650
|
+
"TSV là thêm một thứ ghi-tay-bởi-LLM (đúng lớp lỗi G38 mà lint-trace tồn tại để chống),",
|
|
1651
|
+
"trong khi `git diff` trả lời chính xác cùng câu hỏi và không sai được.",
|
|
1652
|
+
"",
|
|
1653
|
+
"VÌ SAO KHÔNG NẰM TRONG `gate.blocking` — quyết định có chủ ý, không phải bỏ sót:",
|
|
1654
|
+
" 1. `gate.blocking` có nghĩa HẸP là CODE ĐANG HỎNG, và R9(e) tồn tại để giữ ranh giới",
|
|
1655
|
+
" đó. Cờ này nói về SPEC; code có thể đang hoàn toàn đúng.",
|
|
1656
|
+
" 2. Nợ tồn khi mới bật: mọi project đang chạy đều đã có PRD sửa tay. Một cờ chặn mới",
|
|
1657
|
+
" sẽ đỏ khắp nơi ở lần chạy đầu ⇒ người ta TẮT CỔNG ⇒ mất luôn 4 cờ 🔴 thật. Đó",
|
|
1658
|
+
" đúng là thất bại R9(e) được viết ra để chặn, chỉ đến bằng một cửa khác.",
|
|
1659
|
+
" 3. Nó vẫn 🔴 trong REPORT và in mỗi lần chạy — đủ để thấy, không đủ để làm tắt cổng.",
|
|
1660
|
+
"Team nào đã dọn sạch nợ tồn thì tự thêm counter này vào `gate.blocking`; một dòng.",
|
|
1661
|
+
"",
|
|
1662
|
+
"ĐƯỜNG RA TỰ LÀNH — cố ý KHÔNG có lệnh escape riêng: cách sửa đúng là bump version +",
|
|
1663
|
+
"ghi một row changelog (tức chính việc /amend-prd làm hộ). Làm xong thì",
|
|
1664
|
+
"`version != version_at_audit` ⇒ cờ tự tắt, và logic PRD_DRIFT bình thường tiếp quản.",
|
|
1665
|
+
"Thêm một `--accept-edit` sẽ là thêm một đường DÁN NHÃN lên thay đổi chưa ai xem — đúng",
|
|
1666
|
+
"cái sai mà rào của `--realign` tồn tại để chặn."
|
|
1667
|
+
],
|
|
1668
|
+
"flag": "PRD_UNTRACKED_EDIT",
|
|
1669
|
+
"detects": "nội dung file PRD đã đổi kể từ lần audit trước NHƯNG nhãn `Version` không đổi ⇒ có người sửa ngoài /generate-prd · /extend-prd · /amend-prd · /refine-prd · /review-context",
|
|
1670
|
+
"baseline_fields": {
|
|
1671
|
+
"$comment": "validate-traces GHI khối này vào trace-report.json mỗi lần chạy; lần chạy sau ĐỌC nó làm mốc. Thiếu nửa GHI thì cờ không bao giờ bật — R6/R7 chỉ canh được nửa BÁO CÁO (giá trị enum có xuất hiện · counter có trong summary), nên self-check R13 canh nửa này.",
|
|
1672
|
+
"path": "spec_baseline",
|
|
1673
|
+
"keys": ["prd_path", "sha_at_audit", "version_at_audit"]
|
|
1674
|
+
},
|
|
1675
|
+
"evidence": [
|
|
1676
|
+
{ "source": "git diff", "cmd": "git -C {specs repo} diff --name-only {sha_at_audit}..HEAD -- {prd_path}", "catches": "sửa đã commit" },
|
|
1677
|
+
{ "source": "git status", "cmd": "git -C {specs repo} status --porcelain -- {prd_path}", "catches": "sửa CHƯA commit — ca thường gặp nhất khi PO đang gõ" }
|
|
1678
|
+
],
|
|
1679
|
+
"no_false_positive": "PO sửa VÀ bump version → `version != version_at_audit` → KHÔNG bật cờ. Chỉ đúng ca \"đổi nội dung, giữ nguyên nhãn\" mới bật.",
|
|
1680
|
+
"degraded": "Không phải git repo, hoặc `sha_at_audit` không còn (history bị rewrite) → BỎ QUA check này và in một dòng ⚠️ nói rõ là đang mù, KHÔNG bịa cờ và KHÔNG im lặng.",
|
|
1681
|
+
"written_by": ["validate-traces"],
|
|
1682
|
+
"read_by": ["validate-traces", "sync"],
|
|
1683
|
+
"$read_by_comment": [
|
|
1684
|
+
"`sync` đọc mốc này để trả lời câu KHÁC với câu của diff pull-to-pull (G56).",
|
|
1685
|
+
"Diff `{old_sha}..{new_sha}` trả lời \"đổi gì kể từ lần PULL trước\" — mốc đó RESET mỗi lần",
|
|
1686
|
+
"pull. Pull thứ Hai, thứ Ba, thứ Tư mà không audit lần nào thì đến thứ Năm cái thấy được chỉ",
|
|
1687
|
+
"là delta của MỘT ngày, không phải nợ đã tích. `sha_at_audit` trả lời \"đổi gì kể từ lần",
|
|
1688
|
+
"AUDIT gần nhất\" — con số đó tích luỹ đúng, không bao giờ reset sai."
|
|
1689
|
+
]
|
|
1690
|
+
},
|
|
1691
|
+
"positive_assertion_guards": {
|
|
1692
|
+
"$comment": [
|
|
1693
|
+
"QUYỀN ĐƯỢC KHẲNG ĐỊNH `pass` (G55) — mệnh đề ĐỐI NGẪU của luật G28.",
|
|
1694
|
+
"",
|
|
1695
|
+
"rules/workflow.md §\"Làm mất hiệu lực ≠ ghi đè\" nói: ai làm một giá trị HẾT ĐÚNG thì BẮT",
|
|
1696
|
+
"BUỘC hạ nó xuống. Luật đó đúng và được thực thi tốt (/generate-bdd, /generate-code,",
|
|
1697
|
+
"/fix-bug đều làm). Nhưng nửa còn lại chưa được viết: AI KHẲNG ĐỊNH MỘT GIÁ TRỊ DƯƠNG THÌ",
|
|
1698
|
+
"PHẢI KIỂM RẰNG MÌNH ĐƯỢC PHÉP KHẲNG ĐỊNH.",
|
|
1699
|
+
"",
|
|
1700
|
+
"Thiếu nửa sau nên chuỗi thành: hạ xuống → dựng lại → hạ xuống → dựng lại.",
|
|
1701
|
+
" 1. PO đổi AC → /generate-bdd đặt status=DRIFT và HẠ dev_selftest→not_run, kèm cảnh báo",
|
|
1702
|
+
" \"{n} test của {sc_id} viết cho spec cũ — /dev-gen-test rà lại trước khi chạy\".",
|
|
1703
|
+
" 2. Sáng sau dev chạy /dev-run-test (thói quen bình thường), CHƯA /generate-code, CHƯA",
|
|
1704
|
+
" /dev-gen-test. Test cũ + code cũ ⇒ xanh hết.",
|
|
1705
|
+
" 3. /dev-run-test ghi dev_selftest=pass, dev_selftest_at=HÔM NAY.",
|
|
1706
|
+
"Row giờ mang status=DRIFT + dev_selftest=pass với ngày hôm nay. Lệnh kế tiếp trong vòng",
|
|
1707
|
+
"lặp dev BÌNH THƯỜNG vừa dựng lại đúng cái tín hiệu /generate-bdd hạ xuống.",
|
|
1708
|
+
"",
|
|
1709
|
+
"VÌ SAO `status` KHÔNG TRỰC GIAO Ở ĐÂY: hai file lệnh viết `dev_selftest`/`qc_status`",
|
|
1710
|
+
"\"trực giao với status\". Trực giao về KẾT QUẢ CHẠY thì đúng. Nhưng ô này không mang nghĩa",
|
|
1711
|
+
"\"test đã chạy và xanh\" — nó mang nghĩa \"scenario này đã được nghiệm thu theo spec HIỆN",
|
|
1712
|
+
"TẠI\". Trên row DRIFT, nghĩa thứ nhất đúng và nghĩa thứ hai SAI. `pass` ở đó không phải",
|
|
1713
|
+
"kết quả sai; nó là lời khẳng định sai về điều mà kết quả đó chứng minh.",
|
|
1714
|
+
"",
|
|
1715
|
+
"TIN XẤU LUÔN HỢP LỆ: `fail` VẪN được ghi trên row DRIFT. Đây là guard cho lời khẳng định",
|
|
1716
|
+
"DƯƠNG, không phải lệnh \"bỏ qua kết quả khi DRIFT\". Test đỏ trên row DRIFT vẫn là thông",
|
|
1717
|
+
"tin thật. Chỉ `pass` cần giấy phép.",
|
|
1718
|
+
"",
|
|
1719
|
+
"VÌ SAO CẦN CẢ HAI TẦNG:",
|
|
1720
|
+
" PA-1 (lệnh đọc status trước khi ghi) chặn NGUỒN.",
|
|
1721
|
+
" PA-2 (lint-trace T12) bắt TRẠNG THÁI, bất kể ai ghi — sổ sửa tay, sổ sinh bởi version",
|
|
1722
|
+
" framework cũ, hay một lệnh tương lai quên luật. T12 rẻ, xác định, chạy được trong",
|
|
1723
|
+
" CI mà không cần LLM.",
|
|
1724
|
+
"T1–T8 kiểm HÌNH DẠNG TỪNG Ô (đủ 24 cột, giá trị trong vocabulary, ngày parse được) —",
|
|
1725
|
+
"không rule nào kiểm NHẤT QUÁN GIỮA CÁC Ô. Nên `status=DRIFT` + `dev_selftest=pass` là một",
|
|
1726
|
+
"sổ HOÀN TOÀN HỢP LỆ với cả 11 rule cũ. T12 là rule đầu tiên nhìn nhiều ô cùng lúc.",
|
|
1727
|
+
"",
|
|
1728
|
+
"LỖ ĐÃ BIẾT, chấp nhận có chủ ý: ca \"spec đổi theo hướng THÊM hành vi mới\". Sau khi",
|
|
1729
|
+
"/generate-code bắt kịp, gen_ver=spec_ver ⇒ status=OK; test cũ vẫn PASS (chúng không sai,",
|
|
1730
|
+
"chỉ KHÔNG PHỦ phần mới); test_count>0 nên không có GAP ⇒ bảng xanh trên một hành vi chưa",
|
|
1731
|
+
"test lần nào. Đóng hẳn ca này cần một cột thứ 25 `test_spec_ver` — đổi contract + lint",
|
|
1732
|
+
"binding + backward-compat với mọi sổ 24 cột đang tồn tại. Hoãn có chủ ý; guard này vẫn",
|
|
1733
|
+
"thu hẹp đáng kể vì trong lúc row còn DRIFT thì dev_selftest bị giữ ở not_run, nên dev",
|
|
1734
|
+
"buộc phải làm gì đó và đường đúng là /dev-gen-test."
|
|
1735
|
+
],
|
|
1736
|
+
"lint_rule": "T12",
|
|
1737
|
+
"blocked_when_status": ["DRIFT", "ORPHANED"],
|
|
1738
|
+
"negative_always_written": "`fail` được ghi bình thường trên MỌI status — guard này chỉ chặn giá trị KHẲNG ĐỊNH. Chặn cả `fail` là biến một guard chống-báo-cáo-sai thành một guard che-tin-xấu.",
|
|
1739
|
+
"guards": [
|
|
1740
|
+
{
|
|
1741
|
+
"column": "dev_selftest",
|
|
1742
|
+
"owner": "dev-run-test",
|
|
1743
|
+
"positive_values": ["pass"],
|
|
1744
|
+
"downgrade_to": "not_run",
|
|
1745
|
+
"companion": "dev_selftest_at",
|
|
1746
|
+
"companion_downgrade": "—",
|
|
1747
|
+
"why": "trên row DRIFT, test cũ đang nghiệm thu một hành vi không còn tồn tại; trên row ORPHANED, scenario đã bị xoá khỏi .feature nên không còn gì để nghiệm thu"
|
|
1748
|
+
},
|
|
1749
|
+
{
|
|
1750
|
+
"column": "qc_status",
|
|
1751
|
+
"owner": "qc-run-test",
|
|
1752
|
+
"positive_values": ["pass"],
|
|
1753
|
+
"downgrade_to": "not_run",
|
|
1754
|
+
"companion": "qc_run_at",
|
|
1755
|
+
"companion_downgrade": "—",
|
|
1756
|
+
"why": "đối xứng hoàn toàn với dev_selftest — `skip` KHÔNG bị chặn vì nó là giá trị trung tính, không phải lời khẳng định"
|
|
1757
|
+
}
|
|
1758
|
+
]
|
|
1759
|
+
},
|
|
1373
1760
|
"path_keys": {
|
|
1374
1761
|
"$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
1762
|
"config_file": "templates/project-context.yaml",
|
package/core/FRAMEWORK_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.7.1
|