mustflow 2.11.0 → 2.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -103,7 +103,7 @@ available as a direct shell command, install mustflow globally:
103
103
  npm install -g mustflow
104
104
  mf version --check
105
105
 
106
- bun install -g mustflow
106
+ bun add -g mustflow@latest
107
107
  mf version --check
108
108
  ```
109
109
 
@@ -282,10 +282,10 @@ npx mf update --dry-run
282
282
  npx mf update --apply
283
283
  ```
284
284
 
285
- After updating the mustflow package, `mf upgrade` combines the package freshness check with the safe project-file update step. It does not install packages by itself; update npm, pnpm, or Bun first.
285
+ After updating the mustflow package, `mf upgrade` combines the package freshness check with the safe project-file update step. It does not install packages by itself; refresh mustflow with the package manager you used first. When a newer release exists, `mf version --check` and `mf upgrade` print update commands for npm, Bun, pnpm, Yarn, and Deno.
286
286
 
287
287
  ```sh
288
- bun update -g mustflow
288
+ bun add -g mustflow@latest
289
289
  mf upgrade --dry-run
290
290
  mf upgrade
291
291
  ```
@@ -331,7 +331,7 @@ mf run mustflow_update_apply
331
331
  | `mf help <topic>` | Show installed mustflow help. |
332
332
  | `mf dashboard` | Start a local inspection dashboard for status, verification recommendations, release/version-source status, template update readiness, latest run receipt, skill routes, safe preferences, and documentation review. Use `--export-json <path>` or `--export <path>` for a bounded static report. It does not execute commands or apply fixes. |
333
333
  | `mf version` | Print the installed mustflow package version. |
334
- | `mf version --check` | Compare the installed package version with the latest npm release and print an update command if a newer version exists. |
334
+ | `mf version --check` | Compare the installed package version with the latest npm release and print package-manager update commands if a newer version exists. |
335
335
  | `mf version-sources` | Inspect detected package, template, and declared version sources without modifying files. |
336
336
  | `mf impact --changed` | Report whether changed paths require a package or template version decision. |
337
337
  | `mf verify --reason <event>` | Run configured verification intents selected by `required_after` metadata. |
@@ -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'}`,
@@ -26,7 +26,9 @@ function printPackageCheck(check, reporter, lang) {
26
26
  if (check.updateAvailable) {
27
27
  reporter.stdout('');
28
28
  reporter.stdout(t(lang, 'version.check.updateCommand'));
29
- reporter.stdout(check.updateCommand);
29
+ for (const entry of check.updateCommands) {
30
+ reporter.stdout(`${entry.manager}: ${entry.command}`);
31
+ }
30
32
  }
31
33
  }
32
34
  export async function runUpgrade(args, reporter, lang = 'en') {