mustflow 2.58.1 → 2.68.6

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 (47) hide show
  1. package/README.md +4 -0
  2. package/dist/cli/commands/context.js +81 -6
  3. package/dist/cli/commands/quality.js +89 -0
  4. package/dist/cli/commands/skill.js +116 -0
  5. package/dist/cli/i18n/en.js +16 -0
  6. package/dist/cli/i18n/es.js +16 -0
  7. package/dist/cli/i18n/fr.js +16 -0
  8. package/dist/cli/i18n/hi.js +16 -0
  9. package/dist/cli/i18n/ko.js +16 -0
  10. package/dist/cli/i18n/zh.js +16 -0
  11. package/dist/cli/index.js +1 -0
  12. package/dist/cli/lib/agent-context.js +981 -8
  13. package/dist/cli/lib/command-registry.js +12 -0
  14. package/dist/cli/lib/local-index/constants.js +4 -5
  15. package/dist/cli/lib/local-index/freshness.js +5 -1
  16. package/dist/cli/lib/local-index/index.js +1 -1
  17. package/dist/cli/lib/repo-map.js +7 -1
  18. package/dist/cli/lib/validation/constants.js +3 -0
  19. package/dist/cli/lib/validation/index.js +41 -2
  20. package/dist/core/check-issues.js +5 -0
  21. package/dist/core/prompt-cache-rendering.js +19 -0
  22. package/dist/core/public-json-contracts.js +35 -0
  23. package/dist/core/quality-gaming.js +304 -0
  24. package/dist/core/skill-route-fixtures.js +173 -0
  25. package/dist/core/skill-route-resolution.js +398 -0
  26. package/dist/core/source-anchors.js +91 -5
  27. package/package.json +1 -1
  28. package/schemas/README.md +9 -1
  29. package/schemas/context-report.schema.json +442 -0
  30. package/schemas/quality-gaming-report.schema.json +96 -0
  31. package/schemas/route-fixture.schema.json +57 -0
  32. package/schemas/skill-route-report.schema.json +242 -0
  33. package/templates/default/common/.mustflow/config/commands.toml +34 -2
  34. package/templates/default/common/.mustflow/config/mustflow.toml +16 -10
  35. package/templates/default/i18n.toml +14 -8
  36. package/templates/default/locales/en/.mustflow/context/PROJECT.md +5 -3
  37. package/templates/default/locales/en/.mustflow/docs/agent-workflow.md +13 -9
  38. package/templates/default/locales/en/.mustflow/skills/INDEX.md +3 -2
  39. package/templates/default/locales/en/.mustflow/skills/llm-token-cost-control-review/SKILL.md +5 -2
  40. package/templates/default/locales/en/.mustflow/skills/quality-gaming-guard/SKILL.md +165 -0
  41. package/templates/default/locales/en/.mustflow/skills/router.toml +67 -0
  42. package/templates/default/locales/en/.mustflow/skills/routes.toml +6 -0
  43. package/templates/default/locales/en/AGENTS.md +15 -7
  44. package/templates/default/locales/ko/.mustflow/context/PROJECT.md +4 -2
  45. package/templates/default/locales/ko/.mustflow/docs/agent-workflow.md +18 -12
  46. package/templates/default/locales/ko/AGENTS.md +8 -6
  47. package/templates/default/manifest.toml +9 -1
@@ -265,11 +265,90 @@ export function sourceAnchorPathIsGeneratedOrVendor(relativePath) {
265
265
  export function sourceAnchorTextContainsSecretLike(value) {
266
266
  return textContainsSecretLike(value);
267
267
  }
268
- export function parseSourceAnchorsInContent(relativePath, content) {
268
+ function collectCommentLines(content) {
269
269
  const lines = content.split(/\r?\n/);
270
+ const commentLines = [];
271
+ let insideBlockComment = false;
272
+ let stringQuote = null;
273
+ let escaped = false;
274
+ let lineIndex = 0;
275
+ while (lineIndex < lines.length) {
276
+ const line = lines[lineIndex] ?? '';
277
+ let index = 0;
278
+ while (index < line.length) {
279
+ if (insideBlockComment) {
280
+ const endIndex = line.indexOf('*/', index);
281
+ const segmentEnd = endIndex === -1 ? line.length : endIndex;
282
+ commentLines.push({ lineNumber: lineIndex + 1, text: line.slice(index, segmentEnd) });
283
+ if (endIndex === -1) {
284
+ index = line.length;
285
+ continue;
286
+ }
287
+ insideBlockComment = false;
288
+ index = endIndex + 2;
289
+ continue;
290
+ }
291
+ const character = line[index];
292
+ const nextCharacter = line[index + 1];
293
+ if (stringQuote) {
294
+ if (escaped) {
295
+ escaped = false;
296
+ index += 1;
297
+ continue;
298
+ }
299
+ if (character === '\\') {
300
+ escaped = true;
301
+ index += 1;
302
+ continue;
303
+ }
304
+ if (character === stringQuote) {
305
+ stringQuote = null;
306
+ }
307
+ index += 1;
308
+ continue;
309
+ }
310
+ if (character === '"' || character === "'" || character === '`') {
311
+ stringQuote = character;
312
+ index += 1;
313
+ continue;
314
+ }
315
+ if (character === '/' && nextCharacter === '*') {
316
+ const commentStart = index + 2;
317
+ const endIndex = line.indexOf('*/', commentStart);
318
+ const segmentEnd = endIndex === -1 ? line.length : endIndex;
319
+ commentLines.push({ lineNumber: lineIndex + 1, text: line.slice(commentStart, segmentEnd) });
320
+ if (endIndex === -1) {
321
+ insideBlockComment = true;
322
+ index = line.length;
323
+ continue;
324
+ }
325
+ index = endIndex + 2;
326
+ continue;
327
+ }
328
+ if (character === '/' && nextCharacter === '/') {
329
+ commentLines.push({ lineNumber: lineIndex + 1, text: line.slice(index + 2) });
330
+ break;
331
+ }
332
+ if (character === '#' && line.slice(0, index).trim().length === 0) {
333
+ commentLines.push({ lineNumber: lineIndex + 1, text: line.slice(index + 1) });
334
+ break;
335
+ }
336
+ index += 1;
337
+ }
338
+ if (stringQuote !== '`') {
339
+ stringQuote = null;
340
+ }
341
+ escaped = false;
342
+ lineIndex += 1;
343
+ }
344
+ return commentLines;
345
+ }
346
+ export function parseSourceAnchorsInContent(relativePath, content) {
347
+ const lines = collectCommentLines(content);
270
348
  const anchors = [];
271
349
  for (let index = 0; index < lines.length; index += 1) {
272
- const normalized = stripSourceAnchorCommentPrefix(lines[index] ?? '');
350
+ const commentLine = lines[index];
351
+ const normalized = stripSourceAnchorCommentPrefix(commentLine?.text ?? '');
273
352
  if (!normalized.startsWith('mf:anchor')) {
274
353
  continue;
275
354
  }
@@ -278,12 +357,18 @@ export function parseSourceAnchorsInContent(relativePath, content) {
278
357
  const fields = new Map();
279
358
  const unsupportedFields = [];
280
359
  const rawLines = [normalized];
360
+ let previousLineNumber = commentLine?.lineNumber ?? 0;
281
361
  for (let fieldIndex = index + 1; fieldIndex < lines.length; fieldIndex += 1) {
282
- const fieldLine = stripSourceAnchorCommentPrefix(lines[fieldIndex] ?? '');
362
+ const nextCommentLine = lines[fieldIndex];
363
+ if (!nextCommentLine || nextCommentLine.lineNumber > previousLineNumber + 1) {
364
+ break;
365
+ }
366
+ const fieldLine = stripSourceAnchorCommentPrefix(nextCommentLine.text);
283
367
  if (fieldLine.length === 0) {
368
+ previousLineNumber = nextCommentLine.lineNumber;
284
369
  continue;
285
370
  }
286
- if (fieldLine.startsWith('@') || /^[A-Za-z_$][\w$]*\s/u.test(fieldLine)) {
371
+ if (fieldLine.startsWith('mf:anchor') || fieldLine.startsWith('@') || /^[A-Za-z_$][\w$]*\s/u.test(fieldLine)) {
287
372
  break;
288
373
  }
289
374
  const field = readSourceAnchorField(fieldLine);
@@ -291,6 +376,7 @@ export function parseSourceAnchorsInContent(relativePath, content) {
291
376
  break;
292
377
  }
293
378
  rawLines.push(fieldLine);
379
+ previousLineNumber = nextCommentLine.lineNumber;
294
380
  if (!SOURCE_ANCHOR_ALLOWED_FIELDS.has(field.key)) {
295
381
  unsupportedFields.push(field.key);
296
382
  continue;
@@ -302,7 +388,7 @@ export function parseSourceAnchorsInContent(relativePath, content) {
302
388
  rawId,
303
389
  idValid: SOURCE_ANCHOR_ID_PATTERN.test(rawId),
304
390
  path: relativePath,
305
- lineStart: index + 1,
391
+ lineStart: commentLine?.lineNumber ?? index + 1,
306
392
  fields,
307
393
  unsupportedFields,
308
394
  rawText: rawLines.join('\n'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustflow",
3
- "version": "2.58.1",
3
+ "version": "2.68.6",
4
4
  "description": "Agent workflow documents and CLI for mustflow repository roots.",
5
5
  "type": "module",
6
6
  "license": "MIT-0",
package/schemas/README.md CHANGED
@@ -7,7 +7,7 @@ Current schemas:
7
7
 
8
8
  - `doctor-report.schema.json`: output of `mf doctor --json`
9
9
  - `adapter-compatibility-report.schema.json`: output of `mf adapters status --json`
10
- - `context-report.schema.json`: output of `mf context --json`
10
+ - `context-report.schema.json`: output of `mf context --json`, including prompt-cache profiles and optional cache audit data
11
11
  - `workspace-summary.schema.json`: output of `mf api workspace-summary --json`
12
12
  - `command-catalog.schema.json`: output of `mf api command-catalog --json`
13
13
  - `verification-plan.schema.json`: output of `mf api verification-plan --changed --json`
@@ -49,6 +49,14 @@ Current schemas:
49
49
  `mf impact <path...> --json`
50
50
  - `line-endings-report.schema.json`: output of `mf line-endings check --json` and
51
51
  `mf line-endings normalize --json`
52
+ - `quality-gaming-report.schema.json`: output of `mf quality check --json`, containing changed-file
53
+ quality-gaming risks such as line stuffing, validation suppressions, test bypass markers, type
54
+ escapes, generated/vendor logic, empty catch swallowing, and placeholder implementations
55
+ - `skill-route-report.schema.json`: output of `mf skill route --json`, containing compact route
56
+ candidates, selected main and adjunct skills, score breakdowns, route read plans, and source
57
+ route shards without granting command authority or replacing selected `SKILL.md` reads
58
+ - `route-fixture.schema.json`: parsed `.mustflow/skills/route-fixtures.json`, containing strict
59
+ skill-route golden cases with required and forbidden route expectations
52
60
  - `latest-run-pointer.schema.json`: `.mustflow/state/runs/latest.json` when `mf verify` writes a
53
61
  pointer to the latest verify run bundle, including the verify completion verdict, evidence model,
54
62
  and coverage matrix
@@ -79,6 +79,9 @@
79
79
  "stable_prefix": { "$ref": "#/$defs/stablePrefixLayer" },
80
80
  "task_context": { "$ref": "#/$defs/taskContextLayer" },
81
81
  "volatile_suffix": { "$ref": "#/$defs/volatileSuffixLayer" },
82
+ "prompt_bundle": { "$ref": "#/$defs/promptBundle" },
83
+ "prompt_bundle_diff": { "$ref": "#/$defs/promptBundleDiff" },
84
+ "cache_audit": { "$ref": "#/$defs/promptCacheAudit" },
82
85
  "issues": {
83
86
  "type": "array",
84
87
  "items": { "type": "string" }
@@ -375,9 +378,79 @@
375
378
  "type": "array",
376
379
  "items": { "type": "string" }
377
380
  },
381
+ "route_read_plan": { "$ref": "#/$defs/taskRouteReadPlan" },
382
+ "repo_map_read_plan": { "$ref": "#/$defs/taskRepoMapReadPlan" },
378
383
  "local_index": { "$ref": "#/$defs/promptCacheLocalIndex" }
379
384
  }
380
385
  },
386
+ "taskRouteReadPlan": {
387
+ "type": "object",
388
+ "additionalProperties": false,
389
+ "required": [
390
+ "resolver_command",
391
+ "stable_kernel",
392
+ "route_sources",
393
+ "selected_skill_paths_source",
394
+ "route_metadata_fallback",
395
+ "expanded_index_fallback",
396
+ "selection_limits"
397
+ ],
398
+ "properties": {
399
+ "resolver_command": {
400
+ "type": "array",
401
+ "items": { "type": "string" }
402
+ },
403
+ "stable_kernel": {
404
+ "type": "array",
405
+ "items": { "type": "string" }
406
+ },
407
+ "route_sources": {
408
+ "type": "array",
409
+ "items": { "type": "string" }
410
+ },
411
+ "selected_skill_paths_source": { "type": "string" },
412
+ "route_metadata_fallback": { "$ref": "#/$defs/taskRouteFallback" },
413
+ "expanded_index_fallback": { "$ref": "#/$defs/taskRouteFallback" },
414
+ "selection_limits": { "$ref": "#/$defs/taskRouteSelectionLimits" }
415
+ }
416
+ },
417
+ "taskRouteFallback": {
418
+ "type": "object",
419
+ "additionalProperties": false,
420
+ "required": ["path", "read_when", "avoid_by_default"],
421
+ "properties": {
422
+ "path": { "type": "string" },
423
+ "read_when": {
424
+ "type": "array",
425
+ "items": { "type": "string" }
426
+ },
427
+ "avoid_by_default": { "type": "boolean" }
428
+ }
429
+ },
430
+ "taskRouteSelectionLimits": {
431
+ "type": "object",
432
+ "additionalProperties": false,
433
+ "required": ["candidates", "main", "adjuncts"],
434
+ "properties": {
435
+ "candidates": { "type": "integer", "minimum": 0 },
436
+ "main": { "type": "integer", "minimum": 0 },
437
+ "adjuncts": { "type": "integer", "minimum": 0 }
438
+ }
439
+ },
440
+ "taskRepoMapReadPlan": {
441
+ "type": "object",
442
+ "additionalProperties": false,
443
+ "required": ["source", "strategy", "anchor_sources", "fallback"],
444
+ "properties": {
445
+ "source": { "const": "repo_map_navigation" },
446
+ "strategy": { "const": "select_anchors_or_spans_before_full_map" },
447
+ "anchor_sources": {
448
+ "type": "array",
449
+ "items": { "type": "string" }
450
+ },
451
+ "fallback": { "$ref": "#/$defs/taskRouteFallback" }
452
+ }
453
+ },
381
454
  "promptCacheLocalIndex": {
382
455
  "type": "object",
383
456
  "additionalProperties": false,
@@ -425,6 +498,375 @@
425
498
  "include_absolute_root": { "const": false },
426
499
  "include_latest_run": { "const": false }
427
500
  }
501
+ },
502
+ "promptCacheAudit": {
503
+ "type": "object",
504
+ "additionalProperties": false,
505
+ "required": ["measurement", "estimator", "canonicalization", "summary", "layers", "issues"],
506
+ "properties": {
507
+ "measurement": { "const": "reference_bundle" },
508
+ "estimator": { "$ref": "#/$defs/promptCacheAuditEstimator" },
509
+ "canonicalization": {
510
+ "type": "array",
511
+ "items": { "type": "string" }
512
+ },
513
+ "summary": { "$ref": "#/$defs/promptCacheAuditSummary" },
514
+ "layers": {
515
+ "type": "array",
516
+ "items": { "$ref": "#/$defs/promptCacheAuditLayer" }
517
+ },
518
+ "issues": {
519
+ "type": "array",
520
+ "items": { "type": "string" }
521
+ }
522
+ }
523
+ },
524
+ "promptBundle": {
525
+ "type": "object",
526
+ "additionalProperties": false,
527
+ "required": [
528
+ "schema_version",
529
+ "renderer",
530
+ "content_included",
531
+ "request_shape_hash",
532
+ "bundle_hash",
533
+ "layers",
534
+ "issues"
535
+ ],
536
+ "properties": {
537
+ "schema_version": { "const": "1" },
538
+ "renderer": { "const": "reference_bundle_utf8_lf_v1" },
539
+ "content_included": { "const": false },
540
+ "request_shape_hash": { "type": "string" },
541
+ "bundle_hash": { "type": "string" },
542
+ "layers": {
543
+ "type": "array",
544
+ "items": { "$ref": "#/$defs/promptBundleLayer" }
545
+ },
546
+ "issues": {
547
+ "type": "array",
548
+ "items": { "type": "string" }
549
+ }
550
+ }
551
+ },
552
+ "promptBundleLayer": {
553
+ "type": "object",
554
+ "additionalProperties": false,
555
+ "required": ["cache_layer", "blocks"],
556
+ "properties": {
557
+ "cache_layer": { "enum": ["stable", "task", "volatile"] },
558
+ "blocks": {
559
+ "type": "array",
560
+ "items": { "$ref": "#/$defs/promptBundleBlock" }
561
+ }
562
+ }
563
+ },
564
+ "promptBundleBlock": {
565
+ "type": "object",
566
+ "additionalProperties": false,
567
+ "required": [
568
+ "id",
569
+ "cache_layer",
570
+ "order",
571
+ "kind",
572
+ "path",
573
+ "source",
574
+ "source_kind",
575
+ "selection_policy",
576
+ "content_included",
577
+ "content_hash",
578
+ "rendered_digest",
579
+ "rendered_bytes",
580
+ "estimated_tokens",
581
+ "cacheability",
582
+ "reload_on",
583
+ "issue"
584
+ ],
585
+ "properties": {
586
+ "id": { "type": "string" },
587
+ "cache_layer": { "enum": ["stable", "task", "volatile"] },
588
+ "order": { "type": "integer", "minimum": 1 },
589
+ "kind": { "enum": ["file", "source_placeholder"] },
590
+ "path": { "type": ["string", "null"] },
591
+ "source": { "type": ["string", "null"] },
592
+ "source_kind": { "enum": ["file_reference", "dynamic_selection", "runtime_volatile"] },
593
+ "selection_policy": {
594
+ "enum": [
595
+ "always_rendered",
596
+ "read_when_selected",
597
+ "fallback_when_needed",
598
+ "selected_at_runtime",
599
+ "volatile_runtime"
600
+ ]
601
+ },
602
+ "content_included": { "const": false },
603
+ "content_hash": { "type": ["string", "null"] },
604
+ "rendered_digest": { "type": ["string", "null"] },
605
+ "rendered_bytes": { "type": ["integer", "null"], "minimum": 0 },
606
+ "estimated_tokens": { "type": ["integer", "null"], "minimum": 0 },
607
+ "cacheability": {
608
+ "enum": [
609
+ "provider_prefix_candidate",
610
+ "task_selective",
611
+ "task_fallback",
612
+ "runtime_selection",
613
+ "volatile_suffix"
614
+ ]
615
+ },
616
+ "reload_on": {
617
+ "type": "array",
618
+ "items": { "type": "string" }
619
+ },
620
+ "issue": { "type": ["string", "null"] }
621
+ }
622
+ },
623
+ "promptBundleDiff": {
624
+ "type": "object",
625
+ "additionalProperties": false,
626
+ "required": [
627
+ "baseline_path",
628
+ "status",
629
+ "baseline_request_shape_hash",
630
+ "current_request_shape_hash",
631
+ "request_shape_changed",
632
+ "baseline_bundle_hash",
633
+ "current_bundle_hash",
634
+ "bundle_changed",
635
+ "first_difference",
636
+ "stable_diff",
637
+ "changed_blocks",
638
+ "issues"
639
+ ],
640
+ "properties": {
641
+ "baseline_path": { "type": "string" },
642
+ "status": {
643
+ "enum": [
644
+ "unchanged",
645
+ "changed",
646
+ "baseline_missing",
647
+ "baseline_unreadable",
648
+ "baseline_invalid",
649
+ "baseline_without_prompt_bundle"
650
+ ]
651
+ },
652
+ "baseline_request_shape_hash": { "type": ["string", "null"] },
653
+ "current_request_shape_hash": { "type": "string" },
654
+ "request_shape_changed": { "type": ["boolean", "null"] },
655
+ "baseline_bundle_hash": { "type": ["string", "null"] },
656
+ "current_bundle_hash": { "type": "string" },
657
+ "bundle_changed": { "type": ["boolean", "null"] },
658
+ "first_difference": {
659
+ "anyOf": [
660
+ { "type": "null" },
661
+ { "$ref": "#/$defs/promptBundleBlockDiff" }
662
+ ]
663
+ },
664
+ "stable_diff": { "$ref": "#/$defs/promptBundleStableDiff" },
665
+ "changed_blocks": {
666
+ "type": "array",
667
+ "items": { "$ref": "#/$defs/promptBundleBlockDiff" }
668
+ },
669
+ "issues": {
670
+ "type": "array",
671
+ "items": { "type": "string" }
672
+ }
673
+ }
674
+ },
675
+ "promptBundleStableDiff": {
676
+ "type": "object",
677
+ "additionalProperties": false,
678
+ "required": [
679
+ "stable_block_count",
680
+ "baseline_stable_block_count",
681
+ "matching_prefix_blocks",
682
+ "matching_prefix_ratio",
683
+ "stable_prefix_preserved",
684
+ "first_stable_difference",
685
+ "first_stable_invalidation_reason"
686
+ ],
687
+ "properties": {
688
+ "stable_block_count": { "type": "integer", "minimum": 0 },
689
+ "baseline_stable_block_count": { "type": ["integer", "null"], "minimum": 0 },
690
+ "matching_prefix_blocks": { "type": "integer", "minimum": 0 },
691
+ "matching_prefix_ratio": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
692
+ "stable_prefix_preserved": { "type": ["boolean", "null"] },
693
+ "first_stable_difference": {
694
+ "anyOf": [
695
+ { "type": "null" },
696
+ { "$ref": "#/$defs/promptBundleBlockDiff" }
697
+ ]
698
+ },
699
+ "first_stable_invalidation_reason": { "type": ["string", "null"] }
700
+ }
701
+ },
702
+ "promptBundleBlockDiff": {
703
+ "type": "object",
704
+ "additionalProperties": false,
705
+ "required": [
706
+ "kind",
707
+ "cache_layer",
708
+ "order",
709
+ "current_id",
710
+ "baseline_id",
711
+ "reason",
712
+ "fields"
713
+ ],
714
+ "properties": {
715
+ "kind": { "enum": ["added", "removed", "changed"] },
716
+ "cache_layer": { "type": ["string", "null"], "enum": ["stable", "task", "volatile", null] },
717
+ "order": { "type": ["integer", "null"], "minimum": 1 },
718
+ "current_id": { "type": ["string", "null"] },
719
+ "baseline_id": { "type": ["string", "null"] },
720
+ "reason": { "type": "string" },
721
+ "fields": {
722
+ "type": "array",
723
+ "items": { "type": "string" }
724
+ }
725
+ }
726
+ },
727
+ "promptCacheAuditEstimator": {
728
+ "type": "object",
729
+ "additionalProperties": false,
730
+ "required": ["name", "estimated_bytes_per_token", "caveat"],
731
+ "properties": {
732
+ "name": { "const": "reference_bundle_utf8_lf_v1" },
733
+ "estimated_bytes_per_token": { "const": 4 },
734
+ "caveat": { "type": "string" }
735
+ }
736
+ },
737
+ "promptCacheAuditSummary": {
738
+ "type": "object",
739
+ "additionalProperties": false,
740
+ "required": [
741
+ "rendered_bytes",
742
+ "estimated_tokens",
743
+ "measured_block_count",
744
+ "dynamic_source_count",
745
+ "unresolved_reference_count",
746
+ "volatile_before_stable_count",
747
+ "serialization_deterministic",
748
+ "stable_leaf_skill_isolated",
749
+ "stable_leaf_skill_risk_paths",
750
+ "leaf_skill_change_stable_hash_delta",
751
+ "stable_rendered_bytes",
752
+ "stable_estimated_tokens",
753
+ "stable_budget_status",
754
+ "stable_largest_block_budget_share",
755
+ "task_budget_status",
756
+ "volatile_budget_status"
757
+ ],
758
+ "properties": {
759
+ "rendered_bytes": { "type": ["integer", "null"], "minimum": 0 },
760
+ "estimated_tokens": { "type": ["integer", "null"], "minimum": 0 },
761
+ "measured_block_count": { "type": "integer", "minimum": 0 },
762
+ "dynamic_source_count": { "type": "integer", "minimum": 0 },
763
+ "unresolved_reference_count": { "type": "integer", "minimum": 0 },
764
+ "volatile_before_stable_count": { "type": "integer", "minimum": 0 },
765
+ "serialization_deterministic": { "const": true },
766
+ "stable_leaf_skill_isolated": { "type": ["boolean", "null"] },
767
+ "stable_leaf_skill_risk_paths": {
768
+ "type": "array",
769
+ "items": { "type": "string" }
770
+ },
771
+ "leaf_skill_change_stable_hash_delta": {
772
+ "type": ["integer", "null"],
773
+ "enum": [0, null]
774
+ },
775
+ "stable_rendered_bytes": { "type": ["integer", "null"], "minimum": 0 },
776
+ "stable_estimated_tokens": { "type": ["integer", "null"], "minimum": 0 },
777
+ "stable_budget_status": {
778
+ "type": ["string", "null"],
779
+ "enum": ["within_budget", "over_budget", "unknown", null]
780
+ },
781
+ "stable_largest_block_budget_share": { "type": ["number", "null"], "minimum": 0 },
782
+ "task_budget_status": {
783
+ "type": ["string", "null"],
784
+ "enum": ["within_budget", "over_budget", "unknown", null]
785
+ },
786
+ "volatile_budget_status": {
787
+ "type": ["string", "null"],
788
+ "enum": ["within_budget", "over_budget", "unknown", null]
789
+ }
790
+ }
791
+ },
792
+ "promptCacheAuditLayer": {
793
+ "type": "object",
794
+ "additionalProperties": false,
795
+ "required": [
796
+ "cache_layer",
797
+ "budget_kb",
798
+ "budget_bytes",
799
+ "rendered_bytes",
800
+ "estimated_tokens",
801
+ "budget_status",
802
+ "blocks",
803
+ "largest_blocks",
804
+ "issues"
805
+ ],
806
+ "properties": {
807
+ "cache_layer": { "enum": ["stable", "task", "volatile"] },
808
+ "budget_kb": { "type": ["integer", "null"] },
809
+ "budget_bytes": { "type": ["integer", "null"] },
810
+ "target_kb": { "type": ["integer", "null"] },
811
+ "target_bytes": { "type": ["integer", "null"] },
812
+ "target_status": { "enum": ["within_budget", "over_budget", "unknown"] },
813
+ "rendered_bytes": { "type": ["integer", "null"], "minimum": 0 },
814
+ "estimated_tokens": { "type": ["integer", "null"], "minimum": 0 },
815
+ "budget_status": { "enum": ["within_budget", "over_budget", "unknown"] },
816
+ "blocks": {
817
+ "type": "array",
818
+ "items": { "$ref": "#/$defs/promptCacheAuditBlock" }
819
+ },
820
+ "largest_blocks": {
821
+ "type": "array",
822
+ "items": { "$ref": "#/$defs/promptCacheAuditBlock" }
823
+ },
824
+ "issues": {
825
+ "type": "array",
826
+ "items": { "type": "string" }
827
+ }
828
+ }
829
+ },
830
+ "promptCacheAuditBlock": {
831
+ "type": "object",
832
+ "additionalProperties": false,
833
+ "required": [
834
+ "id",
835
+ "kind",
836
+ "path",
837
+ "source",
838
+ "exists",
839
+ "content_hash",
840
+ "rendered_bytes",
841
+ "estimated_tokens",
842
+ "budget_share",
843
+ "issue"
844
+ ],
845
+ "properties": {
846
+ "id": { "type": "string" },
847
+ "kind": { "enum": ["file", "source_placeholder"] },
848
+ "path": { "type": ["string", "null"] },
849
+ "source": { "type": ["string", "null"] },
850
+ "source_kind": { "enum": ["file_reference", "dynamic_selection", "runtime_volatile"] },
851
+ "selection_policy": {
852
+ "enum": [
853
+ "always_rendered",
854
+ "read_when_selected",
855
+ "fallback_when_needed",
856
+ "selected_at_runtime",
857
+ "volatile_runtime"
858
+ ]
859
+ },
860
+ "measurement_status": { "enum": ["measured", "hash_only_deferred", "dynamic_unmeasured"] },
861
+ "candidate_exists": { "type": ["boolean", "null"] },
862
+ "candidate_content_hash": { "type": ["string", "null"] },
863
+ "exists": { "type": ["boolean", "null"] },
864
+ "content_hash": { "type": ["string", "null"] },
865
+ "rendered_bytes": { "type": ["integer", "null"], "minimum": 0 },
866
+ "estimated_tokens": { "type": ["integer", "null"], "minimum": 0 },
867
+ "budget_share": { "type": ["number", "null"], "minimum": 0 },
868
+ "issue": { "type": ["string", "null"] }
869
+ }
428
870
  }
429
871
  }
430
872
  }