mustflow 1.31.0 → 2.16.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.
Files changed (66) hide show
  1. package/README.md +23 -9
  2. package/dist/cli/commands/classify.js +61 -6
  3. package/dist/cli/commands/contract-lint.js +13 -4
  4. package/dist/cli/commands/dashboard.js +77 -2
  5. package/dist/cli/commands/explain-verify.js +11 -1
  6. package/dist/cli/commands/index.js +14 -0
  7. package/dist/cli/commands/run.js +4 -1
  8. package/dist/cli/commands/verify.js +986 -43
  9. package/dist/cli/i18n/en.js +61 -10
  10. package/dist/cli/i18n/es.js +61 -10
  11. package/dist/cli/i18n/fr.js +61 -10
  12. package/dist/cli/i18n/hi.js +61 -10
  13. package/dist/cli/i18n/ko.js +61 -10
  14. package/dist/cli/i18n/zh.js +61 -10
  15. package/dist/cli/lib/dashboard-export.js +62 -12
  16. package/dist/cli/lib/dashboard-html/client-script.js +1936 -0
  17. package/dist/cli/lib/dashboard-html/locale-bootstrap.js +8 -0
  18. package/dist/cli/lib/dashboard-html/styles.js +572 -0
  19. package/dist/cli/lib/dashboard-html/template.js +134 -0
  20. package/dist/cli/lib/dashboard-html/types.js +1 -0
  21. package/dist/cli/lib/dashboard-html.js +1 -1907
  22. package/dist/cli/lib/dashboard-locale.js +37 -0
  23. package/dist/cli/lib/local-index/constants.js +48 -0
  24. package/dist/cli/lib/local-index/index.js +2951 -0
  25. package/dist/cli/lib/local-index/sql.js +15 -0
  26. package/dist/cli/lib/local-index/types.js +1 -0
  27. package/dist/cli/lib/local-index.js +1 -1911
  28. package/dist/cli/lib/run-plan.js +76 -1
  29. package/dist/cli/lib/templates.js +18 -1
  30. package/dist/cli/lib/validation/command-intents.js +11 -0
  31. package/dist/cli/lib/validation/constants.js +238 -0
  32. package/dist/cli/lib/validation/index.js +1384 -0
  33. package/dist/cli/lib/validation/primitives.js +198 -0
  34. package/dist/cli/lib/validation/test-selection.js +95 -0
  35. package/dist/cli/lib/validation/types.js +1 -0
  36. package/dist/cli/lib/validation.js +1 -1770
  37. package/dist/core/check-issues.js +6 -0
  38. package/dist/core/completion-verdict.js +341 -0
  39. package/dist/core/contract-lint.js +221 -6
  40. package/dist/core/external-evidence.js +9 -0
  41. package/dist/core/public-json-contracts.js +21 -0
  42. package/dist/core/repeated-failure.js +179 -0
  43. package/dist/core/repro-evidence.js +134 -0
  44. package/dist/core/scope-risk.js +64 -0
  45. package/dist/core/skill-route-alignment.js +20 -0
  46. package/dist/core/source-anchor-status.js +4 -1
  47. package/dist/core/test-selection.js +3 -0
  48. package/dist/core/validation-ratchet.js +196 -0
  49. package/dist/core/verification-evidence.js +249 -0
  50. package/examples/README.md +12 -4
  51. package/package.json +3 -3
  52. package/schemas/README.md +13 -3
  53. package/schemas/change-verification-report.schema.json +16 -2
  54. package/schemas/commands.schema.json +4 -0
  55. package/schemas/contract-lint-report.schema.json +29 -0
  56. package/schemas/dashboard-export.schema.json +310 -0
  57. package/schemas/explain-report.schema.json +173 -1
  58. package/schemas/latest-run-pointer.schema.json +601 -0
  59. package/schemas/run-receipt.schema.json +4 -0
  60. package/schemas/test-selection.schema.json +81 -0
  61. package/schemas/verify-report.schema.json +578 -1
  62. package/schemas/verify-run-manifest.schema.json +627 -0
  63. package/templates/default/i18n.toml +1 -1
  64. package/templates/default/locales/en/.mustflow/skills/INDEX.md +124 -29
  65. package/templates/default/locales/en/.mustflow/skills/routes.toml +289 -0
  66. package/templates/default/manifest.toml +29 -2
@@ -56,6 +56,7 @@ export const hiMessages = {
56
56
  "check.result.strictPassed": "mustflow strict check पास हुआ",
57
57
  "contractLint.help.summary": ".mustflow/config/commands.toml में command-contract errors और warnings जाँचें.",
58
58
  "contractLint.help.option.coverage": "change-classification reasons के लिए required_after coverage भी report करें",
59
+ "contractLint.help.option.suggest": "package.json, Makefile, या justfile से non-runnable intent snippets सुझाएँ",
59
60
  "contractLint.help.exit.ok": "कमांड अनुबंध बिना blocking errors के जाँचा गया",
60
61
  "contractLint.help.exit.fail": "कमांड अनुबंध errors मिले या input अमान्य था",
61
62
  "contractLint.title": "mustflow contract-lint",
@@ -73,6 +74,7 @@ export const hiMessages = {
73
74
  "contractLint.label.requiredAfterReasons": "required_after reasons",
74
75
  "contractLint.label.runnableReasons": "Runnable reasons",
75
76
  "contractLint.label.coverageFindings": "Coverage findings",
77
+ "contractLint.label.suggestions": "Suggestions",
76
78
  "contractLint.label.issues": "Issues",
77
79
  "context.help.summary": "वर्तमान mustflow रूट के लिए एजेंट संदर्भ प्रिंट करें।",
78
80
  "context.help.option.json": "मशीन-पठनीय संदर्भ JSON प्रिंट करें",
@@ -149,12 +151,28 @@ export const hiMessages = {
149
151
  "dashboard.ui.unsavedChanges": "बिना सहेजे बदलाव",
150
152
  "dashboard.ui.reloaded": "फिर से लोड हुआ",
151
153
  "dashboard.ui.saved": "सहेजा गया",
154
+ "dashboard.ui.loading": "लोड हो रहा है",
155
+ "dashboard.ui.lastUpdated": "आखिरी अपडेट: {time}",
156
+ "dashboard.ui.copied": "कॉपी हुआ",
152
157
  "dashboard.ui.reload": "फिर से लोड करें",
153
158
  "dashboard.ui.save": "सहेजें",
154
159
  "dashboard.ui.locked": "लॉक है",
155
160
  "dashboard.ui.customLocale": "कस्टम भाषा टैग",
156
161
  "dashboard.ui.openMustflow": ".mustflow फ़ोल्डर खोलें",
157
162
  "dashboard.ui.openedMustflow": ".mustflow फ़ोल्डर खोला गया",
163
+ "dashboard.settings.pendingHeading": "बिना सहेजी सेटिंग्स ({count})",
164
+ "dashboard.settings.pendingItem": "{name}: {from} -> {to}",
165
+ "dashboard.settings.resetChanges": "बदलाव रीसेट करें",
166
+ "dashboard.filter.search": "खोज",
167
+ "dashboard.filter.searchPlaceholder": "नाम, path, command या कारण",
168
+ "dashboard.filter.state": "स्थिति",
169
+ "dashboard.filter.all": "सभी",
170
+ "dashboard.filter.runnable": "चलाने योग्य",
171
+ "dashboard.filter.unavailable": "उपलब्ध नहीं",
172
+ "dashboard.filter.aligned": "Aligned",
173
+ "dashboard.filter.mismatch": "Mismatch",
174
+ "dashboard.filter.missing": "Missing",
175
+ "dashboard.filter.noMatches": "मेल खाते item नहीं मिले।",
158
176
  "dashboard.tab.status": "स्थिति",
159
177
  "dashboard.tab.verification": "सत्यापन सुझाव",
160
178
  "dashboard.tab.commands": "कमांड",
@@ -164,6 +182,24 @@ export const hiMessages = {
164
182
  "dashboard.tab.skills": "स्किल",
165
183
  "dashboard.tab.settings": "सेटिंग्स",
166
184
  "dashboard.tab.documents": "दस्तावेज़ समीक्षा",
185
+ "dashboard.actions.heading": "अगले काम",
186
+ "dashboard.actions.empty": "कोई काम नहीं।",
187
+ "dashboard.actions.missingFiles": "Missing files: {count}",
188
+ "dashboard.actions.manifestIssues": "समस्याएँ: {count}",
189
+ "dashboard.actions.verification": "सत्यापन सुझाव: {count}",
190
+ "dashboard.actions.updateBlockers": "अपडेट रोकने वाली चीज़ें: {count}",
191
+ "dashboard.actions.documents": "Review वाले दस्तावेज़: {count}",
192
+ "dashboard.actions.latestRun": "Latest run देखना है",
193
+ "dashboard.actions.openStatus": "स्थिति खोलें",
194
+ "dashboard.actions.openVerification": "सत्यापन खोलें",
195
+ "dashboard.actions.openUpdate": "अपडेट खोलें",
196
+ "dashboard.actions.openDocuments": "दस्तावेज़ खोलें",
197
+ "dashboard.actions.openRuns": "रन इतिहास खोलें",
198
+ "dashboard.a11y.state.ok": "ठीक",
199
+ "dashboard.a11y.state.warn": "ध्यान चाहिए",
200
+ "dashboard.a11y.state.neutral": "स्थिति",
201
+ "dashboard.a11y.copyCommand": "कमांड कॉपी करें: {command}",
202
+ "dashboard.a11y.copyVerificationPlan": "सत्यापन योजना कॉपी करें",
167
203
  "dashboard.status.reloaded": "स्थिति फिर से लोड हुई",
168
204
  "dashboard.status.overview": "सारांश",
169
205
  "dashboard.status.installed": "स्थापित",
@@ -322,6 +358,8 @@ export const hiMessages = {
322
358
  "dashboard.docs.reviewerKind": "Reviewer प्रकार",
323
359
  "dashboard.docs.reviewerId": "Reviewer ID",
324
360
  "dashboard.docs.reviewerIdPlaceholder": "व्यक्ति, LLM या tool-id",
361
+ "dashboard.docs.reviewerState": "{kind}: {id} के रूप में समीक्षा",
362
+ "dashboard.docs.reviewerStateMissing": "समीक्षा actions से पहले Reviewer ID दर्ज करें।",
325
363
  "dashboard.docs.summary": "समीक्षा सारांश",
326
364
  "dashboard.docs.summaryPlaceholder": "वैकल्पिक",
327
365
  "dashboard.docs.comment": "टिप्पणी",
@@ -350,6 +388,7 @@ export const hiMessages = {
350
388
  "dashboard.docs.action.needsReview.tooltip": "इस दस्तावेज को व्यक्ति, LLM, tool या बाहरी प्रक्रिया से फिर समीक्षा के लिए चिह्नित करें।",
351
389
  "dashboard.docs.action.ignore": "अनदेखा करें",
352
390
  "dashboard.docs.action.ignore.tooltip": "इस दस्तावेज की समीक्षा छोड़ें और default सूची से छिपाएं।",
391
+ "dashboard.docs.action.currentStatus": "पहले से {status}",
353
392
  "dashboard.locked.git.auto_push": "Remote push के लिए स्पष्ट अनुरोध आवश्यक है।",
354
393
  "dashboard.group.git": "Git",
355
394
  "dashboard.group.commitMessage": "Commit संदेश",
@@ -525,7 +564,7 @@ export const hiMessages = {
525
564
  "init.help.option.interactive": "प्रॉम्प्ट से init सेटिंग्स चुनें",
526
565
  "init.help.option.merge": "मौजूदा AGENTS.md में mustflow प्रबंधित ब्लॉक मिलाएँ",
527
566
  "init.help.option.force": "टकराती फ़ाइलों का बैकअप लेकर उन्हें overwrite करें",
528
- "init.help.option.profile": "प्रोजेक्ट profile सेट करें: minimal, oss, team, product या library",
567
+ "init.help.option.profile": "प्रोजेक्ट profile सेट करें: minimal, patterns, oss, team, product या library",
529
568
  "init.help.option.locale": "इंस्टॉल किए गए mustflow दस्तावेज़ों की भाषा सेट करें",
530
569
  "init.help.option.agentLang": "पसंदीदा एजेंट प्रतिक्रिया भाषा सेट करें",
531
570
  "init.help.option.set": "git.auto_commit=true या git.auto_push=false जैसी सुरक्षित preference सेट करें",
@@ -612,6 +651,7 @@ export const hiMessages = {
612
651
  "run.help.option.json": "Run record या command plan को JSON के रूप में प्रिंट करें",
613
652
  "run.help.exit.ok": "कमांड अनुमत exit code के साथ पूरी हुई",
614
653
  "run.help.exit.fail": "कमांड अमान्य थी, अस्वीकार हुई, timed out हुई या विफल हुई",
654
+ "run.label.suggestedIntentSnippet": "Suggested command contract snippet",
615
655
  "run.error.missingIntent": "कमांड नाम नहीं दिया गया",
616
656
  "run.error.unknownIntent": "अज्ञात कमांड: {intent}",
617
657
  "run.error.statusNotConfigured": 'कमांड "{intent}" {status} है; केवल configured कमांड चलाई जा सकती हैं',
@@ -670,8 +710,9 @@ export const hiMessages = {
670
710
  "upgrade.noFilesWritten": "कोई project file नहीं लिखी गई.",
671
711
  "upgrade.warning.versionCheckFailed": "npm पर नया version जाँचा नहीं जा सका: {message}",
672
712
  "upgrade.warning.continueWithBundledTemplate": "Current CLI में bundled template के साथ आगे बढ़ रहे हैं.",
673
- "classify.help.summary": "फ़ाइल बदले बिना बदले पथ, सार्वजनिक सतह और जरूरी सत्यापन कारण वर्गीकृत करें.",
713
+ "classify.help.summary": "बदले पथ, सार्वजनिक सतह और जरूरी सत्यापन कारण वर्गीकृत करें.",
674
714
  "classify.help.option.changed": "git status --short --untracked-files=all से पथ पढ़ें",
715
+ "classify.help.option.write": "Classification report को इस repository के अंदर JSON file में लिखें",
675
716
  "classify.help.exit.ok": "बदलाव वर्गीकरण जांचकर प्रिंट किया गया",
676
717
  "classify.title": "mustflow classify",
677
718
  "classify.label.source": "स्रोत",
@@ -686,6 +727,7 @@ export const hiMessages = {
686
727
  "classify.source.changed": "बदली फ़ाइलें",
687
728
  "classify.source.paths": "दिए गए पथ",
688
729
  "classify.error.missingInput": "--changed या कम से कम एक पथ दें",
730
+ "classify.error.write_path_outside_root": "Classification report path mustflow root के अंदर रहना चाहिए",
689
731
  "impact.help.summary": "फ़ाइल बदले बिना बताएं कि बदले पथ package या template version decision मांगते हैं या नहीं.",
690
732
  "impact.help.option.changed": "git status --short --untracked-files=all से पथ पढ़ें",
691
733
  "impact.help.exit.ok": "Version impact जांचकर प्रिंट किया गया",
@@ -701,9 +743,12 @@ export const hiMessages = {
701
743
  "impact.error.missingInput": "--changed या कम से कम एक पथ दें",
702
744
  "verify.help.summary": "required_after metadata से चुने गए configured verification intents चलाएँ।",
703
745
  "verify.help.option.reason": "Verify करने के लिए required_after reason चुनें",
704
- "verify.help.option.fromPlan": "इस repository के अंदर JSON plan से verification reasons पढ़ें",
746
+ "verify.help.option.fromClassification": "इस repository के अंदर mf classify report से verification reasons पढ़ें",
747
+ "verify.help.option.fromPlan": "--from-classification का compatibility alias",
705
748
  "verify.help.option.changed": "Current Git changes classify करके matching reasons verify करें",
706
- "verify.help.option.writePlan": "Changed-file classification plan इस repository के अंदर लिखें",
749
+ "verify.help.option.writePlan": "Changed-file classification report लिखने वाला compatibility option",
750
+ "verify.help.option.reproEvidence": "Repository-local JSON summary से structured bug reproduction evidence पढ़ें",
751
+ "verify.help.option.externalEvidence": "Repository-local JSON summary से lower-authority external CI evidence पढ़ें",
707
752
  "verify.help.option.planOnly": "Commands चलाए बिना verification plan print करें; --json चाहिए",
708
753
  "verify.help.exit.ok": "सभी selected verification intents pass हुए",
709
754
  "verify.help.exit.fail": "Verification fail हुआ, partial रहा, blocked रहा, या input invalid था",
@@ -713,14 +758,20 @@ export const hiMessages = {
713
758
  "verify.label.status": "Status",
714
759
  "verify.label.results": "Results",
715
760
  "verify.error.missingReason": "Verification reason missing है",
716
- "verify.error.conflictingInputs": "--reason, --from-plan, या --changed में से केवल एक इस्तेमाल करें",
761
+ "verify.error.conflictingInputs": "--reason, --from-classification, --from-plan, या --changed में से केवल एक इस्तेमाल करें",
717
762
  "verify.error.writePlanRequiresChanged": "--write-plan के लिए --changed चाहिए",
718
763
  "verify.error.planOnlyJson": "--plan-only के लिए --json चाहिए",
719
- "verify.error.invalid_plan_file": "Verification plan readable JSON file होना चाहिए",
720
- "verify.error.unsupported_plan_source": "Verification plan mf classify --json से बना होना चाहिए",
721
- "verify.error.plan_root_mismatch": "Verification plan इसी mustflow root से आना चाहिए",
722
- "verify.error.missing_plan_reasons": "Verification plan में summary.validationReasons होना चाहिए",
723
- "verify.error.plan_path_outside_root": "Verification plan path mustflow root के अंदर रहना चाहिए",
764
+ "verify.error.reproEvidenceRequiresRun": "--repro-evidence को --plan-only के साथ इस्तेमाल नहीं किया जा सकता",
765
+ "verify.error.externalEvidenceRequiresRun": "--external-evidence को --plan-only के साथ इस्तेमाल नहीं किया जा सकता",
766
+ "verify.error.invalid_plan_file": "Classification report readable JSON file होना चाहिए",
767
+ "verify.error.unsupported_plan_source": "Verification input mf classify report होना चाहिए",
768
+ "verify.error.plan_root_mismatch": "Classification report इसी mustflow root से आना चाहिए",
769
+ "verify.error.missing_plan_reasons": "Classification report में summary.validationReasons होना चाहिए",
770
+ "verify.error.plan_path_outside_root": "Classification report path mustflow root के अंदर रहना चाहिए",
771
+ "verify.error.invalid_repro_evidence_file": "Repro evidence structured evidence fields वाला readable JSON summary होना चाहिए",
772
+ "verify.error.unsupported_repro_evidence_source": "Repro evidence input को command repro-evidence इस्तेमाल करना चाहिए",
773
+ "verify.error.invalid_external_evidence_file": "External evidence checks वाला readable JSON summary होना चाहिए",
774
+ "verify.error.unsupported_external_evidence_source": "External evidence input को command external-evidence इस्तेमाल करना चाहिए",
724
775
  "explain.help.summary": "फ़ाइलें बदले बिना समझाएँ कि mustflow policy decision क्यों लागू होता है।",
725
776
  "explain.help.exit.ok": "Policy decision जाँचा और प्रिंट किया गया",
726
777
  "explain.title": "mustflow explain",
@@ -56,6 +56,7 @@ export const koMessages = {
56
56
  "check.result.strictPassed": "mustflow 엄격 검사 통과",
57
57
  "contractLint.help.summary": ".mustflow/config/commands.toml의 명령 계약 오류와 경고를 확인합니다.",
58
58
  "contractLint.help.option.coverage": "변경 분류 이유에 대한 required_after 연결 상태도 보고합니다",
59
+ "contractLint.help.option.suggest": "package.json, Makefile, justfile에서 실행 불가 후보 조각을 제안합니다",
59
60
  "contractLint.help.exit.ok": "차단 오류 없이 명령 계약을 확인했습니다",
60
61
  "contractLint.help.exit.fail": "명령 계약 오류가 있거나 입력이 잘못되었습니다",
61
62
  "contractLint.title": "mustflow 명령 계약 점검",
@@ -73,6 +74,7 @@ export const koMessages = {
73
74
  "contractLint.label.requiredAfterReasons": "required_after 이유",
74
75
  "contractLint.label.runnableReasons": "실행 가능한 이유",
75
76
  "contractLint.label.coverageFindings": "연결 상태 발견 항목",
77
+ "contractLint.label.suggestions": "제안",
76
78
  "contractLint.label.issues": "문제",
77
79
  "context.help.summary": "현재 mustflow 루트의 에이전트 작업 맥락을 출력합니다.",
78
80
  "context.help.option.json": "맥락을 JSON 형식으로 출력합니다",
@@ -149,12 +151,28 @@ export const koMessages = {
149
151
  "dashboard.ui.unsavedChanges": "저장하지 않은 변경",
150
152
  "dashboard.ui.reloaded": "다시 불러왔습니다",
151
153
  "dashboard.ui.saved": "저장했습니다",
154
+ "dashboard.ui.loading": "불러오는 중",
155
+ "dashboard.ui.lastUpdated": "마지막 갱신: {time}",
156
+ "dashboard.ui.copied": "복사됨",
152
157
  "dashboard.ui.reload": "새로고침",
153
158
  "dashboard.ui.save": "저장",
154
159
  "dashboard.ui.locked": "잠김",
155
160
  "dashboard.ui.customLocale": "직접 입력",
156
161
  "dashboard.ui.openMustflow": ".mustflow 폴더 열기",
157
162
  "dashboard.ui.openedMustflow": ".mustflow 폴더를 열었습니다",
163
+ "dashboard.settings.pendingHeading": "저장 전 설정 ({count})",
164
+ "dashboard.settings.pendingItem": "{name}: {from} -> {to}",
165
+ "dashboard.settings.resetChanges": "변경 되돌리기",
166
+ "dashboard.filter.search": "검색",
167
+ "dashboard.filter.searchPlaceholder": "이름, 경로, 명령, 이유",
168
+ "dashboard.filter.state": "상태",
169
+ "dashboard.filter.all": "전체",
170
+ "dashboard.filter.runnable": "실행 가능",
171
+ "dashboard.filter.unavailable": "사용 불가",
172
+ "dashboard.filter.aligned": "일치",
173
+ "dashboard.filter.mismatch": "불일치",
174
+ "dashboard.filter.missing": "누락",
175
+ "dashboard.filter.noMatches": "일치하는 항목이 없습니다.",
158
176
  "dashboard.tab.status": "상태",
159
177
  "dashboard.tab.verification": "검증 추천",
160
178
  "dashboard.tab.commands": "명령",
@@ -164,6 +182,24 @@ export const koMessages = {
164
182
  "dashboard.tab.skills": "스킬",
165
183
  "dashboard.tab.settings": "설정",
166
184
  "dashboard.tab.documents": "문서 검수",
185
+ "dashboard.actions.heading": "다음 작업",
186
+ "dashboard.actions.empty": "처리할 항목 없음",
187
+ "dashboard.actions.missingFiles": "누락 파일: {count}",
188
+ "dashboard.actions.manifestIssues": "이슈: {count}",
189
+ "dashboard.actions.verification": "검증 추천: {count}",
190
+ "dashboard.actions.updateBlockers": "업데이트 차단: {count}",
191
+ "dashboard.actions.documents": "검수 문서: {count}",
192
+ "dashboard.actions.latestRun": "최근 실행 확인 필요",
193
+ "dashboard.actions.openStatus": "상태 보기",
194
+ "dashboard.actions.openVerification": "검증 보기",
195
+ "dashboard.actions.openUpdate": "업데이트 보기",
196
+ "dashboard.actions.openDocuments": "문서 보기",
197
+ "dashboard.actions.openRuns": "실행 기록 보기",
198
+ "dashboard.a11y.state.ok": "정상",
199
+ "dashboard.a11y.state.warn": "확인 필요",
200
+ "dashboard.a11y.state.neutral": "상태",
201
+ "dashboard.a11y.copyCommand": "명령 복사: {command}",
202
+ "dashboard.a11y.copyVerificationPlan": "검증 계획 복사",
167
203
  "dashboard.status.reloaded": "상태를 다시 불러왔습니다",
168
204
  "dashboard.status.overview": "개요",
169
205
  "dashboard.status.installed": "설치됨",
@@ -322,6 +358,8 @@ export const koMessages = {
322
358
  "dashboard.docs.reviewerKind": "검수자 종류",
323
359
  "dashboard.docs.reviewerId": "검수자 ID",
324
360
  "dashboard.docs.reviewerIdPlaceholder": "사람 이름, LLM, 도구 ID",
361
+ "dashboard.docs.reviewerState": "현재 검수자: {kind} / {id}",
362
+ "dashboard.docs.reviewerStateMissing": "검수 작업 버튼을 쓰려면 검수자 ID를 입력하세요.",
325
363
  "dashboard.docs.summary": "검수 요약",
326
364
  "dashboard.docs.summaryPlaceholder": "선택 입력",
327
365
  "dashboard.docs.comment": "코멘트",
@@ -350,6 +388,7 @@ export const koMessages = {
350
388
  "dashboard.docs.action.needsReview.tooltip": "사람, LLM, 도구 등 다른 검수자가 다시 봐야 하는 문서로 표시합니다.",
351
389
  "dashboard.docs.action.ignore": "무시",
352
390
  "dashboard.docs.action.ignore.tooltip": "검수를 건너뛰기로 결정하고 기본 목록에서 숨깁니다.",
391
+ "dashboard.docs.action.currentStatus": "이미 {status} 상태입니다",
353
392
  "dashboard.locked.git.auto_push": "원격 저장소 변경은 명시적 요청이 필요합니다.",
354
393
  "dashboard.group.git": "Git",
355
394
  "dashboard.group.commitMessage": "커밋 메시지",
@@ -525,7 +564,7 @@ export const koMessages = {
525
564
  "init.help.option.interactive": "질문에 답하며 초기 설정을 선택합니다",
526
565
  "init.help.option.merge": "기존 AGENTS.md에 mustflow 관리 블록만 병합합니다",
527
566
  "init.help.option.force": "충돌 파일을 백업한 뒤 덮어씁니다",
528
- "init.help.option.profile": "프로젝트 유형을 설정합니다: minimal, oss, team, product, library",
567
+ "init.help.option.profile": "프로젝트 유형을 설정합니다: minimal, patterns, oss, team, product, library",
529
568
  "init.help.option.locale": "설치할 mustflow 문서 언어를 설정합니다",
530
569
  "init.help.option.agentLang": "에이전트 응답 언어를 설정합니다",
531
570
  "init.help.option.set": "git.auto_commit=true 또는 git.auto_push=false 같은 안전한 설정 항목의 값을 지정합니다",
@@ -612,6 +651,7 @@ export const koMessages = {
612
651
  "run.help.option.json": "실행 결과 또는 명령 계획을 JSON으로 출력합니다",
613
652
  "run.help.exit.ok": "명령이 허용된 종료 코드로 완료되었습니다",
614
653
  "run.help.exit.fail": "명령이 잘못되었거나, 거부되었거나, 시간 초과되었거나, 실패했습니다",
654
+ "run.label.suggestedIntentSnippet": "제안 명령 계약 조각",
615
655
  "run.error.missingIntent": "명령 이름이 없습니다",
616
656
  "run.error.unknownIntent": "알 수 없는 명령: {intent}",
617
657
  "run.error.statusNotConfigured": '명령 "{intent}"의 상태는 {status}입니다. 설정된 상태(configured)인 명령만 실행할 수 있습니다',
@@ -670,8 +710,9 @@ export const koMessages = {
670
710
  "upgrade.noFilesWritten": "프로젝트 파일은 쓰지 않았습니다.",
671
711
  "upgrade.warning.versionCheckFailed": "npm에서 새 버전을 확인하지 못했습니다: {message}",
672
712
  "upgrade.warning.continueWithBundledTemplate": "현재 CLI에 포함된 템플릿으로 계속 진행합니다.",
673
- "classify.help.summary": "파일을 수정하지 않고 변경 경로, 공개 표면, 필요한 검증 이유를 분류합니다.",
713
+ "classify.help.summary": "변경 경로, 공개 표면, 필요한 검증 이유를 분류합니다.",
674
714
  "classify.help.option.changed": "git status --short --untracked-files=all에서 경로를 읽습니다",
715
+ "classify.help.option.write": "분류 보고서를 이 저장소 안의 JSON 파일로 씁니다",
675
716
  "classify.help.exit.ok": "변경 분류를 확인하고 출력했습니다",
676
717
  "classify.title": "mustflow 변경 분류",
677
718
  "classify.label.source": "입력",
@@ -686,6 +727,7 @@ export const koMessages = {
686
727
  "classify.source.changed": "변경 파일",
687
728
  "classify.source.paths": "지정한 경로",
688
729
  "classify.error.missingInput": "--changed 또는 하나 이상의 경로를 지정하세요",
730
+ "classify.error.write_path_outside_root": "분류 보고서 경로는 mustflow 루트 안에 있어야 합니다",
689
731
  "impact.help.summary": "파일을 수정하지 않고 변경 경로가 패키지나 템플릿 버전 결정을 요구하는지 보고합니다.",
690
732
  "impact.help.option.changed": "git status --short --untracked-files=all에서 경로를 읽습니다",
691
733
  "impact.help.exit.ok": "버전 영향을 확인하고 출력했습니다",
@@ -701,9 +743,12 @@ export const koMessages = {
701
743
  "impact.error.missingInput": "--changed 또는 하나 이상의 경로를 지정하세요",
702
744
  "verify.help.summary": "required_after 메타데이터로 선택된 설정된 검증 의도를 실행합니다.",
703
745
  "verify.help.option.reason": "검증할 required_after 이유를 지정합니다",
704
- "verify.help.option.fromPlan": "이 저장소 안의 JSON 계획 파일에서 검증 이유를 읽습니다",
746
+ "verify.help.option.fromClassification": "이 저장소 안의 mf classify 보고서에서 검증 이유를 읽습니다",
747
+ "verify.help.option.fromPlan": "--from-classification과 같은 호환 옵션입니다",
705
748
  "verify.help.option.changed": "현재 Git 변경을 분류하고 맞는 검증 이유를 실행합니다",
706
- "verify.help.option.writePlan": "변경 파일 분류 계획을 저장소 안에 씁니다",
749
+ "verify.help.option.writePlan": "변경 파일 분류 보고서를 쓰는 호환 옵션입니다",
750
+ "verify.help.option.reproEvidence": "저장소 안의 JSON 요약에서 구조화된 버그 재현 증거를 읽습니다",
751
+ "verify.help.option.externalEvidence": "저장소 안의 JSON 요약에서 낮은 권한의 외부 CI 증거를 읽습니다",
707
752
  "verify.help.option.planOnly": "명령을 실행하지 않고 검증 계획만 출력합니다. --json이 필요합니다",
708
753
  "verify.help.exit.ok": "선택된 모든 검증 의도가 통과했습니다",
709
754
  "verify.help.exit.fail": "검증이 실패했거나, 일부만 실행됐거나, 막혔거나, 입력이 올바르지 않습니다",
@@ -713,14 +758,20 @@ export const koMessages = {
713
758
  "verify.label.status": "상태",
714
759
  "verify.label.results": "결과",
715
760
  "verify.error.missingReason": "검증 이유가 없습니다",
716
- "verify.error.conflictingInputs": "--reason, --from-plan, --changed 중 하나만 사용하세요",
761
+ "verify.error.conflictingInputs": "--reason, --from-classification, --from-plan, --changed 중 하나만 사용하세요",
717
762
  "verify.error.writePlanRequiresChanged": "--write-plan에는 --changed가 필요합니다",
718
763
  "verify.error.planOnlyJson": "--plan-only에는 --json이 필요합니다",
719
- "verify.error.invalid_plan_file": "검증 계획은 읽을있는 JSON 파일이어야 합니다",
720
- "verify.error.unsupported_plan_source": "검증 계획은 mf classify --json이 만든 산출물이어야 합니다",
721
- "verify.error.plan_root_mismatch": "검증 계획은 현재 mustflow 루트에서 나온 것이어야 합니다",
722
- "verify.error.missing_plan_reasons": "검증 계획에는 summary.validationReasons가 있어야 합니다",
723
- "verify.error.plan_path_outside_root": "검증 계획 경로는 mustflow 루트 안에 있어야 합니다",
764
+ "verify.error.reproEvidenceRequiresRun": "--repro-evidence는 --plan-only와 함께 사용할 없습니다",
765
+ "verify.error.externalEvidenceRequiresRun": "--external-evidence는 --plan-only와 함께 사용할 없습니다",
766
+ "verify.error.invalid_plan_file": "분류 보고서는 읽을 있는 JSON 파일이어야 합니다",
767
+ "verify.error.unsupported_plan_source": "검증 입력은 mf classify 보고서여야 합니다",
768
+ "verify.error.plan_root_mismatch": "분류 보고서는 현재 mustflow 루트에서 나온 것이어야 합니다",
769
+ "verify.error.missing_plan_reasons": "분류 보고서에는 summary.validationReasons가 있어야 합니다",
770
+ "verify.error.plan_path_outside_root": "분류 보고서 경로는 mustflow 루트 안에 있어야 합니다",
771
+ "verify.error.invalid_repro_evidence_file": "재현 증거는 구조화된 증거 필드를 포함한 읽을 수 있는 JSON 요약이어야 합니다",
772
+ "verify.error.unsupported_repro_evidence_source": "재현 증거 입력은 command repro-evidence를 사용해야 합니다",
773
+ "verify.error.invalid_external_evidence_file": "외부 증거는 checks를 포함한 읽을 수 있는 JSON 요약이어야 합니다",
774
+ "verify.error.unsupported_external_evidence_source": "외부 증거 입력은 command external-evidence를 사용해야 합니다",
724
775
  "explain.help.summary": "파일을 수정하지 않고 mustflow 정책 결정이 왜 적용되는지 설명합니다.",
725
776
  "explain.help.exit.ok": "정책 결정을 확인하고 출력했습니다",
726
777
  "explain.title": "mustflow 설명",
@@ -56,6 +56,7 @@ export const zhMessages = {
56
56
  "check.result.strictPassed": "mustflow 严格检查已通过",
57
57
  "contractLint.help.summary": "检查 .mustflow/config/commands.toml 中的命令契约错误和警告。",
58
58
  "contractLint.help.option.coverage": "同时报告变更分类原因的 required_after 覆盖情况",
59
+ "contractLint.help.option.suggest": "从 package.json、Makefile 或 justfile 建议不可运行的 intent 片段",
59
60
  "contractLint.help.exit.ok": "命令契约已检查,未发现阻塞错误",
60
61
  "contractLint.help.exit.fail": "发现命令契约错误,或输入无效",
61
62
  "contractLint.title": "mustflow contract-lint",
@@ -73,6 +74,7 @@ export const zhMessages = {
73
74
  "contractLint.label.requiredAfterReasons": "required_after 原因",
74
75
  "contractLint.label.runnableReasons": "可运行原因",
75
76
  "contractLint.label.coverageFindings": "覆盖发现",
77
+ "contractLint.label.suggestions": "建议",
76
78
  "contractLint.label.issues": "问题",
77
79
  "context.help.summary": "输出当前 mustflow 根目录的代理上下文。",
78
80
  "context.help.option.json": "输出机器可读的上下文 JSON",
@@ -149,12 +151,28 @@ export const zhMessages = {
149
151
  "dashboard.ui.unsavedChanges": "未保存的更改",
150
152
  "dashboard.ui.reloaded": "已重新加载",
151
153
  "dashboard.ui.saved": "已保存",
154
+ "dashboard.ui.loading": "正在加载",
155
+ "dashboard.ui.lastUpdated": "上次更新:{time}",
156
+ "dashboard.ui.copied": "已复制",
152
157
  "dashboard.ui.reload": "重新加载",
153
158
  "dashboard.ui.save": "保存",
154
159
  "dashboard.ui.locked": "已锁定",
155
160
  "dashboard.ui.customLocale": "自定义语言标签",
156
161
  "dashboard.ui.openMustflow": "打开 .mustflow 文件夹",
157
162
  "dashboard.ui.openedMustflow": "已打开 .mustflow 文件夹",
163
+ "dashboard.settings.pendingHeading": "未保存设置({count})",
164
+ "dashboard.settings.pendingItem": "{name}: {from} -> {to}",
165
+ "dashboard.settings.resetChanges": "重置更改",
166
+ "dashboard.filter.search": "搜索",
167
+ "dashboard.filter.searchPlaceholder": "名称、路径、命令或原因",
168
+ "dashboard.filter.state": "状态",
169
+ "dashboard.filter.all": "全部",
170
+ "dashboard.filter.runnable": "可运行",
171
+ "dashboard.filter.unavailable": "不可用",
172
+ "dashboard.filter.aligned": "已对齐",
173
+ "dashboard.filter.mismatch": "不匹配",
174
+ "dashboard.filter.missing": "缺失",
175
+ "dashboard.filter.noMatches": "没有匹配项。",
158
176
  "dashboard.tab.status": "状态",
159
177
  "dashboard.tab.verification": "验证建议",
160
178
  "dashboard.tab.commands": "命令",
@@ -164,6 +182,24 @@ export const zhMessages = {
164
182
  "dashboard.tab.skills": "技能",
165
183
  "dashboard.tab.settings": "设置",
166
184
  "dashboard.tab.documents": "文档审阅",
185
+ "dashboard.actions.heading": "下一步",
186
+ "dashboard.actions.empty": "没有待处理项。",
187
+ "dashboard.actions.missingFiles": "缺失文件:{count}",
188
+ "dashboard.actions.manifestIssues": "问题:{count}",
189
+ "dashboard.actions.verification": "验证建议:{count}",
190
+ "dashboard.actions.updateBlockers": "更新阻塞项:{count}",
191
+ "dashboard.actions.documents": "待审阅文档:{count}",
192
+ "dashboard.actions.latestRun": "最近运行需要查看",
193
+ "dashboard.actions.openStatus": "打开状态",
194
+ "dashboard.actions.openVerification": "打开验证",
195
+ "dashboard.actions.openUpdate": "打开更新",
196
+ "dashboard.actions.openDocuments": "打开文档",
197
+ "dashboard.actions.openRuns": "打开运行记录",
198
+ "dashboard.a11y.state.ok": "正常",
199
+ "dashboard.a11y.state.warn": "需要注意",
200
+ "dashboard.a11y.state.neutral": "状态",
201
+ "dashboard.a11y.copyCommand": "复制命令:{command}",
202
+ "dashboard.a11y.copyVerificationPlan": "复制验证计划",
167
203
  "dashboard.status.reloaded": "状态已重新加载",
168
204
  "dashboard.status.overview": "概览",
169
205
  "dashboard.status.installed": "已安装",
@@ -322,6 +358,8 @@ export const zhMessages = {
322
358
  "dashboard.docs.reviewerKind": "审阅者类型",
323
359
  "dashboard.docs.reviewerId": "审阅者 ID",
324
360
  "dashboard.docs.reviewerIdPlaceholder": "人员、LLM 或工具 ID",
361
+ "dashboard.docs.reviewerState": "当前审阅者:{kind} / {id}",
362
+ "dashboard.docs.reviewerStateMissing": "使用审阅操作前请输入审阅者 ID。",
325
363
  "dashboard.docs.summary": "审阅摘要",
326
364
  "dashboard.docs.summaryPlaceholder": "可选",
327
365
  "dashboard.docs.comment": "评论",
@@ -350,6 +388,7 @@ export const zhMessages = {
350
388
  "dashboard.docs.action.needsReview.tooltip": "将此文档标记为需要人员、LLM、工具或外部流程再次审阅。",
351
389
  "dashboard.docs.action.ignore": "忽略",
352
390
  "dashboard.docs.action.ignore.tooltip": "跳过此文档的审阅,并从默认列表中隐藏。",
391
+ "dashboard.docs.action.currentStatus": "已是 {status}",
353
392
  "dashboard.locked.git.auto_push": "远程推送需要明确请求。",
354
393
  "dashboard.group.git": "Git",
355
394
  "dashboard.group.commitMessage": "提交消息",
@@ -525,7 +564,7 @@ export const zhMessages = {
525
564
  "init.help.option.interactive": "通过提示选择初始化设置",
526
565
  "init.help.option.merge": "将 mustflow 管理块合并到现有 AGENTS.md",
527
566
  "init.help.option.force": "备份冲突文件并覆盖它们",
528
- "init.help.option.profile": "设置项目配置:minimal、oss、team、product 或 library",
567
+ "init.help.option.profile": "设置项目配置:minimal、patterns、oss、team、product 或 library",
529
568
  "init.help.option.locale": "设置已安装 mustflow 文档的语言",
530
569
  "init.help.option.agentLang": "设置首选代理响应语言",
531
570
  "init.help.option.set": "设置安全偏好值,例如 git.auto_commit=true 或 git.auto_push=false",
@@ -612,6 +651,7 @@ export const zhMessages = {
612
651
  "run.help.option.json": "将运行记录或命令计划输出为 JSON",
613
652
  "run.help.exit.ok": "命令已以允许的退出码完成",
614
653
  "run.help.exit.fail": "命令无效、被拒绝、超时或失败",
654
+ "run.label.suggestedIntentSnippet": "建议的命令契约片段",
615
655
  "run.error.missingIntent": "缺少命令名称",
616
656
  "run.error.unknownIntent": "未知命令:{intent}",
617
657
  "run.error.statusNotConfigured": '命令 "{intent}" 的状态为 {status};只能运行已配置的命令',
@@ -670,8 +710,9 @@ export const zhMessages = {
670
710
  "upgrade.noFilesWritten": "未写入项目文件。",
671
711
  "upgrade.warning.versionCheckFailed": "无法从 npm 检查新版本:{message}",
672
712
  "upgrade.warning.continueWithBundledTemplate": "继续使用当前 CLI 捆绑的模板。",
673
- "classify.help.summary": "在不修改文件的情况下分类变更路径、公开表面和所需验证原因。",
713
+ "classify.help.summary": "分类变更路径、公开表面和所需验证原因。",
674
714
  "classify.help.option.changed": "从 git status --short --untracked-files=all 读取路径",
715
+ "classify.help.option.write": "将分类报告写入此仓库内的 JSON 文件",
675
716
  "classify.help.exit.ok": "已检查并输出变更分类",
676
717
  "classify.title": "mustflow classify",
677
718
  "classify.label.source": "来源",
@@ -686,6 +727,7 @@ export const zhMessages = {
686
727
  "classify.source.changed": "变更文件",
687
728
  "classify.source.paths": "指定路径",
688
729
  "classify.error.missingInput": "请指定 --changed 或至少一个路径",
730
+ "classify.error.write_path_outside_root": "分类报告路径必须位于 mustflow 根目录内",
689
731
  "impact.help.summary": "在不修改文件的情况下报告变更路径是否需要包或模板版本决策。",
690
732
  "impact.help.option.changed": "从 git status --short --untracked-files=all 读取路径",
691
733
  "impact.help.exit.ok": "已检查并输出版本影响",
@@ -701,9 +743,12 @@ export const zhMessages = {
701
743
  "impact.error.missingInput": "请指定 --changed 或至少一个路径",
702
744
  "verify.help.summary": "运行由 required_after 元数据选出的已配置验证意图。",
703
745
  "verify.help.option.reason": "选择要验证的 required_after 原因",
704
- "verify.help.option.fromPlan": "从此仓库内的 JSON 计划读取验证原因",
746
+ "verify.help.option.fromClassification": "从此仓库内的 mf classify 报告读取验证原因",
747
+ "verify.help.option.fromPlan": "--from-classification 的兼容别名",
705
748
  "verify.help.option.changed": "分类当前 Git 变更并验证匹配的原因",
706
- "verify.help.option.writePlan": "在此仓库内写入变更文件分类计划",
749
+ "verify.help.option.writePlan": "写入变更文件分类报告的兼容选项",
750
+ "verify.help.option.reproEvidence": "从仓库本地 JSON 摘要读取结构化的 bug 复现证据",
751
+ "verify.help.option.externalEvidence": "从仓库本地 JSON 摘要读取低权限外部 CI 证据",
707
752
  "verify.help.option.planOnly": "仅输出验证计划,不执行命令;需要 --json",
708
753
  "verify.help.exit.ok": "选中的所有验证意图均已通过",
709
754
  "verify.help.exit.fail": "验证失败、部分完成、被阻止,或输入无效",
@@ -713,14 +758,20 @@ export const zhMessages = {
713
758
  "verify.label.status": "状态",
714
759
  "verify.label.results": "结果",
715
760
  "verify.error.missingReason": "缺少验证原因",
716
- "verify.error.conflictingInputs": "只能使用 --reason、--from-plan 或 --changed 其中之一",
761
+ "verify.error.conflictingInputs": "只能使用 --reason、--from-classification、--from-plan 或 --changed 其中之一",
717
762
  "verify.error.writePlanRequiresChanged": "--write-plan 需要 --changed",
718
763
  "verify.error.planOnlyJson": "--plan-only 需要 --json",
719
- "verify.error.invalid_plan_file": "验证计划必须是可读取的 JSON 文件",
720
- "verify.error.unsupported_plan_source": "验证计划必须由 mf classify --json 生成",
721
- "verify.error.plan_root_mismatch": "验证计划必须来自当前 mustflow 根目录",
722
- "verify.error.missing_plan_reasons": "验证计划必须包含 summary.validationReasons",
723
- "verify.error.plan_path_outside_root": "验证计划路径必须位于 mustflow 根目录内",
764
+ "verify.error.reproEvidenceRequiresRun": "--repro-evidence 不能与 --plan-only 一起使用",
765
+ "verify.error.externalEvidenceRequiresRun": "--external-evidence 不能与 --plan-only 一起使用",
766
+ "verify.error.invalid_plan_file": "分类报告必须是可读取的 JSON 文件",
767
+ "verify.error.unsupported_plan_source": "验证输入必须是 mf classify 报告",
768
+ "verify.error.plan_root_mismatch": "分类报告必须来自当前 mustflow 根目录",
769
+ "verify.error.missing_plan_reasons": "分类报告必须包含 summary.validationReasons",
770
+ "verify.error.plan_path_outside_root": "分类报告路径必须位于 mustflow 根目录内",
771
+ "verify.error.invalid_repro_evidence_file": "复现证据必须是包含结构化证据字段的可读取 JSON 摘要",
772
+ "verify.error.unsupported_repro_evidence_source": "复现证据输入必须使用 command repro-evidence",
773
+ "verify.error.invalid_external_evidence_file": "外部证据必须是包含 checks 的可读取 JSON 摘要",
774
+ "verify.error.unsupported_external_evidence_source": "外部证据输入必须使用 command external-evidence",
724
775
  "explain.help.summary": "在不修改文件的情况下解释 mustflow 策略决策为何适用。",
725
776
  "explain.help.exit.ok": "已检查并输出策略决策",
726
777
  "explain.title": "mustflow explain",
@@ -1,5 +1,7 @@
1
1
  import { Buffer } from 'node:buffer';
2
2
  import path from 'node:path';
3
+ import { createDashboardCompletionVerdict } from '../../core/completion-verdict.js';
4
+ import { createDashboardEvidenceModel } from '../../core/verification-evidence.js';
3
5
  import { redactSecretLikeText } from '../../core/secret-redaction.js';
4
6
  import { ensureFileTargetInsideWithoutSymlinks, ensureInside, toPosixPath, writeUtf8FileInsideWithoutSymlinks, } from './filesystem.js';
5
7
  export class DashboardExportPathError extends Error {
@@ -380,6 +382,56 @@ function createDashboardHarnessReport(statusValue, docsReviewValue) {
380
382
  .map((entry) => stringOrNull(entry.intent))
381
383
  .filter((entry) => entry !== null)
382
384
  .slice(0, DASHBOARD_HARNESS_MAX_ITEMS);
385
+ const skippedIntents = asArray(verification.skipped)
386
+ .map(asRecord)
387
+ .map((entry) => ({
388
+ intent: text(entry.intent),
389
+ reason_key: text(entry.reason_key),
390
+ }))
391
+ .slice(0, DASHBOARD_HARNESS_MAX_ITEMS);
392
+ const verificationGaps = createVerificationGaps(verification.decision_graph);
393
+ const runHistory = createRunHistorySummary(status);
394
+ const changedFileCount = stringArray(verification.changed_files).length;
395
+ const changedSurfaces = stringArray(verification.surfaces);
396
+ const remainingRisks = createRemainingRisks(status, docsReview, decisionGraphSummary);
397
+ const completionVerdict = createDashboardCompletionVerdict({
398
+ changedFileCount,
399
+ runnableIntentCount: runnableIntents.length,
400
+ skippedIntentCount: skippedIntents.length,
401
+ gapCount: verificationGaps.length,
402
+ latestRunExists: runHistory.exists,
403
+ latestRunValid: runHistory.valid,
404
+ latestRunStatus: runHistory.status,
405
+ });
406
+ const evidenceModel = createDashboardEvidenceModel({
407
+ changedSurfaces,
408
+ runnableIntents,
409
+ skippedChecks: skippedIntents.map((entry) => ({
410
+ intent: entry.intent || null,
411
+ reason: entry.reason_key || null,
412
+ detail: null,
413
+ })),
414
+ gaps: verificationGaps.map((gap) => ({
415
+ reason: gap.reason,
416
+ intent: gap.intent,
417
+ status: gap.kind,
418
+ detail: gap.detail,
419
+ files: gap.files,
420
+ surfaces: gap.surfaces,
421
+ })),
422
+ latestReceipt: runHistory.exists && runHistory.valid
423
+ ? {
424
+ intent: runHistory.intent,
425
+ status: runHistory.status ?? 'unknown',
426
+ skipped: false,
427
+ verification_plan_id: null,
428
+ receipt_path: runHistory.receipt_path,
429
+ receipt_sha256: null,
430
+ }
431
+ : null,
432
+ remainingRisks,
433
+ verdict: completionVerdict,
434
+ });
383
435
  return {
384
436
  schema_version: '1',
385
437
  generated_from: 'dashboard_status_snapshot',
@@ -392,25 +444,21 @@ function createDashboardHarnessReport(statusValue, docsReviewValue) {
392
444
  issues: stringArray(status.issues).length,
393
445
  },
394
446
  verification: {
395
- changed_file_count: stringArray(verification.changed_files).length,
396
- changed_surfaces: stringArray(verification.surfaces),
447
+ completion_verdict: completionVerdict,
448
+ evidence_model: evidenceModel,
449
+ changed_file_count: changedFileCount,
450
+ changed_surfaces: changedSurfaces,
397
451
  decision_graph_summary: decisionGraphSummary,
398
452
  runnable_intents: runnableIntents,
399
- skipped_intents: asArray(verification.skipped)
400
- .map(asRecord)
401
- .map((entry) => ({
402
- intent: text(entry.intent),
403
- reason_key: text(entry.reason_key),
404
- }))
405
- .slice(0, DASHBOARD_HARNESS_MAX_ITEMS),
406
- gaps: createVerificationGaps(verification.decision_graph),
453
+ skipped_intents: skippedIntents,
454
+ gaps: verificationGaps,
407
455
  },
408
- run_history: createRunHistorySummary(status),
456
+ run_history: runHistory,
409
457
  docs_review: {
410
458
  ledger_path: text(docsReview.ledger_path),
411
459
  active_documents: numberOrZero(docsReview.count),
412
460
  },
413
- remaining_risks: createRemainingRisks(status, docsReview, decisionGraphSummary),
461
+ remaining_risks: remainingRisks,
414
462
  };
415
463
  }
416
464
  export function resolveDashboardExportPath(projectRoot, outputPath) {
@@ -582,6 +630,7 @@ export function renderDashboardExportHtml(snapshot) {
582
630
  const harnessReport = asRecord(snapshot.harness_report);
583
631
  const harnessInstall = asRecord(harnessReport.install);
584
632
  const harnessVerification = asRecord(harnessReport.verification);
633
+ const completionVerdict = asRecord(harnessVerification.completion_verdict);
585
634
  const graphSummary = asRecord(harnessVerification.decision_graph_summary);
586
635
  const harnessRunHistory = asRecord(harnessReport.run_history);
587
636
  const harnessDocsReview = asRecord(harnessReport.docs_review);
@@ -676,6 +725,7 @@ ul { margin: 0; padding-left: 22px; }
676
725
  renderMetric('Tracked files', harnessInstall.tracked_files),
677
726
  renderMetric('Changed files', harnessVerification.changed_file_count),
678
727
  renderMetric('Changed surfaces', asArray(harnessVerification.changed_surfaces).join(', ') || 'none'),
728
+ renderMetric('Completion verdict', completionVerdict.status),
679
729
  renderMetric('Runnable verification intents', asArray(harnessVerification.runnable_intents).length),
680
730
  renderMetric('Skipped verification intents', asArray(harnessVerification.skipped_intents).length),
681
731
  renderMetric('Verification gaps', asArray(harnessVerification.gaps).length),