@jjchill/probity-rules 0.1.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/CHANGELOG.md +18 -0
- package/GLOSSARY.template.md +33 -0
- package/README.md +96 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/presets/js.d.ts +63 -0
- package/dist/presets/js.d.ts.map +1 -0
- package/dist/presets/js.js +112 -0
- package/dist/presets/js.js.map +1 -0
- package/dist/presets/kmp.d.ts +27 -0
- package/dist/presets/kmp.d.ts.map +1 -0
- package/dist/presets/kmp.js +253 -0
- package/dist/presets/kmp.js.map +1 -0
- package/dist/presets/kotlin.d.ts +40 -0
- package/dist/presets/kotlin.d.ts.map +1 -0
- package/dist/presets/kotlin.js +172 -0
- package/dist/presets/kotlin.js.map +1 -0
- package/dist/presets/swift.d.ts +10 -0
- package/dist/presets/swift.d.ts.map +1 -0
- package/dist/presets/swift.js +285 -0
- package/dist/presets/swift.js.map +1 -0
- package/dist/rules/acceptance-language.d.ts +95 -0
- package/dist/rules/acceptance-language.d.ts.map +1 -0
- package/dist/rules/acceptance-language.js +443 -0
- package/dist/rules/acceptance-language.js.map +1 -0
- package/dist/rules/gates.d.ts +125 -0
- package/dist/rules/gates.d.ts.map +1 -0
- package/dist/rules/gates.js +285 -0
- package/dist/rules/gates.js.map +1 -0
- package/dist/rules/kotlin.d.ts +323 -0
- package/dist/rules/kotlin.d.ts.map +1 -0
- package/dist/rules/kotlin.js +722 -0
- package/dist/rules/kotlin.js.map +1 -0
- package/dist/rules/ports-and-adapters.d.ts +86 -0
- package/dist/rules/ports-and-adapters.d.ts.map +1 -0
- package/dist/rules/ports-and-adapters.js +366 -0
- package/dist/rules/ports-and-adapters.js.map +1 -0
- package/dist/rules/scoping.d.ts +68 -0
- package/dist/rules/scoping.d.ts.map +1 -0
- package/dist/rules/scoping.js +93 -0
- package/dist/rules/scoping.js.map +1 -0
- package/dist/rules/spec-test-parity.d.ts +164 -0
- package/dist/rules/spec-test-parity.d.ts.map +1 -0
- package/dist/rules/spec-test-parity.js +456 -0
- package/dist/rules/spec-test-parity.js.map +1 -0
- package/dist/rules/swift.d.ts +50 -0
- package/dist/rules/swift.d.ts.map +1 -0
- package/dist/rules/swift.js +50 -0
- package/dist/rules/swift.js.map +1 -0
- package/dist/rules/ubiquitous-language.d.ts +36 -0
- package/dist/rules/ubiquitous-language.d.ts.map +1 -0
- package/dist/rules/ubiquitous-language.js +140 -0
- package/dist/rules/ubiquitous-language.js.map +1 -0
- package/dist/scripts/scope-report.d.ts +3 -0
- package/dist/scripts/scope-report.d.ts.map +1 -0
- package/dist/scripts/scope-report.js +184 -0
- package/dist/scripts/scope-report.js.map +1 -0
- package/kiro/README.md +20 -0
- package/kiro/kiro-agent.template.json +45 -0
- package/kiro/kiro-transcript-to-claude.py +183 -0
- package/kiro/probity-kiro-translate.py +132 -0
- package/kiro/probity-kiro.sh +87 -0
- package/kiro/skill-activation-forced-eval.sh +45 -0
- package/package.json +68 -0
- package/probity.config.kmp.ts +40 -0
- package/probity.config.kotlin.ts +37 -0
- package/probity.config.swift.ts +38 -0
- package/probity.config.ts +43 -0
- package/scripts/spec-parity.mjs +345 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import picomatch from 'picomatch';
|
|
2
|
+
/**
|
|
3
|
+
* Replica of Probity's glob-scoping internals, for the tooling in
|
|
4
|
+
* this template set — the workflow eval and `scripts/scope-report.ts`
|
|
5
|
+
* — which must resolve `{ files, rules }` blocks exactly the way the
|
|
6
|
+
* real engine does. Hand-mirrored scoping predicates were the eval's
|
|
7
|
+
* main blind spot: a template glob edit could silently diverge from
|
|
8
|
+
* what the eval exercised.
|
|
9
|
+
*
|
|
10
|
+
* Probity implements these in `src/rules/utils/match-paths.ts`
|
|
11
|
+
* (`buildMatcher`, `actionMatchesFilesScope`) and `src/config.ts`
|
|
12
|
+
* (`anchorGlob` inside `loadConfig`), but its package `exports` map
|
|
13
|
+
* (".", "./types", "./rules") does not expose them, so they are
|
|
14
|
+
* ported here verbatim — same picomatch options, same anchoring
|
|
15
|
+
* convention. Pinned against @nizos/probity 1.10.0: on a Probity
|
|
16
|
+
* upgrade, diff this file against those two sources; if upstream
|
|
17
|
+
* starts exporting them, delete this file and import instead.
|
|
18
|
+
*
|
|
19
|
+
* picomatch is Probity's own matcher dependency, so the same version
|
|
20
|
+
* resolves here in any project with @nizos/probity installed; if your
|
|
21
|
+
* package manager doesn't hoist it, add it: `npm install -D picomatch`.
|
|
22
|
+
*/
|
|
23
|
+
/** A `Config.rules` entry that carries a `files` scope. */
|
|
24
|
+
export function isRuleBlock(entry) {
|
|
25
|
+
return typeof entry !== 'function';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Builds a path matcher from include/exclude patterns. Patterns
|
|
29
|
+
* prefixed with `!` are negations (picomatch's `ignore` option);
|
|
30
|
+
* everything else is an include. An all-negations list gets `**` as
|
|
31
|
+
* the default include. `dot: true` so `*`/`**` traverse dot-prefixed
|
|
32
|
+
* segments — without it a scoped rule silently skips dotfiles.
|
|
33
|
+
*
|
|
34
|
+
* Port of @nizos/probity `src/rules/utils/match-paths.ts#buildMatcher`.
|
|
35
|
+
*/
|
|
36
|
+
export function buildMatcher(patterns) {
|
|
37
|
+
if (patterns.length === 0)
|
|
38
|
+
return () => false;
|
|
39
|
+
const includes = patterns.filter((p) => !p.startsWith('!'));
|
|
40
|
+
const ignore = patterns
|
|
41
|
+
.filter((p) => p.startsWith('!'))
|
|
42
|
+
.map((p) => p.slice(1));
|
|
43
|
+
const matcher = picomatch(includes.length ? [...includes] : '**', {
|
|
44
|
+
dot: true,
|
|
45
|
+
ignore,
|
|
46
|
+
});
|
|
47
|
+
return (path) => matcher(path);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether a `{ files, rules }` block applies to an action. Empty
|
|
51
|
+
* `files` matches nothing; non-write actions (commands) pass the
|
|
52
|
+
* block-level filter and rules self-filter by action kind; write
|
|
53
|
+
* actions are matched against `files`.
|
|
54
|
+
*
|
|
55
|
+
* Port of @nizos/probity
|
|
56
|
+
* `src/rules/utils/match-paths.ts#actionMatchesFilesScope`.
|
|
57
|
+
*/
|
|
58
|
+
export function actionMatchesFilesScope(files, action) {
|
|
59
|
+
if (files.length === 0)
|
|
60
|
+
return false;
|
|
61
|
+
if (action.kind !== 'write')
|
|
62
|
+
return true;
|
|
63
|
+
return buildMatcher(files)(action.path);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* `**`-prefixed globs are intentional "match anywhere" patterns;
|
|
67
|
+
* anchoring them at the config dir would defeat the user's intent.
|
|
68
|
+
* Negations carry the same convention through the `!` prefix.
|
|
69
|
+
*
|
|
70
|
+
* Port of @nizos/probity `src/config.ts#anchorGlob`.
|
|
71
|
+
*/
|
|
72
|
+
export function anchorGlob(glob, root) {
|
|
73
|
+
if (glob.startsWith('!'))
|
|
74
|
+
return '!' + anchorGlob(glob.slice(1), root);
|
|
75
|
+
if (glob.startsWith('**'))
|
|
76
|
+
return glob;
|
|
77
|
+
return `${root.replace(/\\/g, '/').replace(/\/$/, '')}/${glob}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Anchors every block's relative globs against `root`, the way
|
|
81
|
+
* Probity's `loadConfig` anchors them against the config file's
|
|
82
|
+
* directory — so paths in `Action.path` (absolute POSIX) match
|
|
83
|
+
* regardless of where the session is rooted. Flat rules pass through.
|
|
84
|
+
*/
|
|
85
|
+
export function anchorEntries(entries, root) {
|
|
86
|
+
return entries.map((entry) => {
|
|
87
|
+
if (!isRuleBlock(entry) || !entry.files)
|
|
88
|
+
return entry;
|
|
89
|
+
const [first, ...rest] = entry.files.map((glob) => anchorGlob(glob, root));
|
|
90
|
+
return { ...entry, files: [first, ...rest] };
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=scoping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoping.js","sourceRoot":"","sources":["../../rules/scoping.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAA;AAIjC;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,2DAA2D;AAC3D,MAAM,UAAU,WAAW,CAAC,KAAgB;IAC1C,OAAO,OAAO,KAAK,KAAK,UAAU,CAAA;AACpC,CAAC;AAWD;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC1B,QAA2B;IAE3B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,EAAE,CAAC,KAAK,CAAA;IAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IAC3D,MAAM,MAAM,GAAG,QAAQ;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAChE,GAAG,EAAE,IAAI;QACT,MAAM;KACP,CAAC,CAAA;IACF,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAChC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAwB,EACxB,MAAc;IAEd,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACpC,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAA;IACxC,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AACzC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,IAAY;IACnD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IACtE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACtC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE,CAAA;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,OAA6B,EAC7B,IAAY;IAEZ,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK;YAAE,OAAO,KAAK,CAAA;QACrD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;QAC1E,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,KAAM,EAAE,GAAG,IAAI,CAAU,EAAE,CAAA;IACxD,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import type { Rule } from '@nizos/probity';
|
|
2
|
+
type Scenario = {
|
|
3
|
+
key: string;
|
|
4
|
+
specFile: string;
|
|
5
|
+
title: string;
|
|
6
|
+
wip: boolean;
|
|
7
|
+
/** Driver scopes the heading declares, e.g. `[system]` → ['system']. */
|
|
8
|
+
scopes: string[];
|
|
9
|
+
};
|
|
10
|
+
type CoversRef = {
|
|
11
|
+
key: string;
|
|
12
|
+
testFile: string;
|
|
13
|
+
specFile: string;
|
|
14
|
+
title: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function extractScenarios(specFile: string, content: string): Scenario[];
|
|
17
|
+
export declare function extractCoversRefs(testFile: string, content: string): CoversRef[];
|
|
18
|
+
/**
|
|
19
|
+
* A named driver scope: which test files count as coverage from a
|
|
20
|
+
* given driver suite. Scope names are the vocabulary scenario
|
|
21
|
+
* headings may use in `[scope, ...]` tags — lowercase by convention
|
|
22
|
+
* (tags are lowercased before matching).
|
|
23
|
+
*/
|
|
24
|
+
export type DriverScope = {
|
|
25
|
+
name: string;
|
|
26
|
+
filePattern: RegExp;
|
|
27
|
+
};
|
|
28
|
+
type ScanOptions = {
|
|
29
|
+
specsDir: string;
|
|
30
|
+
testRoots: string[];
|
|
31
|
+
testFilePattern?: RegExp;
|
|
32
|
+
/**
|
|
33
|
+
* Per-scenario driver mapping (optional). Each entry names a driver
|
|
34
|
+
* suite and the test files that belong to it (e.g.
|
|
35
|
+
* `{ name: 'system', filePattern: /AcceptanceTests[/\\]UITests[/\\]/ }`).
|
|
36
|
+
* A scenario tagged `## Scenario [system]:` must then be covered by
|
|
37
|
+
* at least one test matching that scope's pattern — **in addition
|
|
38
|
+
* to** the base requirement that some acceptance test covers it.
|
|
39
|
+
* Tags are floors, never ceilings: extra coverage in other scopes
|
|
40
|
+
* is always fine, and untagged scenarios only need `defaultScopes`
|
|
41
|
+
* (below) plus the base requirement. A tag naming a scope absent
|
|
42
|
+
* from this list is a violation (misspelling protection); with no
|
|
43
|
+
* `driverScopes` configured, any tag is unknown, so adopting tags
|
|
44
|
+
* requires configuring scopes first.
|
|
45
|
+
*/
|
|
46
|
+
driverScopes?: DriverScope[];
|
|
47
|
+
/**
|
|
48
|
+
* Scope names every non-wip, non-baselined scenario must satisfy
|
|
49
|
+
* even without a tag — the project's standard driver set (e.g.
|
|
50
|
+
* `['view-model']`). Names must exist in `driverScopes`. Omit for
|
|
51
|
+
* the status-quo default: untagged scenarios need any one covering
|
|
52
|
+
* test, regardless of driver.
|
|
53
|
+
*/
|
|
54
|
+
defaultScopes?: string[];
|
|
55
|
+
/**
|
|
56
|
+
* Incremental-adoption baseline (optional). Path to a text file of
|
|
57
|
+
* scenario keys — one `<spec>.feature.md :: <title>` per line, `#`
|
|
58
|
+
* comments allowed — that are exempt from the orphan check. Use it
|
|
59
|
+
* to adopt the parity gate on a brownfield spec suite: generate the
|
|
60
|
+
* baseline once (`spec-parity.mjs --baseline <path> --write-baseline`),
|
|
61
|
+
* commit it, and from then on only scenarios *not* in the baseline
|
|
62
|
+
* must carry a covering test — new specs are enforced from day one
|
|
63
|
+
* while the backlog burns down by deleting lines. A missing file
|
|
64
|
+
* means full enforcement (the greenfield default). Dangling Covers
|
|
65
|
+
* tags are never baselined: they are actively wrong, not legacy.
|
|
66
|
+
*/
|
|
67
|
+
baselinePath?: string;
|
|
68
|
+
};
|
|
69
|
+
/** Parses a baseline file into normalized scenario keys. Missing file → empty set. */
|
|
70
|
+
export declare function readBaseline(path: string | undefined): Set<string>;
|
|
71
|
+
/** All spec files (either extension) under a directory. */
|
|
72
|
+
export declare function findSpecFiles(specsDir: string): string[];
|
|
73
|
+
export declare function scanSpecs(specsDir: string): Scenario[];
|
|
74
|
+
export declare function scanCoversRefs(testRoots: string[], testFilePattern: RegExp): CoversRef[];
|
|
75
|
+
/**
|
|
76
|
+
* Bidirectional parity gate on `git commit`: blocks when any
|
|
77
|
+
* non-wip `## Scenario:` heading in `specsDir` has no acceptance
|
|
78
|
+
* test claiming it via a `Covers:` tag, or when any `Covers:` tag
|
|
79
|
+
* points at a scenario that no longer exists (spec renamed or
|
|
80
|
+
* removed). Deterministic filesystem scan — no AI call; milliseconds
|
|
81
|
+
* at typical spec-suite scale.
|
|
82
|
+
*
|
|
83
|
+
* The test claiming a scenario may still be red or quarantined —
|
|
84
|
+
* parity requires the *link*, not a passing run; keeping in-progress
|
|
85
|
+
* specs out of the pipeline is the pipeline's job. Alternatively
|
|
86
|
+
* mark the scenario `## Scenario (wip):` to exempt it entirely.
|
|
87
|
+
*
|
|
88
|
+
* Applies to: command actions matching `git commit`.
|
|
89
|
+
*
|
|
90
|
+
* @param options.specsDir — absolute path to the specs directory
|
|
91
|
+
* (e.g. `<root>/docs/specs`). A missing directory passes: no
|
|
92
|
+
* specs, nothing to enforce.
|
|
93
|
+
* @param options.testRoots — absolute paths to scan for acceptance
|
|
94
|
+
* tests (the repo root is fine; node_modules/build dirs are
|
|
95
|
+
* skipped).
|
|
96
|
+
* @param options.testFilePattern — which files count as acceptance
|
|
97
|
+
* tests (default: any file under an `acceptance/` directory).
|
|
98
|
+
* @param options.baselinePath — optional incremental-adoption
|
|
99
|
+
* baseline; scenarios listed there are exempt from the orphan
|
|
100
|
+
* check (see {@link readBaseline}). Missing file → full enforcement.
|
|
101
|
+
* @param options.driverScopes — optional per-scenario driver mapping;
|
|
102
|
+
* see {@link DriverScope}. Scenarios tagged `[scope]` (and every
|
|
103
|
+
* scenario, for `defaultScopes` entries) must be covered by a test
|
|
104
|
+
* matching that scope's `filePattern`, on top of the base check.
|
|
105
|
+
* @param options.defaultScopes — scope names required of untagged
|
|
106
|
+
* scenarios too (the project's standard driver set).
|
|
107
|
+
*/
|
|
108
|
+
export declare function enforceSpecTestParity(options: ScanOptions): Rule;
|
|
109
|
+
/**
|
|
110
|
+
* Spec-first, made mechanical: a write that adds a new acceptance
|
|
111
|
+
* test case is blocked unless it also adds a `Covers:` tag pointing
|
|
112
|
+
* at a `## Scenario:` heading that ALREADY EXISTS in `specsDir`. The
|
|
113
|
+
* executable specification (`*.feature.md`) must be written before
|
|
114
|
+
* the test that claims it — an agent that codes the test first gets
|
|
115
|
+
* told exactly what to create and where.
|
|
116
|
+
*
|
|
117
|
+
* This is the write-time front half of the traceability story;
|
|
118
|
+
* {@link enforceSpecTestParity} is the commit-time back half (every
|
|
119
|
+
* scenario covered, every tag resolving). Together they close the
|
|
120
|
+
* gap where an agent authors a whole acceptance suite with no
|
|
121
|
+
* feature file and nothing objects until commit — or ever, if the
|
|
122
|
+
* tests carry no tags at all.
|
|
123
|
+
*
|
|
124
|
+
* Delta-based and deterministic (no AI call): only NEW test cases
|
|
125
|
+
* demand a NEW resolving tag, so edits inside an existing brownfield
|
|
126
|
+
* test file pass untouched, and a pre-existing dangling tag can't
|
|
127
|
+
* block unrelated work (the commit gate owns that). `(wip)` and
|
|
128
|
+
* `(planned)` scenarios count as existing — they are exactly the
|
|
129
|
+
* headings outside-in work drives against.
|
|
130
|
+
*
|
|
131
|
+
* Applies to: write actions — scope it via a `{ files, rules }`
|
|
132
|
+
* block to the acceptance test-case layer only (e.g.
|
|
133
|
+
* `**\/acceptance/**\/*Spec.kt`), never to drivers/DSL/infrastructure.
|
|
134
|
+
*
|
|
135
|
+
* @param options.specsDir — absolute path to the specs directory.
|
|
136
|
+
* Missing directory ⇒ every new tag is unresolved ⇒ the deny
|
|
137
|
+
* message says to create the first feature file (greenfield
|
|
138
|
+
* enforcement, not a free pass).
|
|
139
|
+
* @param options.testDeclarationPattern — what counts as a test-case
|
|
140
|
+
* declaration (default: Kotlin/Java `@Test` or Swift `func test…`).
|
|
141
|
+
*/
|
|
142
|
+
export declare function requireSpecBackedAcceptanceTest(options: {
|
|
143
|
+
specsDir: string;
|
|
144
|
+
testDeclarationPattern?: RegExp;
|
|
145
|
+
}): Rule;
|
|
146
|
+
/**
|
|
147
|
+
* Surfaces link breakage at the moment it is created: when a write
|
|
148
|
+
* to a `*.feature.md` file removes or renames a `## Scenario:`
|
|
149
|
+
* heading that acceptance tests still claim, the write is blocked
|
|
150
|
+
* with the list of affected tests — update their `Covers:` tags (or
|
|
151
|
+
* delete the tests) in the same change, then re-apply the spec edit.
|
|
152
|
+
* Removing a scenario nothing covers passes silently.
|
|
153
|
+
*
|
|
154
|
+
* Applies to: write actions to `*.feature.md` files (scope via a
|
|
155
|
+
* `{ files, rules }` block). Deterministic — no AI call.
|
|
156
|
+
*
|
|
157
|
+
* @param options.testRoots — absolute paths to scan for acceptance
|
|
158
|
+
* tests.
|
|
159
|
+
* @param options.testFilePattern — which files count as acceptance
|
|
160
|
+
* tests (default: any file under an `acceptance/` directory).
|
|
161
|
+
*/
|
|
162
|
+
export declare function surfaceScenarioLinkBreakage(options: Omit<ScanOptions, 'specsDir'>): Rule;
|
|
163
|
+
export {};
|
|
164
|
+
//# sourceMappingURL=spec-test-parity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-test-parity.d.ts","sourceRoot":"","sources":["../../rules/spec-test-parity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAU,IAAI,EAA2B,MAAM,gBAAgB,CAAA;AAuE3E,KAAK,QAAQ,GAAG;IACd,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,OAAO,CAAA;IACZ,wEAAwE;IACxE,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AACD,KAAK,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAUnF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CA6C9E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAahF;AAqBD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/D,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,WAAW,EAAE,CAAA;IAC5B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,sFAAsF;AACtF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAelE;AAED,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAIxD;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE,CAItD;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EAAE,EACnB,eAAe,EAAE,MAAM,GACtB,SAAS,EAAE,CAUb;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAyGhE;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE;IACvD,QAAQ,EAAE,MAAM,CAAA;IAChB,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC,GAAG,IAAI,CAqDP;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,GACrC,IAAI,CAyCN"}
|