no-mistakes 0.85.0 → 0.86.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.
@@ -1,9 +1,6 @@
1
- import type {
2
- CiEnvOptions,
3
- CiImpactOptions,
4
- CiTopologyOptions,
5
- ImpactedChecksOptions,
6
- } from "./ci-types";
1
+ import type { TestsAuditOptions } from "./test-audit-types";
2
+ import type { CiTopologyOptions } from "./workflow-topology-types";
3
+ import type { CiEnvOptions, CiImpactOptions, ImpactedChecksOptions } from "./ci-types";
7
4
  import type { FetchesOptions, FlowOptions } from "./flow-types";
8
5
  import type { ImportUsagesOptions } from "./import-usage-types";
9
6
  import type { MermaidValidationOptions } from "./mermaid-types";
@@ -60,7 +57,10 @@ type BatchedReactUsagesOptions = Pick<
60
57
  "root" | "tsconfig" | "config" | "targets" | "include"
61
58
  > &
62
59
  Required<Pick<ProjectOptions, "target">>;
63
- type BatchedCheckOptions = Pick<CheckOptions, "root" | "tsconfig" | "config" | "includeSuppressed">;
60
+ type BatchedCheckOptions = Pick<
61
+ CheckOptions,
62
+ "root" | "tsconfig" | "config" | "includeSuppressed" | "includeRunnerConfigDeadlines"
63
+ >;
64
64
  type BatchedQueryFileOptions<T> = Omit<T, "root" | "tsconfig">;
65
65
  type BatchedRootConfigOptions<T> = Omit<T, "root" | "config">;
66
66
  type BatchedRootTsConfigOptions<T> = Omit<T, "root" | "tsconfig" | "config">;
@@ -115,6 +115,7 @@ export type AnalyzeProjectReportRequest =
115
115
  | ({ type: "fetches"; id?: string } & BatchedRootConfigOptions<FetchesOptions>)
116
116
  | ({ type: "dataPw"; id?: string } & BatchedRootConfigOptions<DataPwOptions>)
117
117
  | ({ type: "registryExtension"; id?: string } & Omit<RegistryExtensionOptions, "root">)
118
+ | ({ type: "testsAudit"; id?: string } & TestsAuditOptions)
118
119
  | ({ type: "testsPlan"; id?: string } & BatchedRootTsConfigOptions<TestsPlanOptions>)
119
120
  | ({ type: "testsImpact"; id?: string } & BatchedRootTsConfigOptions<TestsImpactOptions>)
120
121
  | ({ type: "testsTargets"; id?: string } & Omit<TestsTargetsOptions, "root" | "config">)
@@ -6,6 +6,8 @@ export interface CheckReport {
6
6
  queues: QueueCheckFinding[];
7
7
  rules: RuleFinding[];
8
8
  integration: IntegrationFinding[];
9
+ /** Present only when requested; declaration evidence, not runtime closure. */
10
+ runnerConfigDeadlines?: RunnerConfigDeadlineEvidence[];
9
11
  codebase: UniqueExportFinding[];
10
12
  warnings: string[];
11
13
  advisories: RuleFinding[];
@@ -55,3 +57,50 @@ export interface UniqueExportFinding {
55
57
  exportKind: string;
56
58
  message: string;
57
59
  }
60
+
61
+ export type RunnerDeadlineStatus = "notRequested" | "prepared" | "failed";
62
+ export interface RunnerConfigDeadlineEvidence {
63
+ framework: "playwright" | "vitest";
64
+ status: RunnerDeadlineStatus;
65
+ configs: ConfigDeadlineEvidence[];
66
+ }
67
+ export type ConfigDeadlineEvidence =
68
+ | { status: "prepared"; config: string; projects: ProjectDeadlineEvidence[] }
69
+ | { status: "failed"; config: string; error: string };
70
+ export interface ProjectDeadlineEvidence {
71
+ config: string | null;
72
+ workspace: boolean;
73
+ policyName: string | null;
74
+ runnerProjectArg: string | null;
75
+ scope: string | null;
76
+ case: DeclaredDeadlineSlot;
77
+ hook: DeclaredDeadlineSlot;
78
+ fixture: DeclaredDeadlineSlot;
79
+ }
80
+ export type DeclaredDeadlineSlot =
81
+ | { status: "absent" }
82
+ | { status: "known"; milliseconds: number; provenance: DeadlineProvenance }
83
+ | { status: "unknown"; reason: DeclaredDeadlineUnknownReason; provenance: DeadlineProvenance };
84
+ export type DeclaredDeadlineUnknownReason =
85
+ | "expression"
86
+ | "nonFinite"
87
+ | "opaqueSpread"
88
+ | "opaqueTestObject"
89
+ | "computedProperty"
90
+ | "unresolvedExtends"
91
+ | "unresolvedInheritance"
92
+ | "unprovedConfigRoot"
93
+ | "accessor"
94
+ | "unsupportedConfigCall"
95
+ | "unprovedBinding";
96
+ export interface DeadlineProvenance {
97
+ /** Request-root-relative slash path; outside-root sources retain their path. */
98
+ path: string;
99
+ /** Half-open source byte offsets, never line numbers; null when unavailable. */
100
+ span: [number, number] | null;
101
+ inheritedThrough: DeadlineInheritanceEvidence[];
102
+ }
103
+ export interface DeadlineInheritanceEvidence {
104
+ path: string;
105
+ project: string | null;
106
+ }
@@ -0,0 +1,19 @@
1
+ /** Options for the configured `declared-payload-compatibility` check rule. */
2
+ export interface DeclaredPayloadCompatibilityOptions {
3
+ contracts?: DeclaredPayloadContract[];
4
+ }
5
+
6
+ /** Producer declarations must accept only values accepted by the consumer. */
7
+ export interface DeclaredPayloadContract {
8
+ name: string;
9
+ producer: DeclaredPayloadSchema;
10
+ consumer: DeclaredPayloadSchema;
11
+ }
12
+
13
+ /** A visible JSON document selected explicitly; no runtime adoption is inferred. */
14
+ export interface DeclaredPayloadSchema {
15
+ /** Root-relative path within this rule application's visible file scope. */
16
+ file: string;
17
+ /** RFC 6901 JSON pointer; omitted or empty selects the whole document. */
18
+ pointer?: string;
19
+ }
@@ -28,6 +28,8 @@ import type {
28
28
  SwiftOptions,
29
29
  SwiftTestTargetRow,
30
30
  TestForRow,
31
+ TestAuditReport,
32
+ TestsAuditOptions,
31
33
  WithInvocationOptions,
32
34
  WorkflowTopology,
33
35
  WorkflowTopologyIndex,
@@ -73,3 +75,7 @@ export function swiftTestTargets(
73
75
  options: WithInvocationOptions<SwiftOptions & { file: string }>,
74
76
  ): Promise<SwiftTestTargetRow[]>;
75
77
  export function version(): Promise<string>;
78
+
79
+ export function testsAudit(
80
+ options: WithInvocationOptions<TestsAuditOptions>,
81
+ ): Promise<TestAuditReport>;
package/index.js CHANGED
@@ -66,7 +66,13 @@ const jsonApis = createJsonApis({
66
66
  symbols: "symbolsJson",
67
67
  });
68
68
 
69
- const CAMELIZE_REPORTS = new Set(["testsPlan", "testsImpact", "testsTargets", "testsGraph"]);
69
+ const CAMELIZE_REPORTS = new Set([
70
+ "testsAudit",
71
+ "testsPlan",
72
+ "testsImpact",
73
+ "testsTargets",
74
+ "testsGraph",
75
+ ]);
70
76
  const acquirePlanningArtifactLock = createPlanningArtifactLock(native);
71
77
 
72
78
  async function analyzeProject(options = {}) {
@@ -163,6 +169,7 @@ module.exports.serverRouteEdges = planning.serverRouteEdges;
163
169
  module.exports.serverRouteList = planning.serverRouteList;
164
170
  module.exports.serverRouteRelated = planning.serverRouteRelated;
165
171
  module.exports.serverRoutes = planning.serverRoutes;
172
+ module.exports.testsAudit = planning.testsAudit;
166
173
  module.exports.testsGraph = planning.testsGraph;
167
174
  module.exports.testsImpact = planning.testsImpact;
168
175
  module.exports.testsPlan = planning.testsPlan;
package/index.mjs CHANGED
@@ -54,6 +54,7 @@ export const {
54
54
  swiftImporters,
55
55
  swiftTestTargets,
56
56
  symbols,
57
+ testsAudit,
57
58
  testsComment,
58
59
  testsGraph,
59
60
  testsGraphMermaid,
@@ -2,13 +2,19 @@
2
2
  export interface InvocationOptions {
3
3
  /** Command execution timeout in whole non-negative seconds. Omit, `0`, or `null` disables it. CLI default remains 30. */
4
4
  timeout?: number | null;
5
- /** Maximum time to wait for the machine-wide lock, in whole non-negative seconds. Omit, `0`, or `null` waits indefinitely. CLI default remains 30. */
5
+ /** Maximum time to wait for the current user's invocation lock (shared across project roots), in whole non-negative seconds. Omit, `0`, or `null` waits indefinitely. CLI default remains 30. */
6
6
  lockTimeout?: number | null;
7
7
  /** Fail immediately instead of waiting when another invocation holds the lock. */
8
8
  failOnLock?: boolean;
9
9
  /**
10
- * Rayon worker count. Omit or `0` uses the CPU count, matching CLI `--jobs 0`.
11
- * A positive integer pins the process pool on the first N-API call.
10
+ * Rayon worker count. A positive integer takes precedence over `RAYON_NUM_THREADS`.
11
+ * Omit, `0`, or `null` uses `RAYON_NUM_THREADS`, falling back to CPU count when
12
+ * unset or invalid, matching CLI `--jobs 0`.
13
+ * The first analysis request with valid UTF-8 JSON and invocation controls that
14
+ * acquires the invocation lock initializes the process-wide pool before
15
+ * command-specific options are validated. A later command-validation failure
16
+ * can therefore still select the pool; JSON/control or lock failures cannot.
17
+ * Later calls cannot resize an already initialized pool.
12
18
  */
13
19
  jobs?: number | null;
14
20
  /** `ci` sets unbounded command and lock timeouts. CLI `--profile ci` does the same. */
@@ -37,7 +37,7 @@ export interface EffectsOptions {
37
37
  tsconfig?: string;
38
38
  /** Path to the no-mistakes config file (e.g. .no-mistakes.yml). Auto-discovered in root if omitted. */
39
39
  config?: string;
40
- /** Effect kind to resolve (a key under `effects:` in config). */
40
+ /** Effect family from config; supports spelling lists and binding-aware module/export targets. */
41
41
  kind: string;
42
42
  /** Entry file whose transitive imports are scanned. */
43
43
  entry: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "no-mistakes",
3
- "version": "0.85.0",
3
+ "version": "0.86.0",
4
4
  "description": "Deterministic impact maps, test plans, Playwright coverage, and repository checks for coding agents",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -24,6 +24,7 @@
24
24
  "planning-impact-artifacts-privacy.js",
25
25
  "planning-impact-cli.js",
26
26
  "planning.js",
27
+ "planning-artifact-inputs.js",
27
28
  "workflow-topology-index.js",
28
29
  "workflow-topology-index-helpers.js",
29
30
  "scripts/native-package.js",
@@ -45,9 +46,9 @@
45
46
  "access": "public"
46
47
  },
47
48
  "optionalDependencies": {
48
- "no-mistakes-darwin-arm64": "0.85.0",
49
- "no-mistakes-linux-arm64-gnu": "0.85.0",
50
- "no-mistakes-linux-x64-gnu": "0.85.0",
51
- "no-mistakes-win32-x64-msvc": "0.85.0"
49
+ "no-mistakes-darwin-arm64": "0.86.0",
50
+ "no-mistakes-linux-arm64-gnu": "0.86.0",
51
+ "no-mistakes-linux-x64-gnu": "0.86.0",
52
+ "no-mistakes-win32-x64-msvc": "0.86.0"
52
53
  }
53
54
  }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs/promises");
4
+
5
+ function camelizeKey(key) {
6
+ return key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
7
+ }
8
+
9
+ function decamelizeKey(key) {
10
+ return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
11
+ }
12
+
13
+ function mapKeys(value, mapKey) {
14
+ if (Array.isArray(value)) return value.map((item) => mapKeys(item, mapKey));
15
+ if (value && typeof value === "object") {
16
+ return Object.fromEntries(
17
+ Object.entries(value).map(([key, nested]) => [mapKey(key), mapKeys(nested, mapKey)]),
18
+ );
19
+ }
20
+ return value;
21
+ }
22
+
23
+ function camelizeValue(value) {
24
+ return mapKeys(value, camelizeKey);
25
+ }
26
+
27
+ function decamelizeValue(value) {
28
+ return mapKeys(value, decamelizeKey);
29
+ }
30
+
31
+ function loadPlanJson(planJson) {
32
+ let parsed = planJson;
33
+ if (typeof parsed === "string") {
34
+ try {
35
+ parsed = JSON.parse(parsed);
36
+ } catch {
37
+ return planJson;
38
+ }
39
+ }
40
+ if (parsed && typeof parsed === "object") {
41
+ return decamelizeValue(parsed);
42
+ }
43
+ return planJson;
44
+ }
45
+
46
+ async function readPlanFile(planPath) {
47
+ try {
48
+ return JSON.parse(await fs.readFile(planPath, "utf8"));
49
+ } catch {
50
+ return undefined;
51
+ }
52
+ }
53
+
54
+ async function decamelizePlanOptions(options = {}) {
55
+ const next = { ...options };
56
+ if (next.planJson != null) {
57
+ next.planJson = loadPlanJson(next.planJson);
58
+ } else if (typeof next.plan === "string") {
59
+ const document = await readPlanFile(next.plan);
60
+ if (document !== undefined) {
61
+ next.planJson = loadPlanJson(document);
62
+ delete next.plan;
63
+ }
64
+ }
65
+ return next;
66
+ }
67
+
68
+ module.exports = { camelizeValue, decamelizePlanOptions, loadPlanJson, readPlanFile };
package/planning.js CHANGED
@@ -7,6 +7,12 @@ const { resolveNativePackage } = require("./scripts/native-package");
7
7
  const native = require(
8
8
  process.env.NO_MISTAKES_TEST_NAPI_ADDON_PATH || resolveNativePackage().addonPath,
9
9
  );
10
+ const {
11
+ camelizeValue,
12
+ decamelizePlanOptions,
13
+ loadPlanJson,
14
+ readPlanFile,
15
+ } = require("./planning-artifact-inputs");
10
16
  const PLAN_INPUT_REPORTS = new Set(["testsComment", "testsGraph", "testsGraphMermaid"]);
11
17
 
12
18
  async function callJson(fn, options) {
@@ -23,69 +29,6 @@ function createJsonApis(descriptors) {
23
29
  );
24
30
  }
25
31
 
26
- function camelizeKey(key) {
27
- return key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
28
- }
29
-
30
- function decamelizeKey(key) {
31
- return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
32
- }
33
-
34
- function mapKeys(value, mapKey) {
35
- if (Array.isArray(value)) return value.map((item) => mapKeys(item, mapKey));
36
- if (value && typeof value === "object") {
37
- return Object.fromEntries(
38
- Object.entries(value).map(([key, nested]) => [mapKey(key), mapKeys(nested, mapKey)]),
39
- );
40
- }
41
- return value;
42
- }
43
-
44
- function camelizeValue(value) {
45
- return mapKeys(value, camelizeKey);
46
- }
47
-
48
- function decamelizeValue(value) {
49
- return mapKeys(value, decamelizeKey);
50
- }
51
-
52
- function loadPlanJson(planJson) {
53
- let parsed = planJson;
54
- if (typeof parsed === "string") {
55
- try {
56
- parsed = JSON.parse(parsed);
57
- } catch {
58
- return planJson;
59
- }
60
- }
61
- if (parsed && typeof parsed === "object") {
62
- return decamelizeValue(parsed);
63
- }
64
- return planJson;
65
- }
66
-
67
- async function readPlanFile(planPath) {
68
- try {
69
- return JSON.parse(await fs.readFile(planPath, "utf8"));
70
- } catch {
71
- return undefined;
72
- }
73
- }
74
-
75
- async function decamelizePlanOptions(options = {}) {
76
- const next = { ...options };
77
- if (next.planJson != null) {
78
- next.planJson = loadPlanJson(next.planJson);
79
- } else if (typeof next.plan === "string") {
80
- const document = await readPlanFile(next.plan);
81
- if (document !== undefined) {
82
- next.planJson = loadPlanJson(document);
83
- delete next.plan;
84
- }
85
- }
86
- return next;
87
- }
88
-
89
32
  async function prepareWhyPlan(options = {}) {
90
33
  const next = { ...options };
91
34
  let document = next.planJson;
@@ -163,6 +106,7 @@ const jsonApis = createJsonApis({
163
106
  serverRouteList: "serverRouteListJson",
164
107
  serverRouteRelated: "serverRouteRelatedJson",
165
108
  serverRoutes: "serverRoutesJson",
109
+ testsAudit: "testsAuditJson",
166
110
  testsGraph: "testsGraphJson",
167
111
  testsImpact: "testsImpactJson",
168
112
  testsPlan: "testsPlanJson",
@@ -170,6 +114,10 @@ const jsonApis = createJsonApis({
170
114
  testsWhy: "testsWhyJson",
171
115
  });
172
116
 
117
+ async function testsAudit(options) {
118
+ return camelizeValue(await jsonApis.testsAudit(options));
119
+ }
120
+
173
121
  async function testsPlan(options) {
174
122
  return camelizeValue(await jsonApis.testsPlan(options));
175
123
  }
@@ -206,6 +154,7 @@ module.exports = {
206
154
  testsComment,
207
155
  testsGraphMermaid,
208
156
  ...jsonApis,
157
+ testsAudit,
209
158
  testsGraph,
210
159
  testsImpact,
211
160
  testsPlan,
@@ -87,6 +87,8 @@ export interface PostgresSqlQueryColumn {
87
87
  }
88
88
  export interface PostgresSqlPredicateContext {
89
89
  mandatory: boolean;
90
+ /** Required conjunct after wrapping NOT inverts AND/OR; null through opaque wrappers. */
91
+ effectiveMandatory: boolean | null;
90
92
  underOr: boolean;
91
93
  underNot: boolean;
92
94
  underCase: boolean;
package/query-types.d.ts CHANGED
@@ -19,7 +19,27 @@ export interface ImportersTestImpact {
19
19
  count: number;
20
20
  }
21
21
 
22
- export interface ImportersResult {
22
+ /** A recorded gap in the prepared reverse-query source inventory. */
23
+ export type QueryIncompleteReason =
24
+ | "operational-error"
25
+ | "parse-error"
26
+ | "missing-facts"
27
+ | "missing-symbols";
28
+
29
+ export interface QueryIncompleteFile {
30
+ /** Root-relative candidate path; relevance can be unknown when imports are missing. */
31
+ file: string;
32
+ reason: QueryIncompleteReason;
33
+ message: string;
34
+ }
35
+
36
+ export interface QueryDiagnostics {
37
+ /** Recorded collection gaps exist. False does not guarantee exhaustive references. */
38
+ partial: boolean;
39
+ incompleteFiles: QueryIncompleteFile[];
40
+ }
41
+
42
+ export interface ImportersResult extends QueryDiagnostics {
23
43
  file: string;
24
44
  directImporters: string[];
25
45
  dependentsCount: number;
@@ -43,6 +63,10 @@ export interface ExportRowResult {
43
63
  export interface ExportsOfResult {
44
64
  file: string;
45
65
  exports: ExportRowResult[];
66
+ /** Omitted with noImporters because the reverse scan was not requested. */
67
+ partial?: boolean;
68
+ /** Omitted with noImporters. */
69
+ incompleteFiles?: QueryIncompleteFile[];
46
70
  }
47
71
 
48
72
  export interface DeadExportsOptions extends QueryFileOptions {
@@ -56,14 +80,14 @@ export interface DeadExportResult {
56
80
  importerCount: number;
57
81
  }
58
82
 
59
- export interface DeadExportsResult {
83
+ export interface DeadExportsResult extends QueryDiagnostics {
60
84
  file: string;
61
85
  results: DeadExportResult[];
62
86
  anyDead: boolean;
63
87
  }
64
88
 
65
89
  export interface CallSitesOptions extends QueryFileOptions {
66
- /** The exported function name to find call sites for. */
90
+ /** Exported callable to resolve through namespaces, static lexical aliases, and barrels. */
67
91
  exportName: string;
68
92
  }
69
93
 
@@ -90,7 +114,7 @@ export interface CallSite {
90
114
  args: ArgShape[];
91
115
  }
92
116
 
93
- export interface CallSitesResult {
117
+ export interface CallSitesResult extends QueryDiagnostics {
94
118
  file: string;
95
119
  export: string;
96
120
  callSites: CallSite[];
@@ -0,0 +1,100 @@
1
+ import type { ImpactReason, TestPlan } from "./test-types";
2
+
3
+ /** Caller-recorded immutable identities; audit compares but does not verify the digests. */
4
+ export interface TestAuditProvenance {
5
+ /** Lowercase 40- or 64-digit Git revision. */
6
+ checkoutRevision: string;
7
+ /** SHA-256 of the complete source/config snapshot, including dirty changes. */
8
+ sourceDigest: string;
9
+ /** SHA-256 of the runner/project/config/instrumentation scope. */
10
+ scopeDigest: string;
11
+ }
12
+
13
+ export interface TestAuditSymbol {
14
+ file: string;
15
+ /** Exact exported/callable identity agreed upon by the producer and adapter. */
16
+ symbol: string;
17
+ }
18
+
19
+ export interface TestAuditPlanArtifact {
20
+ schemaVersion: 1;
21
+ provenance: TestAuditProvenance;
22
+ plan: TestPlan;
23
+ /** Explicit root-relative scope; must match plan.changedFiles when nonempty. */
24
+ changedFiles: string[];
25
+ /** Refines matching for these files to exact symbols rather than any file execution. */
26
+ changedSymbols: TestAuditSymbol[];
27
+ }
28
+
29
+ export interface TestAuditObservation {
30
+ /** Inventory identity; does not alone prove execution. */
31
+ testFile: string;
32
+ /** Explicit execution evidence, including the test file itself when its source was evaluated. */
33
+ executedFiles: string[];
34
+ executedSymbols: TestAuditSymbol[];
35
+ /** Complete file AND symbol tracing for the declared scope; false makes negative evidence unknown. */
36
+ traceComplete: boolean;
37
+ }
38
+
39
+ export interface TestAuditObservationsArtifact {
40
+ schemaVersion: 1;
41
+ provenance: TestAuditProvenance;
42
+ granularity: "per-test-file";
43
+ suite: "full";
44
+ /** Declares the full suite finished; does not assert instrumentation completeness. */
45
+ complete: true;
46
+ /** One merged observation per test file; aggregate suite coverage is unsupported. */
47
+ tests: TestAuditObservation[];
48
+ }
49
+
50
+ export interface TestsAuditPlanFileInput {
51
+ plan: string;
52
+ planJson?: never;
53
+ }
54
+
55
+ export interface TestsAuditPlanInlineInput {
56
+ plan?: never;
57
+ planJson: TestAuditPlanArtifact | string;
58
+ }
59
+
60
+ export interface TestsAuditObservationsFileInput {
61
+ observations: string;
62
+ observationsJson?: never;
63
+ }
64
+
65
+ export interface TestsAuditObservationsInlineInput {
66
+ observations?: never;
67
+ observationsJson: TestAuditObservationsArtifact | string;
68
+ }
69
+
70
+ export type TestsAuditPlanInput = TestsAuditPlanFileInput | TestsAuditPlanInlineInput;
71
+ export type TestsAuditObservationsInput =
72
+ | TestsAuditObservationsFileInput
73
+ | TestsAuditObservationsInlineInput;
74
+ /** Requires exactly one path or inline artifact for each input. */
75
+ export type TestsAuditOptions = TestsAuditPlanInput & TestsAuditObservationsInput;
76
+
77
+ export interface TestAuditExecutionEvidence {
78
+ testFile: string;
79
+ matchedFiles: string[];
80
+ matchedSymbols: TestAuditSymbol[];
81
+ }
82
+
83
+ export interface TestAuditSelectionEvidence {
84
+ testFile: string;
85
+ /** Original static selection reasons for investigating excess selection. */
86
+ reasons: ImpactReason[];
87
+ }
88
+
89
+ export interface TestAuditReport {
90
+ provenance: TestAuditProvenance;
91
+ observedTestFiles: number;
92
+ selectedTestFiles: number;
93
+ selectedObservedTests: TestAuditExecutionEvidence[];
94
+ missedObservedTests: TestAuditExecutionEvidence[];
95
+ selectedWithoutObservedExecution: TestAuditSelectionEvidence[];
96
+ selectedWithoutObservations: string[];
97
+ selectedWithIncompleteTraces: string[];
98
+ /** Always explains the limits of observed execution and caller-recorded provenance. */
99
+ limitations: string[];
100
+ }
package/test-types.d.ts CHANGED
@@ -1,5 +1,14 @@
1
1
  import type { SymbolEntrypoint } from "./traversal-types";
2
2
 
3
+ /** A named project under `.no-mistakes.yml` `tests.vitest.projects`. */
4
+ export interface VitestProjectPolicy {
5
+ include?: string[];
6
+ exclude?: string[];
7
+ /** Repository-root-relative setup modules for this project's matched tests. */
8
+ setup_files?: string[];
9
+ integration_suites?: Record<string, string[]>;
10
+ }
11
+
3
12
  /** Runner accepted by `testsPlan`, `testsTargets`, and `TestExecutionTarget`. */
4
13
  export type TestPlanFramework =
5
14
  | "vitest"
@@ -205,4 +205,6 @@ export interface ProjectOptions {
205
205
  export interface CheckOptions extends ProjectOptions {
206
206
  /** Add deterministic accounting for findings hidden by no-mistakes directives. */
207
207
  includeSuppressed?: boolean;
208
+ /** Add declared config evidence; absent slots never imply SDK defaults. */
209
+ includeRunnerConfigDeadlines?: boolean;
208
210
  }
package/types.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from "./analyze-project-types";
4
4
  export * from "./flow-types";
5
5
  export * from "./import-usage-types";
6
6
  export * from "./test-types";
7
+ export * from "./test-audit-types";
7
8
  export * from "./report-types";
8
9
  export * from "./server-contract-types";
9
10
  export * from "./ci-types";
@@ -14,3 +15,4 @@ export * from "./mermaid-types";
14
15
  export * from "./resolve-config-types";
15
16
  export * from "./postgres-query-annotation-types";
16
17
  export * from "./planning-impact-artifacts-types";
18
+ export * from "./declared-payload-types";