@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 @@
|
|
|
1
|
+
{"version":3,"file":"kotlin.js","sourceRoot":"","sources":["../../rules/kotlin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { Rule } from '@nizos/probity';
|
|
2
|
+
/**
|
|
3
|
+
* AI-validated enforcement of the `ports-and-adapters` skill: the
|
|
4
|
+
* Dependency Rule (core imports nothing from adapters, frameworks,
|
|
5
|
+
* vendors, or OS I/O), thin adapters (no business conditionals), and
|
|
6
|
+
* ports as the only test seam.
|
|
7
|
+
*
|
|
8
|
+
* Applies to: write actions. Scope it with a `{ files, rules }` block
|
|
9
|
+
* to the code you care about — every matching write costs an AI call.
|
|
10
|
+
* Pair it with `forbidContentPattern` blocks for known-bad imports so
|
|
11
|
+
* the obvious violations are caught deterministically and free.
|
|
12
|
+
*
|
|
13
|
+
* @param options.instructions — overrides or extends the default
|
|
14
|
+
* boundary rules text. Pass a string to replace it, or a function
|
|
15
|
+
* `(defaults) => ...` to extend it (e.g. name your project's core
|
|
16
|
+
* and adapter directories so the validator infers roles precisely).
|
|
17
|
+
* @param options.glossaryPath — absolute path to the project's
|
|
18
|
+
* ubiquitous-language glossary. When set and readable, the
|
|
19
|
+
* glossary is included in the validator's prompt and port/domain
|
|
20
|
+
* names that conflict with recorded terms become violations.
|
|
21
|
+
* @param options.maxGlossaryChars — truncate the glossary beyond
|
|
22
|
+
* this length when building the prompt (default 8000).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* { files: ['src/core/**', 'src/domain/**'], rules: [enforcePortsBoundary()] }
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* enforcePortsBoundary({
|
|
29
|
+
* instructions: (defaults) =>
|
|
30
|
+
* `${defaults}\n\n### Project layout\n\nCore lives in src/core; adapters in src/infra.`,
|
|
31
|
+
* })
|
|
32
|
+
*/
|
|
33
|
+
export declare function enforcePortsBoundary(options?: {
|
|
34
|
+
instructions?: string | ((defaults: string) => string);
|
|
35
|
+
glossaryPath?: string;
|
|
36
|
+
maxGlossaryChars?: number;
|
|
37
|
+
}): Rule;
|
|
38
|
+
/**
|
|
39
|
+
* AI-validated companion to `enforcePortsBoundary`, judging the
|
|
40
|
+
* opposite concern: adapters must be thin, but not blind. A new
|
|
41
|
+
* adapter code path performing external I/O with no boundary
|
|
42
|
+
* observability — no structured event, no tap/recording decorator, no
|
|
43
|
+
* span — is blocked; pure mappers, wiring, tests, and untouched
|
|
44
|
+
* legacy paths pass (delta-based).
|
|
45
|
+
*
|
|
46
|
+
* Applies to: write actions. Scope it to adapter paths only (e.g.
|
|
47
|
+
* `**\/adapter\/**`, `**\/infra\/**`) — every matching write costs an
|
|
48
|
+
* AI call.
|
|
49
|
+
*
|
|
50
|
+
* @param options.conventionHint — appended to the validator prompt to
|
|
51
|
+
* name the project's telemetry/tap convention (e.g. "structured
|
|
52
|
+
* Logger.event(tag, event, fields); port taps wired in the demo
|
|
53
|
+
* flavor's Koin module"), so the verdict and its fix suggestion
|
|
54
|
+
* speak the project's language.
|
|
55
|
+
* @param options.instructions — replaces or extends the default rules
|
|
56
|
+
* text (string, or `(defaults) => ...`).
|
|
57
|
+
*/
|
|
58
|
+
export declare function enforceAdapterObservability(options?: {
|
|
59
|
+
conventionHint?: string;
|
|
60
|
+
instructions?: string | ((defaults: string) => string);
|
|
61
|
+
}): Rule;
|
|
62
|
+
/**
|
|
63
|
+
* Deterministic companion to `enforcePortsBoundary`: blocks test
|
|
64
|
+
* writes that introduce `jest.mock()` / `vi.mock()` calls with a
|
|
65
|
+
* relative specifier — mocking the team's own modules instead of
|
|
66
|
+
* substituting a fake at a port ("Ports Are the Only Test Seam").
|
|
67
|
+
*
|
|
68
|
+
* Only newly introduced mocks are blocked: a specifier already mocked
|
|
69
|
+
* in the file on disk doesn't re-trigger on later edits, so existing
|
|
70
|
+
* suites can be migrated incrementally. Mocks of bare (package)
|
|
71
|
+
* specifiers are ignored — vendor modules are the adapter's problem,
|
|
72
|
+
* and adapter tests may legitimately isolate them.
|
|
73
|
+
*
|
|
74
|
+
* Applies to: write actions. No AI call; free to run broadly.
|
|
75
|
+
*
|
|
76
|
+
* @param options.allow — specifier pattern(s) exempt from the rule
|
|
77
|
+
* (literal substring or RegExp against the mocked path), e.g. a
|
|
78
|
+
* sanctioned test-helper module.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* { files: ['**\/*.test.*', '**\/*.spec.*'], rules: [forbidInternalModuleMocks()] }
|
|
82
|
+
*/
|
|
83
|
+
export declare function forbidInternalModuleMocks(options?: {
|
|
84
|
+
allow?: string | RegExp;
|
|
85
|
+
}): Rule;
|
|
86
|
+
//# sourceMappingURL=ports-and-adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports-and-adapters.d.ts","sourceRoot":"","sources":["../../rules/ports-and-adapters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,IAAI,EAA2B,MAAM,gBAAgB,CAAA;AAmJ3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,CAAA;IACtD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACrB,GACL,IAAI,CAuCN;AA6DD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,GAAE;IACP,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,CAAA;CAClD,GACL,IAAI,CAoCN;AAcD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAO,GACxC,IAAI,CAkCN"}
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
// reason comes FIRST in the shape: an autoregressive model commits to
|
|
2
|
+
// each field in order, so kind-first forces the verdict before the
|
|
3
|
+
// analysis — observed live producing a "violation" whose reason
|
|
4
|
+
// reasoned its way to "Passing." Reason-first lets the model conclude,
|
|
5
|
+
// then label.
|
|
6
|
+
const RESPONSE_SPEC = `## Response format
|
|
7
|
+
|
|
8
|
+
Respond with a single JSON object of exactly this shape:
|
|
9
|
+
{"reason":"<your analysis>","kind":"pass"|"violation"}
|
|
10
|
+
Write reason FIRST and set kind to the conclusion your reason reached —
|
|
11
|
+
the two must agree. Keep reason brief on a clear pass ("" is fine).
|
|
12
|
+
Return JSON only. No prose, no code fences.`;
|
|
13
|
+
const PROCESS_INSTRUCTIONS = `## Role
|
|
14
|
+
|
|
15
|
+
You are an architecture-boundary validator. Judge whether the pending
|
|
16
|
+
write respects the ports-and-adapters (hexagonal) rules below.
|
|
17
|
+
|
|
18
|
+
## Inputs
|
|
19
|
+
|
|
20
|
+
You will see two or three inputs:
|
|
21
|
+
|
|
22
|
+
1. "Current file content" — what's on disk right now at the file the
|
|
23
|
+
agent is about to write. May be a parenthesized marker (e.g.
|
|
24
|
+
\`(file does not exist)\`).
|
|
25
|
+
2. "Pending action" — the file path and what the agent is about to
|
|
26
|
+
write. Content may be raw file text or a patch/diff.
|
|
27
|
+
|
|
28
|
+
## What you judge
|
|
29
|
+
|
|
30
|
+
Judge the change this write makes (the difference between the current
|
|
31
|
+
file content and the pending action), not the resulting file as a
|
|
32
|
+
whole. Infer the file's architectural role — core/domain, inbound or
|
|
33
|
+
outbound adapter, composition root, or test — from its path and
|
|
34
|
+
content.
|
|
35
|
+
|
|
36
|
+
A transient file state is never itself a violation: an unresolved
|
|
37
|
+
symbol, a dead definition, a half-finished multi-step change. Whether
|
|
38
|
+
the file compiles or runs is checked by the test suite, not by you.
|
|
39
|
+
|
|
40
|
+
A block recorded earlier in the session is a past verdict, not a rule.
|
|
41
|
+
Re-derive your judgment from the rules below. When the user tells you
|
|
42
|
+
in the session to let this change through, treat it as authoritative
|
|
43
|
+
and pass.
|
|
44
|
+
|
|
45
|
+
The bar for blocking is a clear violation of a rule below. Boundary
|
|
46
|
+
placement often involves judgment the agent can defend (composition
|
|
47
|
+
roots wire vendors by design; pure computation libraries need no
|
|
48
|
+
port); when the call is genuinely ambiguous, pass.`;
|
|
49
|
+
const DEFAULT_BOUNDARY_RULES = `## Ports-and-adapters rules
|
|
50
|
+
|
|
51
|
+
The strict rule of this codebase: **an adapter is required for every
|
|
52
|
+
dependency the team doesn't own, and every dependency that isn't
|
|
53
|
+
deployed and released together with this code** — UI toolkits, web and
|
|
54
|
+
application frameworks, databases, third-party APIs and SDKs, message
|
|
55
|
+
brokers, other teams' services, and the operating system itself
|
|
56
|
+
(clock, filesystem, environment, randomness, network).
|
|
57
|
+
|
|
58
|
+
### The Dependency Rule (core code)
|
|
59
|
+
|
|
60
|
+
Core/domain/use-case code depends only on ports: interfaces the team
|
|
61
|
+
defines, named in the language of the domain, shaped by what the core
|
|
62
|
+
needs.
|
|
63
|
+
|
|
64
|
+
- Core files import NOTHING from adapters, frameworks, vendor SDKs,
|
|
65
|
+
ORMs, or OS I/O modules. \`new Date()\`, \`Date.now()\`,
|
|
66
|
+
\`Math.random()\`, \`process.env\`, filesystem or network access in
|
|
67
|
+
core code are violations — clock, config, randomness, and storage
|
|
68
|
+
are ports.
|
|
69
|
+
- Port signatures use core types only. A vendor type (a Stripe
|
|
70
|
+
object, an ORM entity, an HTTP request/response) appearing in a
|
|
71
|
+
port is a leaked boundary.
|
|
72
|
+
- A module in the same repo and the same deployable unit needs no
|
|
73
|
+
port; a dependency owned by another team or released on its own
|
|
74
|
+
schedule does, even when "it's internal".
|
|
75
|
+
|
|
76
|
+
### Adapters must be thin
|
|
77
|
+
|
|
78
|
+
An adapter's only job is translation: port call → vendor call, vendor
|
|
79
|
+
result/error → core type. An adapter contains no conditional that
|
|
80
|
+
expresses a business rule. Mapping a vendor error code to a domain
|
|
81
|
+
error is translation; deciding what to do about it is core logic.
|
|
82
|
+
Retry policies, fallback decisions, caching rules, and validation
|
|
83
|
+
belong in the core behind the port — block adapter writes that add
|
|
84
|
+
them. Inbound adapters are equally thin: a route handler parses, calls
|
|
85
|
+
one use-case port, serializes the result.
|
|
86
|
+
|
|
87
|
+
### Ports are the only test seam
|
|
88
|
+
|
|
89
|
+
Test doubles are substituted at ports and nowhere else. Block test
|
|
90
|
+
writes that introduce module-mocking of the team's own code
|
|
91
|
+
(\`jest.mock('./our-module')\`, \`vi.mock('../internal')\`),
|
|
92
|
+
monkey-patching, or spying on internals — the substitute belongs at a
|
|
93
|
+
port, as an in-memory fake. Faking at a port (an \`InMemoryOrderStore\`
|
|
94
|
+
implementing the \`OrderStore\` port, a controlled \`Clock\`) is the
|
|
95
|
+
intended pattern and always passes.
|
|
96
|
+
|
|
97
|
+
### Always allowed
|
|
98
|
+
|
|
99
|
+
- Composition roots and factory/wiring modules importing both core
|
|
100
|
+
and adapters to assemble the system.
|
|
101
|
+
- Adapter files importing their own vendor (that is their job).
|
|
102
|
+
- Deleting code. Renames and moves that don't change dependencies.
|
|
103
|
+
- Pure computation libraries with no external effects used directly.`;
|
|
104
|
+
const GLOSSARY_RULES = `### Ubiquitous language
|
|
105
|
+
|
|
106
|
+
A glossary is provided below. Ports, domain types, use cases, and
|
|
107
|
+
their members name domain concepts with the glossary's terms
|
|
108
|
+
verbatim — one term per concept. Naming a recorded concept with a
|
|
109
|
+
synonym or conflicting term is a violation; a concept the glossary
|
|
110
|
+
does not cover is not a violation by itself.`;
|
|
111
|
+
function formatBefore(before) {
|
|
112
|
+
switch (before.kind) {
|
|
113
|
+
case 'present':
|
|
114
|
+
return before.content;
|
|
115
|
+
case 'absent':
|
|
116
|
+
return '(file does not exist)';
|
|
117
|
+
case 'unknown':
|
|
118
|
+
return '(current file content unavailable)';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function buildPrompt(rules, glossary, before, action) {
|
|
122
|
+
const sections = [PROCESS_INSTRUCTIONS, rules];
|
|
123
|
+
if (glossary) {
|
|
124
|
+
sections.push(GLOSSARY_RULES, `## Glossary\n\n${glossary}`);
|
|
125
|
+
}
|
|
126
|
+
sections.push(`## Current file content\n\n${formatBefore(before)}`, `## Pending action\n\nFile: ${action.path}\n\n${action.content}`, RESPONSE_SPEC);
|
|
127
|
+
return sections.join('\n\n');
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* AI-validated enforcement of the `ports-and-adapters` skill: the
|
|
131
|
+
* Dependency Rule (core imports nothing from adapters, frameworks,
|
|
132
|
+
* vendors, or OS I/O), thin adapters (no business conditionals), and
|
|
133
|
+
* ports as the only test seam.
|
|
134
|
+
*
|
|
135
|
+
* Applies to: write actions. Scope it with a `{ files, rules }` block
|
|
136
|
+
* to the code you care about — every matching write costs an AI call.
|
|
137
|
+
* Pair it with `forbidContentPattern` blocks for known-bad imports so
|
|
138
|
+
* the obvious violations are caught deterministically and free.
|
|
139
|
+
*
|
|
140
|
+
* @param options.instructions — overrides or extends the default
|
|
141
|
+
* boundary rules text. Pass a string to replace it, or a function
|
|
142
|
+
* `(defaults) => ...` to extend it (e.g. name your project's core
|
|
143
|
+
* and adapter directories so the validator infers roles precisely).
|
|
144
|
+
* @param options.glossaryPath — absolute path to the project's
|
|
145
|
+
* ubiquitous-language glossary. When set and readable, the
|
|
146
|
+
* glossary is included in the validator's prompt and port/domain
|
|
147
|
+
* names that conflict with recorded terms become violations.
|
|
148
|
+
* @param options.maxGlossaryChars — truncate the glossary beyond
|
|
149
|
+
* this length when building the prompt (default 8000).
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* { files: ['src/core/**', 'src/domain/**'], rules: [enforcePortsBoundary()] }
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* enforcePortsBoundary({
|
|
156
|
+
* instructions: (defaults) =>
|
|
157
|
+
* `${defaults}\n\n### Project layout\n\nCore lives in src/core; adapters in src/infra.`,
|
|
158
|
+
* })
|
|
159
|
+
*/
|
|
160
|
+
export function enforcePortsBoundary(options = {}) {
|
|
161
|
+
const rules = typeof options.instructions === 'function'
|
|
162
|
+
? options.instructions(DEFAULT_BOUNDARY_RULES)
|
|
163
|
+
: (options.instructions ?? DEFAULT_BOUNDARY_RULES);
|
|
164
|
+
const maxGlossaryChars = options.maxGlossaryChars ?? 8000;
|
|
165
|
+
return async function enforcePortsBoundary(action, ctx) {
|
|
166
|
+
if (action.kind !== 'write')
|
|
167
|
+
return { kind: 'pass' };
|
|
168
|
+
if (!ctx?.agent) {
|
|
169
|
+
return {
|
|
170
|
+
kind: 'violation',
|
|
171
|
+
reason: 'enforcePortsBoundary: no AI agent available; configure Config.ai or use a vendor that ships one.',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
let glossary;
|
|
175
|
+
if (options.glossaryPath && ctx.readFile) {
|
|
176
|
+
const file = await ctx.readFile(options.glossaryPath);
|
|
177
|
+
if (file.kind === 'present') {
|
|
178
|
+
glossary =
|
|
179
|
+
file.content.length > maxGlossaryChars
|
|
180
|
+
? `${file.content.slice(0, maxGlossaryChars)}\n(...glossary truncated...)`
|
|
181
|
+
: file.content;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const before = (await ctx.readFile?.(action.path)) ?? {
|
|
185
|
+
kind: 'unknown',
|
|
186
|
+
};
|
|
187
|
+
const verdict = await ctx.agent.reason(buildPrompt(rules, glossary, before, action));
|
|
188
|
+
if (verdict.kind === 'violation') {
|
|
189
|
+
return { kind: 'violation', reason: verdict.reason };
|
|
190
|
+
}
|
|
191
|
+
return { kind: 'pass', reason: verdict.reason };
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const ADAPTER_OBS_INSTRUCTIONS = `## Role
|
|
195
|
+
|
|
196
|
+
You are an adapter-observability validator. Adapters are the
|
|
197
|
+
integration points of this codebase, and an uninstrumented
|
|
198
|
+
integration point is undiagnosable in the field. Judge whether the
|
|
199
|
+
pending write keeps new adapter code observable, per the rules below.
|
|
200
|
+
|
|
201
|
+
## Inputs
|
|
202
|
+
|
|
203
|
+
1. "Current file content" — what's on disk right now (may be a marker
|
|
204
|
+
like \`(file does not exist)\`).
|
|
205
|
+
2. "Pending action" — the file path and what the agent is about to
|
|
206
|
+
write.
|
|
207
|
+
|
|
208
|
+
## What you judge
|
|
209
|
+
|
|
210
|
+
Judge only the change this write makes (before → after), never
|
|
211
|
+
pre-existing code. A transient state (unresolved import, half-built
|
|
212
|
+
class) is never itself a violation. A block recorded earlier in the
|
|
213
|
+
session is a past verdict, not a rule; when the user says to let a
|
|
214
|
+
change through, treat that as authoritative and pass.
|
|
215
|
+
|
|
216
|
+
## Adapter observability rules
|
|
217
|
+
|
|
218
|
+
A NEW adapter code path that performs external I/O — a network or SDK
|
|
219
|
+
call, database access, filesystem, platform service — must carry
|
|
220
|
+
boundary observability on that path: at least one structured telemetry
|
|
221
|
+
event (call made / outcome / retry, with machine-readable fields), a
|
|
222
|
+
recording tap/decorator around the port, or a span. The point: when
|
|
223
|
+
the integration misbehaves, someone can see what was sent and what
|
|
224
|
+
came back without attaching a debugger.
|
|
225
|
+
|
|
226
|
+
Always pass:
|
|
227
|
+
- Pure type mappers and translators with no external effect.
|
|
228
|
+
- Composition roots and DI wiring (including wiring a tap decorator
|
|
229
|
+
— that IS the observability).
|
|
230
|
+
- Test code and test fixtures/fakes.
|
|
231
|
+
- Edits that only touch existing uninstrumented paths without adding
|
|
232
|
+
new external calls (delta-based: legacy migrates incrementally).
|
|
233
|
+
- Files that are clearly not adapters despite the path.
|
|
234
|
+
|
|
235
|
+
Do not demand a specific API: any structured, greppable event or
|
|
236
|
+
tap/trace convention counts. Never punish redaction (omitting payload
|
|
237
|
+
fields for secrecy) — presence of an event is what matters. You judge
|
|
238
|
+
presence, not field safety: whether a logged field is itself too
|
|
239
|
+
sensitive (a uid, PII) is review's job, not yours. When genuinely
|
|
240
|
+
ambiguous, pass.
|
|
241
|
+
|
|
242
|
+
## When you block
|
|
243
|
+
|
|
244
|
+
Phrase the remediation concretely: name the exact call to add and
|
|
245
|
+
where. If a "Project convention" section is provided below, use its
|
|
246
|
+
vocabulary verbatim in the remediation (its API or tap pattern, not a
|
|
247
|
+
generic "add logging"). And remind the agent that under this
|
|
248
|
+
codebase's TDD gate, instrumentation should be ASSERTED in the failing
|
|
249
|
+
test first (a fake/recording telemetry collector) — that way the TDD
|
|
250
|
+
validator accepts the event as tested behavior instead of flagging it
|
|
251
|
+
as over-implementation.`;
|
|
252
|
+
/**
|
|
253
|
+
* AI-validated companion to `enforcePortsBoundary`, judging the
|
|
254
|
+
* opposite concern: adapters must be thin, but not blind. A new
|
|
255
|
+
* adapter code path performing external I/O with no boundary
|
|
256
|
+
* observability — no structured event, no tap/recording decorator, no
|
|
257
|
+
* span — is blocked; pure mappers, wiring, tests, and untouched
|
|
258
|
+
* legacy paths pass (delta-based).
|
|
259
|
+
*
|
|
260
|
+
* Applies to: write actions. Scope it to adapter paths only (e.g.
|
|
261
|
+
* `**\/adapter\/**`, `**\/infra\/**`) — every matching write costs an
|
|
262
|
+
* AI call.
|
|
263
|
+
*
|
|
264
|
+
* @param options.conventionHint — appended to the validator prompt to
|
|
265
|
+
* name the project's telemetry/tap convention (e.g. "structured
|
|
266
|
+
* Logger.event(tag, event, fields); port taps wired in the demo
|
|
267
|
+
* flavor's Koin module"), so the verdict and its fix suggestion
|
|
268
|
+
* speak the project's language.
|
|
269
|
+
* @param options.instructions — replaces or extends the default rules
|
|
270
|
+
* text (string, or `(defaults) => ...`).
|
|
271
|
+
*/
|
|
272
|
+
export function enforceAdapterObservability(options = {}) {
|
|
273
|
+
const base = typeof options.instructions === 'function'
|
|
274
|
+
? options.instructions(ADAPTER_OBS_INSTRUCTIONS)
|
|
275
|
+
: (options.instructions ?? ADAPTER_OBS_INSTRUCTIONS);
|
|
276
|
+
const rules = options.conventionHint
|
|
277
|
+
? `${base}\n\n### Project convention\n\n${options.conventionHint}`
|
|
278
|
+
: base;
|
|
279
|
+
return async function enforceAdapterObservability(action, ctx) {
|
|
280
|
+
if (action.kind !== 'write')
|
|
281
|
+
return { kind: 'pass' };
|
|
282
|
+
if (!ctx?.agent) {
|
|
283
|
+
return {
|
|
284
|
+
kind: 'violation',
|
|
285
|
+
reason: 'enforceAdapterObservability: no AI agent available; configure Config.ai or use a vendor that ships one.',
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
const before = (await ctx.readFile?.(action.path)) ?? {
|
|
289
|
+
kind: 'unknown',
|
|
290
|
+
};
|
|
291
|
+
const verdict = await ctx.agent.reason([
|
|
292
|
+
rules,
|
|
293
|
+
`## Current file content\n\n${formatBefore(before)}`,
|
|
294
|
+
`## Pending action\n\nFile: ${action.path}\n\n${action.content}`,
|
|
295
|
+
RESPONSE_SPEC,
|
|
296
|
+
].join('\n\n'));
|
|
297
|
+
if (verdict.kind === 'violation') {
|
|
298
|
+
return { kind: 'violation', reason: verdict.reason };
|
|
299
|
+
}
|
|
300
|
+
return { kind: 'pass', reason: verdict.reason };
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
const MODULE_MOCK_PATTERN = /\b(?:jest|vi)\.(?:mock|doMock)\(\s*(['"`])(\.\.?\/[^'"`]+)\1/g;
|
|
304
|
+
function relativeMockSpecifiers(content) {
|
|
305
|
+
const specifiers = new Set();
|
|
306
|
+
for (const match of content.matchAll(MODULE_MOCK_PATTERN)) {
|
|
307
|
+
const specifier = match[2];
|
|
308
|
+
if (specifier)
|
|
309
|
+
specifiers.add(specifier);
|
|
310
|
+
}
|
|
311
|
+
return specifiers;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Deterministic companion to `enforcePortsBoundary`: blocks test
|
|
315
|
+
* writes that introduce `jest.mock()` / `vi.mock()` calls with a
|
|
316
|
+
* relative specifier — mocking the team's own modules instead of
|
|
317
|
+
* substituting a fake at a port ("Ports Are the Only Test Seam").
|
|
318
|
+
*
|
|
319
|
+
* Only newly introduced mocks are blocked: a specifier already mocked
|
|
320
|
+
* in the file on disk doesn't re-trigger on later edits, so existing
|
|
321
|
+
* suites can be migrated incrementally. Mocks of bare (package)
|
|
322
|
+
* specifiers are ignored — vendor modules are the adapter's problem,
|
|
323
|
+
* and adapter tests may legitimately isolate them.
|
|
324
|
+
*
|
|
325
|
+
* Applies to: write actions. No AI call; free to run broadly.
|
|
326
|
+
*
|
|
327
|
+
* @param options.allow — specifier pattern(s) exempt from the rule
|
|
328
|
+
* (literal substring or RegExp against the mocked path), e.g. a
|
|
329
|
+
* sanctioned test-helper module.
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* { files: ['**\/*.test.*', '**\/*.spec.*'], rules: [forbidInternalModuleMocks()] }
|
|
333
|
+
*/
|
|
334
|
+
export function forbidInternalModuleMocks(options = {}) {
|
|
335
|
+
const allowed = (specifier) => {
|
|
336
|
+
if (options.allow === undefined)
|
|
337
|
+
return false;
|
|
338
|
+
if (typeof options.allow === 'string')
|
|
339
|
+
return specifier.includes(options.allow);
|
|
340
|
+
return options.allow.test(specifier);
|
|
341
|
+
};
|
|
342
|
+
return async function forbidInternalModuleMocks(action, ctx) {
|
|
343
|
+
if (action.kind !== 'write')
|
|
344
|
+
return { kind: 'pass' };
|
|
345
|
+
const pending = relativeMockSpecifiers(action.content);
|
|
346
|
+
if (pending.size === 0)
|
|
347
|
+
return { kind: 'pass' };
|
|
348
|
+
const before = await ctx?.readFile?.(action.path);
|
|
349
|
+
const existing = before?.kind === 'present'
|
|
350
|
+
? relativeMockSpecifiers(before.content)
|
|
351
|
+
: new Set();
|
|
352
|
+
const introduced = [...pending].filter((specifier) => !existing.has(specifier) && !allowed(specifier));
|
|
353
|
+
if (introduced.length === 0)
|
|
354
|
+
return { kind: 'pass' };
|
|
355
|
+
return {
|
|
356
|
+
kind: 'violation',
|
|
357
|
+
reason: `This write introduces module-mocking of our own code (${introduced
|
|
358
|
+
.map((s) => `'${s}'`)
|
|
359
|
+
.join(', ')}). Ports are the only test seam: substitute an ` +
|
|
360
|
+
'in-memory fake at the port the module sits behind instead of ' +
|
|
361
|
+
'mocking the module. If no port exists yet, that is the missing ' +
|
|
362
|
+
'design step — see the ports-and-adapters skill.',
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
//# sourceMappingURL=ports-and-adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports-and-adapters.js","sourceRoot":"","sources":["../../rules/ports-and-adapters.ts"],"names":[],"mappings":"AAIA,sEAAsE;AACtE,mEAAmE;AACnE,gEAAgE;AAChE,uEAAuE;AACvE,cAAc;AACd,MAAM,aAAa,GAAG;;;;;;4CAMsB,CAAA;AAE5C,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mDAmCsB,CAAA;AAEnD,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAsDwC,CAAA;AAEvE,MAAM,cAAc,GAAG;;;;;;6CAMsB,CAAA;AAE7C,SAAS,YAAY,CAAC,MAAmB;IACvC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,OAAO,CAAA;QACvB,KAAK,QAAQ;YACX,OAAO,uBAAuB,CAAA;QAChC,KAAK,SAAS;YACZ,OAAO,oCAAoC,CAAA;IAC/C,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAClB,KAAa,EACb,QAA4B,EAC5B,MAAmB,EACnB,MAAyC;IAEzC,MAAM,QAAQ,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAA;IAC9C,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,kBAAkB,QAAQ,EAAE,CAAC,CAAA;IAC7D,CAAC;IACD,QAAQ,CAAC,IAAI,CACX,8BAA8B,YAAY,CAAC,MAAM,CAAC,EAAE,EACpD,8BAA8B,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,OAAO,EAAE,EAChE,aAAa,CACd,CAAA;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAII,EAAE;IAEN,MAAM,KAAK,GACT,OAAO,OAAO,CAAC,YAAY,KAAK,UAAU;QACxC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC;QAC9C,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,IAAI,sBAAsB,CAAC,CAAA;IACtD,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAA;IACzD,OAAO,KAAK,UAAU,oBAAoB,CACxC,MAAc,EACd,GAAiB;QAEjB,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;QACpD,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;YAChB,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,MAAM,EACJ,kGAAkG;aACrG,CAAA;QACH,CAAC;QACD,IAAI,QAA4B,CAAA;QAChC,IAAI,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;YACrD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC5B,QAAQ;oBACN,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,gBAAgB;wBACpC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,8BAA8B;wBAC1E,CAAC,CAAC,IAAI,CAAC,OAAO,CAAA;YACpB,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAgB,CAAC,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI;YACjE,IAAI,EAAE,SAAS;SAChB,CAAA;QACD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,CACpC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAC7C,CAAA;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;QACtD,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;IACjD,CAAC,CAAA;AACH,CAAC;AAED,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAyDT,CAAA;AAExB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,2BAA2B,CACzC,UAGI,EAAE;IAEN,MAAM,IAAI,GACR,OAAO,OAAO,CAAC,YAAY,KAAK,UAAU;QACxC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC;QAChD,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,IAAI,wBAAwB,CAAC,CAAA;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,cAAc;QAClC,CAAC,CAAC,GAAG,IAAI,iCAAiC,OAAO,CAAC,cAAc,EAAE;QAClE,CAAC,CAAC,IAAI,CAAA;IACR,OAAO,KAAK,UAAU,2BAA2B,CAC/C,MAAc,EACd,GAAiB;QAEjB,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;QACpD,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;YAChB,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,MAAM,EACJ,yGAAyG;aAC5G,CAAA;QACH,CAAC;QACD,MAAM,MAAM,GAAgB,CAAC,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI;YACjE,IAAI,EAAE,SAAS;SAChB,CAAA;QACD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,CACpC;YACE,KAAK;YACL,8BAA8B,YAAY,CAAC,MAAM,CAAC,EAAE;YACpD,8BAA8B,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,OAAO,EAAE;YAChE,aAAa;SACd,CAAC,IAAI,CAAC,MAAM,CAAC,CACf,CAAA;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;QACtD,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;IACjD,CAAC,CAAA;AACH,CAAC;AAED,MAAM,mBAAmB,GACvB,+DAA+D,CAAA;AAEjE,SAAS,sBAAsB,CAAC,OAAe;IAC7C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;IACpC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC1D,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1B,IAAI,SAAS;YAAE,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC1C,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,yBAAyB,CACvC,UAAuC,EAAE;IAEzC,MAAM,OAAO,GAAG,CAAC,SAAiB,EAAW,EAAE;QAC7C,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QAC7C,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YACnC,OAAO,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC1C,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACtC,CAAC,CAAA;IACD,OAAO,KAAK,UAAU,yBAAyB,CAC7C,MAAc,EACd,GAAiB;QAEjB,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;QACpD,MAAM,OAAO,GAAG,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACtD,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;QAC/C,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACjD,MAAM,QAAQ,GACZ,MAAM,EAAE,IAAI,KAAK,SAAS;YACxB,CAAC,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC;YACxC,CAAC,CAAC,IAAI,GAAG,EAAU,CAAA;QACvB,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,CACpC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAC/D,CAAA;QACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;QACpD,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,MAAM,EACJ,yDAAyD,UAAU;iBAChE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;iBACpB,IAAI,CAAC,IAAI,CAAC,iDAAiD;gBAC9D,+DAA+D;gBAC/D,iEAAiE;gBACjE,iDAAiD;SACpD,CAAA;IACH,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Action, RuleBlock, RuleEntry } from '@nizos/probity';
|
|
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 declare function isRuleBlock(entry: RuleEntry): entry is RuleBlock;
|
|
25
|
+
/**
|
|
26
|
+
* The non-empty glob list `RuleBlock.files` requires. A plain
|
|
27
|
+
* `string[]` (even one built from a non-empty literal) is NOT
|
|
28
|
+
* assignable to it — TS can't prove non-emptiness for a general array
|
|
29
|
+
* type — so preset option types and any `files:` glob list built up
|
|
30
|
+
* before use should be typed `Globs`, not `string[]`.
|
|
31
|
+
*/
|
|
32
|
+
export type Globs = NonNullable<RuleBlock['files']>;
|
|
33
|
+
/**
|
|
34
|
+
* Builds a path matcher from include/exclude patterns. Patterns
|
|
35
|
+
* prefixed with `!` are negations (picomatch's `ignore` option);
|
|
36
|
+
* everything else is an include. An all-negations list gets `**` as
|
|
37
|
+
* the default include. `dot: true` so `*`/`**` traverse dot-prefixed
|
|
38
|
+
* segments — without it a scoped rule silently skips dotfiles.
|
|
39
|
+
*
|
|
40
|
+
* Port of @nizos/probity `src/rules/utils/match-paths.ts#buildMatcher`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildMatcher(patterns: readonly string[]): (path: string) => boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Whether a `{ files, rules }` block applies to an action. Empty
|
|
45
|
+
* `files` matches nothing; non-write actions (commands) pass the
|
|
46
|
+
* block-level filter and rules self-filter by action kind; write
|
|
47
|
+
* actions are matched against `files`.
|
|
48
|
+
*
|
|
49
|
+
* Port of @nizos/probity
|
|
50
|
+
* `src/rules/utils/match-paths.ts#actionMatchesFilesScope`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function actionMatchesFilesScope(files: readonly string[], action: Action): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* `**`-prefixed globs are intentional "match anywhere" patterns;
|
|
55
|
+
* anchoring them at the config dir would defeat the user's intent.
|
|
56
|
+
* Negations carry the same convention through the `!` prefix.
|
|
57
|
+
*
|
|
58
|
+
* Port of @nizos/probity `src/config.ts#anchorGlob`.
|
|
59
|
+
*/
|
|
60
|
+
export declare function anchorGlob(glob: string, root: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Anchors every block's relative globs against `root`, the way
|
|
63
|
+
* Probity's `loadConfig` anchors them against the config file's
|
|
64
|
+
* directory — so paths in `Action.path` (absolute POSIX) match
|
|
65
|
+
* regardless of where the session is rooted. Flat rules pass through.
|
|
66
|
+
*/
|
|
67
|
+
export declare function anchorEntries(entries: readonly RuleEntry[], root: string): RuleEntry[];
|
|
68
|
+
//# sourceMappingURL=scoping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoping.d.ts","sourceRoot":"","sources":["../../rules/scoping.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAElE;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,IAAI,SAAS,CAEhE;AAED;;;;;;GAMG;AACH,MAAM,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;AAEnD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAW3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI7D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,SAAS,SAAS,EAAE,EAC7B,IAAI,EAAE,MAAM,GACX,SAAS,EAAE,CAMb"}
|