@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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
First packaged release. Previously, consumers `cp`'d `probity.config.ts` +
|
|
6
|
+
`rules/` + `scripts/` into their project; rule fixes in this fork never
|
|
7
|
+
reached them. Rules and scripts are now a versioned npm package
|
|
8
|
+
(`@jjchill/probity-rules`); the config stays project-owned and imports
|
|
9
|
+
preset factories from the package.
|
|
10
|
+
|
|
11
|
+
Migrating from the copied-templates layout:
|
|
12
|
+
|
|
13
|
+
- `./rules/<x>.js` imports → `@jjchill/probity-rules/rules/<x>`
|
|
14
|
+
- `npx tsx scripts/scope-report.ts` → `npx probity-scope-report`
|
|
15
|
+
- `node scripts/spec-parity.mjs` → `npx probity-spec-parity`
|
|
16
|
+
|
|
17
|
+
Or run `/probity-update`, which detects the legacy layout and offers to
|
|
18
|
+
migrate it for you.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
Ubiquitous-language glossary (see the ubiquitous-language skill).
|
|
5
|
+
Copy to docs/GLOSSARY.md and point the probity config's glossaryPath
|
|
6
|
+
at it.
|
|
7
|
+
|
|
8
|
+
Format convention — the probity rules parse this file:
|
|
9
|
+
- one term per level-2 heading: `## Term`
|
|
10
|
+
- one term per concept, one concept per term; no aliases — if two
|
|
11
|
+
words compete for a concept, hold the glossary conversation and
|
|
12
|
+
record the winner
|
|
13
|
+
- definition text below the heading is free-form; record decisions
|
|
14
|
+
("was called X until 2026-07; renamed because...") in the entry
|
|
15
|
+
- multi-word terms are matched in code as PascalCase / camelCase /
|
|
16
|
+
snake_case, so `## Delivery Window` covers DeliveryWindow,
|
|
17
|
+
deliveryWindow, delivery_window
|
|
18
|
+
|
|
19
|
+
Enforcement, when wired in probity.config:
|
|
20
|
+
- renaming/removing a term still used by specs, tests, or code blocks
|
|
21
|
+
the glossary edit with the list of users (surfaceGlossaryTermBreakage)
|
|
22
|
+
- spec content naming a recorded concept with a conflicting term is
|
|
23
|
+
blocked (enforceAcceptanceLanguage with glossaryPath)
|
|
24
|
+
- port/domain names conflicting with recorded terms are blocked
|
|
25
|
+
(enforcePortsBoundary with glossaryPath)
|
|
26
|
+
- optional strict mode: spec concepts with no entry at all are blocked
|
|
27
|
+
(enforceAcceptanceLanguage with requireGlossaryEntry: true)
|
|
28
|
+
-->
|
|
29
|
+
|
|
30
|
+
## Example Term
|
|
31
|
+
|
|
32
|
+
Replace with your first real term. State what the concept is in the
|
|
33
|
+
problem domain's own words, not how the system implements it.
|
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# @jjchill/probity-rules
|
|
2
|
+
|
|
3
|
+
Versioned [Probity](https://github.com/nizos/probity) rule presets and CLI
|
|
4
|
+
tooling for the [agent-skills](https://github.com/addyosmani/agent-skills)
|
|
5
|
+
catalog. Turns three of the catalog's prose disciplines —
|
|
6
|
+
test-driven-development, ports-and-adapters, acceptance-testing — into hard
|
|
7
|
+
PreToolUse gates, plus spec-test parity and ubiquitous-language checks. See
|
|
8
|
+
[`hooks/PROBITY.md`](../PROBITY.md) for full rule semantics.
|
|
9
|
+
|
|
10
|
+
Rules and scripts live in this package now instead of being copied into a
|
|
11
|
+
project; a project's `probity.config.ts` imports from it, so `npm update`
|
|
12
|
+
brings rule fixes in instead of a fork rotting.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
Not yet published to npm. Install from a clone until then:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm install -D @nizos/probity /path/to/agent-skills/hooks/probity
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
(run `npm run build` in `hooks/probity` first — the package resolves its
|
|
23
|
+
own compiled `dist/`, not the TypeScript sources.)
|
|
24
|
+
|
|
25
|
+
Target, once published:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
npm install -D @nizos/probity @jjchill/probity-rules
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Presets
|
|
32
|
+
|
|
33
|
+
Each preset is a factory returning `RuleEntry[]` from `@nizos/probity`. Copy
|
|
34
|
+
the matching thin config template from the package root (`probity.config.ts`,
|
|
35
|
+
`probity.config.kotlin.ts`, `probity.config.kmp.ts`,
|
|
36
|
+
`probity.config.swift.ts`) into your project root, then edit its options.
|
|
37
|
+
|
|
38
|
+
| Preset | Import | Config template |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| Plain JS/TS | `@jjchill/probity-rules/presets/js` — `jsRuleEntries(options?)` | `probity.config.ts` |
|
|
41
|
+
| Kotlin/JVM/Android | `@jjchill/probity-rules/presets/kotlin` — `kotlinRuleEntries(root, options?)` | `probity.config.kotlin.ts` |
|
|
42
|
+
| Kotlin Multiplatform | `@jjchill/probity-rules/presets/kmp` — `kmpRuleEntries(root, parity?)` | `probity.config.kmp.ts` |
|
|
43
|
+
| Swift/iOS | `@jjchill/probity-rules/presets/swift` — `swiftRuleEntries(root)` | `probity.config.swift.ts` |
|
|
44
|
+
|
|
45
|
+
Minimal example (plain JS/TS):
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// probity.config.ts
|
|
49
|
+
import { defineConfig } from '@nizos/probity'
|
|
50
|
+
import { jsRuleEntries } from '@jjchill/probity-rules/presets/js'
|
|
51
|
+
|
|
52
|
+
export default defineConfig({
|
|
53
|
+
rules: jsRuleEntries({
|
|
54
|
+
coreGlobs: ['src/core/**', 'src/domain/**'],
|
|
55
|
+
}),
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Kotlin Multiplatform:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// probity.config.kmp.ts
|
|
63
|
+
import { dirname } from 'node:path'
|
|
64
|
+
import { fileURLToPath } from 'node:url'
|
|
65
|
+
import { defineConfig } from '@nizos/probity'
|
|
66
|
+
import { kmpRuleEntries } from '@jjchill/probity-rules/presets/kmp'
|
|
67
|
+
|
|
68
|
+
const ROOT = dirname(fileURLToPath(import.meta.url))
|
|
69
|
+
export default defineConfig({ rules: kmpRuleEntries(ROOT) })
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Every preset's options and their current defaults are documented at the top
|
|
73
|
+
of its module in `presets/`.
|
|
74
|
+
|
|
75
|
+
## Bins
|
|
76
|
+
|
|
77
|
+
- `npx probity-scope-report [--config probity.config.ts] [--root .] [--strict]`
|
|
78
|
+
— dry-runs your config's `{ files, rules }` blocks against your real repo
|
|
79
|
+
and reports dead scopes (globs matching zero files) and suspicious claims
|
|
80
|
+
(core-purity rules touching adapter code, the language rule touching
|
|
81
|
+
driver code).
|
|
82
|
+
- `npx probity-spec-parity` — the CI mirror of the spec↔test traceability
|
|
83
|
+
rule: checks that every non-`wip` scenario under `docs/specs` is claimed
|
|
84
|
+
by an acceptance test.
|
|
85
|
+
|
|
86
|
+
## Updating
|
|
87
|
+
|
|
88
|
+
Run `/probity-update` (a plugin slash command) from your project to update
|
|
89
|
+
the package, migrate your config to new options, refresh the Kiro shim
|
|
90
|
+
files, and re-verify scoping — see the command for the full procedure.
|
|
91
|
+
|
|
92
|
+
## Kiro
|
|
93
|
+
|
|
94
|
+
`kiro/` ships the Kiro hook shim (unchanged install model: copy into your
|
|
95
|
+
project's `.kiro/hooks/`). `/probity-update` re-copies changed files from
|
|
96
|
+
here.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@jjchill/probity-rules` barrel — language-NEUTRAL rule modules
|
|
3
|
+
* only.
|
|
4
|
+
*
|
|
5
|
+
* kotlin.ts and swift.ts are deliberately NOT re-exported here: both
|
|
6
|
+
* export `requireGreenTestRun` and `forbidNewAmbientEffects` with
|
|
7
|
+
* different signatures than the language-neutral versions in
|
|
8
|
+
* gates.ts, so a combined `export *` would collide. Reach the
|
|
9
|
+
* language-specific rules directly via `@jjchill/probity-rules/rules/kotlin`
|
|
10
|
+
* or `@jjchill/probity-rules/rules/swift`, or use a preset
|
|
11
|
+
* (`@jjchill/probity-rules/presets/*`) which already wires the right
|
|
12
|
+
* ones together.
|
|
13
|
+
*/
|
|
14
|
+
export * from './rules/gates.js';
|
|
15
|
+
export * from './rules/ports-and-adapters.js';
|
|
16
|
+
export * from './rules/acceptance-language.js';
|
|
17
|
+
export * from './rules/spec-test-parity.js';
|
|
18
|
+
export * from './rules/ubiquitous-language.js';
|
|
19
|
+
export * from './rules/scoping.js';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,cAAc,kBAAkB,CAAA;AAChC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oBAAoB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@jjchill/probity-rules` barrel — language-NEUTRAL rule modules
|
|
3
|
+
* only.
|
|
4
|
+
*
|
|
5
|
+
* kotlin.ts and swift.ts are deliberately NOT re-exported here: both
|
|
6
|
+
* export `requireGreenTestRun` and `forbidNewAmbientEffects` with
|
|
7
|
+
* different signatures than the language-neutral versions in
|
|
8
|
+
* gates.ts, so a combined `export *` would collide. Reach the
|
|
9
|
+
* language-specific rules directly via `@jjchill/probity-rules/rules/kotlin`
|
|
10
|
+
* or `@jjchill/probity-rules/rules/swift`, or use a preset
|
|
11
|
+
* (`@jjchill/probity-rules/presets/*`) which already wires the right
|
|
12
|
+
* ones together.
|
|
13
|
+
*/
|
|
14
|
+
export * from './rules/gates.js';
|
|
15
|
+
export * from './rules/ports-and-adapters.js';
|
|
16
|
+
export * from './rules/acceptance-language.js';
|
|
17
|
+
export * from './rules/spec-test-parity.js';
|
|
18
|
+
export * from './rules/ubiquitous-language.js';
|
|
19
|
+
export * from './rules/scoping.js';
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,cAAc,kBAAkB,CAAA;AAChC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probity rule-entry factory — plain JS/TS preset.
|
|
3
|
+
*
|
|
4
|
+
* Turns three of the agent-skills catalog's prose disciplines into
|
|
5
|
+
* hard PreToolUse gates via https://github.com/nizos/probity :
|
|
6
|
+
*
|
|
7
|
+
* test-driven-development → enforceTdd (built-in)
|
|
8
|
+
* ports-and-adapters → enforcePortsBoundary + forbidInternalModuleMocks
|
|
9
|
+
* + a deterministic import screen
|
|
10
|
+
* acceptance-testing → enforceAcceptanceLanguage
|
|
11
|
+
*
|
|
12
|
+
* `jsRuleEntries(options?)` reproduces exactly what the shipped
|
|
13
|
+
* `probity.config.ts` template wires by default — every option below
|
|
14
|
+
* defaults to that template's current value. A consuming project
|
|
15
|
+
* copies the thin template (which calls this factory) and overrides
|
|
16
|
+
* only the options its layout needs.
|
|
17
|
+
*/
|
|
18
|
+
import { type RuleEntry } from '@nizos/probity';
|
|
19
|
+
import type { Globs } from '../rules/scoping.js';
|
|
20
|
+
/**
|
|
21
|
+
* Deterministic first line of defense for the Dependency Rule: known
|
|
22
|
+
* framework/vendor/OS-I/O imports never belong in core code, so block
|
|
23
|
+
* them without spending an AI call. Extend with your stack's usual
|
|
24
|
+
* suspects; enforcePortsBoundary catches what this list misses.
|
|
25
|
+
*/
|
|
26
|
+
export declare const KNOWN_INFRASTRUCTURE_IMPORTS: RegExp;
|
|
27
|
+
export type JsPresetOptions = {
|
|
28
|
+
/** Core/domain globs — adapters and composition roots import
|
|
29
|
+
* vendors by design and must NOT match here. */
|
|
30
|
+
coreGlobs?: Globs;
|
|
31
|
+
/** The deterministic infrastructure-import screen for core code. */
|
|
32
|
+
infrastructureImports?: RegExp;
|
|
33
|
+
/** Point at your canonical ports once they exist, e.g. "inject the
|
|
34
|
+
* Clock port from src/ports/clock.ts". */
|
|
35
|
+
seamHint?: string;
|
|
36
|
+
/** Files where internal-module mocking is forbidden (the only test
|
|
37
|
+
* seam is a port). */
|
|
38
|
+
mockGlobs?: Globs;
|
|
39
|
+
/** Files the TDD gate (the expensive, AI-validated rule) applies
|
|
40
|
+
* to — scope this to the code you actually TDD. */
|
|
41
|
+
tddGlobs?: Globs;
|
|
42
|
+
/** The spec/acceptance layer the Language Test applies to. Do NOT
|
|
43
|
+
* widen this to DSL or protocol-driver files. */
|
|
44
|
+
specGlobs?: Globs;
|
|
45
|
+
/** Absolute path to a glossary (ubiquitous-language skill) to hold
|
|
46
|
+
* specs to. */
|
|
47
|
+
glossaryPath?: string;
|
|
48
|
+
/** The real test command your commit gate should look for. */
|
|
49
|
+
commitCommand?: RegExp;
|
|
50
|
+
/** Your runner's green summary line. */
|
|
51
|
+
commitSuccessPattern?: RegExp;
|
|
52
|
+
/** Your runner's failure summary line. */
|
|
53
|
+
commitFailurePattern?: RegExp;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Rule entries for a plain JS/TS project. Probity stops at the first
|
|
57
|
+
* violation, so deterministic screens (pattern match, free, instant)
|
|
58
|
+
* are ordered before AI-validated rules (a model call per matching
|
|
59
|
+
* write): a vendor import in core code is rejected free by the
|
|
60
|
+
* import screen, never after a TDD model call.
|
|
61
|
+
*/
|
|
62
|
+
export declare function jsRuleEntries(options?: JsPresetOptions): RuleEntry[];
|
|
63
|
+
//# sourceMappingURL=js.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"js.d.ts","sourceRoot":"","sources":["../../presets/js.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAYjF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,QAC2O,CAAA;AAEpR,MAAM,MAAM,eAAe,GAAG;IAC5B;qDACiD;IACjD,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,oEAAoE;IACpE,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;+CAC2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;2BACuB;IACvB,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB;wDACoD;IACpD,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB;sDACkD;IAClD,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB;oBACgB;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,0CAA0C;IAC1C,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,SAAS,EAAE,CAkFxE"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probity rule-entry factory — plain JS/TS preset.
|
|
3
|
+
*
|
|
4
|
+
* Turns three of the agent-skills catalog's prose disciplines into
|
|
5
|
+
* hard PreToolUse gates via https://github.com/nizos/probity :
|
|
6
|
+
*
|
|
7
|
+
* test-driven-development → enforceTdd (built-in)
|
|
8
|
+
* ports-and-adapters → enforcePortsBoundary + forbidInternalModuleMocks
|
|
9
|
+
* + a deterministic import screen
|
|
10
|
+
* acceptance-testing → enforceAcceptanceLanguage
|
|
11
|
+
*
|
|
12
|
+
* `jsRuleEntries(options?)` reproduces exactly what the shipped
|
|
13
|
+
* `probity.config.ts` template wires by default — every option below
|
|
14
|
+
* defaults to that template's current value. A consuming project
|
|
15
|
+
* copies the thin template (which calls this factory) and overrides
|
|
16
|
+
* only the options its layout needs.
|
|
17
|
+
*/
|
|
18
|
+
import { enforceTdd, forbidContentPattern } from '@nizos/probity';
|
|
19
|
+
import { enforceAcceptanceLanguage } from '../rules/acceptance-language.js';
|
|
20
|
+
import { forbidNewAmbientEffects, JS_AMBIENT_EFFECT_PATTERNS, requireGreenTestRun, } from '../rules/gates.js';
|
|
21
|
+
import { enforcePortsBoundary, forbidInternalModuleMocks, } from '../rules/ports-and-adapters.js';
|
|
22
|
+
/**
|
|
23
|
+
* Deterministic first line of defense for the Dependency Rule: known
|
|
24
|
+
* framework/vendor/OS-I/O imports never belong in core code, so block
|
|
25
|
+
* them without spending an AI call. Extend with your stack's usual
|
|
26
|
+
* suspects; enforcePortsBoundary catches what this list misses.
|
|
27
|
+
*/
|
|
28
|
+
export const KNOWN_INFRASTRUCTURE_IMPORTS = /from\s+['"](?:node:(?:fs|http|https|net|child_process|process)|fs|http|https|express|fastify|@nestjs\/[^'"]+|next\/[^'"]+|pg|mysql2?|mongodb|mongoose|redis|ioredis|@prisma\/client|typeorm|knex|axios|node-fetch|got|undici|stripe|@aws-sdk\/[^'"]+|aws-sdk|firebase-admin)['"]/;
|
|
29
|
+
/**
|
|
30
|
+
* Rule entries for a plain JS/TS project. Probity stops at the first
|
|
31
|
+
* violation, so deterministic screens (pattern match, free, instant)
|
|
32
|
+
* are ordered before AI-validated rules (a model call per matching
|
|
33
|
+
* write): a vendor import in core code is rejected free by the
|
|
34
|
+
* import screen, never after a TDD model call.
|
|
35
|
+
*/
|
|
36
|
+
export function jsRuleEntries(options = {}) {
|
|
37
|
+
const coreGlobs = options.coreGlobs ?? ['src/core/**', 'src/domain/**'];
|
|
38
|
+
const mockGlobs = options.mockGlobs ?? ['**/*.test.*', '**/*.spec.*', 'test/**', 'tests/**'];
|
|
39
|
+
const tddGlobs = options.tddGlobs ?? ['src/**', 'test/**', 'tests/**'];
|
|
40
|
+
const specGlobs = options.specGlobs ?? ['specs/**', 'acceptance/**', '**/*.feature'];
|
|
41
|
+
return [
|
|
42
|
+
// ── Boundaries: ports-and-adapters ──────────────────────────────
|
|
43
|
+
// Core purity. Point these globs at your core/domain/use-case
|
|
44
|
+
// code only — adapters and composition roots import vendors by
|
|
45
|
+
// design and must NOT match here.
|
|
46
|
+
{
|
|
47
|
+
files: coreGlobs,
|
|
48
|
+
rules: [
|
|
49
|
+
forbidContentPattern({
|
|
50
|
+
match: options.infrastructureImports ?? KNOWN_INFRASTRUCTURE_IMPORTS,
|
|
51
|
+
reason: 'Core code imports an infrastructure module. The Dependency ' +
|
|
52
|
+
'Rule: core imports nothing from adapters, frameworks, ' +
|
|
53
|
+
'vendors, or OS I/O — define a port in the core and reach ' +
|
|
54
|
+
'the dependency through an adapter (see the ' +
|
|
55
|
+
'ports-and-adapters skill).',
|
|
56
|
+
}),
|
|
57
|
+
// Clock, randomness, and environment are ports too. Delta-based:
|
|
58
|
+
// existing call sites don't block; net-new ones do. Point
|
|
59
|
+
// seamHint at your canonical ports once they exist.
|
|
60
|
+
forbidNewAmbientEffects({
|
|
61
|
+
patterns: JS_AMBIENT_EFFECT_PATTERNS,
|
|
62
|
+
seamHint: options.seamHint,
|
|
63
|
+
}),
|
|
64
|
+
enforcePortsBoundary(),
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
// Ports are the only test seam: no jest.mock()/vi.mock() of our
|
|
68
|
+
// own modules anywhere in the suite. Deterministic — free to run
|
|
69
|
+
// broadly.
|
|
70
|
+
{
|
|
71
|
+
files: mockGlobs,
|
|
72
|
+
rules: [forbidInternalModuleMocks()],
|
|
73
|
+
},
|
|
74
|
+
// ── Inner loop: test-driven-development ─────────────────────────
|
|
75
|
+
// Red → Green → Refactor on all production and test code. This is
|
|
76
|
+
// the expensive rule (AI call per matching write) — scope it to
|
|
77
|
+
// the code you actually TDD. Listed AFTER the deterministic
|
|
78
|
+
// screens above: Probity stops at the first violation, so a
|
|
79
|
+
// vendor import in core code is rejected free by the import
|
|
80
|
+
// screen, never after a model call.
|
|
81
|
+
{
|
|
82
|
+
files: tddGlobs,
|
|
83
|
+
rules: [enforceTdd()],
|
|
84
|
+
},
|
|
85
|
+
// ── Outer loop: acceptance-testing ──────────────────────────────
|
|
86
|
+
// The Language Test on the spec layer only. Do NOT widen this to
|
|
87
|
+
// DSL or protocol-driver files — those layers are supposed to
|
|
88
|
+
// contain the mechanics this rule blocks. To hold specs to your
|
|
89
|
+
// glossary (ubiquitous-language skill), pass glossaryPath as an
|
|
90
|
+
// absolute path, e.g.:
|
|
91
|
+
// enforceAcceptanceLanguage({
|
|
92
|
+
// glossaryPath: fileURLToPath(new URL('./docs/GLOSSARY.md', import.meta.url)),
|
|
93
|
+
// })
|
|
94
|
+
{
|
|
95
|
+
files: specGlobs,
|
|
96
|
+
rules: [enforceAcceptanceLanguage({ glossaryPath: options.glossaryPath })],
|
|
97
|
+
},
|
|
98
|
+
// ── Ship gate ────────────────────────────────────────────────────
|
|
99
|
+
// No commit on an unverified tree — and the recorded run must be
|
|
100
|
+
// GREEN. Probity's built-in requireCommand only checks that a test
|
|
101
|
+
// command ran after the last write; a run whose output was all
|
|
102
|
+
// failures would still unlock the commit. Match your real test
|
|
103
|
+
// command and your runner's summary lines (defaults below cover
|
|
104
|
+
// vitest and jest).
|
|
105
|
+
requireGreenTestRun({
|
|
106
|
+
command: options.commitCommand ?? /npm (run )?test|vitest|jest/,
|
|
107
|
+
successPattern: options.commitSuccessPattern ?? /Test Files\s+\d+ passed|Tests:\s+.*\b\d+ passed/,
|
|
108
|
+
failurePattern: options.commitFailurePattern ?? /\d+ failed|FAIL\s/,
|
|
109
|
+
}),
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=js.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"js.js","sourceRoot":"","sources":["../../presets/js.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAkB,MAAM,gBAAgB,CAAA;AAEjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAA;AAC3E,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,gCAAgC,CAAA;AAGvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,4BAA4B,GACvC,kRAAkR,CAAA;AA+BpR;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,UAA2B,EAAE;IACzD,MAAM,SAAS,GAAU,OAAO,CAAC,SAAS,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,CAAA;IAC9E,MAAM,SAAS,GAAU,OAAO,CAAC,SAAS,IAAI,CAAC,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;IACnG,MAAM,QAAQ,GAAU,OAAO,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;IAC7E,MAAM,SAAS,GAAU,OAAO,CAAC,SAAS,IAAI,CAAC,UAAU,EAAE,eAAe,EAAE,cAAc,CAAC,CAAA;IAE3F,OAAO;QACL,mEAAmE;QACnE,8DAA8D;QAC9D,+DAA+D;QAC/D,kCAAkC;QAClC;YACE,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE;gBACL,oBAAoB,CAAC;oBACnB,KAAK,EAAE,OAAO,CAAC,qBAAqB,IAAI,4BAA4B;oBACpE,MAAM,EACJ,6DAA6D;wBAC7D,wDAAwD;wBACxD,2DAA2D;wBAC3D,6CAA6C;wBAC7C,4BAA4B;iBAC/B,CAAC;gBACF,iEAAiE;gBACjE,0DAA0D;gBAC1D,oDAAoD;gBACpD,uBAAuB,CAAC;oBACtB,QAAQ,EAAE,0BAA0B;oBACpC,QAAQ,EAAE,OAAO,CAAC,QAAQ;iBAC3B,CAAC;gBACF,oBAAoB,EAAE;aACvB;SACF;QAED,gEAAgE;QAChE,iEAAiE;QACjE,WAAW;QACX;YACE,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,CAAC,yBAAyB,EAAE,CAAC;SACrC;QAED,mEAAmE;QACnE,kEAAkE;QAClE,gEAAgE;QAChE,4DAA4D;QAC5D,4DAA4D;QAC5D,4DAA4D;QAC5D,oCAAoC;QACpC;YACE,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,CAAC,UAAU,EAAE,CAAC;SACtB;QAED,mEAAmE;QACnE,iEAAiE;QACjE,8DAA8D;QAC9D,gEAAgE;QAChE,gEAAgE;QAChE,uBAAuB;QACvB,gCAAgC;QAChC,mFAAmF;QACnF,OAAO;QACP;YACE,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,CAAC,yBAAyB,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;SAC3E;QAED,oEAAoE;QACpE,iEAAiE;QACjE,mEAAmE;QACnE,+DAA+D;QAC/D,+DAA+D;QAC/D,gEAAgE;QAChE,oBAAoB;QACpB,mBAAmB,CAAC;YAClB,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,6BAA6B;YAC/D,cAAc,EACZ,OAAO,CAAC,oBAAoB,IAAI,iDAAiD;YACnF,cAAc,EAAE,OAAO,CAAC,oBAAoB,IAAI,mBAAmB;SACpE,CAAC;KACH,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type RuleEntry } from '@nizos/probity';
|
|
2
|
+
import { type DriverScope } from '../rules/spec-test-parity.js';
|
|
3
|
+
/**
|
|
4
|
+
* The rule entries, as a factory over the project root. Probity only
|
|
5
|
+
* reads the default export below; the factory exists so tooling can
|
|
6
|
+
* instantiate the exact same blocks against a different root — the
|
|
7
|
+
* workflow eval runs them in a temp directory, and
|
|
8
|
+
* `scripts/scope-report.ts` resolves their `files` scopes against the
|
|
9
|
+
* real tree. Keeping the entries in one place is what lets the eval's
|
|
10
|
+
* scoping stay derived from this config instead of hand-mirrored.
|
|
11
|
+
*
|
|
12
|
+
* Relative globs (`docs/...`) are NOT anchored here: Probity's
|
|
13
|
+
* `loadConfig` anchors them against this file's directory at load
|
|
14
|
+
* time, and the tooling replicates that via `rules/scoping.ts`.
|
|
15
|
+
*
|
|
16
|
+
* `parity` optionally switches on the per-scenario driver mapping
|
|
17
|
+
* (`driverScopes`/`defaultScopes` on the commit-time parity gate) —
|
|
18
|
+
* projects normally enable it by uncommenting the block in the
|
|
19
|
+
* `enforceSpecTestParity` call below; the parameter exists so the
|
|
20
|
+
* workflow eval can exercise the scope checks without changing the
|
|
21
|
+
* template's default-off posture.
|
|
22
|
+
*/
|
|
23
|
+
export declare function kmpRuleEntries(root: string, parity?: {
|
|
24
|
+
driverScopes?: DriverScope[];
|
|
25
|
+
defaultScopes?: string[];
|
|
26
|
+
}): RuleEntry[];
|
|
27
|
+
//# sourceMappingURL=kmp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kmp.d.ts","sourceRoot":"","sources":["../../presets/kmp.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAQjF,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAA;AAmBrC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAClE,SAAS,EAAE,CAwOb"}
|