mustflow 2.11.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.
@@ -15,7 +15,7 @@ import { isRecord, readCommandContract, readPositiveInteger, readString, readStr
15
15
  import { readDashboardPreferences, updateDashboardPreferences, } from '../lib/dashboard-preferences.js';
16
16
  import { DOC_REVIEW_LEDGER_RELATIVE_PATH, isDocReviewStatus, isReviewerKind, listDocReviewEntries, markDocReviewEntry, } from '../lib/doc-review-ledger.js';
17
17
  import { inspectManifestLock } from '../lib/manifest-lock.js';
18
- import { readLocalCommandEffectGraphs } from '../lib/local-index.js';
18
+ import { readLatestLocalVerificationReadModelQueries, readLocalCommandEffectGraphs, } from '../lib/local-index.js';
19
19
  import { readPackageMetadata } from '../lib/package-info.js';
20
20
  import { t } from '../lib/i18n.js';
21
21
  import { resolveMustflowRoot } from '../lib/project-root.js';
@@ -383,6 +383,70 @@ function toDashboardCommandEffectGraph(graph) {
383
383
  })),
384
384
  };
385
385
  }
386
+ function toDashboardVerificationReadModel(readModel) {
387
+ return {
388
+ source: readModel.source,
389
+ authority: readModel.authority,
390
+ command_authority: readModel.commandAuthority,
391
+ grants_command_authority: readModel.grantsCommandAuthority,
392
+ status: readModel.status,
393
+ database_path: readModel.databasePath,
394
+ index_fresh: readModel.indexFresh,
395
+ stale_paths: readModel.stalePaths,
396
+ plan_id: readModel.planId,
397
+ refresh_hint: readModel.refreshHint,
398
+ uncovered_criteria: readModel.uncoveredCriteria.map((criterion) => ({
399
+ criterion_id: criterion.criterionId,
400
+ source: criterion.source,
401
+ reason: criterion.reason,
402
+ surface: criterion.surface,
403
+ path_hash: criterion.pathHash,
404
+ coverage_status: criterion.coverageStatus,
405
+ receipt_count: criterion.receiptCount,
406
+ gap_count: criterion.gapCount,
407
+ risk_count: criterion.riskCount,
408
+ })),
409
+ severe_risks: readModel.severeRisks.map((risk) => ({
410
+ source_path: risk.sourcePath,
411
+ ordinal: risk.ordinal,
412
+ code: risk.code,
413
+ severity: risk.severity,
414
+ detail_hash: risk.detailHash,
415
+ })),
416
+ non_passing_receipts: readModel.nonPassingReceipts.map((receipt) => ({
417
+ receipt_hash: receipt.receiptHash,
418
+ plan_id: receipt.planId,
419
+ intent: receipt.intent,
420
+ status: receipt.status,
421
+ command_fingerprint: receipt.commandFingerprint,
422
+ contract_fingerprint: receipt.contractFingerprint,
423
+ current_state_hash: receipt.currentStateHash,
424
+ write_drift_status: receipt.writeDriftStatus,
425
+ })),
426
+ repeated_failure_fingerprints: readModel.repeatedFailureFingerprints.map((fingerprint) => ({
427
+ source_path: fingerprint.sourcePath,
428
+ fingerprint: fingerprint.fingerprint,
429
+ verification_plan_id: fingerprint.verificationPlanId,
430
+ status: fingerprint.status,
431
+ failed_intents: fingerprint.failedIntents,
432
+ primary_reason: fingerprint.primaryReason,
433
+ failed_intents_hash: fingerprint.failedIntentsHash,
434
+ risk_codes_hash: fingerprint.riskCodesHash,
435
+ affected_surfaces_hash: fingerprint.affectedSurfacesHash,
436
+ seen_count: fingerprint.seenCount,
437
+ requires_new_evidence: fingerprint.requiresNewEvidence,
438
+ })),
439
+ validation_weakening_signals: readModel.validationWeakeningSignals.map((signal) => ({
440
+ signal_id: signal.signalId,
441
+ plan_id: signal.planId,
442
+ code: signal.code,
443
+ severity: signal.severity,
444
+ path_hash: signal.pathHash,
445
+ before_hash: signal.beforeHash,
446
+ after_hash: signal.afterHash,
447
+ })),
448
+ };
449
+ }
386
450
  async function readCommandEffectGraphMap(projectRoot, intentNames) {
387
451
  if (intentNames.length === 0) {
388
452
  return { graphs: new Map() };
@@ -620,6 +684,8 @@ async function renderStatusResponse(projectRoot) {
620
684
  const commandContract = await renderCommandContractResponse(projectRoot, rawCommandContract);
621
685
  const gitChangedFiles = readGitChangedFiles(projectRoot);
622
686
  const packageMetadata = readPackageMetadata();
687
+ const verification = createDashboardVerificationSnapshot(projectRoot, rawCommandContract, commandContract.intents, gitChangedFiles, manifest.changedFiles, manifest.missingFiles);
688
+ const readModel = await readLatestLocalVerificationReadModelQueries(projectRoot);
623
689
  return {
624
690
  schema_version: '1',
625
691
  command: 'dashboard status',
@@ -641,7 +707,10 @@ async function renderStatusResponse(projectRoot) {
641
707
  issues: manifest.issues,
642
708
  runnable_intents: context.command_contract.runnable_intents,
643
709
  command_contract: commandContract,
644
- verification: createDashboardVerificationSnapshot(projectRoot, rawCommandContract, commandContract.intents, gitChangedFiles, manifest.changedFiles, manifest.missingFiles),
710
+ verification: {
711
+ ...verification,
712
+ read_model: toDashboardVerificationReadModel(readModel),
713
+ },
645
714
  latest_run: context.latest_run,
646
715
  active_review_documents: activeDocuments.length,
647
716
  };
@@ -4,7 +4,7 @@ import { createVerificationDecisionGraph, } from '../../core/verification-decisi
4
4
  import { createVerificationPlan, } from '../../core/verification-plan.js';
5
5
  import { createVerificationSchedule } from '../../core/verification-scheduler.js';
6
6
  import { t } from '../lib/i18n.js';
7
- import { readLocalCommandEffectGraphs, } from '../lib/local-index.js';
7
+ import { readLatestLocalVerificationReadModelQueries, readLocalCommandEffectGraphs, } from '../lib/local-index.js';
8
8
  import { planErrorMessageKey, readInputFromPlan } from './verify.js';
9
9
  export function parseExplainVerifyArgs(args) {
10
10
  let reason;
@@ -104,6 +104,7 @@ export async function getVerifyExplainOutput(schemaVersion, projectRoot, reasons
104
104
  ...new Set(plans.flatMap((plan) => plan.candidates.map((candidate) => candidate.intent).filter((intent) => intent.length > 0))),
105
105
  ];
106
106
  const graphsByIntent = intentNames.length > 0 ? await readLocalCommandEffectGraphs(projectRoot, intentNames) : new Map();
107
+ const readModel = await readLatestLocalVerificationReadModelQueries(projectRoot);
107
108
  const requirements = plans.map((plan) => {
108
109
  const candidates = plan.candidates.map((candidate) => {
109
110
  const command = candidate.intent ? explainCommandIntent(contract, candidate.intent).intent : null;
@@ -166,6 +167,7 @@ export async function getVerifyExplainOutput(schemaVersion, projectRoot, reasons
166
167
  skippedCount,
167
168
  requirements,
168
169
  decisionGraph,
170
+ readModel,
169
171
  },
170
172
  },
171
173
  };
@@ -182,7 +184,15 @@ export function renderVerifyExplainDecision(decision, lang) {
182
184
  `- skipped: ${verification.skippedCount}`,
183
185
  `- decision_graph_nodes: ${verification.decisionGraph.summary.nodeCount}`,
184
186
  `- decision_graph_gaps: ${verification.decisionGraph.summary.gapCount}`,
187
+ `- read_model: ${verification.readModel.status}`,
188
+ `- read_model_plan_id: ${verification.readModel.planId ?? t(lang, 'value.none')}`,
185
189
  ];
190
+ if (verification.readModel.refreshHint) {
191
+ lines.push(`- read_model_refresh_hint: ${verification.readModel.refreshHint}`);
192
+ }
193
+ if (verification.readModel.status === 'fresh') {
194
+ lines.push(`- uncovered_criteria: ${verification.readModel.uncoveredCriteria.length}`, `- severe_risks: ${verification.readModel.severeRisks.length}`, `- non_passing_receipts: ${verification.readModel.nonPassingReceipts.length}`, `- repeated_failures_requiring_new_evidence: ${verification.readModel.repeatedFailureFingerprints.length}`, `- validation_weakening_signals: ${verification.readModel.validationWeakeningSignals.length}`);
195
+ }
186
196
  for (const requirement of verification.requirements) {
187
197
  lines.push(`- required_after: ${requirement.reason}`);
188
198
  if (requirement.matchingIntents.length > 0) {
@@ -43,11 +43,20 @@ function renderIndexSummary(result, lang) {
43
43
  `${t(lang, 'label.commandIntents')}: ${result.command_intent_count}`,
44
44
  `command_effects: ${result.command_effect_count}`,
45
45
  `verification_evidence_summaries: ${result.verification_evidence_summary_count}`,
46
+ `verification_plans: ${result.verification_plan_count}`,
47
+ `acceptance_criteria: ${result.acceptance_criteria_count}`,
48
+ `criterion_coverage: ${result.criterion_coverage_count}`,
46
49
  `verification_receipt_summaries: ${result.verification_receipt_summary_count}`,
50
+ `command_receipt_summaries: ${result.command_receipt_summary_count}`,
47
51
  `verification_coverage_states: ${result.verification_coverage_state_count}`,
48
52
  `verification_risk_signals: ${result.verification_risk_signal_count}`,
53
+ `validation_ratchet_signals: ${result.validation_ratchet_signal_count}`,
54
+ `completion_verdict_summaries: ${result.completion_verdict_summary_count}`,
55
+ `repro_routes: ${result.repro_route_count}`,
56
+ `repro_observations: ${result.repro_observation_count}`,
49
57
  `failure_fingerprints: ${result.failure_fingerprint_count}`,
50
58
  `source_anchors: ${result.source_anchor_count}`,
59
+ `source_anchor_risk_signals: ${result.source_anchor_risk_signal_count}`,
51
60
  `index_mode: ${result.index_mode}`,
52
61
  `reused_existing: ${result.reused_existing ? 'yes' : 'no'}`,
53
62
  `${t(lang, 'label.wroteFiles')}: ${result.wrote_files ? 'yes' : 'no'}`,