qfai 2.1.1 → 2.2.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 +56 -36
- package/assets/defaults/agent-routing/qfai-implement.yml +9 -0
- package/assets/defaults/agent-routing/qfai-triage.yml +18 -0
- package/assets/defaults/workflows/answer-in-session.yml +8 -0
- package/assets/defaults/workflows/quarantine-flaky.yml +3 -0
- package/assets/defaults/workflows/repair-consistency.yml +1 -0
- package/assets/defaults/workflows/run-operation.yml +11 -0
- package/assets/defaults/workflows/run-owned-cleanup.yml +12 -0
- package/assets/defaults/workflows/write-procedure.yml +18 -0
- package/assets/graph/codegraph-native.mjs +174 -0
- package/assets/graph/graphify-native.py +72 -0
- package/assets/init/.claude/settings.json +9 -9
- package/assets/init/.codex/hooks.json +8 -8
- package/assets/init/.qfai/assistant/agent/frontend-engineer.md +5 -0
- package/assets/init/.qfai/assistant/agent/product-experience-architect.md +4 -0
- package/assets/init/.qfai/assistant/agent/product-surface-reviewer.md +7 -0
- package/assets/init/.qfai/assistant/agent/requirements-analyst.md +8 -0
- package/assets/init/.qfai/assistant/rule/communication.md +18 -8
- package/assets/init/.qfai/assistant/rule/constitution.md +31 -15
- package/assets/init/.qfai/assistant/rule/drift-protocol.md +119 -2
- package/assets/init/.qfai/assistant/rule/references/asset-authoring.md +6 -4
- package/assets/init/.qfai/assistant/rule/references/codex-delegation.md +27 -0
- package/assets/init/.qfai/assistant/rule/references/griller-recommendations.md +21 -9
- package/assets/init/.qfai/assistant/rule/references/worker-edit-boundary.md +48 -0
- package/assets/init/.qfai/assistant/rule/review-convergence.md +25 -12
- package/assets/init/.qfai/assistant/rule/shared-skill-delegation-baseline.md +16 -25
- package/assets/init/.qfai/assistant/rule/shared-skill-operating-baseline.md +16 -11
- package/assets/init/.qfai/assistant/rule/ui-definition-protocol.md +6 -1
- package/assets/init/.qfai/assistant/rule/workflow.md +2 -1
- package/assets/init/.qfai/assistant/skill/qfai-configure/SKILL.md +3 -3
- package/assets/init/.qfai/assistant/skill/qfai-discussion/SKILL.md +6 -0
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/discussion-completion-matrix.md +20 -15
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/ui-bearing-playbook.md +2 -4
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/ui_ux_best_practices.md +1 -6
- package/assets/init/.qfai/assistant/skill/qfai-discussion/templates/uiux/00_index.md +0 -16
- package/assets/init/.qfai/assistant/skill/qfai-grilling/SKILL.md +30 -20
- package/assets/init/.qfai/assistant/skill/qfai-grilling/references/delegated-session.md +4 -3
- package/assets/init/.qfai/assistant/skill/qfai-grilling/references/session-record.md +8 -2
- package/assets/init/.qfai/assistant/skill/qfai-implement/SKILL.md +16 -3
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/parallelization-policy.md +9 -1
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/red-admissibility.md +46 -0
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/ui-affecting.md +5 -2
- package/assets/init/.qfai/assistant/skill/qfai-maintain/SKILL.md +3 -3
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/SKILL.md +12 -6
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/references/migration-guide.md +1 -265
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/references/migration-placement.md +273 -0
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/SKILL.md +4 -3
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/review-payload-schema.md +2 -3
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/reviewer-prompt.md +17 -1
- package/assets/init/.qfai/assistant/skill/qfai-run/SKILL.md +52 -37
- package/assets/init/.qfai/assistant/skill/qfai-run/references/codex-cloud-install.md +80 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/evidence-delivery.md +322 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/extraction.md +83 -49
- package/assets/init/.qfai/assistant/skill/qfai-run/references/operator-screens.md +226 -11
- package/assets/init/.qfai/assistant/skill/qfai-run/references/plan.md +6 -3
- package/assets/init/.qfai/assistant/skill/qfai-run/references/reached-step-observations.md +132 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/stage-points.md +14 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/scripts/codex-cloud-install.mjs +117 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/SKILL.md +4 -3
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/contract-artifact-rules.md +1 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/design-anti-patterns.md +23 -5
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/design-md-authoring.md +20 -7
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/requirements-decomposition.md +8 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-execution-playbook.md +29 -4
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-phase-checklists.md +1 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-pre-draft-grilling.md +4 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-quality-gate.md +1 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-triage.md +159 -4
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/spec-traceability-rules.md +14 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/ui-contract-guide.md +146 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/ui-design-contract-normalization.md +4 -29
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/change-request.md +38 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/contracts/ui-contract.sample.yaml +52 -5
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/spec/decisions.md +12 -0
- package/assets/init/.qfai/assistant/skill/qfai-triage/SKILL.md +34 -21
- package/assets/init/.qfai/assistant/skill/qfai-verify/SKILL.md +5 -4
- package/assets/init/.qfai/assistant/skill/qfai-verify/references/context-load.md +9 -6
- package/assets/init/.qfai/assistant/skill/qfai-verify/references/verify-output-contract.md +80 -15
- package/assets/init/.qfai/assistant/skill/web-research/SKILL.md +35 -21
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/brave-search/config.toml +2 -4
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/brave-search/mcp-config.json +9 -5
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/.mcp.json +1 -2
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/config.toml +3 -3
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/mcp-config.json +11 -8
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/playwright/config.toml +1 -1
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/playwright/mcp-config.json +7 -3
- package/assets/init/.qfai/assistant/step/common-design-md/STEP.md +33 -20
- package/assets/init/.qfai/assistant/step/common-gate-run/STEP.md +124 -8
- package/assets/init/.qfai/assistant/step/common-grilling-record/STEP.md +10 -2
- package/assets/init/.qfai/assistant/step/common-policy-check/STEP.md +1 -0
- package/assets/init/.qfai/assistant/step/common-review-cycle/STEP.md +26 -9
- package/assets/init/.qfai/assistant/step/discussion-interview/STEP.md +15 -8
- package/assets/init/.qfai/assistant/step/discussion-oq/STEP.md +5 -1
- package/assets/init/.qfai/assistant/step/discussion-pack/STEP.md +6 -1
- package/assets/init/.qfai/assistant/step/discussion-research/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/discussion-uiux/STEP.md +6 -4
- package/assets/init/.qfai/assistant/step/implement-backport/STEP.md +1 -1
- package/assets/init/.qfai/assistant/step/implement-benchmark/STEP.md +7 -4
- package/assets/init/.qfai/assistant/step/implement-dep-bump/STEP.md +11 -2
- package/assets/init/.qfai/assistant/step/implement-diagnose/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/implement-oracle-parity/STEP.md +2 -2
- package/assets/init/.qfai/assistant/step/implement-procedure/STEP.md +69 -0
- package/assets/init/.qfai/assistant/step/implement-quarantine/STEP.md +24 -7
- package/assets/init/.qfai/assistant/step/implement-refactor/STEP.md +2 -2
- package/assets/init/.qfai/assistant/step/implement-regression-fix/STEP.md +7 -6
- package/assets/init/.qfai/assistant/step/implement-retire/STEP.md +6 -3
- package/assets/init/.qfai/assistant/step/implement-revert/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/implement-seam/STEP.md +6 -5
- package/assets/init/.qfai/assistant/step/implement-stress-harness/STEP.md +34 -3
- package/assets/init/.qfai/assistant/step/implement-sweep/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/implement-tdd/STEP.md +39 -5
- package/assets/init/.qfai/assistant/step/implement-tooling/STEP.md +22 -2
- package/assets/init/.qfai/assistant/step/maintain-edit/STEP.md +18 -14
- package/assets/init/.qfai/assistant/step/prototyping-grill/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/prototyping-loop/STEP.md +4 -0
- package/assets/init/.qfai/assistant/step/prototyping-preflight/STEP.md +9 -3
- package/assets/init/.qfai/assistant/step/sdd-contract/STEP.md +11 -0
- package/assets/init/.qfai/assistant/step/sdd-flow/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/sdd-story/STEP.md +10 -0
- package/assets/init/.qfai/assistant/step/sdd-triage/STEP.md +34 -10
- package/assets/init/.qfai/assistant/step/triage-answer/STEP.md +7 -6
- package/assets/init/.qfai/assistant/step/triage-close/STEP.md +33 -23
- package/assets/init/.qfai/assistant/step/triage-cluster/STEP.md +5 -3
- package/assets/init/.qfai/assistant/step/triage-decompose/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/triage-dedupe/STEP.md +4 -0
- package/assets/init/.qfai/assistant/step/triage-handoff/STEP.md +13 -4
- package/assets/init/.qfai/assistant/step/triage-investigate/STEP.md +8 -5
- package/assets/init/.qfai/assistant/step/triage-operate/STEP.md +50 -0
- package/assets/init/.qfai/assistant/step/triage-owned-cleanup/STEP.md +86 -0
- package/assets/init/.qfai/assistant/step/triage-request-info/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/triage-security-intake/STEP.md +6 -3
- package/assets/init/.qfai/assistant/step/verify-change-note/STEP.md +1 -0
- package/assets/init/.qfai/assistant/step/verify-commit/STEP.md +37 -9
- package/assets/init/.qfai/assistant/step/verify-external/STEP.md +5 -2
- package/assets/init/.qfai/assistant/step/verify-qfai-gate/STEP.md +14 -16
- package/assets/init/.qfai/assistant/step/verify-release-notes/STEP.md +1 -0
- package/assets/init/.qfai/assistant/step/verify-repeat-run/STEP.md +46 -4
- package/assets/init/.qfai/assistant/step/verify-repo-gate/STEP.md +133 -30
- package/assets/init/root/.agents/rules/ai-readable-markdown.md +2 -2
- package/assets/init/root/.agents/rules/api-budget.md +187 -8
- package/assets/init/root/.agents/rules/document-schema.md +17 -0
- package/assets/init/root/.agents/rules/documentation-clarity.md +163 -34
- package/assets/init/root/.agents/rules/graph-exploration.md +150 -0
- package/assets/init/root/.agents/rules/grilling.md +100 -43
- package/assets/init/root/.agents/rules/minimal-implementation.md +3 -3
- package/assets/init/root/.agents/rules/reminders.json +27 -18
- package/assets/init/root/.agents/rules/session-feedback.md +131 -0
- package/assets/init/root/.agents/rules/temporary-files.md +33 -0
- package/assets/init/root/.agents/rules/untrusted-content.md +2 -2
- package/assets/init/root/.agents/rules/user-questions.md +51 -40
- package/assets/init/root/.github/workflows/qfai-docs.yml +3 -3
- package/assets/init/root/.github/workflows/qfai-tests.yml +88 -35
- package/assets/init/root/.github/workflows/qfai-validate.yml +2 -2
- package/assets/init/root/AGENTS.md +24 -22
- package/assets/sandbox-templates/default-deny.yaml +9 -3
- package/assets/schemas/workflow/extraction.schema.json +89 -5
- package/assets/scripts/check-mdschema.mjs +77 -8
- package/assets/uix-rev/comparison-review.md +1 -1
- package/assets/uix-rev/contracts-review.md +1 -2
- package/dist/cli/index.cjs +9444 -10071
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +9421 -10041
- package/dist/cli/index.mjs.map +1 -1
- package/dist/graph/cli.cjs +1568 -0
- package/dist/graph/cli.cjs.map +1 -0
- package/dist/graph/cli.d.cts +9 -0
- package/dist/graph/cli.d.ts +9 -0
- package/dist/graph/cli.mjs +1541 -0
- package/dist/graph/cli.mjs.map +1 -0
- package/dist/graph/hook.cjs +817 -0
- package/dist/graph/hook.cjs.map +1 -0
- package/dist/graph/hook.d.cts +9 -0
- package/dist/graph/hook.d.ts +9 -0
- package/dist/graph/hook.mjs +792 -0
- package/dist/graph/hook.mjs.map +1 -0
- package/dist/index.cjs +7634 -8517
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +146 -658
- package/dist/index.d.ts +146 -658
- package/dist/index.mjs +7462 -8318
- package/dist/index.mjs.map +1 -1
- package/dist/process-C21nTvkT.d.cts +12 -0
- package/dist/process-C21nTvkT.d.ts +12 -0
- package/package.json +4 -6
- package/assets/init/root/CLAUDE.md +0 -46
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { G as GraphProcess } from './process-C21nTvkT.cjs';
|
|
2
|
+
|
|
1
3
|
type IssueSeverity = "info" | "warning" | "error";
|
|
2
4
|
type IssueCategory = "canonical" | "change";
|
|
3
5
|
type IssueLocation = {
|
|
@@ -93,6 +95,16 @@ type ValidationTimings = {
|
|
|
93
95
|
uiuxBudgetMs: number;
|
|
94
96
|
htmlMockMs: number;
|
|
95
97
|
htmlMockBudgetMs: number;
|
|
98
|
+
/**
|
|
99
|
+
* What each validator of the UI/UX group took, slowest first. The validators run side by side
|
|
100
|
+
* on one event loop, so each time includes waiting for the others: the parts overlap, do not
|
|
101
|
+
* add up to `uiuxMs`, and can credit a fast validator with another's time. They say where to
|
|
102
|
+
* look, not how the time divides.
|
|
103
|
+
*/
|
|
104
|
+
uiuxParts: readonly {
|
|
105
|
+
name: string;
|
|
106
|
+
ms: number;
|
|
107
|
+
}[];
|
|
96
108
|
};
|
|
97
109
|
type ValidationResult = {
|
|
98
110
|
toolVersion: string;
|
|
@@ -129,42 +141,14 @@ type ValidationResult = {
|
|
|
129
141
|
timings?: ValidationTimings;
|
|
130
142
|
};
|
|
131
143
|
|
|
132
|
-
type RenderEvidenceConfig = {
|
|
133
|
-
enabled?: boolean;
|
|
134
|
-
viewports?: string[];
|
|
135
|
-
out?: string;
|
|
136
|
-
baseUrl?: string;
|
|
137
|
-
failOpen?: boolean;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
144
|
type FailOn = "never" | "warning" | "error";
|
|
141
145
|
type OutputFormat = "text" | "github";
|
|
142
|
-
type TraceabilitySeverity = "warning" | "error";
|
|
143
|
-
/**
|
|
144
|
-
* The value set of the retired orphanContractsPolicy. Compatibility fields
|
|
145
|
-
* annotate their type with this one: referencing the public alias would trigger
|
|
146
|
-
* `@typescript-eslint/no-deprecated` and force a lint-suppression comment. Delete
|
|
147
|
-
* this internal type when the compatibility acceptance ends.
|
|
148
|
-
*/
|
|
149
|
-
type RetiredOrphanContractsPolicy = "error" | "warning" | "allow";
|
|
150
|
-
/**
|
|
151
|
-
* @deprecated validation.traceability.orphanContractsPolicy is retired.
|
|
152
|
-
* No check reads it, so setting it changes nothing. It stays for the
|
|
153
|
-
* compatibility period only, so existing TypeScript consumers that import it
|
|
154
|
-
* keep type-checking.
|
|
155
|
-
*/
|
|
156
|
-
type OrphanContractsPolicy = RetiredOrphanContractsPolicy;
|
|
157
146
|
type QfaiPaths = {
|
|
158
147
|
contractsDir: string;
|
|
159
148
|
specsDir: string;
|
|
160
149
|
discussionDir: string;
|
|
161
150
|
outDir: string;
|
|
162
151
|
skillsDir: string;
|
|
163
|
-
/**
|
|
164
|
-
* @deprecated Use paths.skillsDir.
|
|
165
|
-
* It is still read for compatibility and is not used on the main validation path.
|
|
166
|
-
*/
|
|
167
|
-
promptsDir: string;
|
|
168
152
|
srcDir: string;
|
|
169
153
|
testsDir: string;
|
|
170
154
|
/**
|
|
@@ -178,6 +162,10 @@ type QfaiPaths = {
|
|
|
178
162
|
*/
|
|
179
163
|
migrationsDir?: string;
|
|
180
164
|
};
|
|
165
|
+
type QfaiForbiddenIdentifier = {
|
|
166
|
+
sha256: string;
|
|
167
|
+
byteLength: number;
|
|
168
|
+
};
|
|
181
169
|
type QfaiValidationConfig = {
|
|
182
170
|
failOn: FailOn;
|
|
183
171
|
/**
|
|
@@ -186,6 +174,8 @@ type QfaiValidationConfig = {
|
|
|
186
174
|
* (QFAI-STORY-016). Unset means no term is checked.
|
|
187
175
|
*/
|
|
188
176
|
staleTerms?: string[];
|
|
177
|
+
/** Hash-only identifiers checked against tracked names and current file bytes. */
|
|
178
|
+
forbiddenIdentifiers?: QfaiForbiddenIdentifier[];
|
|
189
179
|
testStrategy: {
|
|
190
180
|
/**
|
|
191
181
|
* When true (default), `qfai validate` reports the silent-placeholder
|
|
@@ -195,42 +185,10 @@ type QfaiValidationConfig = {
|
|
|
195
185
|
* Set to false to opt out while migrating an existing project.
|
|
196
186
|
*/
|
|
197
187
|
forbidTestTodoStubs: boolean;
|
|
198
|
-
/**
|
|
199
|
-
* @deprecated A dead knob: no validation reads it, so setting it to true
|
|
200
|
-
* raises no diagnostic. It is already removed from the shipped
|
|
201
|
-
* `qfai.config.yaml` and will be removed from the type in the next major
|
|
202
|
-
* release. As with paths.promptsDir, the default and the parsing stay as
|
|
203
|
-
* they were until then (this is a public type, so existing TypeScript
|
|
204
|
-
* consumers can keep referring to it as a `boolean`).
|
|
205
|
-
*/
|
|
206
|
-
requireLayerTags: boolean;
|
|
207
|
-
/**
|
|
208
|
-
* @deprecated Treated the same as `testStrategy.requireLayerTags`.
|
|
209
|
-
*/
|
|
210
|
-
requireSizeTags: boolean;
|
|
211
188
|
};
|
|
212
189
|
traceability: {
|
|
213
190
|
testFileGlobs: string[];
|
|
214
191
|
testFileExcludeGlobs: string[];
|
|
215
|
-
/**
|
|
216
|
-
* @deprecated Retired. No check reads it, so setting it changes nothing,
|
|
217
|
-
* and loading it reports QFAI-CFG-001 as an error. It stays as an optional
|
|
218
|
-
* field for the compatibility period only, so existing config object
|
|
219
|
-
* literals keep type-checking.
|
|
220
|
-
*/
|
|
221
|
-
brMustHaveSc?: boolean;
|
|
222
|
-
/**
|
|
223
|
-
* @deprecated Retired. The finding for a missing SC test reference has a
|
|
224
|
-
* fixed severity, so this value is not read. It stays as an optional field
|
|
225
|
-
* for the compatibility period only.
|
|
226
|
-
*/
|
|
227
|
-
scNoTestSeverity?: TraceabilitySeverity;
|
|
228
|
-
/**
|
|
229
|
-
* @deprecated Retired. The orphan-contract finding no longer exists, so
|
|
230
|
-
* this value is not read. It stays as an optional field for the
|
|
231
|
-
* compatibility period only.
|
|
232
|
-
*/
|
|
233
|
-
orphanContractsPolicy?: RetiredOrphanContractsPolicy;
|
|
234
192
|
};
|
|
235
193
|
};
|
|
236
194
|
type QfaiOutputConfig = {
|
|
@@ -272,19 +230,15 @@ type QfaiUiuxConfig = {
|
|
|
272
230
|
* key declares nothing.
|
|
273
231
|
*/
|
|
274
232
|
surfacePaths?: string[];
|
|
275
|
-
renderEvidence?: RenderEvidenceConfig;
|
|
276
233
|
audit?: QfaiUiuxAuditConfig;
|
|
277
234
|
};
|
|
278
235
|
type QfaiPrototypingExecutionConfig = {
|
|
279
236
|
targetUrl?: string | null;
|
|
280
237
|
/**
|
|
281
|
-
* Browser tool handed to the AI evaluator sub-agent.
|
|
282
|
-
*
|
|
283
|
-
* Only `"playwright"` is accepted. `"playwright-cli"` is retired:
|
|
284
|
-
* `normalizePrototypingExecution` rejects the value, and the doctor probe
|
|
285
|
-
* reports `D-DEPRECATED-PROBE` at `error`.
|
|
238
|
+
* Browser tool handed to the AI evaluator sub-agent. Only `"playwright"` is
|
|
239
|
+
* accepted.
|
|
286
240
|
*/
|
|
287
|
-
browserTool: "playwright"
|
|
241
|
+
browserTool: "playwright";
|
|
288
242
|
};
|
|
289
243
|
type QfaiPrototypingConfig = {
|
|
290
244
|
execution?: QfaiPrototypingExecutionConfig;
|
|
@@ -404,449 +358,20 @@ declare function resolvePath(root: string, config: QfaiConfig, key: ConfigPathKe
|
|
|
404
358
|
declare function readRejectedPrimaryUiContract(loaded: ConfigLoadResult): string | undefined;
|
|
405
359
|
|
|
406
360
|
type AtddTestKind = "e2e" | "api" | "integration";
|
|
407
|
-
type AtddUnknownRefKind = "us" | "tc" | "conApi" | "conDb";
|
|
408
|
-
type AtddUnknownRef = {
|
|
409
|
-
file: string;
|
|
410
|
-
token: string;
|
|
411
|
-
kind: AtddUnknownRefKind;
|
|
412
|
-
};
|
|
413
|
-
type AtddForbiddenRef = {
|
|
414
|
-
file: string;
|
|
415
|
-
ids: string[];
|
|
416
|
-
};
|
|
417
|
-
type AtddSpecRefs = Map<string, Map<string, Set<string>>>;
|
|
418
|
-
type AtddTraceabilityScan = {
|
|
419
|
-
globs: string[];
|
|
420
|
-
/**
|
|
421
|
-
* Files collected, which is also the number an acceptance layer owns.
|
|
422
|
-
*
|
|
423
|
-
* The collector drops a file in no acceptance layer before it is counted,
|
|
424
|
-
* so this is the count the coverage rules are computed from rather than a
|
|
425
|
-
* match total a reader has to discount.
|
|
426
|
-
*/
|
|
427
|
-
matchedFileCount: number;
|
|
428
|
-
truncated: boolean;
|
|
429
|
-
limit: number;
|
|
430
|
-
/**
|
|
431
|
-
* The selecting patterns whose files could not all be read, each with the
|
|
432
|
-
* reason. The others were still scanned, so a reference missing from the
|
|
433
|
-
* tests only these select is not evidence those tests hold none.
|
|
434
|
-
*/
|
|
435
|
-
unreadable: string[];
|
|
436
|
-
/**
|
|
437
|
-
* Directories the scan could not read and read past, in POSIX form: relative
|
|
438
|
-
* to the repository, or absolute where a scanned root lies outside it. The
|
|
439
|
-
* rest of each pattern reaching one was still read, but no test inside the
|
|
440
|
-
* directory is counted.
|
|
441
|
-
*/
|
|
442
|
-
unreadableDirectories: string[];
|
|
443
|
-
};
|
|
444
|
-
/**
|
|
445
|
-
* Obligation refs bucketed by ID kind.
|
|
446
|
-
*
|
|
447
|
-
* Shared by the two partitions the coverage result reports: `missing` (owed and
|
|
448
|
-
* referenced nowhere) and `coveredByCarrierOnly` (owed, referenced, but from no
|
|
449
|
-
* carrier that declares a runnable test).
|
|
450
|
-
*/
|
|
451
|
-
type AtddObligationRefs = {
|
|
452
|
-
us: string[];
|
|
453
|
-
tc: string[];
|
|
454
|
-
conApi: string[];
|
|
455
|
-
conDb: string[];
|
|
456
|
-
};
|
|
457
|
-
type AtddTraceabilityMissing = AtddObligationRefs;
|
|
458
|
-
type AtddCodeTraceabilityResult = {
|
|
459
|
-
specsRoot: string;
|
|
460
|
-
/**
|
|
461
|
-
* The configured tests directory, resolved.
|
|
462
|
-
*
|
|
463
|
-
* The bound on the per-spec owner scan. Test paths are absolute, so a
|
|
464
|
-
* checkout that itself lives under `/srv/integration/spec-0002/repo` has an
|
|
465
|
-
* ancestor pair that reads exactly like the canonical layout, and a flat
|
|
466
|
-
* `tests/integration/a.test.ts` inside it was attributed to `0002`.
|
|
467
|
-
*/
|
|
468
|
-
testsRoot: string;
|
|
469
|
-
contractsApiRoot: string;
|
|
470
|
-
/**
|
|
471
|
-
* Spec number -> the directory `collectSpecEntries` enumerated for it.
|
|
472
|
-
*
|
|
473
|
-
* Two questions, one map. **Existence** is not the same as `specUsIds.has(n)`:
|
|
474
|
-
* a spec created moments ago has a directory and empty catalogues, and scope
|
|
475
|
-
* logic that asks the id maps treats it as nonexistent — so a typo naming it
|
|
476
|
-
* is handled as repo-wide when that spec's own gate would in fact own it.
|
|
477
|
-
* **Its path** is the enumerated one, never `spec-${n}` rebuilt from the
|
|
478
|
-
* number: on a case-sensitive filesystem a `SPEC-0001/` directory is valid and
|
|
479
|
-
* kept verbatim by `listSpecDirs`, and a synthesised lower-case path would
|
|
480
|
-
* send the CLI report and the GitHub annotation at a file that is not there.
|
|
481
|
-
*/
|
|
482
|
-
declaredSpecDirs: Map<string, string>;
|
|
483
|
-
/**
|
|
484
|
-
* Scanned test file, normalised as the findings name it -> the spec whose
|
|
485
|
-
* `<layer>/spec-NNNN/` directory holds it, at `paths.testsDir` or at a
|
|
486
|
-
* package's own test root. A file in no such directory has no entry.
|
|
487
|
-
*/
|
|
488
|
-
testFileSpecOwners: Map<string, string>;
|
|
489
|
-
/**
|
|
490
|
-
* Every declared `US-*`, active and deferred alike — the same
|
|
491
|
-
* declared-not-owed distinction the contract sets draw. A deferred story is
|
|
492
|
-
* still a known id, so an E2E test written ahead of its slice must not become
|
|
493
|
-
* a `QFAI-ATDD-101` unknown reference.
|
|
494
|
-
*/
|
|
495
|
-
specUsIds: Map<string, Set<string>>;
|
|
496
|
-
/**
|
|
497
|
-
* `US-*` refs excluded from the `QFAI-ATDD-111` obligation because their
|
|
498
|
-
* story declares `- x-qfai-status: planned`, formatted as `SPEC-NNNN:US-…`.
|
|
499
|
-
* Reported at `info` (`QFAI-ATDD-118`) so the deferral stays visible rather
|
|
500
|
-
* than silently shrinking the gate — the same treatment `QFAI-ATDD-114` and
|
|
501
|
-
* `-116` give the two contract kinds.
|
|
502
|
-
*
|
|
503
|
-
* Restricted to specs that owe `QFAI-ATDD-111` at all: under surface typing a
|
|
504
|
-
* non-UI-bearing spec's stories are already outside the E2E gate, so nothing
|
|
505
|
-
* there is deferred by the marker.
|
|
506
|
-
*/
|
|
507
|
-
deferredUsIds: string[];
|
|
508
|
-
specTcIds: Map<string, Set<string>>;
|
|
509
|
-
/**
|
|
510
|
-
* Every declared `API-NNNN`, active and deferred alike. This is the public
|
|
511
|
-
* meaning the field has always had — adding `x-qfai-status: planned` defers
|
|
512
|
-
* the test obligation, it does not un-declare the contract, so an external
|
|
513
|
-
* consumer using this set for "is this ID declared?" must keep seeing it.
|
|
514
|
-
*/
|
|
515
|
-
apiContractIds: Set<string>;
|
|
516
|
-
/** The subset that carries the `QFAI-ATDD-113` obligation. */
|
|
517
|
-
activeApiContractIds: Set<string>;
|
|
518
|
-
/**
|
|
519
|
-
* `API-NNNN` IDs excluded from the `QFAI-ATDD-113` obligation because their
|
|
520
|
-
* contract declares `x-qfai-status: planned`. Reported as `info` so the
|
|
521
|
-
* deferral stays visible instead of silently shrinking the gate.
|
|
522
|
-
*/
|
|
523
|
-
deferredApiContractIds: Set<string>;
|
|
524
|
-
contractsDbRoot: string;
|
|
525
|
-
/** Every declared `DB-NNNN`, active and deferred alike. */
|
|
526
|
-
dbContractIds: Set<string>;
|
|
527
|
-
/** The subset that carries the `QFAI-ATDD-115` obligation. */
|
|
528
|
-
activeDbContractIds: Set<string>;
|
|
529
|
-
/** `DB-NNNN` IDs deferred by `-- x-qfai-status: planned`; reported at `info`. */
|
|
530
|
-
deferredDbContractIds: Set<string>;
|
|
531
|
-
refs: {
|
|
532
|
-
us: AtddSpecRefs;
|
|
533
|
-
tc: AtddSpecRefs;
|
|
534
|
-
api: Map<string, Set<string>>;
|
|
535
|
-
/**
|
|
536
|
-
* `DB-NNNN` references found in integration tests. L3 Integration is the
|
|
537
|
-
* layer whose declared scope is real-infrastructure integration including
|
|
538
|
-
* the database, so it is the one that can actually exercise a DB contract.
|
|
539
|
-
*/
|
|
540
|
-
db: Map<string, Set<string>>;
|
|
541
|
-
};
|
|
542
|
-
unknown: AtddUnknownRef[];
|
|
543
|
-
forbidden: {
|
|
544
|
-
tcInApi: AtddForbiddenRef[];
|
|
545
|
-
tcInE2e: AtddForbiddenRef[];
|
|
546
|
-
/** TC annotated under integration although its declared Level routes elsewhere. */
|
|
547
|
-
tcInIntegration: AtddForbiddenRef[];
|
|
548
|
-
};
|
|
549
|
-
missing: AtddTraceabilityMissing;
|
|
550
|
-
/**
|
|
551
|
-
* Owed obligations whose every carrier declares no test a runner collects.
|
|
552
|
-
*
|
|
553
|
-
* Satisfaction is a text match, and the scan deliberately reads past test
|
|
554
|
-
* code so a Gherkin feature or a markdown ledger can carry annotations. The
|
|
555
|
-
* consequence is that a bullet list of IDs discharges `QFAI-ATDD-111` /
|
|
556
|
-
* `-112` / `-113` / `-115` exactly as an executable acceptance test does, and
|
|
557
|
-
* `missing: []` cannot tell the two apart. Reported at `info`
|
|
558
|
-
* (`QFAI-ATDD-119`) and persisted into the summary artifact for the same
|
|
559
|
-
* reason `unitComponentTcIds` is: a coverage scan must never leave "covered
|
|
560
|
-
* by a test" and "covered by an ID written down" indistinguishable.
|
|
561
|
-
*
|
|
562
|
-
* Membership is decided per carrier by {@link hasRunnableTestStructure}, not
|
|
563
|
-
* by extension: markdown never qualifies, a `.feature` with a `Scenario:`
|
|
564
|
-
* does, and a `.test.ts` holding only an annotation comment does not — so
|
|
565
|
-
* renaming the ledger cannot clear the obligation. Skip state is out of
|
|
566
|
-
* scope, so this asserts a test is *declared*, never that it is enabled.
|
|
567
|
-
*
|
|
568
|
-
* Empty whenever `scan.truncated` is set or `scan.unreadable` or
|
|
569
|
-
* `scan.unreadableDirectories` is not empty: an executable carrier may sit
|
|
570
|
-
* past the file limit or in what was not read, so the claim is unproven and
|
|
571
|
-
* suppressed rather than guessed.
|
|
572
|
-
*/
|
|
573
|
-
coveredByCarrierOnly: AtddObligationRefs;
|
|
574
|
-
/**
|
|
575
|
-
* Formatted missing TC ref -> the test kind its declared `Level` routes to.
|
|
576
|
-
* Lets the CLI phrase `QFAI-ATDD-112` (message, `suggested_action`, report)
|
|
577
|
-
* per declared layer instead of naming `tests/integration/**` for every TC.
|
|
578
|
-
*/
|
|
579
|
-
missingTcHomes: Map<string, AtddTestKind>;
|
|
580
|
-
/**
|
|
581
|
-
* `TC-*` refs excluded from the `QFAI-ATDD-112` obligation because their
|
|
582
|
-
* declared `Level` is Unit or Component. Reported at `info`
|
|
583
|
-
* (`QFAI-ATDD-117`) so the exclusion is visible rather than silent — the
|
|
584
|
-
* shape a coverage scan must never take, since "nothing owed" and "nothing
|
|
585
|
-
* scanned" are otherwise indistinguishable. No validate rule demands a test
|
|
586
|
-
* for them.
|
|
587
|
-
*/
|
|
588
|
-
unitComponentTcIds: string[];
|
|
589
|
-
/**
|
|
590
|
-
* `TC-*` refs declaring a `Level` of L4/API or L5/E2E.
|
|
591
|
-
*
|
|
592
|
-
* `catalog/test-layers.md` states that a `TC-*` row's `Level` stays within
|
|
593
|
-
* L1-L3: L4's goal is a `API-NNNN` and L5's is a `US-*`, so an oracle that
|
|
594
|
-
* derives to either means the obligation is filed under the wrong ID type —
|
|
595
|
-
* not that the test case is an L4/L5 test.
|
|
596
|
-
*
|
|
597
|
-
* The routing table sends such a row to `tests/api/**` or `tests/e2e/**`
|
|
598
|
-
* rather than rejecting it, so that the row is reported once by the rule
|
|
599
|
-
* naming the real cause (`QFAI-ATDD-128`) instead of twice as "uncovered in
|
|
600
|
-
* integration" and "forbidden in api".
|
|
601
|
-
*
|
|
602
|
-
* Every declared row, not only the ones missing an annotation: the defect is
|
|
603
|
-
* the row's own `Level`, and covering it changes nothing about that.
|
|
604
|
-
*/
|
|
605
|
-
misfiledLevelTcIds: string[];
|
|
606
|
-
/**
|
|
607
|
-
* Carrier files whose suite is bound through a variable, so nothing static —
|
|
608
|
-
* including this scan — can say whether their tests run.
|
|
609
|
-
*
|
|
610
|
-
* Reported rather than counted, for the same reason `unitComponentTcIds` is:
|
|
611
|
-
* the coverage gate's evidence here is a string in a file, and "nothing owed"
|
|
612
|
-
* must not look like "nothing checked".
|
|
613
|
-
*/
|
|
614
|
-
computedSuiteCarriers: string[];
|
|
615
|
-
/**
|
|
616
|
-
* `TC-*` refs a status marker in their own block suspends, each with the
|
|
617
|
-
* status and — for `external` — where the obligation is really verified.
|
|
618
|
-
*
|
|
619
|
-
* Reported at `info` for the same reason `QFAI-ATDD-118` reports a deferred
|
|
620
|
-
* story: an exit nobody can see is one nobody reviews.
|
|
621
|
-
*/
|
|
622
|
-
deferredTcIds: DeferredTc[];
|
|
623
|
-
/**
|
|
624
|
-
* `TC-*` refs that claim `external` and name no verifier.
|
|
625
|
-
*
|
|
626
|
-
* They keep their obligation. The marker is not a way to say "not here": it
|
|
627
|
-
* is a way to say where the obligation is met instead, and without that it
|
|
628
|
-
* says nothing a reader can act on.
|
|
629
|
-
*/
|
|
630
|
-
unsupportedTcStatusIds: string[];
|
|
631
|
-
/** Test files outside the scanned roots; surfaced instead of dropped. */
|
|
632
|
-
skippedTestFiles: string[];
|
|
633
|
-
scan: AtddTraceabilityScan;
|
|
634
|
-
};
|
|
635
361
|
/** Test directory each `AtddTestKind` owns, for user-facing messages. */
|
|
636
362
|
declare const ATDD_TEST_KIND_DIRS: Record<AtddTestKind, string>;
|
|
637
363
|
/**
|
|
638
364
|
* The same map rendered against the project's configured `paths.testsDir`.
|
|
639
365
|
*
|
|
640
366
|
* The scan already follows `testsDir`, so a project that renamed it to e.g.
|
|
641
|
-
* `
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
* other direction: the scan reads `api/**` at the repository root, so the
|
|
367
|
+
* `acceptance` would otherwise be told to annotate `tests/api/**` — a directory
|
|
368
|
+
* the scan never reads. A root-level layout (`testsDir: "."`) is the same trap in
|
|
369
|
+
* the other direction: the scan reads `api/**` at the repository root, so the
|
|
645
370
|
* `tests/` segment must be dropped rather than kept.
|
|
646
371
|
* {@link ATDD_TEST_KIND_DIRS} stays as the default-shaped fallback for callers
|
|
647
372
|
* with no config in hand.
|
|
648
373
|
*/
|
|
649
374
|
declare function atddTestKindDirs(testsDirRelative: string): Record<AtddTestKind, string>;
|
|
650
|
-
declare function evaluateAtddCodeTraceability(root: string, config: QfaiConfig): Promise<AtddCodeTraceabilityResult>;
|
|
651
|
-
/**
|
|
652
|
-
* Reads the declared `Level` of every TC in `06_Test-Cases.md` so the TC
|
|
653
|
-
* obligation can be routed by declared layer instead of being hard-pinned to
|
|
654
|
-
* `tests/integration/**`.
|
|
655
|
-
*
|
|
656
|
-
* Both shipped shapes are read, matching `parseTestCases` in
|
|
657
|
-
* `core/atdd/scaffold.ts`: the heading form (`## TC-NNNN` plus `- Level: L4`
|
|
658
|
-
* meta lines) and the table form. Heading form wins on duplicates; within
|
|
659
|
-
* either form the first declaration wins. Every `TC-ID` table is scanned, not
|
|
660
|
-
* just the first — a spec may split its catalogue across several tables, and
|
|
661
|
-
* only scanning the first silently dropped the later tables' layers.
|
|
662
|
-
*/
|
|
663
|
-
declare function collectTcLevels(rawTcText: string): Map<string, string>;
|
|
664
|
-
declare function collectDeclaredTcIds(rawTcText: string): Set<string>;
|
|
665
|
-
/**
|
|
666
|
-
* Every heading-form TC id, whether or not the block declares a `Level`.
|
|
667
|
-
*
|
|
668
|
-
* The level collector yields a pair only when a `- Level:` line follows the
|
|
669
|
-
* heading, so it cannot answer "does this spec declare this TC?" — a
|
|
670
|
-
* level-less TC is still declared. {@link collectDeclaredTcIds} reads this
|
|
671
|
-
* for that reason.
|
|
672
|
-
*/
|
|
673
|
-
declare function collectHeadingTcIdsFrom(rawTcText: string): string[];
|
|
674
|
-
/**
|
|
675
|
-
* Where a declared `Level` routes its ATDD annotation obligation, or `null`
|
|
676
|
-
* when it owes none at all (Unit / Component).
|
|
677
|
-
*
|
|
678
|
-
* **The single answer to "what does this `Level` mean for ATDD".** One
|
|
679
|
-
* question answered in several places is several chances for the routing rule
|
|
680
|
-
* and the exclusion rule to disagree about the same cell.
|
|
681
|
-
*
|
|
682
|
-
* `undefined` means the spec declares no `Level` for the TC (no column, no
|
|
683
|
-
* row): that is not "no obligation", it is the default home.
|
|
684
|
-
*/
|
|
685
|
-
declare function resolveAtddHomeKind(level: string | undefined): AtddTestKind | null;
|
|
686
|
-
/**
|
|
687
|
-
* Splits the declared `US-*` ids into those that still owe an E2E reference and
|
|
688
|
-
* those a `- x-qfai-status: planned` marker defers.
|
|
689
|
-
*
|
|
690
|
-
* The deferred half is returned as formatted `SPEC-NNNN:US-…` refs — the shape
|
|
691
|
-
* `narrowToScope` filters and the CLI prints — so a `--spec` run reports its own
|
|
692
|
-
* deferrals only, exactly as it does for `QFAI-ATDD-117`.
|
|
693
|
-
*
|
|
694
|
-
* Only a spec inside `usObligationScope` can defer anything. A non-UI-bearing
|
|
695
|
-
* spec's stories are already outside `QFAI-ATDD-111` under surface typing, so
|
|
696
|
-
* reporting them at `QFAI-ATDD-118` would claim an obligation was suspended
|
|
697
|
-
* that never existed — and its remediation would tell the implementer to add an
|
|
698
|
-
* E2E annotation there, the annotation-only E2E that the surface-scope rule
|
|
699
|
-
* exists to prevent.
|
|
700
|
-
*/
|
|
701
|
-
/** A suspended test case, carried with what suspended it. */
|
|
702
|
-
type DeferredTc = {
|
|
703
|
-
/** `SPEC-NNNN:TC-NNNN`, the form every ref list here uses. */
|
|
704
|
-
ref: string;
|
|
705
|
-
status: TcVerificationStatus;
|
|
706
|
-
/** Where the obligation is verified. Present whenever `status` is `external`. */
|
|
707
|
-
verifiedBy?: string;
|
|
708
|
-
};
|
|
709
|
-
declare const PLANNED_CONTRACT_KEY = "x-qfai-status";
|
|
710
|
-
/**
|
|
711
|
-
* True when the contract declares itself not yet implemented.
|
|
712
|
-
*
|
|
713
|
-
* `/qfai-sdd` authors contracts in Phase 0 (Contracts-first) but slices them in
|
|
714
|
-
* Phase 2, so between the second contract and the last slice every declared
|
|
715
|
-
* `API-NNNN` would otherwise be a `QFAI-ATDD-113` error. The marker makes the
|
|
716
|
-
* deferral explicit and reviewable in the contract itself.
|
|
717
|
-
*
|
|
718
|
-
* The marker is only honoured at the **document root**. A text scan that
|
|
719
|
-
* accepted any indentation would let an `x-qfai-status: planned` on a single
|
|
720
|
-
* OpenAPI operation defer the whole file, silently dropping the API-test
|
|
721
|
-
* obligation for every other `API-NNNN` it declares. The document is therefore
|
|
722
|
-
* parsed (YAML is a superset of JSON, so both contract formats go through the
|
|
723
|
-
* same path) and only a top-level key counts. An unparseable document falls
|
|
724
|
-
* back to a column-0 text match, which cannot see a nested key either.
|
|
725
|
-
*/
|
|
726
|
-
declare function isPlannedApiContract(text: string): boolean;
|
|
727
|
-
/**
|
|
728
|
-
* What a test case says about where it is verified.
|
|
729
|
-
*
|
|
730
|
-
* `planned` is the `US-*` deferral, one layer down: the test is not written
|
|
731
|
-
* yet, the obligation is suspended, and the marker keeps it visible rather than
|
|
732
|
-
* silent.
|
|
733
|
-
*
|
|
734
|
-
* `external` is the state the story marker has no counterpart for. Some
|
|
735
|
-
* acceptance criteria are true of the deployment rather than of the code — a
|
|
736
|
-
* TLS floor, an HTTPS redirect terminated by the platform — and no layer the
|
|
737
|
-
* annotation gate routes to can observe them. Before this, every exit was
|
|
738
|
-
* closed: annotating anyway makes the gate green over a test that checks
|
|
739
|
-
* something else, a waiver may not cover an error, and retiring the row walks
|
|
740
|
-
* up the coverage rules until the requirement itself is deleted.
|
|
741
|
-
*/
|
|
742
|
-
type TcVerificationStatus = "planned" | "external";
|
|
743
|
-
/** A test case's declared status, with the pointer `external` requires. */
|
|
744
|
-
type TcStatusDeclaration = {
|
|
745
|
-
status: TcVerificationStatus;
|
|
746
|
-
/** Where the obligation is verified. Required for `external`. */
|
|
747
|
-
verifiedBy?: string;
|
|
748
|
-
};
|
|
749
|
-
/** The key an `external` test case names its real verifier with. */
|
|
750
|
-
declare const TC_VERIFIED_BY_KEY = "x-qfai-verified-by";
|
|
751
|
-
/**
|
|
752
|
-
* Status markers declared in `06_Test-Cases.md`, by test case id.
|
|
753
|
-
*
|
|
754
|
-
* **Read from a `##`-or-deeper `TC-NNNN` block only, never from the table.**
|
|
755
|
-
* That is the design, not a limitation. The field evidence behind this marker
|
|
756
|
-
* is that two test cases looked identical from the spec's side — same level,
|
|
757
|
-
* same note calling them deployment-bound — and only one of them actually was;
|
|
758
|
-
* a marker cheap enough to write in a table cell would have been applied to
|
|
759
|
-
* both, and the one that was observable in-process would have lost its only
|
|
760
|
-
* real test.
|
|
761
|
-
*
|
|
762
|
-
* So deferring a test case costs a block of its own. The author has to lift the
|
|
763
|
-
* row out of the table, write the status, and — for `external` — name where the
|
|
764
|
-
* obligation is really checked. That is the price of the exit, and it is meant
|
|
765
|
-
* to be paid deliberately.
|
|
766
|
-
*
|
|
767
|
-
* Fenced samples and HTML comments are masked first, on the same terms as
|
|
768
|
-
* {@link collectTcLevels}: a block in a format example must not defer a real
|
|
769
|
-
* test case.
|
|
770
|
-
*/
|
|
771
|
-
declare function collectTcStatuses(rawTcText: string): Map<string, TcStatusDeclaration>;
|
|
772
|
-
/**
|
|
773
|
-
* Whether a declaration actually suspends the annotation obligation.
|
|
774
|
-
*
|
|
775
|
-
* `external` without a pointer does not. The pointer is the whole cost of the
|
|
776
|
-
* marker: without it the line says only "not here", which is the blanket
|
|
777
|
-
* silencer this exit exists to avoid being. Such a test case keeps its
|
|
778
|
-
* obligation and is reported, so the marker cannot be written and forgotten.
|
|
779
|
-
*/
|
|
780
|
-
declare function suspendsObligation(declaration: TcStatusDeclaration): boolean;
|
|
781
|
-
/**
|
|
782
|
-
* The `US-*` ids a spec pack defers from the `QFAI-ATDD-111` obligation.
|
|
783
|
-
*
|
|
784
|
-
* A story whose acceptance cannot be observed at E2E in this slice had no
|
|
785
|
-
* in-band way to say so: `API-NNNN` and `DB-NNNN` both defer with
|
|
786
|
-
* `x-qfai-status: planned`, while a `US-*` could only be left uncovered (a hard
|
|
787
|
-
* `QFAI-ATDD-111` error), covered by a test asserting nothing, or erased by
|
|
788
|
-
* declaring the whole spec non-user-facing. This is the per-story counterpart.
|
|
789
|
-
*
|
|
790
|
-
* Fenced samples and HTML comments are masked first, on the same terms as
|
|
791
|
-
* {@link collectTcLevels}: an illustrative block showing the marker must not
|
|
792
|
-
* silently drop a real story's obligation.
|
|
793
|
-
*
|
|
794
|
-
* A block opens at either shape {@link collectDeclaredUsIds} declares an id from — a
|
|
795
|
-
* `##`-or-deeper heading ({@link US_HEADING_RE}) or a catalog list entry
|
|
796
|
-
* ({@link US_LIST_ITEM_RE}) — and closes at the next opener or any heading, so
|
|
797
|
-
* every declared story can carry the marker and none inherits a neighbour's.
|
|
798
|
-
*
|
|
799
|
-
* A catalog entry closes on its Markdown item boundary as well: its block ends
|
|
800
|
-
* at the first non-blank line that does not reach the entry's *content* column —
|
|
801
|
-
* the column its marker plus the whitespace after it ends at, which is where
|
|
802
|
-
* Markdown puts the item's own children. Without that, prose or a blank line
|
|
803
|
-
* after `- US-0001: …` left the entry open to the next heading, and a
|
|
804
|
-
* document-level `- x-qfai-status: planned` written well outside it deferred
|
|
805
|
-
* US-0001 — the very leak the document-root rule closes on the heading side.
|
|
806
|
-
*
|
|
807
|
-
* Comparing against the *marker* column instead would leave a narrower version
|
|
808
|
-
* of the same leak: under a column-0 `- US-0001: …` a one-space-indented
|
|
809
|
-
* ` - x-qfai-status: planned` clears the marker column while falling short of
|
|
810
|
-
* the two columns a child needs, so Markdown reads it as a separate list item
|
|
811
|
-
* and the entry must already be closed by then. The marker has to sit *inside*
|
|
812
|
-
* the entry, indented to its content.
|
|
813
|
-
*/
|
|
814
|
-
declare function collectPlannedUsIds(rawUsText: string): Set<string>;
|
|
815
|
-
/**
|
|
816
|
-
* The `US-*` ids a spec pack declares, read from the entries that declare them.
|
|
817
|
-
*
|
|
818
|
-
* An entry is a `##`-or-deeper heading ({@link US_HEADING_RE}) or a catalog
|
|
819
|
-
* list item ({@link US_LIST_ITEM_RE}) — the two shapes
|
|
820
|
-
* {@link collectPlannedUsIds} already opens a block at. A mention anywhere else
|
|
821
|
-
* is prose about a story, not a declaration of one.
|
|
822
|
-
*
|
|
823
|
-
* What this replaces took the union of those entries and every loose
|
|
824
|
-
* `US-NNNN` in the file, so any sentence naming an id declared it. A note
|
|
825
|
-
* reserving a deleted story's id — the id is retired, do not reuse it — made
|
|
826
|
-
* the story live again, and `QFAI-ATDD-111` then demanded an E2E reference
|
|
827
|
-
* for something with no entry, no acceptance criteria and no behaviour. The
|
|
828
|
-
* three ways out all cost something: an annotation with nothing behind it, the
|
|
829
|
-
* note hidden in an HTML comment where the people it warns cannot read it, or
|
|
830
|
-
* the id spelled so the scan misses it.
|
|
831
|
-
*
|
|
832
|
-
* This is the rule {@link collectDeclaredTcIds} already applies one document
|
|
833
|
-
* over, for the same reason: an id read from somewhere other than its
|
|
834
|
-
* declaration carries an obligation nobody wrote.
|
|
835
|
-
*
|
|
836
|
-
* Fenced samples and HTML comments are masked first, so an illustrative block
|
|
837
|
-
* showing the entry shape declares nothing.
|
|
838
|
-
*/
|
|
839
|
-
declare function collectDeclaredUsIds(rawUsText: string): Set<string>;
|
|
840
|
-
/**
|
|
841
|
-
* True when a DB contract declares itself not yet implemented.
|
|
842
|
-
*
|
|
843
|
-
* The counterpart of `isPlannedApiContract`, and deliberately a different rule:
|
|
844
|
-
* the API marker counts at the document root only, while this one counts on any
|
|
845
|
-
* line of the file. Exported so the shipped estimator procedure, which has to
|
|
846
|
-
* describe both forms, can be pinned against the behaviour rather than restate
|
|
847
|
-
* it and drift.
|
|
848
|
-
*/
|
|
849
|
-
declare function isPlannedDbContract(text: string): boolean;
|
|
850
375
|
/**
|
|
851
376
|
* The extensions a set of globs names, and whether any of them was too large to
|
|
852
377
|
* write out.
|
|
@@ -905,11 +430,6 @@ type TestLayerRoots = {
|
|
|
905
430
|
/** Shared directory crosswalk for acceptance checks and migration. */
|
|
906
431
|
declare function createTestLayerRoots(root: string, config: QfaiConfig): TestLayerRoots;
|
|
907
432
|
declare function resolveTestKind(filePath: string, roots: TestLayerRoots): AtddTestKind | null;
|
|
908
|
-
/**
|
|
909
|
-
* The owning spec of a test file, read as {@link layerSpecNumber} reads it, for
|
|
910
|
-
* callers outside the scan. `null` for a file in no acceptance layer.
|
|
911
|
-
*/
|
|
912
|
-
declare function atddTestOwnerProbe(root: string, config: QfaiConfig): (absolutePath: string) => string | null;
|
|
913
433
|
/**
|
|
914
434
|
* Whether a directory carries a package manifest, memoised per scan.
|
|
915
435
|
*
|
|
@@ -1017,22 +537,6 @@ declare function extractAcSpecNumber(acId: string): string | null;
|
|
|
1017
537
|
declare function extractCaseSpecNumber(caseId: string): string | null;
|
|
1018
538
|
declare function extractScSpecNumber(scId: string): string | null;
|
|
1019
539
|
|
|
1020
|
-
declare const CANONICAL_PROTOTYPING_SURFACES: readonly ["web", "mobile", "desktop", "cli", "mixed"];
|
|
1021
|
-
type CanonicalPrototypingSurface = (typeof CANONICAL_PROTOTYPING_SURFACES)[number];
|
|
1022
|
-
|
|
1023
|
-
/**
|
|
1024
|
-
* Prototyping surface helpers.
|
|
1025
|
-
*
|
|
1026
|
-
* Kept here: surface-type helpers and a `playwright-cli` constant used by
|
|
1027
|
-
* the capture wiring.
|
|
1028
|
-
*/
|
|
1029
|
-
|
|
1030
|
-
declare const PROTOTYPING_SUPPORTED_SURFACES: readonly ["web", "mobile", "desktop", "mixed"];
|
|
1031
|
-
type PrototypingSurface = CanonicalPrototypingSurface;
|
|
1032
|
-
type PrototypingBrowserTool = "playwright-cli";
|
|
1033
|
-
declare function isValidPrototypingSurface(value: unknown): value is PrototypingSurface;
|
|
1034
|
-
declare function isSupportedPrototypingSurface(surface: string): surface is PrototypingSurface;
|
|
1035
|
-
|
|
1036
540
|
/**
|
|
1037
541
|
* The input source preflight selected: the discussion pack, or an imported
|
|
1038
542
|
* specification the caller names with `importPath`. An explicit user
|
|
@@ -1113,6 +617,17 @@ type ValidationOptions = {
|
|
|
1113
617
|
flowIds?: readonly string[];
|
|
1114
618
|
};
|
|
1115
619
|
declare function validateProject(root: string, configResult?: ConfigLoadResult, options?: ValidationOptions): Promise<ValidationResult>;
|
|
620
|
+
/**
|
|
621
|
+
* The parts of the UI/UX group, slowest first. The html-mock part leaves out the one-off load of
|
|
622
|
+
* its parser, as the group's own time does.
|
|
623
|
+
*/
|
|
624
|
+
declare function orderUiuxParts(parts: readonly {
|
|
625
|
+
name: string;
|
|
626
|
+
ms: number;
|
|
627
|
+
}[], htmlMockLoadMs: number): {
|
|
628
|
+
name: string;
|
|
629
|
+
ms: number;
|
|
630
|
+
}[];
|
|
1116
631
|
/**
|
|
1117
632
|
* Count findings by severity, skipping suppressed ones. `counts` is the SSOT
|
|
1118
633
|
* every gate reads, so anything that rebuilds a `ValidationResult` from an
|
|
@@ -1224,6 +739,44 @@ declare function classifyAgainstDeclaration(declaringDir: string, packageDir: st
|
|
|
1224
739
|
* statement but still a statement.
|
|
1225
740
|
*/
|
|
1226
741
|
declare function findDeclaringDir(root: string): Promise<string | null>;
|
|
742
|
+
/**
|
|
743
|
+
* The range the nearest `package.json` declaring qfai gives it, or `null` when
|
|
744
|
+
* no manifest at or above `root` declares it with a text range.
|
|
745
|
+
*
|
|
746
|
+
* Read from the manifest {@link findDeclaringDir} stops at, so the range and the
|
|
747
|
+
* directory it is compared against are one declaration.
|
|
748
|
+
*/
|
|
749
|
+
declare function readDeclaredQfaiRange(root: string): Promise<string | null>;
|
|
750
|
+
/**
|
|
751
|
+
* The lowest version a dependency range admits, as `x.y.z`, or `null` when the
|
|
752
|
+
* range does not state one this reads.
|
|
753
|
+
*
|
|
754
|
+
* Only the forms a project writes for a pinned dependency are read: an exact
|
|
755
|
+
* version, and a caret, tilde or `>=` range, each optionally followed by more
|
|
756
|
+
* comparators (`>=2.1.1 <3`). A tag (`latest`), a wildcard (`2.x`), an
|
|
757
|
+
* alternative (`||`), a protocol (`workspace:`, `file:`, `github:`) and a
|
|
758
|
+
* partial version (`^2.1`) answer `null`, so nothing is compared against them.
|
|
759
|
+
*/
|
|
760
|
+
declare function lowestVersionOfRange(range: string): string | null;
|
|
761
|
+
/** Whether `version` is strictly older than `other`; `false` where either is unreadable. */
|
|
762
|
+
declare function isOlderVersion(version: string, other: string): boolean;
|
|
763
|
+
/** An installed qfai that is older than the version the project declares. */
|
|
764
|
+
type InstalledOlderThanDeclared = {
|
|
765
|
+
readonly installed: string;
|
|
766
|
+
readonly declaredRange: string;
|
|
767
|
+
readonly declaredLowest: string;
|
|
768
|
+
};
|
|
769
|
+
/**
|
|
770
|
+
* Whether the running qfai is older than the lowest version this project's
|
|
771
|
+
* dependency declaration admits.
|
|
772
|
+
*
|
|
773
|
+
* The declaration is the only record of "the qfai this tree was written for"
|
|
774
|
+
* that a project keeps: the files `qfai init` writes carry no version. An
|
|
775
|
+
* installed copy below that floor is the state a lockfile that moved after the
|
|
776
|
+
* last install leaves, and every rule whose input is a generated file can then
|
|
777
|
+
* disagree with the tree for a reason that is not in the tree.
|
|
778
|
+
*/
|
|
779
|
+
declare function compareInstalledToDeclared(installed: string, declaredRange: string | null): InstalledOlderThanDeclared | null;
|
|
1227
780
|
/**
|
|
1228
781
|
* Whether `packageDir` is an installed copy resolved from outside `root`.
|
|
1229
782
|
*
|
|
@@ -1287,6 +840,9 @@ declare function validateContracts(root: string, config: QfaiConfig): Promise<Is
|
|
|
1287
840
|
declare function validateUiContractParse(root: string, config: QfaiConfig): Promise<Issue[]>;
|
|
1288
841
|
declare function lintSql(text: string, file: string): Issue[];
|
|
1289
842
|
|
|
843
|
+
declare const CANONICAL_PROTOTYPING_SURFACES: readonly ["web", "mobile", "desktop", "cli", "mixed"];
|
|
844
|
+
type CanonicalPrototypingSurface = (typeof CANONICAL_PROTOTYPING_SURFACES)[number];
|
|
845
|
+
|
|
1290
846
|
type SurfaceType = CanonicalPrototypingSurface | "non-ui";
|
|
1291
847
|
declare const DISCUSSION_UI_BEARING_SURFACES: Set<SurfaceType>;
|
|
1292
848
|
declare const DISCUSSION_NON_UI_SURFACES: Set<SurfaceType>;
|
|
@@ -1295,137 +851,6 @@ declare function isDiscussionUiBearingSurfaceType(surface: SurfaceType): boolean
|
|
|
1295
851
|
declare function isNonUiDiscussionSurface(surface: SurfaceType): boolean;
|
|
1296
852
|
declare function requiresVisualBrowserEvidence(surface: SurfaceType): boolean;
|
|
1297
853
|
|
|
1298
|
-
type BrowserQaPhase = "smoke" | "interaction" | "visual" | "accessibility";
|
|
1299
|
-
declare const BROWSER_QA_PHASES: readonly BrowserQaPhase[];
|
|
1300
|
-
type BrowserQaPhaseStatus = "passed" | "executed" | "failed" | "skipped";
|
|
1301
|
-
type BrowserQaFindingSeverity = "info" | "warn" | "warning" | "error";
|
|
1302
|
-
interface BrowserQaFinding {
|
|
1303
|
-
phase: BrowserQaPhase;
|
|
1304
|
-
severity: BrowserQaFindingSeverity;
|
|
1305
|
-
summary: string;
|
|
1306
|
-
detail: string;
|
|
1307
|
-
screen_id?: string;
|
|
1308
|
-
selector?: string;
|
|
1309
|
-
evidence_refs: string[];
|
|
1310
|
-
repair_suggestions: string[];
|
|
1311
|
-
category?: BrowserQaPhase;
|
|
1312
|
-
message?: string;
|
|
1313
|
-
route?: string;
|
|
1314
|
-
repair_hint?: string;
|
|
1315
|
-
}
|
|
1316
|
-
type BrowserQaScreenContractRef = {
|
|
1317
|
-
screen_id: string;
|
|
1318
|
-
route?: string;
|
|
1319
|
-
primary_tasks?: string[];
|
|
1320
|
-
};
|
|
1321
|
-
type BrowserQaPhaseResult = {
|
|
1322
|
-
phase: BrowserQaPhase;
|
|
1323
|
-
status: BrowserQaPhaseStatus;
|
|
1324
|
-
findings: BrowserQaFinding[];
|
|
1325
|
-
repair_suggestions: string[];
|
|
1326
|
-
evidence_refs: string[];
|
|
1327
|
-
checks_performed: string[];
|
|
1328
|
-
skippedReason?: string;
|
|
1329
|
-
screen_id?: string;
|
|
1330
|
-
route?: string;
|
|
1331
|
-
};
|
|
1332
|
-
type BrowserQaInput = {
|
|
1333
|
-
htmlContent?: string;
|
|
1334
|
-
targetUrl?: string;
|
|
1335
|
-
routes?: string[];
|
|
1336
|
-
surface: SurfaceType;
|
|
1337
|
-
required?: boolean;
|
|
1338
|
-
executionSource?: "html" | "url" | "none";
|
|
1339
|
-
screenContracts?: BrowserQaScreenContractRef[];
|
|
1340
|
-
};
|
|
1341
|
-
type BrowserQaRunResult = {
|
|
1342
|
-
phases: BrowserQaPhaseResult[];
|
|
1343
|
-
provider: string;
|
|
1344
|
-
timestamp: string;
|
|
1345
|
-
};
|
|
1346
|
-
type BrowserQaSummary = {
|
|
1347
|
-
providerId: string;
|
|
1348
|
-
phases: Record<BrowserQaPhase, {
|
|
1349
|
-
status: BrowserQaPhaseStatus;
|
|
1350
|
-
findingsCount: number;
|
|
1351
|
-
checksCount: number;
|
|
1352
|
-
passed?: number;
|
|
1353
|
-
failed?: number;
|
|
1354
|
-
}>;
|
|
1355
|
-
totalFindings: number;
|
|
1356
|
-
totalRepairs: number;
|
|
1357
|
-
skippedReasons: string[];
|
|
1358
|
-
};
|
|
1359
|
-
interface BrowserQaProvider {
|
|
1360
|
-
providerId: string;
|
|
1361
|
-
canRun(surface: SurfaceType): boolean;
|
|
1362
|
-
runSmoke(input: BrowserQaInput): Promise<BrowserQaPhaseResult>;
|
|
1363
|
-
runInteraction(input: BrowserQaInput): Promise<BrowserQaPhaseResult>;
|
|
1364
|
-
runVisual(input: BrowserQaInput): Promise<BrowserQaPhaseResult>;
|
|
1365
|
-
runAccessibility(input: BrowserQaInput): Promise<BrowserQaPhaseResult>;
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
declare function runBrowserQaOrchestrated(input: BrowserQaInput, provider?: BrowserQaProvider): Promise<BrowserQaRunResult>;
|
|
1369
|
-
declare function summarizeBrowserQaResult(result: BrowserQaRunResult): BrowserQaSummary;
|
|
1370
|
-
|
|
1371
|
-
/**
|
|
1372
|
-
* Render evidence types
|
|
1373
|
-
*
|
|
1374
|
-
* Canonical types for the render evidence capture pipeline.
|
|
1375
|
-
*/
|
|
1376
|
-
type RenderCaptureTarget = {
|
|
1377
|
-
targetId: string;
|
|
1378
|
-
route?: string;
|
|
1379
|
-
descriptor?: string;
|
|
1380
|
-
viewport: string;
|
|
1381
|
-
width?: number;
|
|
1382
|
-
height?: number;
|
|
1383
|
-
};
|
|
1384
|
-
type RenderCaptureAdapter = {
|
|
1385
|
-
captureScreenshot(target: RenderCaptureTarget, outputDir: string): Promise<string>;
|
|
1386
|
-
captureHtml?(target: RenderCaptureTarget, outputDir: string): Promise<string>;
|
|
1387
|
-
};
|
|
1388
|
-
type RenderEvidenceEntryResult = {
|
|
1389
|
-
capture_id: string;
|
|
1390
|
-
target: string;
|
|
1391
|
-
status: "captured" | "skipped" | "failed";
|
|
1392
|
-
screenshot_path?: string;
|
|
1393
|
-
html_path?: string;
|
|
1394
|
-
viewport: string;
|
|
1395
|
-
reason?: string;
|
|
1396
|
-
};
|
|
1397
|
-
type RenderRunnerResult = {
|
|
1398
|
-
entries: RenderEvidenceEntryResult[];
|
|
1399
|
-
filesWritten: string[];
|
|
1400
|
-
surface?: string;
|
|
1401
|
-
mode?: string;
|
|
1402
|
-
generatedAt?: string;
|
|
1403
|
-
coverageSummary?: {
|
|
1404
|
-
total: number;
|
|
1405
|
-
captured: number;
|
|
1406
|
-
failed: number;
|
|
1407
|
-
skipped: number;
|
|
1408
|
-
};
|
|
1409
|
-
};
|
|
1410
|
-
|
|
1411
|
-
/**
|
|
1412
|
-
* Render runner
|
|
1413
|
-
*
|
|
1414
|
-
* Executes render capture for a list of targets, producing truthful
|
|
1415
|
-
* evidence entries. No placeholder paths are emitted.
|
|
1416
|
-
*/
|
|
1417
|
-
|
|
1418
|
-
/**
|
|
1419
|
-
* Run render capture for all targets.
|
|
1420
|
-
*
|
|
1421
|
-
* - adapter present + capture succeeds → `captured` with real file paths
|
|
1422
|
-
* - adapter present + capture throws → `failed` with reason
|
|
1423
|
-
* - adapter absent → `skipped` with reason
|
|
1424
|
-
*/
|
|
1425
|
-
declare function runRenderCapture(targets: RenderCaptureTarget[], outputDir: string, adapter?: RenderCaptureAdapter, options?: {
|
|
1426
|
-
required?: boolean;
|
|
1427
|
-
}): Promise<RenderRunnerResult>;
|
|
1428
|
-
|
|
1429
854
|
declare const ARCHETYPES: readonly ["minimal", "bold", "corporate", "playful", "organic", "tech", "elegant", "casual"];
|
|
1430
855
|
type Archetype = (typeof ARCHETYPES)[number];
|
|
1431
856
|
declare const COLOR_KEYS: readonly ["primary", "secondary", "accent", "surface", "surface_muted", "text", "text_muted", "danger", "warning", "success", "border", "overlay"];
|
|
@@ -1535,12 +960,8 @@ declare const DESIGN_MD_SAMPLE_MARKER = "QFAI-SAMPLE-DESIGN-MD";
|
|
|
1535
960
|
* an unauthored brand as the project's brand contract, and to surface the
|
|
1536
961
|
* same condition from `qfai validate` (QFAI-DCON-034).
|
|
1537
962
|
*
|
|
1538
|
-
*
|
|
1539
|
-
*
|
|
1540
|
-
* 1. `DESIGN_MD_SAMPLE_MARKER` — current samples, survives any edit that
|
|
1541
|
-
* leaves the comment in place.
|
|
1542
|
-
* 2. Legacy content fingerprint — samples seeded before the marker
|
|
1543
|
-
* existed, which `qfai init` will never overwrite.
|
|
963
|
+
* The test is `DESIGN_MD_SAMPLE_MARKER`, which survives any edit that leaves
|
|
964
|
+
* the comment in place.
|
|
1544
965
|
*
|
|
1545
966
|
* `text` is `unknown` rather than `string` because this is re-exported from
|
|
1546
967
|
* `core/index.ts` and so is reachable from untyped JavaScript, where a caller
|
|
@@ -1551,7 +972,74 @@ declare const DESIGN_MD_SAMPLE_MARKER = "QFAI-SAMPLE-DESIGN-MD";
|
|
|
1551
972
|
*/
|
|
1552
973
|
declare function isUnreplacedDesignMdSample(text: unknown): boolean;
|
|
1553
974
|
|
|
975
|
+
interface GraphPreparation {
|
|
976
|
+
runtime: "installed" | "not-ready";
|
|
977
|
+
tools?: {
|
|
978
|
+
codegraph: "installed" | "not-ready";
|
|
979
|
+
graphify: "installed" | "not-ready";
|
|
980
|
+
};
|
|
981
|
+
code: "code-ready" | "code-not-ready";
|
|
982
|
+
documents: "documents-not-ready";
|
|
983
|
+
failedStep?: string;
|
|
984
|
+
recovery?: string;
|
|
985
|
+
previousInstallation?: "retained" | "none";
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
type GraphHookHost = "claude" | "codex" | "copilot" | "vscode";
|
|
989
|
+
|
|
990
|
+
interface GraphHostFacts {
|
|
991
|
+
host: GraphHookHost;
|
|
992
|
+
version?: string;
|
|
993
|
+
configuration: "configured" | "not-configured" | "failed";
|
|
994
|
+
denialEvent?: string;
|
|
995
|
+
failureProtocol?: "supported" | "unsupported" | "unverified";
|
|
996
|
+
trust: "required" | "granted" | "not-required" | "unknown";
|
|
997
|
+
}
|
|
998
|
+
interface GraphHostProtection {
|
|
999
|
+
host: GraphHookHost;
|
|
1000
|
+
version?: string;
|
|
1001
|
+
state: "configured" | "trust-required" | "runtime-verified" | "unsupported" | "failed";
|
|
1002
|
+
events: readonly string[];
|
|
1003
|
+
recovery: string;
|
|
1004
|
+
configuration?: GraphHostFacts["configuration"];
|
|
1005
|
+
trust?: GraphHostFacts["trust"];
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
interface GraphSettingsComposition {
|
|
1009
|
+
files: string[];
|
|
1010
|
+
conflicts: string[];
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
type GraphIntegrationPreparation = GraphPreparation & GraphSettingsComposition & {
|
|
1014
|
+
hosts: GraphHostProtection[];
|
|
1015
|
+
};
|
|
1016
|
+
declare function prepareGraphIntegration(root: string, run?: GraphProcess): Promise<GraphIntegrationPreparation>;
|
|
1017
|
+
|
|
1018
|
+
declare function renderGraphPreparation(preparation: GraphPreparation, hosts?: readonly GraphHostProtection[]): string;
|
|
1019
|
+
|
|
1020
|
+
interface GraphReuseEnvironment {
|
|
1021
|
+
platform: string;
|
|
1022
|
+
architecture: string;
|
|
1023
|
+
machine: string;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
interface DocumentPreparation {
|
|
1027
|
+
status: "prepared" | "not-ready" | "failed";
|
|
1028
|
+
source?: "current" | "restored" | "generated";
|
|
1029
|
+
reuse?: "published" | "unavailable";
|
|
1030
|
+
recovery?: string;
|
|
1031
|
+
}
|
|
1032
|
+
interface ExternalProcessingRequest {
|
|
1033
|
+
readonly destination: string;
|
|
1034
|
+
readonly scope: readonly string[];
|
|
1035
|
+
readonly backend: string;
|
|
1036
|
+
readonly model: string;
|
|
1037
|
+
readonly worktree: string;
|
|
1038
|
+
}
|
|
1039
|
+
type ApproveExternalProcessing = (request: ExternalProcessingRequest) => Promise<boolean>;
|
|
1040
|
+
declare function prepareDocumentAnalysis(root: string, run?: GraphProcess, approveExternal?: ApproveExternalProcessing, environment?: GraphReuseEnvironment): Promise<DocumentPreparation>;
|
|
1041
|
+
|
|
1554
1042
|
/** Run one ordered spec-to-story migration step from the current project root. */
|
|
1555
1043
|
declare function runMigrationStep(step: number, argv: string[]): Promise<number>;
|
|
1556
1044
|
|
|
1557
|
-
export { AC_GHERKIN_SECTION, ARCHETYPES, ATDD_TEST_KIND_DIRS, type
|
|
1045
|
+
export { AC_GHERKIN_SECTION, ARCHETYPES, ATDD_TEST_KIND_DIRS, type ApproveExternalProcessing, type Archetype, type AtddTestKind, COLOR_KEYS, type ColorKey, type ConfigLoadResult, type ConfigPathKey, type ConfigSearchResult, DESIGN_MD_SAMPLE_MARKER, DISCUSSION_NON_UI_SURFACES, DISCUSSION_UI_BEARING_SURFACES, type DesignMd, type DesignMdColors, type DesignMdFonts, type DesignMdRadius, type DesignMdShadow, type DocumentPreparation, type ExternalProcessingRequest, FONT_KEYS, type FailOn, type FenceMaskOptions, type FontKey, ID_PREFIXES, type IdFormatPrefix, type IdPrefix, type InstalledOlderThanDeclared, type InvalidIdOccurrence, type Issue, type IssueCategory, type IssueLocation, type IssueSeverity, type OutputFormat, type ParseError, type ParseResult, type QfaiConfig, type QfaiForbiddenIdentifier, type QfaiOutputConfig, type QfaiPaths, type QfaiPrototypingConfig, type QfaiPrototypingExecutionConfig, type QfaiReportConfig, type QfaiReviewProfile, type QfaiRoutingEntry, type QfaiUiuxAuditConfig, type QfaiUiuxConfig, type QfaiValidationConfig, RADIUS_KEYS, type RadiusKey, type ReportData, type RunSddPreflightOptions, SHADOW_KEYS, SKIPPED_WORKFLOWS_MESSAGE, type SddPreflightResult, type SddPreflightSource, type SddPreflightStatus, type ShadowKey, type TestFileExtensions, type TestLayerRoots, VISUAL_BROWSER_SURFACES, type ValidationCounts, type ValidationIssue, type ValidationOptions, type ValidationProfile, type ValidationResult, type ValidationTimings, type ValidationWaiverAction, type ValidationWaiverDowngradeTo, type ValidationWaiverEntry, type ValidationWaiverMatch, type ValidationWaiverScope, type ValidationWaiverSeverity, type ValidationWaiverSuppressed, type ValidationWaivers, WORKFLOW_MODE_MESSAGE, type WorkflowMode, atddAcceptanceLayerFilter, atddAcceptanceTestGlobs, atddTestKindDirs, classifyAgainstDeclaration, classifyToolLocation, compareInstalledToDeclared, countIssues, createReportData, createTestLayerRoots, defaultConfig, deriveAtddFilePattern, deriveTestFileExtensions, extractAcSpecNumber, extractAllIds, extractBrSpecNumber, extractCapSpecNumber, extractCaseSpecNumber, extractIds, extractInvalidIdOccurrences, extractInvalidIds, extractScSpecNumber, extractSpecNumber, extractUsSpecNumber, findConfigRoot, findDeclaringDir, findLinkingNodeModules, findPackageJsonUpward, formatReportJson, formatReportMarkdown, getConfigPath, isDiscussionUiBearingSurfaceType, isNonUiDiscussionSurface, isOlderVersion, isUnreplacedDesignMdSample, lintSql, loadConfig, locateToolAgainstProject, lowestVersionOfRange, maskFencedCodeBlocks, orderUiuxParts, packageRootProbe, parseDesignMd, prepareDocumentAnalysis, prepareGraphIntegration, reachedThroughLinkedNodeModules, readDeclaredQfaiRange, readRejectedPrimaryUiContract, readSkippedWorkflows, readTestFileExtensions, readWorkflowMode, renderGraphPreparation, requiresVisualBrowserEvidence, resolvePath, resolveTestKind, resolveToolPackageDir, resolveToolVersion, resolvesThroughOwnNodeModules, routingEntryName, runMigrationStep, runSddPreflight, validateContracts, validateDesignMd, validateProject, validateUiContractParse };
|