@sun-asterisk/sungen 3.2.21-beta.2 → 3.2.21-beta.4

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 (37) hide show
  1. package/dist/cli/commands/delivery.d.ts +3 -0
  2. package/dist/cli/commands/delivery.d.ts.map +1 -1
  3. package/dist/cli/commands/delivery.js +2 -0
  4. package/dist/cli/commands/delivery.js.map +1 -1
  5. package/dist/cli/commands/inspect.d.ts +41 -0
  6. package/dist/cli/commands/inspect.d.ts.map +1 -0
  7. package/dist/cli/commands/inspect.js +134 -0
  8. package/dist/cli/commands/inspect.js.map +1 -0
  9. package/dist/cli/index.js +2 -0
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/exporters/matrix/build.d.ts.map +1 -1
  12. package/dist/exporters/matrix/build.js +1 -0
  13. package/dist/exporters/matrix/build.js.map +1 -1
  14. package/dist/exporters/matrix/types.d.ts +2 -0
  15. package/dist/exporters/matrix/types.d.ts.map +1 -1
  16. package/dist/exporters/matrix/types.js.map +1 -1
  17. package/dist/harness/audit.d.ts.map +1 -1
  18. package/dist/harness/audit.js +10 -1
  19. package/dist/harness/audit.js.map +1 -1
  20. package/dist/harness/flow-contract.d.ts +16 -0
  21. package/dist/harness/flow-contract.d.ts.map +1 -1
  22. package/dist/harness/flow-contract.js +26 -2
  23. package/dist/harness/flow-contract.js.map +1 -1
  24. package/dist/orchestrator/templates/ai-src/commands/add-flow.md +5 -0
  25. package/dist/orchestrator/templates/ai-src/commands/run-test.md +23 -0
  26. package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +8 -0
  27. package/package.json +3 -3
  28. package/src/cli/commands/delivery.ts +2 -2
  29. package/src/cli/commands/inspect.ts +128 -0
  30. package/src/cli/index.ts +2 -0
  31. package/src/exporters/matrix/build.ts +1 -0
  32. package/src/exporters/matrix/types.ts +2 -0
  33. package/src/harness/audit.ts +10 -1
  34. package/src/harness/flow-contract.ts +34 -2
  35. package/src/orchestrator/templates/ai-src/commands/add-flow.md +5 -0
  36. package/src/orchestrator/templates/ai-src/commands/run-test.md +23 -0
  37. package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +8 -0
@@ -40,6 +40,11 @@ export interface FlowContract {
40
40
  /** The mutated collection (cart, order, application …) — enables regression dims. */
41
41
  stateful?: string;
42
42
  budgets?: Record<string, number>;
43
+ /** External-system legs (owned by another team/vendor) — ISTQB System INTEGRATION Testing
44
+ * scope (#580 P10). Scenarios touching these namespaces are classified SIT. */
45
+ external?: Array<{ name: string; owner?: string; screens: string[] }>;
46
+ /** This flow is release-critical: Final Inspection expects a @golden scenario here (P9). */
47
+ golden?: boolean;
43
48
  }
44
49
 
45
50
  export interface FlowQualityResult {
@@ -60,6 +65,9 @@ export interface FlowQualityResult {
60
65
  phaseRatio: number;
61
66
  /** Cross-namespace transitions followed by an assertion / all transitions. */
62
67
  handoffs: { total: number; asserted: number; ratio: number };
68
+ /** ISTQB SIT classification (#580 P10): scenarios whose steps touch an external-system
69
+ * namespace declared in the contract's `external:` block. */
70
+ sit: Array<{ name: string; external: string; mockOnly: boolean }>;
63
71
  }
64
72
 
65
73
  const DEFAULT_PHASES = ['HP', 'ER', 'EH'];
@@ -100,6 +108,16 @@ export function loadFlowContract(unitDir: string): { contract: FlowContract | nu
100
108
  phases,
101
109
  stateful: raw.stateful !== undefined ? String(raw.stateful).toLowerCase() : undefined,
102
110
  budgets: (raw.budgets && typeof raw.budgets === 'object') ? raw.budgets as Record<string, number> : undefined,
111
+ external: Array.isArray(raw.external)
112
+ ? (raw.external as Array<Record<string, unknown>>)
113
+ .filter((e) => e && typeof e === 'object' && e.name)
114
+ .map((e) => ({
115
+ name: String(e.name),
116
+ owner: e.owner !== undefined ? String(e.owner) : undefined,
117
+ screens: Array.isArray(e.screens) ? (e.screens as unknown[]).map((x) => String(x).toLowerCase()) : [],
118
+ }))
119
+ : undefined,
120
+ golden: raw.golden === true,
103
121
  },
104
122
  errors: [],
105
123
  };
@@ -139,7 +157,7 @@ export function flowQuality(unitDir: string, scenarios: ScenarioInfo[]): FlowQua
139
157
  const neutral: FlowQualityResult = {
140
158
  hasContract: false, errors, outcomeProven: false, outcomeManualOnly: false,
141
159
  offGoal: [], offGoalRatio: 0, offGoalCategories: [],
142
- phases: [], phaseRatio: 1, handoffs: { total: 0, asserted: 0, ratio: 1 },
160
+ phases: [], phaseRatio: 1, handoffs: { total: 0, asserted: 0, ratio: 1 }, sit: [],
143
161
  };
144
162
  if (!contract) return neutral;
145
163
 
@@ -202,12 +220,26 @@ export function flowQuality(unitDir: string, scenarios: ScenarioInfo[]): FlowQua
202
220
  }
203
221
  const handoffs = { total, asserted, ratio: total ? asserted / total : 1 };
204
222
 
223
+ // --- SIT classification (#580 P10): a scenario whose steps touch an external-system
224
+ // namespace belongs to the System INTEGRATION group the QA matrix keeps separate. When
225
+ // that scenario is also verified only against mocks, its pass says nothing about the
226
+ // real vendor behaviour — the exit criteria the QA doc holds open (Pass (Mocked)).
227
+ const MOCK_STEP = /\[[^\]]+\]\s+mock\s+(?:is\s+active|called)\b/i;
228
+ const sit: FlowQualityResult['sit'] = [];
229
+ for (const leg of contract.external ?? []) {
230
+ const legScreens = new Set(leg.screens);
231
+ for (const s of scenarios) {
232
+ if (!namespacesInOrder(s).some((ns) => legScreens.has(ns))) continue;
233
+ sit.push({ name: s.name.slice(0, 80), external: leg.name, mockOnly: MOCK_STEP.test(s.stepsText) });
234
+ }
235
+ }
236
+
205
237
  return {
206
238
  hasContract: true, contract, errors: [],
207
239
  outcomeProven, outcomeManualOnly,
208
240
  offGoal: offGoalScenarios.map((s) => s.name.slice(0, 80)),
209
241
  offGoalRatio, offGoalCategories,
210
- phases, phaseRatio, handoffs,
242
+ phases, phaseRatio, handoffs, sit,
211
243
  };
212
244
  }
213
245
 
@@ -132,6 +132,11 @@ outcome:
132
132
  value: "The customer has paid; the shop has a new order"
133
133
  phases: [HP, ER, EH] # journey phases (default); add UI only if the flow owns UI states
134
134
  stateful: cart # the mutated collection, if any — enables regression-depth dims
135
+ golden: true # optional — release-critical: Final Inspection expects @golden scenarios here
136
+ external: # optional — legs owned by another team/vendor (System INTEGRATION Testing)
137
+ - name: payment-gateway
138
+ owner: vendor-x
139
+ screens: [payment] # the flow namespaces that leg passes through
135
140
  ```
136
141
 
137
142
  **A filled contract is an INPUT to generation — never an output.** Like `test-viewpoint.md`,
@@ -7,6 +7,29 @@ claude-tools: "Read, Grep, Bash, Glob, Edit, Write, AskUserQuestion, mcp__playwr
7
7
  copilot-tools: "[read, execute, edit, vscode/askQuestions, playwright/*, appium/*]"
8
8
  codex-trigger: "Run when the user asks to RUN, execute, or compile tests, generate selectors.yaml, or run tests. Step 4. Do NOT use for authoring/creating new test cases."
9
9
  ---
10
+ ## ⛔ HARD RULE — the transition INTO this run is a tool call, never prose
11
+
12
+ A QA field report: the user picked "Run test" from create-test's hand-back, and the session
13
+ answered with a BRIEFING — missing selector, expected reds, "run under Node 22" — written as
14
+ "Before you do…", then stopped. Correct facts, wrong role: those are conditions YOU handle
15
+ inside the run, not reasons to stop and hand the work back.
16
+
17
+ - The first thing this command produces is a **tool call** (platform detection, preflight,
18
+ compile — whatever comes first). Never open with a plan and end the turn.
19
+ - A **missing selector** goes to the selector-generation/fix step — that is what this command
20
+ is FOR.
21
+ - **Expected-red scenarios** (@known-defect asserting a live defect) stay red; note them in
22
+ the results summary, never "fix" them and never stop for them.
23
+ - **Runtime selection is yours**: check `node -v` first. If the major version is ≥ 23 and
24
+ Playwright browser runs are known-broken on it, select Node 22 yourself when available —
25
+ `export PATH="$HOME/.nvm/versions/node/$(ls $HOME/.nvm/versions/node | grep '^v22' | tail -1)/bin:$PATH"`
26
+ — and say so in one line. Only if NO compatible Node exists do you stop, with the exact
27
+ install command as the hand-back.
28
+ - Ending this run follows the same law as create-test: the LAST action is the next-step
29
+ hand-back (the AskUserQuestion in "After showing results"), no matter how the run went.
30
+
31
+ ---
32
+
10
33
  ## Role
11
34
 
12
35
  You are a **Senior Developer**.
@@ -619,6 +619,14 @@ scenarios differ only in data. **Mocked dependencies**: a flow scenario using `@
619
619
  delivered as *Pass (Mocked)* — verified handling logic, not the real dependency; the delivery's
620
620
  External Dependency Tracking table lists it until re-verified real.
621
621
 
622
+ **Release selection & external legs**: when the contract declares `golden: true`, tag the
623
+ happy-path scenario(s) that prove the outcome with **`@golden`** — that is the set
624
+ `sungen inspect` (Final Inspection, Go/No-Go) runs before a release; `GOLDEN-MISSING` fires
625
+ until it exists, and a @golden scenario that passes only against mocks BLOCKS the release.
626
+ When the contract declares `external:` legs (another team/vendor's system), scenarios touching
627
+ those namespaces are the **System INTEGRATION** group — keep their oracles about the boundary
628
+ (contract/format/handoff), and expect `SIT-MOCK-ONLY` until they are re-verified real.
629
+
622
630
 
623
631
  > **Auto-detect**: if path is `qa/flows/<name>/` → use this section. Skip Steps 1–4 above.
624
632