@sun-asterisk/sungen 3.2.16-beta.1 → 3.2.16-beta.11

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 (146) hide show
  1. package/dist/cli/commands/audit.d.ts.map +1 -1
  2. package/dist/cli/commands/audit.js +6 -0
  3. package/dist/cli/commands/audit.js.map +1 -1
  4. package/dist/cli/commands/delivery.d.ts.map +1 -1
  5. package/dist/cli/commands/delivery.js +67 -20
  6. package/dist/cli/commands/delivery.js.map +1 -1
  7. package/dist/exporters/feature-parser.d.ts +16 -1
  8. package/dist/exporters/feature-parser.d.ts.map +1 -1
  9. package/dist/exporters/feature-parser.js +21 -2
  10. package/dist/exporters/feature-parser.js.map +1 -1
  11. package/dist/exporters/matrix/build.d.ts +27 -2
  12. package/dist/exporters/matrix/build.d.ts.map +1 -1
  13. package/dist/exporters/matrix/build.js +277 -47
  14. package/dist/exporters/matrix/build.js.map +1 -1
  15. package/dist/exporters/matrix/export.d.ts +7 -4
  16. package/dist/exporters/matrix/export.d.ts.map +1 -1
  17. package/dist/exporters/matrix/export.js +22 -6
  18. package/dist/exporters/matrix/export.js.map +1 -1
  19. package/dist/exporters/matrix/gates.d.ts.map +1 -1
  20. package/dist/exporters/matrix/gates.js +112 -3
  21. package/dist/exporters/matrix/gates.js.map +1 -1
  22. package/dist/exporters/matrix/map-loader.d.ts.map +1 -1
  23. package/dist/exporters/matrix/map-loader.js +20 -0
  24. package/dist/exporters/matrix/map-loader.js.map +1 -1
  25. package/dist/exporters/matrix/render-csv.d.ts +3 -2
  26. package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
  27. package/dist/exporters/matrix/render-csv.js +53 -30
  28. package/dist/exporters/matrix/render-csv.js.map +1 -1
  29. package/dist/exporters/matrix/render-xlsx.d.ts +32 -8
  30. package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
  31. package/dist/exporters/matrix/render-xlsx.js +215 -83
  32. package/dist/exporters/matrix/render-xlsx.js.map +1 -1
  33. package/dist/exporters/matrix/types.d.ts +53 -7
  34. package/dist/exporters/matrix/types.d.ts.map +1 -1
  35. package/dist/exporters/matrix/types.js +2 -2
  36. package/dist/exporters/matrix/types.js.map +1 -1
  37. package/dist/exporters/matrix/wording.d.ts +61 -0
  38. package/dist/exporters/matrix/wording.d.ts.map +1 -0
  39. package/dist/exporters/matrix/wording.js +221 -0
  40. package/dist/exporters/matrix/wording.js.map +1 -0
  41. package/dist/exporters/scenario-merger.d.ts.map +1 -1
  42. package/dist/exporters/scenario-merger.js +2 -1
  43. package/dist/exporters/scenario-merger.js.map +1 -1
  44. package/dist/exporters/spec-parser.d.ts.map +1 -1
  45. package/dist/exporters/spec-parser.js +2 -1
  46. package/dist/exporters/spec-parser.js.map +1 -1
  47. package/dist/harness/audit.d.ts +6 -0
  48. package/dist/harness/audit.d.ts.map +1 -1
  49. package/dist/harness/audit.js +80 -15
  50. package/dist/harness/audit.js.map +1 -1
  51. package/dist/harness/blindspot.d.ts.map +1 -1
  52. package/dist/harness/blindspot.js +2 -1
  53. package/dist/harness/blindspot.js.map +1 -1
  54. package/dist/harness/capability-plan.d.ts.map +1 -1
  55. package/dist/harness/capability-plan.js +3 -2
  56. package/dist/harness/capability-plan.js.map +1 -1
  57. package/dist/harness/feedback.d.ts.map +1 -1
  58. package/dist/harness/feedback.js +3 -2
  59. package/dist/harness/feedback.js.map +1 -1
  60. package/dist/harness/flow-check.d.ts.map +1 -1
  61. package/dist/harness/flow-check.js +2 -1
  62. package/dist/harness/flow-check.js.map +1 -1
  63. package/dist/harness/flow-plan.d.ts.map +1 -1
  64. package/dist/harness/flow-plan.js +3 -2
  65. package/dist/harness/flow-plan.js.map +1 -1
  66. package/dist/harness/intent.d.ts.map +1 -1
  67. package/dist/harness/intent.js +2 -1
  68. package/dist/harness/intent.js.map +1 -1
  69. package/dist/harness/journey.d.ts.map +1 -1
  70. package/dist/harness/journey.js +3 -2
  71. package/dist/harness/journey.js.map +1 -1
  72. package/dist/harness/ledger.d.ts.map +1 -1
  73. package/dist/harness/ledger.js +3 -2
  74. package/dist/harness/ledger.js.map +1 -1
  75. package/dist/harness/manifest.d.ts.map +1 -1
  76. package/dist/harness/manifest.js +4 -3
  77. package/dist/harness/manifest.js.map +1 -1
  78. package/dist/harness/parse.d.ts.map +1 -1
  79. package/dist/harness/parse.js +16 -3
  80. package/dist/harness/parse.js.map +1 -1
  81. package/dist/harness/quality-gates.d.ts.map +1 -1
  82. package/dist/harness/quality-gates.js +2 -1
  83. package/dist/harness/quality-gates.js.map +1 -1
  84. package/dist/harness/read-text.d.ts +22 -0
  85. package/dist/harness/read-text.d.ts.map +1 -0
  86. package/dist/harness/read-text.js +64 -0
  87. package/dist/harness/read-text.js.map +1 -0
  88. package/dist/harness/script-check.d.ts.map +1 -1
  89. package/dist/harness/script-check.js +3 -2
  90. package/dist/harness/script-check.js.map +1 -1
  91. package/dist/harness/sensors.d.ts +13 -1
  92. package/dist/harness/sensors.d.ts.map +1 -1
  93. package/dist/harness/sensors.js +63 -20
  94. package/dist/harness/sensors.js.map +1 -1
  95. package/dist/harness/spec-coverage.d.ts +5 -0
  96. package/dist/harness/spec-coverage.d.ts.map +1 -1
  97. package/dist/harness/spec-coverage.js +17 -7
  98. package/dist/harness/spec-coverage.js.map +1 -1
  99. package/dist/harness/trace.d.ts.map +1 -1
  100. package/dist/harness/trace.js +4 -3
  101. package/dist/harness/trace.js.map +1 -1
  102. package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
  103. package/dist/harness/viewpoint-ledger.js +2 -1
  104. package/dist/harness/viewpoint-ledger.js.map +1 -1
  105. package/dist/orchestrator/templates/ai-src/commands/create-test.md +9 -0
  106. package/dist/orchestrator/templates/ai-src/commands/delivery.md +103 -18
  107. package/dist/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +77 -11
  108. package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -0
  109. package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +22 -0
  110. package/package.json +4 -4
  111. package/src/cli/commands/audit.ts +5 -0
  112. package/src/cli/commands/delivery.ts +68 -22
  113. package/src/exporters/feature-parser.ts +21 -2
  114. package/src/exporters/matrix/build.ts +281 -43
  115. package/src/exporters/matrix/export.ts +31 -6
  116. package/src/exporters/matrix/gates.ts +119 -3
  117. package/src/exporters/matrix/map-loader.ts +22 -1
  118. package/src/exporters/matrix/render-csv.ts +53 -30
  119. package/src/exporters/matrix/render-xlsx.ts +216 -85
  120. package/src/exporters/matrix/types.ts +58 -8
  121. package/src/exporters/matrix/wording.ts +221 -0
  122. package/src/exporters/scenario-merger.ts +2 -1
  123. package/src/exporters/spec-parser.ts +2 -1
  124. package/src/harness/audit.ts +84 -16
  125. package/src/harness/blindspot.ts +2 -1
  126. package/src/harness/capability-plan.ts +3 -2
  127. package/src/harness/feedback.ts +3 -2
  128. package/src/harness/flow-check.ts +2 -1
  129. package/src/harness/flow-plan.ts +3 -2
  130. package/src/harness/intent.ts +2 -1
  131. package/src/harness/journey.ts +3 -2
  132. package/src/harness/ledger.ts +3 -2
  133. package/src/harness/manifest.ts +4 -3
  134. package/src/harness/parse.ts +17 -3
  135. package/src/harness/quality-gates.ts +2 -1
  136. package/src/harness/read-text.ts +28 -0
  137. package/src/harness/script-check.ts +3 -2
  138. package/src/harness/sensors.ts +55 -8
  139. package/src/harness/spec-coverage.ts +22 -7
  140. package/src/harness/trace.ts +4 -3
  141. package/src/harness/viewpoint-ledger.ts +2 -1
  142. package/src/orchestrator/templates/ai-src/commands/create-test.md +9 -0
  143. package/src/orchestrator/templates/ai-src/commands/delivery.md +103 -18
  144. package/src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +77 -11
  145. package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -0
  146. package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +22 -0
@@ -10,6 +10,6 @@
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.MAX_VARIANTS_PER_ITEM = void 0;
13
- /** Complexity warning threshold (rules draft Gate I) — echoed in the manifest. */
14
- exports.MAX_VARIANTS_PER_ITEM = 12;
13
+ /** Complexity warning threshold (rules draft Gate I; raised for compact grouping) — echoed in the manifest. */
14
+ exports.MAX_VARIANTS_PER_ITEM = 20;
15
15
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/exporters/matrix/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAsKH,kFAAkF;AACrE,QAAA,qBAAqB,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/exporters/matrix/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAwNH,+GAA+G;AAClG,QAAA,qBAAqB,GAAG,EAAE,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Wording normalization — deterministic rendering step AFTER semantic
3
+ * normalization (review feedback §10): turn sungen DSL steps into controlled
4
+ * manual-test English without changing the target, condition, trigger,
5
+ * precondition, oracle, or trace.
6
+ *
7
+ * - Actions render in the imperative: "User fill [Email] field with X"
8
+ * → "Enter X in the Email field."
9
+ * - Expected results render as observable assertions (never tester actions):
10
+ * "User see [Jobs] page" → "The Jobs page is displayed."
11
+ * - Manual `# Tester verifies:` labels (Setup:/Action:/Observable:/Oracle:)
12
+ * become structured fields instead of prose: Setup → precondition,
13
+ * Action → action, Observable → expected, Oracle → verification method.
14
+ */
15
+ /** A step that CAPTURES a runtime value: `User remember [X] text as {{var}}`. */
16
+ export declare const RUNTIME_CAPTURE: RegExp;
17
+ /**
18
+ * Variable names a scenario defines at RUN TIME rather than reading from
19
+ * test-data: values captured from the page (`remember … as {{v}}`) and values
20
+ * bound by a capability precondition tag (`@query:`, `@api:`, `@dataFactory:`).
21
+ * The compiler already treats these as "captured" (DataResolver.registerCaptured);
22
+ * the delivery matrix must agree or it demands a static value that cannot exist.
23
+ */
24
+ export declare function runtimeVarsOf(stepTexts: string[], tags: string[]): Set<string>;
25
+ /**
26
+ * Render one action step in the imperative. Pattern table covers the common
27
+ * sungen step verbs; anything unmatched falls back to actor-stripped text —
28
+ * still readable, never a raw `User fill`.
29
+ */
30
+ export declare function renderAction(raw: string): string;
31
+ /**
32
+ * Render one expected step as an observable assertion (no tester action, no
33
+ * `should`, no DSL `User see`).
34
+ */
35
+ export declare function renderExpected(raw: string): string;
36
+ /** Precondition wording: a state, not an action ("The user is signed out."). */
37
+ export declare function renderPrecondition(raw: string): string;
38
+ /**
39
+ * A manual `Setup:` line is an INSTRUCTION the tester performs to establish the
40
+ * state — imperative reads correctly ("Seed the locked account."), while
41
+ * "The user seed …" is broken grammar (review GAP-08).
42
+ */
43
+ export declare function renderSetupInstruction(raw: string): string;
44
+ export interface ManualProcedure {
45
+ /** Setup/Precondition/Arrange lines — the state to establish first. */
46
+ preconditions: string[];
47
+ /** Action/unlabelled lines — the imperative procedure. */
48
+ actions: string[];
49
+ /** Observable/Expect/Result/Assert lines — the observable outcome. */
50
+ expected: string[];
51
+ /** Oracle/Verify lines — HOW to check (tools, panes, queries). */
52
+ verification: string[];
53
+ }
54
+ /**
55
+ * Split a manual scenario's numbered comment lines into the four structured
56
+ * fields. Labels are consumed (structured), never left inside the prose —
57
+ * review feedback §10.2(3). Continuation lines append to the previous item;
58
+ * pre-amble (rationale/header/dividers) is skipped.
59
+ */
60
+ export declare function classifyManualComments(comments: string[]): ManualProcedure;
61
+ //# sourceMappingURL=wording.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wording.d.ts","sourceRoot":"","sources":["../../../src/exporters/matrix/wording.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,iFAAiF;AACjF,eAAO,MAAM,eAAe,QAAkB,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAc9E;AAkBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyChD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAuClD;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAMD,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kEAAkE;IAClE,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,eAAe,CA2B1E"}
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ /**
3
+ * Wording normalization — deterministic rendering step AFTER semantic
4
+ * normalization (review feedback §10): turn sungen DSL steps into controlled
5
+ * manual-test English without changing the target, condition, trigger,
6
+ * precondition, oracle, or trace.
7
+ *
8
+ * - Actions render in the imperative: "User fill [Email] field with X"
9
+ * → "Enter X in the Email field."
10
+ * - Expected results render as observable assertions (never tester actions):
11
+ * "User see [Jobs] page" → "The Jobs page is displayed."
12
+ * - Manual `# Tester verifies:` labels (Setup:/Action:/Observable:/Oracle:)
13
+ * become structured fields instead of prose: Setup → precondition,
14
+ * Action → action, Observable → expected, Oracle → verification method.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.RUNTIME_CAPTURE = void 0;
18
+ exports.runtimeVarsOf = runtimeVarsOf;
19
+ exports.renderAction = renderAction;
20
+ exports.renderExpected = renderExpected;
21
+ exports.renderPrecondition = renderPrecondition;
22
+ exports.renderSetupInstruction = renderSetupInstruction;
23
+ exports.classifyManualComments = classifyManualComments;
24
+ /** A step that CAPTURES a runtime value: `User remember [X] text as {{var}}`. */
25
+ exports.RUNTIME_CAPTURE = /\bremember\b/i;
26
+ /**
27
+ * Variable names a scenario defines at RUN TIME rather than reading from
28
+ * test-data: values captured from the page (`remember … as {{v}}`) and values
29
+ * bound by a capability precondition tag (`@query:`, `@api:`, `@dataFactory:`).
30
+ * The compiler already treats these as "captured" (DataResolver.registerCaptured);
31
+ * the delivery matrix must agree or it demands a static value that cannot exist.
32
+ */
33
+ function runtimeVarsOf(stepTexts, tags) {
34
+ const out = new Set();
35
+ for (const text of stepTexts) {
36
+ if (!exports.RUNTIME_CAPTURE.test(text))
37
+ continue;
38
+ const m = text.match(/\bas\s+\{\{\s*([^}]+?)\s*\}\}/i);
39
+ if (m)
40
+ out.add(m[1].trim());
41
+ }
42
+ // A capability precondition binds its result under the endpoint/query/recipe
43
+ // name, so `{{<name>}}` and `{{<name>.field}}` exist only during the run.
44
+ for (const t of tags) {
45
+ const m = t.match(/^@(?:query|api|dataFactory):([^(\s]+)/);
46
+ if (m)
47
+ out.add(m[1]);
48
+ }
49
+ return out;
50
+ }
51
+ // `[Email] field` → `Email field` (the visible label + its element type).
52
+ function deRef(text) {
53
+ return text.replace(/\[([^\]]+)\]/g, '$1');
54
+ }
55
+ function sentence(text) {
56
+ // Trim the ENDS only — internal whitespace may be the test data itself
57
+ // (a padded email, a spaces-only value); collapsing it would silently
58
+ // change what the tester types (review GAP-04).
59
+ let s = text.trim();
60
+ if (!s)
61
+ return s;
62
+ s = s.charAt(0).toUpperCase() + s.slice(1);
63
+ if (!/[.!?…"]$/.test(s))
64
+ s += '.';
65
+ return s;
66
+ }
67
+ /**
68
+ * Render one action step in the imperative. Pattern table covers the common
69
+ * sungen step verbs; anything unmatched falls back to actor-stripped text —
70
+ * still readable, never a raw `User fill`.
71
+ */
72
+ function renderAction(raw) {
73
+ let s = raw.trim().replace(/^(User|The user)\s+/i, '');
74
+ // `remember … as {{v}}` DECLARES a runtime variable — the trailing token is a
75
+ // name, not a value to resolve. Quote it so no `{{brace}}` reaches the sheet
76
+ // whatever rule matches below.
77
+ if (exports.RUNTIME_CAPTURE.test(s))
78
+ s = s.replace(/\bas\s+\{\{\s*([^}]+?)\s*\}\}/i, 'as "$1"');
79
+ const rules = [
80
+ // remember [X] (text|value) as "v" — capture a value for a later comparison
81
+ [/^remembers? \[([^\]]+)\]\s*(text|value)?\s*as "([^"]+)"$/i,
82
+ (m) => `Note the ${m[1]} ${m[2] || 'text'} for later (as "${m[3]}")`],
83
+ // fill [X] field with V
84
+ [/^fills? \[([^\]]+)\][a-z ]* with (.+)$/i, (m) => `Enter ${m[2]} in the ${m[1]} field`],
85
+ // clear [X] field
86
+ [/^clears? \[([^\]]+)\](.*)$/i, (m) => `Clear the ${m[1]}${m[2] || ' field'}`],
87
+ // click [X] <type>
88
+ [/^clicks? \[([^\]]+)\]\s*(\w+)?$/i, (m) => `Click the ${m[1]}${m[2] ? ` ${m[2]}` : ''}`],
89
+ // press <Key> at/in [X] field
90
+ [/^press(?:es)? (.+?) (?:at|in|on|inside) \[([^\]]+)\](?: field)?$/i, (m) => `Press ${m[1]} in the ${m[2]} field`],
91
+ [/^press(?:es)? (.+)$/i, (m) => `Press ${m[1]}`],
92
+ // select V in/from [X] dropdown
93
+ [/^selects? (.+?) (?:in|from) \[([^\]]+)\]\s*(\w+)?$/i, (m) => `Select ${m[1]} in the ${m[2]}${m[3] ? ` ${m[3]}` : ''}`],
94
+ // check/uncheck [X] checkbox
95
+ [/^(un)?checks? \[([^\]]+)\]\s*(\w+)?$/i, (m) => `${m[1] ? 'Uncheck' : 'Check'} the ${m[2]}${m[3] ? ` ${m[3]}` : ''}`],
96
+ // hover [X]
97
+ [/^hovers? (?:over )?\[([^\]]+)\]\s*(\w+)?$/i, (m) => `Hover over the ${m[1]}${m[2] ? ` ${m[2]}` : ''}`],
98
+ // upload V to [X]
99
+ [/^uploads? (.+?) (?:to|into) \[([^\]]+)\]\s*(\w+)?$/i, (m) => `Upload ${m[1]} to the ${m[2]}${m[3] ? ` ${m[3]}` : ''}`],
100
+ // is on [X] page (as an action = navigate)
101
+ [/^is on \[([^\]]+)\] page(.*)$/i, (m) => `Open the ${m[1]} page${m[2] ?? ''}`],
102
+ // wait for [X] <type> (is )?visible
103
+ [/^waits? for \[([^\]]+)\]\s*(\w+)?(?: is)?(?: visible)?$/i, (m) => `Wait until the ${m[1]}${m[2] ? ` ${m[2]}` : ''} is visible`],
104
+ // scroll to [X]
105
+ [/^scrolls? (?:to|into) \[([^\]]+)\]\s*(\w+)?$/i, (m) => `Scroll to the ${m[1]}${m[2] ? ` ${m[2]}` : ''}`],
106
+ ];
107
+ for (const [re, out] of rules) {
108
+ const m = s.match(re);
109
+ if (m)
110
+ return sentence(deRef(out(m)));
111
+ }
112
+ return sentence(deRef(s));
113
+ }
114
+ /**
115
+ * Render one expected step as an observable assertion (no tester action, no
116
+ * `should`, no DSL `User see`).
117
+ */
118
+ function renderExpected(raw) {
119
+ // A capture step is an INSTRUCTION wherever it sits — Gherkin often chains
120
+ // `remember … / remember … / expect a is not b` inside one Then block. Render
121
+ // it as the note-it-down action, never as an assertion (and never leaving the
122
+ // declared `{{name}}` token behind).
123
+ if (exports.RUNTIME_CAPTURE.test(raw) && /\bas\s+\{\{/.test(raw))
124
+ return renderAction(raw);
125
+ let s = raw.trim().replace(/^(User|The user)\s+/i, '');
126
+ const rules = [
127
+ // expect A is (not) B — comparing two captured values (order matters: "is not" first)
128
+ [/^expects? (.+?) is not (.+)$/i, (m) => `${m[1]} differs from ${m[2]}`],
129
+ [/^expects? (.+?) is (.+)$/i, (m) => `${m[1]} equals ${m[2]}`],
130
+ // see all [X] <type> contain(s) V — every matching element, not just the first
131
+ [/^sees? all \[([^\]]+)\]\s*(\w+)? (?:contains?|match(?:es)?|belongs?) (.+)$/i,
132
+ (m) => `Every ${m[1]}${m[2] ? ` ${m[2]}` : ''} contains ${m[3]}`],
133
+ // see all [X] <type> contain [Child] <type> — structural per-item proof
134
+ [/^sees? all \[([^\]]+)\]\s*(\w+)? (?:contains?|includes?) \[([^\]]+)\]\s*(\w+)?$/i,
135
+ (m) => `Every ${m[1]}${m[2] ? ` ${m[2]}` : ''} contains a ${m[3]}${m[4] ? ` ${m[4]}` : ''}`],
136
+ // see [X] page
137
+ [/^sees? \[([^\]]+)\] page$/i, (m) => `The ${m[1]} page is displayed`],
138
+ // see [X] <type> with V
139
+ [/^sees? \[([^\]]+)\]\s*(\w+)? with (.+)$/i, (m) => `The ${m[1]}${m[2] ? ` ${m[2]}` : ''} shows ${m[3]}`],
140
+ // see [X] <type> contains V
141
+ [/^sees? \[([^\]]+)\]\s*(\w+)? contains (.+)$/i, (m) => `The ${m[1]}${m[2] ? ` ${m[2]}` : ''} contains ${m[3]}`],
142
+ // see [X] <type> has text V
143
+ [/^sees? \[([^\]]+)\]\s*(\w+)? has text (.+)$/i, (m) => `The ${m[1]}${m[2] ? ` ${m[2]}` : ''} shows ${m[3]}`],
144
+ // see [X] <type> is hidden / is disabled / is enabled / …
145
+ [/^sees? \[([^\]]+)\]\s*(\w+)? is (.+)$/i, (m) => `The ${m[1]}${m[2] ? ` ${m[2]}` : ''} is ${m[3]}`],
146
+ // not see [X] <type>
147
+ [/^(?:do(?:es)? )?not sees? \[([^\]]+)\]\s*(\w+)?$/i, (m) => `The ${m[1]}${m[2] ? ` ${m[2]}` : ''} is not displayed`],
148
+ // see [X] <type>
149
+ [/^sees? \[([^\]]+)\]\s*(\w+)?$/i, (m) => `The ${m[1]}${m[2] ? ` ${m[2]}` : ''} is visible`],
150
+ ];
151
+ for (const [re, out] of rules) {
152
+ const m = s.match(re);
153
+ if (m)
154
+ return sentence(deRef(out(m)));
155
+ }
156
+ return sentence(deRef(s));
157
+ }
158
+ /** Precondition wording: a state, not an action ("The user is signed out."). */
159
+ function renderPrecondition(raw) {
160
+ const s = raw.trim().replace(/^(User|The user)\s+/i, '');
161
+ const m = s.match(/^is on \[([^\]]+)\] page(.*)$/i);
162
+ if (m)
163
+ return sentence(`The user is on the ${m[1]} page${m[2] ?? ''}`);
164
+ // "wait for [X] <type> (is) visible" is a STATE once established, not an action.
165
+ const w = s.match(/^waits? for \[([^\]]+)\]\s*(\w+)?(?: is)?(?: visible)?$/i);
166
+ if (w)
167
+ return sentence(`The ${w[1]}${w[2] ? ` ${w[2]}` : ''} is visible`);
168
+ const auth = s.match(/^is (signed|logged) (in|out)(.*)$/i);
169
+ if (auth)
170
+ return sentence(`The user is ${auth[1]} ${auth[2]}${auth[3] ?? ''}`);
171
+ return sentence(deRef(`The user ${s.charAt(0).toLowerCase()}${s.slice(1)}`));
172
+ }
173
+ /**
174
+ * A manual `Setup:` line is an INSTRUCTION the tester performs to establish the
175
+ * state — imperative reads correctly ("Seed the locked account."), while
176
+ * "The user seed …" is broken grammar (review GAP-08).
177
+ */
178
+ function renderSetupInstruction(raw) {
179
+ return renderAction(raw);
180
+ }
181
+ /**
182
+ * Split a manual scenario's numbered comment lines into the four structured
183
+ * fields. Labels are consumed (structured), never left inside the prose —
184
+ * review feedback §10.2(3). Continuation lines append to the previous item;
185
+ * pre-amble (rationale/header/dividers) is skipped.
186
+ */
187
+ function classifyManualComments(comments) {
188
+ const out = { preconditions: [], actions: [], expected: [], verification: [] };
189
+ let last = null;
190
+ const bucketOf = (label) => {
191
+ if (/setup|precondition|arrange|given/i.test(label))
192
+ return 'preconditions';
193
+ if (/oracle|verify|verification|how to check/i.test(label))
194
+ return 'verification';
195
+ if (/observ|expect|result|then|assert/i.test(label))
196
+ return 'expected';
197
+ return 'actions';
198
+ };
199
+ for (const raw of comments) {
200
+ const line = raw.trim();
201
+ if (!line)
202
+ continue;
203
+ if (/^[-=*_]{2,}/.test(line)) {
204
+ last = null;
205
+ continue;
206
+ }
207
+ const m = line.match(/^\d+[.)]\s*(?:([A-Za-z][A-Za-z /]*?):\s*)?(.+)$/);
208
+ if (m) {
209
+ const label = (m[1] || '').trim();
210
+ const text = m[2].trim();
211
+ const list = out[bucketOf(label)];
212
+ list.push(text);
213
+ last = { list, idx: list.length - 1 };
214
+ }
215
+ else if (last) {
216
+ last.list[last.idx] += ' ' + line;
217
+ }
218
+ }
219
+ return out;
220
+ }
221
+ //# sourceMappingURL=wording.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wording.js","sourceRoot":"","sources":["../../../src/exporters/matrix/wording.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scenario-merger.d.ts","sourceRoot":"","sources":["../../src/exporters/scenario-merger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGjG;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;CAAE,CAwBzG;AAED,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,OAAO,EAAE,gBAAgB,CAAC;IAE1B,oEAAoE;IACpE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEtB;;;;;;OAMG;IACH,iBAAiB,EAAG,MAAM,EAAE,CAAC;IAC7B,iBAAiB,EAAG,MAAM,EAAE,CAAC;IAC7B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B;;;OAGG;IACH,gBAAgB,EAAE,WAAW,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,YAAY,GACjB,cAAc,EAAE,CAkElB"}
1
+ {"version":3,"file":"scenario-merger.d.ts","sourceRoot":"","sources":["../../src/exporters/scenario-merger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAIjG;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;CAAE,CAwBzG;AAED,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,OAAO,EAAE,gBAAgB,CAAC;IAE1B,oEAAoE;IACpE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEtB;;;;;;OAMG;IACH,iBAAiB,EAAG,MAAM,EAAE,CAAC;IAC7B,iBAAiB,EAAG,MAAM,EAAE,CAAC;IAC7B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B;;;OAGG;IACH,gBAAgB,EAAE,WAAW,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,YAAY,GACjB,cAAc,EAAE,CAkElB"}
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.parseManualComments = parseManualComments;
13
13
  exports.mergeFeatureAndSpec = mergeFeatureAndSpec;
14
14
  const feature_parser_1 = require("./feature-parser");
15
+ const feature_parser_2 = require("./feature-parser");
15
16
  /**
16
17
  * Parse a @manual scenario's `# Tester verifies:` comment block into procedure vs
17
18
  * expected. Each item is a numbered line, optionally prefixed with a label:
@@ -127,7 +128,7 @@ function findMatchingSpecTest(scenario, tests) {
127
128
  if (exact)
128
129
  return exact;
129
130
  // Fallback: match by VP-ID prefix (ignore trailing text differences)
130
- const vpMatch = scenario.name.match(/^(VP-[A-Z][A-Z0-9]*-\d+(?:[a-zA-Z]|-[A-Z0-9]+)?)/);
131
+ const vpMatch = scenario.name.match(feature_parser_2.SCENARIO_ID);
131
132
  if (vpMatch) {
132
133
  const vpId = vpMatch[1];
133
134
  const byVp = tests.find((t) => t.vpId === vpId);
@@ -1 +1 @@
1
- {"version":3,"file":"scenario-merger.js","sourceRoot":"","sources":["../../src/exporters/scenario-merger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scenario-merger.js","sourceRoot":"","sources":["../../src/exporters/scenario-merger.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"spec-parser.d.ts","sourceRoot":"","sources":["../../src/exporters/spec-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAY,YAAY,EAAE,MAAM,SAAS,CAAC;AAqKjD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CA+ChE"}
1
+ {"version":3,"file":"spec-parser.d.ts","sourceRoot":"","sources":["../../src/exporters/spec-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAY,YAAY,EAAE,MAAM,SAAS,CAAC;AAsKjD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CA+ChE"}
@@ -39,6 +39,7 @@ var __importStar = (this && this.__importStar) || (function () {
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
40
  exports.parseSpecFile = parseSpecFile;
41
41
  const fs = __importStar(require("fs"));
42
+ const feature_parser_1 = require("./feature-parser");
42
43
  /**
43
44
  * Extract the inner body of a test('title', async (...) => { BODY }) block.
44
45
  * Returns null if no match.
@@ -190,7 +191,7 @@ function classifyBlock(block) {
190
191
  * Try to extract VP ID (e.g., VP-UI-001) from the start of a scenario title.
191
192
  */
192
193
  function extractVpId(title) {
193
- const match = title.match(/^(VP-[A-Z][A-Z0-9]*-\d+(?:[a-zA-Z]|-[A-Z0-9]+)?)\b/);
194
+ const match = title.match(new RegExp(feature_parser_1.SCENARIO_ID.source + '\\b'));
194
195
  return match ? match[1] : undefined;
195
196
  }
196
197
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"spec-parser.js","sourceRoot":"","sources":["../../src/exporters/spec-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spec-parser.js","sourceRoot":"","sources":["../../src/exporters/spec-parser.ts"],"names":[],"mappings":"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"}
@@ -28,9 +28,15 @@ export interface AuditReport {
28
28
  value: number;
29
29
  };
30
30
  inflated: boolean;
31
+ /** Axes excluded for lack of evidence (no spec / viewpoint file / decidable page type). */
32
+ notApplicable?: string[];
33
+ /** Set when a weak critical axis holds the overall down. */
34
+ cappedAt?: number;
31
35
  };
32
36
  score: {
33
37
  overall: number;
38
+ notApplicable?: string[];
39
+ cappedAt?: number;
34
40
  coverage: number;
35
41
  businessDepth: number;
36
42
  balance: number;
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/harness/audit.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAW,uBAAuB,EAAE,eAAe,EAAE,oBAAoB,EAChL,MAAM,WAAW,CAAC;AAInB,OAAO,EAAwC,aAAa,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAiB,UAAU,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAgB,kBAAkB,EAAoB,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAA2C,gBAAgB,EAAE,kBAAkB,EACQ,MAAM,iBAAiB,CAAC;AACtH,OAAO,EAAwC,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKxF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,YAAY,EAAE,kBAAkB,CAAC;IACjC,iBAAiB,EAAE,uBAAuB,CAAC;IAC3C,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QACzC,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAcD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQrI;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,CAAC,EAAE;IAAE,YAAY,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,GAC1F,MAAM,CAGR;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAgT3E"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/harness/audit.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAW,uBAAuB,EAAE,eAAe,EAAE,oBAAoB,EAChL,MAAM,WAAW,CAAC;AAInB,OAAO,EAAwC,aAAa,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAiB,UAAU,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAgB,kBAAkB,EAAoB,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAA2C,gBAAgB,EAAE,kBAAkB,EACQ,MAAM,iBAAiB,CAAC;AACtH,OAAO,EAAwC,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMxF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,YAAY,EAAE,kBAAkB,CAAC;IACjC,iBAAiB,EAAE,uBAAuB,CAAC;IAC3C,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QACzC,QAAQ,EAAE,OAAO,CAAC;QAClB,2FAA2F;QAC3F,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,4DAA4D;QAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAcD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQrI;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,CAAC,EAAE;IAAE,YAAY,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,GAC1F,MAAM,CAGR;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CA6W3E"}
@@ -60,6 +60,7 @@ const viewpoint_ledger_1 = require("./viewpoint-ledger");
60
60
  const registry_1 = require("../capabilities/registry");
61
61
  const discover_1 = require("../capabilities/discover");
62
62
  const context_router_1 = require("../capabilities/context-router");
63
+ const read_text_1 = require("./read-text");
63
64
  /** The catalog-resolution id for a unit dir (relative to qa/): screen · flows/<flow> · api/<area> · api/flows/<flow>. */
64
65
  function catalogIdFromScreenDir(screenDir) {
65
66
  const parts = screenDir.split(path.sep);
@@ -111,7 +112,7 @@ function runAudit(screenDir, screenName) {
111
112
  // the old behaviour (so the audit-sample snapshot is unchanged); flows/api now resolve correctly.
112
113
  const catalogScreenName = catalogIdFromScreenDir(screenDir);
113
114
  const specPath = path.join(screenDir, 'requirements', 'spec.md');
114
- const featureText = fs.existsSync(featurePath) ? fs.readFileSync(featurePath, 'utf-8') : '';
115
+ const featureText = fs.existsSync(featurePath) ? (0, read_text_1.readTextFile)(featurePath) : '';
115
116
  const scenarios = (0, parse_1.loadScenarios)(featurePath);
116
117
  const viewpoints = (0, parse_1.parseViewpointOverview)(viewpointPath);
117
118
  // AO-1 — capability-routed scoring: the viewpoint catalog + score-bearing gate are owned by the
@@ -137,7 +138,8 @@ function runAudit(screenDir, screenName) {
137
138
  // catalog) + the focus depth threshold (so it scores depth with the SAME bar as the UI gate).
138
139
  const capGate = scoringCap?.gateProvider;
139
140
  const provided = capGate?.({ scenarios, viewpoints, catalog, focus: intent.focus, cwd: (0, intent_1.projectRootFromScreenDir)(screenDir), screenName: catalogScreenName, threshold: (0, sensors_1.depthThresholdFor)(intent.focus), businessCriticalMethods: intent.businessCriticalMethods });
140
- const gate = provided?.gate ?? (0, sensors_1.viewpointGate)(scenarios, viewpoints, catalog, platform === 'mobile');
141
+ const viewpointText = fs.existsSync(viewpointPath) ? (0, read_text_1.readTextFile)(viewpointPath) : '';
142
+ const gate = provided?.gate ?? (0, sensors_1.viewpointGate)(scenarios, viewpoints, catalog, platform === 'mobile', viewpointText);
141
143
  const depth = provided?.depth ?? (0, sensors_1.assertionDepth)(scenarios, (0, sensors_1.dataThemesFor)(catalog, gate.pageType), intent.focus);
142
144
  // TQ-4 — deferral-aware coverage credit: an inherently cross-screen theme (cart / detail /
143
145
  // filter correctness) belongs in a FLOW, not on the screen. When a flow deeply covers a screen
@@ -197,8 +199,53 @@ function runAudit(screenDir, screenName) {
197
199
  ? Math.min(1, balance.coreCount / Math.max(1, balance.secondaryCount))
198
200
  : 1;
199
201
  const traceScore = 0.5 * trace.withVpCodeRatio + 0.5 * trace.mappedRatio;
200
- // Business-weighted overall (coverage + depth dominate)
201
- const rawOverall = (0.4 * coverage + 0.3 * businessDepth + 0.15 * balanceScore + 0.15 * traceScore) * 10;
202
+ // ---- Business-weighted overall -------------------------------------------
203
+ //
204
+ // Two rules make the number mean what it says:
205
+ //
206
+ // 1. Only axes the project supplies EVIDENCE for are scored, and the weights
207
+ // are renormalised over them. The old formula spent 40% on page-type theme
208
+ // coverage — which is 1.0 whenever no page type is detected — so a screen
209
+ // with no detectable type collected 4 free points, while a mis-detected one
210
+ // was judged against themes it can never have. Missing spec / viewpoint
211
+ // files are treated the same way: absent evidence scores nothing, in either
212
+ // direction.
213
+ // 2. The three axes the harness already measured but never counted —
214
+ // claimProof, specFR, atomicLedger — now carry weight. A suite where two
215
+ // thirds of the scenarios do not prove their own title used to score 7.9.
216
+ const specRatio = spec.frTotal ? spec.frCovered / spec.frTotal : 1;
217
+ const axisDefs = [
218
+ { key: 'coverage', value: coverage, weight: 0.22, applicable: !!gate.pageType && gate.themesTotal > 0, critical: true },
219
+ { key: 'specFR', value: specRatio, weight: 0.15, applicable: spec.hasSpec && spec.frTotal > 0, critical: true },
220
+ { key: 'atomicLedger', value: ledger.ratio, weight: 0.13, applicable: ledger.hasViewpoint && ledger.total > 0, critical: true },
221
+ { key: 'businessDepth', value: businessDepth, weight: 0.20, applicable: true, critical: true },
222
+ { key: 'claimProof', value: claim.ratio, weight: 0.15, applicable: claim.withClaims > 0, critical: true },
223
+ { key: 'traceability', value: traceScore, weight: 0.09, applicable: viewpoints.length > 0, critical: false },
224
+ { key: 'balance', value: balanceScore, weight: 0.06, applicable: true, critical: false },
225
+ ];
226
+ const scored = axisDefs.filter((a) => a.applicable);
227
+ const weightSum = scored.reduce((t, a) => t + a.weight, 0) || 1;
228
+ const weighted = scored.reduce((t, a) => t + a.weight * a.value, 0) / weightSum;
229
+ // A weak axis is a hole, and a hole must not be averaged away: the pass
230
+ // threshold teams set (7.x) has to mean "no hole", not "good on balance".
231
+ const criticalScored = scored.filter((a) => a.critical);
232
+ const weakestCritical = criticalScored.slice().sort((a, b) => a.value - b.value)[0];
233
+ const CAP_SEVERE = 6.9; // below any 7.x gate
234
+ const CAP_WEAK = 7.9;
235
+ // Dropping an axis for lack of evidence must not become a shortcut to a perfect
236
+ // score: with no spec and no viewpoint file the remaining axes are easy to max.
237
+ // A top mark has to rest on complete evidence, so partial evidence caps below it.
238
+ const CAP_PARTIAL_EVIDENCE = 8.9;
239
+ let cap = 10;
240
+ if (weakestCritical && weakestCritical.value < 0.5)
241
+ cap = CAP_SEVERE;
242
+ else if (weakestCritical && weakestCritical.value < 0.7)
243
+ cap = CAP_WEAK;
244
+ const missingEvidence = axisDefs.filter((a) => !a.applicable).map((a) => a.key);
245
+ if (missingEvidence.length > 0)
246
+ cap = Math.min(cap, CAP_PARTIAL_EVIDENCE);
247
+ const rawOverall = Math.min(weighted * 10, cap);
248
+ const capped = weakestCritical ? weighted * 10 > cap : false;
202
249
  // H7 — senior-grade band: the top decile (≥9) is reserved for suites that also clear the senior
203
250
  // axes — a stateful flow with FULL regression depth (count + teardown + multi-source), no weak
204
251
  // facet oracle, and no parallel-cart isolation risk. Otherwise the score is held just below 9, so
@@ -206,11 +253,20 @@ function runAudit(screenDir, screenName) {
206
253
  const isoRisk = (0, quality_gates_1.isolationRisk)(featureText, flowDepth.stateful);
207
254
  const overall = seniorBandedOverall(rawOverall, { flowStateful: flowDepth.stateful, flowRatio: flowDepth.ratio, oracleWeak: oracle.weak.length, isolationRisk: isoRisk });
208
255
  const findings = [];
256
+ if (capped) {
257
+ const why = weakestCritical && weakestCritical.value < 0.7
258
+ ? `"${weakestCritical.key}" is ${(weakestCritical.value * 100).toFixed(0)}% — a weak axis is a hole, not something the other axes can average away`
259
+ : `this unit supplies no evidence for [${missingEvidence.join(', ')}], and a top mark has to rest on complete evidence`;
260
+ findings.push(`SCORE-CAPPED: overall held at ${cap.toFixed(1)} because ${why}.`);
261
+ }
262
+ if (gate.pageTypeSource === 'undetermined') {
263
+ findings.push(`PAGE-TYPE-UNDETERMINED: no page type fits this screen with enough confidence (best ${gate.pageTypeEvidence?.hits ?? 0} keyword hit(s)), so NO critical themes were demanded and the coverage axis is excluded from the score — declare it in test-viewpoint.md (\`page-type: <id>\`) to have the theme checklist applied.`);
264
+ }
209
265
  for (const c of flowCredits) {
210
266
  findings.push(`COVERED-VIA-FLOW: critical theme "${c.theme}" is not covered on this screen but is deeply covered by flow "${c.flow}" — cross-screen depth correctly owned by the flow, so it is credited (not a screen gap). Verify with \`sungen flow-check\`.`);
211
267
  }
212
268
  // Verification-scope (advisory): API/DB verification the project's recorded test type never asked for.
213
- for (const v of (0, capability_1.verificationScopeFindings)(featureText, fs.existsSync(viewpointPath) ? fs.readFileSync(viewpointPath, 'utf-8') : '', capProfile)) {
269
+ for (const v of (0, capability_1.verificationScopeFindings)(featureText, fs.existsSync(viewpointPath) ? (0, read_text_1.readTextFile)(viewpointPath) : '', capProfile)) {
214
270
  findings.push(`VERIFICATION-OUT-OF-SCOPE (${v.layer}): this unit ${v.message}`);
215
271
  }
216
272
  for (const g of gate.gaps) {
@@ -274,6 +330,14 @@ function runAudit(screenDir, screenName) {
274
330
  for (const u of spec.uncoveredMust) {
275
331
  findings.push(`SPEC-UNCOVERED: ${u.id} (MUST) has no covering scenario — "${u.text}" → add a scenario or tag one @spec:${u.id}.`);
276
332
  }
333
+ if (spec.inferredOnly.length > 0) {
334
+ // Covered, but only by keyword inference — no scenario cites the id. Delivery's
335
+ // requirement table (and any later refactor) cannot follow an inferred link, so
336
+ // the trace has to be written down while the author still knows which scenario
337
+ // proves what.
338
+ const shown = spec.inferredOnly.slice(0, 8).join(', ');
339
+ findings.push(`SPEC-TRACE-IMPLICIT: ${spec.inferredOnly.length} requirement(s) are covered by keyword inference only (${shown}${spec.inferredOnly.length > 8 ? ', …' : ''}) — add \`@spec:<id>\` to the scenario that proves each so the trace survives edits and delivery can report it.`);
340
+ }
277
341
  if (taxonomyMismatch) {
278
342
  findings.push(`VP-TAXONOMY-MISMATCH: only ${(trace.mappedRatio * 100).toFixed(0)}% of scenarios use the viewpoint IDs declared in test-viewpoint.md — scenarios invented a generic VP-<CAT> scheme. Re-tag to the project's viewpoint IDs so the coverage matrix is accurate.`);
279
343
  }
@@ -351,15 +415,16 @@ function runAudit(screenDir, screenName) {
351
415
  // #8 — multi-axis calibration: a high overall must not hide a weak axis.
352
416
  const manualCompleteness = manualOracleResult.manualTotal
353
417
  ? 1 - manualOracleResult.insufficient.length / manualOracleResult.manualTotal : 1;
354
- const axes = {
355
- coverage: Math.round(coverage * 100) / 100,
356
- businessDepth: Math.round(businessDepth * 100) / 100,
357
- claimProof: Math.round(claim.ratio * 100) / 100,
358
- specFR: spec.frTotal ? Math.round((spec.frCovered / spec.frTotal) * 100) / 100 : 1,
359
- atomicLedger: Math.round(ledger.ratio * 100) / 100,
360
- manualOracle: Math.round(manualCompleteness * 100) / 100,
361
- taxonomy: taxonomyMismatch ? 0 : Math.round(trace.mappedRatio * 100) / 100,
362
- };
418
+ // Only the axes that were actually scored appear here — an axis with no evidence
419
+ // (no spec, no viewpoint file, no decidable page type) is reported as such rather
420
+ // than as a silent 100%, which is what let empty inputs look like perfect ones.
421
+ const axes = {};
422
+ for (const a of scored)
423
+ axes[a.key] = Math.round(a.value * 100) / 100;
424
+ // Measured but not weighted: they drive findings, not the headline.
425
+ axes.manualOracle = Math.round(manualCompleteness * 100) / 100;
426
+ axes.taxonomy = taxonomyMismatch ? 0 : Math.round(trace.mappedRatio * 100) / 100;
427
+ const notApplicable = axisDefs.filter((a) => !a.applicable).map((a) => a.key);
363
428
  const weakestEntry = Object.entries(axes).sort((a, b) => a[1] - b[1])[0];
364
429
  const weakest = { axis: weakestEntry[0], value: weakestEntry[1] };
365
430
  // Inflated when breadth hides a weak axis, OR when businessDepth is high but rests on a
@@ -369,7 +434,7 @@ function runAudit(screenDir, screenName) {
369
434
  if (inflated) {
370
435
  findings.push(`SCORE-INFLATED-BY-BREADTH: overall ${Math.round(overall * 10) / 10}/10 but the weakest axis "${weakest.axis}" is ${(weakest.value * 100).toFixed(0)}% — breadth is hiding a weak dimension. Raise "${weakest.axis}" before trusting the headline.`);
371
436
  }
372
- const calibration = { axes, weakest, inflated };
437
+ const calibration = { axes, weakest, inflated, notApplicable, cappedAt: capped ? cap : undefined };
373
438
  // Gate spans coverage (viewpoint themes), depth, claim-proof, spec-clause coverage,
374
439
  // AND taxonomy-match (scenarios must use the project's viewpoint IDs when defined).
375
440
  const gateStatus = gate.gaps.length === 0 && depth.verdict !== 'fail' && claim.verdict !== 'fail' && spec.verdict !== 'fail' && !taxonomyMismatch && !gateSensorError ? 'PASS' : 'FAIL';