@jjchill/probity-rules 0.4.15 → 0.4.17

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 CHANGED
@@ -1,5 +1,182 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.17
4
+
5
+ The Kotlin and KMP presets can now keep driving adapters thin (#76):
6
+ Compose screens and CLI commands, in the same repo as the core or in a
7
+ separate app that consumes it as a library. Opt-in.
8
+
9
+ - **What was missing.** 0.4.16 wired `enforceThinDrivingAdapter` and
10
+ `forbidNewDomainDiscriminantChecks` into the JS preset only. Kotlin
11
+ had three more gaps:
12
+ - Its discriminant screen matched only string literals, but Kotlin
13
+ compares to enum entries (`role == Role.SUPER_USER`).
14
+ - The export list only read JS/TS `export` declarations.
15
+ - A UI-only app depending on the core as a library has no core
16
+ source to scan at all.
17
+ - **Opt-in, unlike JS.** `kotlinRuleEntries` and `kmpRuleEntries` get
18
+ a `drivingAdapterGlobs` option with **no default**. A core-only repo
19
+ (mysudo-core has no `@Composable` files) has no UI, so a default glob
20
+ would only show up as `DEAD SCOPE`. Upgrading changes nothing until
21
+ the option is set. When set, the block is listed before the TDD
22
+ judge, and `coreGlobs` are excluded from it (in KMP, that keeps
23
+ `presentation/` ViewModels core). Starting globs per layout are in
24
+ hooks/PROBITY.md, "Driving adapters by project layout".
25
+ - **New options** (both presets):
26
+ - `domainDiscriminants`: turns on the free screen with Kotlin
27
+ patterns. It blocks net-new `role == Role.X` (either order) or
28
+ string-literal comparisons, `when (viewer.role)` subjects, and
29
+ `status is Status.Draft`.
30
+ - `domainHint`: appended to the screen's deny.
31
+ - `coreExportsInJudge`: the judge gets the public names declared in
32
+ `coreGlobs` sources. Capped at `coreExportsMaxChars`, default
33
+ 16,000.
34
+ - `coreApiPaths`: for a UI-only app. The judge gets the core's public
35
+ API read from binary-compatibility-validator dumps (`.api` and
36
+ `.klib.api`, as files or directories). Generated members (getters,
37
+ `component1`, `copy`, `equals`…) are dropped; on kotlinx.coroutines'
38
+ real dumps this cuts 125 KB to about 10 KB.
39
+ - **Kotlin judge addendum** (`KOTLIN_DRIVING_ADAPTER_ADDENDUM`). A CLI
40
+ command's options, help text, precondition checks and exhaustive
41
+ `when` over its use case's sealed outcome (to exit code, error code,
42
+ message and JSON) are translation. Branching on domain state,
43
+ retrying, or chaining use cases is not. It also lists Compose view
44
+ state and wiring (`remember`, `collectAsState`, `LaunchedEffect`
45
+ forwarding one intent, `@Preview`) as allowed.
46
+ - **Export scanning (all presets).** Nested worktrees and submodules
47
+ (a directory with a `.git` file, such as `.claude/worktrees/*`) are
48
+ skipped, as the parity rule already does (#55). Paths are printed
49
+ relative to the directory the modules share. On mysudo-core, the
50
+ worktree copies would otherwise have filled the cap several times
51
+ over. Kotlin nested types (mostly sealed-outcome cases) are left out,
52
+ which takes mysudo-core's core list from 29,000 to 13,000 characters.
53
+ - **Shared block.** `presets/driving-adapter.ts` (`drivingAdapterBlock`)
54
+ builds the block for all three presets. The JS preset's wiring is
55
+ unchanged.
56
+ - **Measured** with Probity's real Claude Code judge, wired as the KMP
57
+ preset wires it, 5 runs per case.
58
+ - **mysudo-core's CLI** (`cli/src/main/**/commands/**`, its real
59
+ `coreGlobs`, `coreExportsInJudge: true`):
60
+ - Allowed: four real writes (adding the real `sudos delete`
61
+ command, the real `RegisterCommand` with its extra read for
62
+ display, the real 432-line `PhoneCallsCommand`, and a help-text
63
+ change).
64
+ - Blocked: four splices into real commands (label validation the
65
+ `CreateSudo` use case already does; a last-Sudo rule plus a retry
66
+ in `delete`; a role/status filter in `list`; a locked-account
67
+ sign-out-and-deregister policy in `register`).
68
+ - Result: 40/40 correct. The free screen caught the two enum cases
69
+ before any AI call.
70
+ - **Synthetic Compose versions** of the #72 cases (blocked) and
71
+ controls (allowed: a pure render change, calling `canApprove()`,
72
+ one ViewModel intent, local `remember` state): 40/40 correct.
73
+ - **Addendum check.** Without the Kotlin addendum, the CLI set was
74
+ also correct (39/39 verdicts, 1 run failed on the judge's login).
75
+ So the addendum is guidance these cases didn't need, not a measured
76
+ fix.
77
+ - **Scope.** `probity-scope-report` was run on mysudo-core's tree from
78
+ a scratch copy of its config. Relative globs are anchored to the
79
+ config's own directory, so that copy used the unanchored
80
+ `**/cli/src/main/**/commands/**`. It reported the block with no
81
+ warning but also matched `.claude/worktrees/` copies (123 files). In
82
+ mysudo-core's own config, the anchored `cli/src/main/**/commands/**`
83
+ matches the 31 command files. A scope-report test confirms the block
84
+ leaves out `Composition.kt`.
85
+ - New exports: `drivingAdapterBlock` (`presets/driving-adapter`).
86
+ `ExportLanguage`, `JS_EXPORTS`, `ApiDumpFormat` and
87
+ `listPublishedApi` (`rules/ports-and-adapters`). `kotlinExportedNames`,
88
+ `KOTLIN_EXPORTS`, `readKotlinApiDump`, `KOTLIN_API_DUMP`,
89
+ `kotlinDomainDiscriminantPatterns` and `KOTLIN_DRIVING_ADAPTER_ADDENDUM`
90
+ (`rules/kotlin`). `forbidNewDomainDiscriminantChecks` takes
91
+ `patternsFor`; `enforceThinDrivingAdapter` takes `publishedApi` and a
92
+ `coreExports.language`.
93
+
94
+ ## 0.4.16
95
+
96
+ The JS preset now keeps driving adapters (UI components, pages, route
97
+ handlers) thin (#72). Business logic leaking out of the core into UI
98
+ code is blocked, and the deny names where it should go.
99
+
100
+ - **What went wrong.** The existing ports-and-adapters rules stop
101
+ vendors getting *into* core code. Nothing stopped logic leaking *out*
102
+ of it. In a React consumer on 0.4.14, with clean and fully policed
103
+ core boundaries, `src/ui/` grew:
104
+ - a submit handler running a whole use case (domain `submit()`,
105
+ `repository.save()`, `notifier.timesheetSubmitted()`, and a "a
106
+ failed notification must never fail the submit" policy)
107
+ - `viewer.role === 'SuperUser'` permission checks in four places,
108
+ next to a domain that already exported `canEdit` and `canApprove`
109
+ - a display-name rule copied seven times, with two copies disagreeing
110
+ - a React-free use case filed under `src/ui/`
111
+
112
+ Each one had a component test, so the TDD judge had no reason to
113
+ object. It checks whether code is tested, not where it belongs.
114
+ - **Now:** two new rules in `rules/ports-and-adapters.ts`.
115
+ - `enforceThinDrivingAdapter`, an AI judge. It blocks a write that
116
+ adds (a) a decision in domain terms, (b) coordination of more than
117
+ one port or use-case call, (c) a re-implementation of something the
118
+ core exports, or (d) a framework-free use case under a UI path. The
119
+ deny names the extraction target: a domain function or a use case.
120
+ Rendering, display formatting, local view state, and one call per
121
+ user intent pass. Only what a write adds is judged, so an existing
122
+ thick component doesn't freeze.
123
+ - `forbidNewDomainDiscriminantChecks`, a free deterministic screen.
124
+ It blocks net-new comparisons of configured fields to a literal
125
+ (`viewer.role === 'SuperUser'`, either order) and points to a domain
126
+ function. Off until you list the fields: there is no default,
127
+ because `status === 'loading'` is ordinary view state.
128
+ - **Preset wiring (JS only).** `jsRuleEntries` gets a block on the new
129
+ `drivingAdapterGlobs` option, **on by default**: `src/ui/**`,
130
+ `src/components/**` and `src/**/*.tsx`, minus `*.test.*`, `*.spec.*`
131
+ and `*.stories.*`. It runs before the TDD judge, so a denial costs one
132
+ AI call. New options:
133
+ - `drivingAdapterGlobs`: the scope; `[]` switches the rules off.
134
+ - `domainDiscriminants`: turns on the free screen, e.g. `['role']`.
135
+ - `domainHint`: appended to the screen's deny, e.g. where permission
136
+ rules live.
137
+ - `coreExportsInJudge`: gives the judge the export names of every
138
+ module under `coreGlobs` (capped at 8,000 characters), so it can
139
+ name the existing function a copy duplicates. Off by default; it
140
+ scans the tree on each judged write.
141
+ - **Measured** with Probity's real Claude Code judge, 5 runs per case,
142
+ on synthetic writes built from the four cases above plus five
143
+ controls that must pass: a pure render change, adding a `canX()`
144
+ call, a single use-case call, a local `status === 'loading'` check,
145
+ and calling an existing `displayName` export. These are written from
146
+ the issue's descriptions, not replays of the consumer's real writes.
147
+ With and without the export list, 90/90 verdicts were correct (40
148
+ blocked, 50 allowed). The prompt's examples were then made
149
+ domain-neutral and the replay rerun: 76 of 90 runs returned a verdict
150
+ and all 76 were correct. The other 14 hit a judge login failure in
151
+ the test environment. On 0.4.14 no rule judged these writes, so all
152
+ would pass.
153
+ - **Cost:** one extra AI call per write to a matching UI file, on top of
154
+ the TDD judge.
155
+ - **Migration.** Consumers calling `jsRuleEntries` get the new block on
156
+ upgrade. Check it with `probity-scope-report`: it lists the block and
157
+ flags it `DEAD SCOPE` if your UI lives elsewhere. Then set
158
+ `drivingAdapterGlobs` to your layout, or `[]` to opt out. Hand-composed
159
+ configs add the block themselves:
160
+
161
+ ```ts
162
+ {
163
+ files: ['src/ui/**', '!**/*.test.*'],
164
+ rules: [
165
+ forbidNewDomainDiscriminantChecks({ discriminants: ['role'] }),
166
+ withJudgeFailureDiagnostics(withContradictionRetry(enforceThinDrivingAdapter())),
167
+ ],
168
+ }
169
+ ```
170
+
171
+ The Kotlin, KMP and Swift presets are unchanged; Compose and SwiftUI
172
+ globs are a follow-up.
173
+ - New exports: `enforceThinDrivingAdapter`,
174
+ `forbidNewDomainDiscriminantChecks`, `domainDiscriminantPatterns`,
175
+ `exportedNames` and `listCoreExports`.
176
+ - Skills: `ports-and-adapters` gets a "Driving adapters are equally
177
+ thin" section with a checklist, red flags and a rationalization;
178
+ `frontend-ui-engineering` points to it.
179
+
3
180
  ## 0.4.15
4
181
 
5
182
  The JS/TS TDD judge no longer blocks adding a new red test (#73), and it
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The thin-driving-adapter block (issues #72, #76), built once for
3
+ * every preset: the free discriminant screen when discriminants are
4
+ * configured, then the AI judge, wrapped in the same failure
5
+ * diagnostics and contradiction retry as the presets' TDD judges.
6
+ * Presets list it before their TDD block, so a denial costs one AI
7
+ * call, not two.
8
+ */
9
+ import type { RuleEntry } from '@nizos/probity';
10
+ import type { NamedPattern } from '../rules/gates.js';
11
+ import { type ApiDumpFormat, type ExportLanguage } from '../rules/ports-and-adapters.js';
12
+ export type DrivingAdapterBlockOptions = {
13
+ /** Driving-adapter files. No include glob → no block. */
14
+ globs: readonly string[];
15
+ /** Core scope, excluded: core code is never a driving adapter. */
16
+ coreGlobs: readonly string[];
17
+ /** Fields whose literal comparison is a domain decision. */
18
+ domainDiscriminants?: readonly string[];
19
+ /** Appended to the discriminant screen's deny. */
20
+ domainHint?: string;
21
+ /** Builds the discriminant patterns (default: JS/TS literals). */
22
+ patternsFor?: (discriminants: readonly string[]) => NamedPattern[];
23
+ /** Give the judge the export names of `coreGlobs` sources. */
24
+ coreExports?: {
25
+ root?: string;
26
+ language?: ExportLanguage;
27
+ maxChars?: number;
28
+ };
29
+ /** Give the judge the public API read from published dumps. */
30
+ publishedApi?: {
31
+ paths: readonly string[];
32
+ format: ApiDumpFormat;
33
+ root?: string;
34
+ };
35
+ /** Extends or replaces the judge's rules text. */
36
+ instructions?: string | ((defaults: string) => string);
37
+ };
38
+ export declare function drivingAdapterBlock(options: DrivingAdapterBlockOptions): RuleEntry | undefined;
39
+ //# sourceMappingURL=driving-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driving-adapter.d.ts","sourceRoot":"","sources":["../../presets/driving-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,gCAAgC,CAAA;AAEvC,MAAM,MAAM,0BAA0B,GAAG;IACvC,yDAAyD;IACzD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,kEAAkE;IAClE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,4DAA4D;IAC5D,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,YAAY,EAAE,CAAA;IAClE,8DAA8D;IAC9D,WAAW,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7E,+DAA+D;IAC/D,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,aAAa,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACjF,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,CAAA;CACvD,CAAA;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,SAAS,GAAG,SAAS,CAgC9F"}
@@ -0,0 +1,33 @@
1
+ import { withContradictionRetry, withJudgeFailureDiagnostics } from '../rules/gates.js';
2
+ import { enforceThinDrivingAdapter, forbidNewDomainDiscriminantChecks, } from '../rules/ports-and-adapters.js';
3
+ export function drivingAdapterBlock(options) {
4
+ if (!options.globs.some((glob) => !glob.startsWith('!')))
5
+ return undefined;
6
+ const [first, ...rest] = [
7
+ ...options.globs,
8
+ ...options.coreGlobs.filter((glob) => !glob.startsWith('!')).map((glob) => `!${glob}`),
9
+ ];
10
+ return {
11
+ files: [first, ...rest],
12
+ rules: [
13
+ ...(options.domainDiscriminants?.length
14
+ ? [
15
+ forbidNewDomainDiscriminantChecks({
16
+ discriminants: options.domainDiscriminants,
17
+ domainHint: options.domainHint,
18
+ patternsFor: options.patternsFor,
19
+ }),
20
+ ]
21
+ : []),
22
+ withJudgeFailureDiagnostics(withContradictionRetry(enforceThinDrivingAdapter({
23
+ coreExports: options.coreExports && {
24
+ globs: options.coreGlobs,
25
+ ...options.coreExports,
26
+ },
27
+ publishedApi: options.publishedApi,
28
+ instructions: options.instructions,
29
+ }))),
30
+ ],
31
+ };
32
+ }
33
+ //# sourceMappingURL=driving-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driving-adapter.js","sourceRoot":"","sources":["../../presets/driving-adapter.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAA;AACvF,OAAO,EACL,yBAAyB,EACzB,iCAAiC,GAGlC,MAAM,gCAAgC,CAAA;AAqBvC,MAAM,UAAU,mBAAmB,CAAC,OAAmC;IACrE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IAC1E,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG;QACvB,GAAG,OAAO,CAAC,KAAK;QAChB,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;KACvF,CAAA;IACD,OAAO;QACL,KAAK,EAAE,CAAC,KAAM,EAAE,GAAG,IAAI,CAAC;QACxB,KAAK,EAAE;YACL,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM;gBACrC,CAAC,CAAC;oBACE,iCAAiC,CAAC;wBAChC,aAAa,EAAE,OAAO,CAAC,mBAAmB;wBAC1C,UAAU,EAAE,OAAO,CAAC,UAAU;wBAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;qBACjC,CAAC;iBACH;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,2BAA2B,CACzB,sBAAsB,CACpB,yBAAyB,CAAC;gBACxB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI;oBAClC,KAAK,EAAE,OAAO,CAAC,SAAS;oBACxB,GAAG,OAAO,CAAC,WAAW;iBACvB;gBACD,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,YAAY,EAAE,OAAO,CAAC,YAAY;aACnC,CAAC,CACH,CACF;SACF;KACF,CAAA;AACH,CAAC"}
@@ -17,6 +17,27 @@ export type JsPresetOptions = {
17
17
  /** Point at your canonical ports once they exist, e.g. "inject the
18
18
  * Clock port from src/ports/clock.ts". */
19
19
  seamHint?: string;
20
+ /** Driving (inbound) adapter files — UI components, pages, route
21
+ * handlers, CLI commands — held thin by `enforceThinDrivingAdapter`
22
+ * (an AI call per matching write). Default: `src/ui/**`,
23
+ * `src/components/**` and every `.tsx` under `src/`, minus tests
24
+ * and stories. Pass `[]` to switch
25
+ * the thinness rules off. */
26
+ drivingAdapterGlobs?: readonly string[];
27
+ /** Field names whose comparison to a literal in a driving adapter is
28
+ * a domain decision (e.g. `['role', 'plan']`). OFF by default —
29
+ * `status === 'loading'` is ordinary view state, so only your model
30
+ * knows which fields carry domain meaning. Set it to block net-new
31
+ * comparisons free, before the AI call. */
32
+ domainDiscriminants?: string[];
33
+ /** Appended to the discriminant block message, e.g. "permission
34
+ * rules live in src/domain/permissions.ts". */
35
+ domainHint?: string;
36
+ /** Give the thin-driving-adapter judge the export names of every
37
+ * module under `coreGlobs`, so it can spot a copy of an existing
38
+ * domain rule. Off by default: it costs a directory scan per judged
39
+ * write. */
40
+ coreExportsInJudge?: boolean;
20
41
  /** Files where internal-module mocking is forbidden (the only test
21
42
  * seam is a port). */
22
43
  mockGlobs?: Globs;
@@ -1 +1 @@
1
- {"version":3,"file":"js.d.ts","sourceRoot":"","sources":["../../presets/js.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAarE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAA;AAGrC;;;;;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;IAC7B;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,KAAK,CAAA;IAC3B;;wCAEoC;IACpC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;qEACiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;mCAG+B;IAC/B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,WAAW,EAAE,CAAA;IAC5B,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;oEACgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,SAAS,EAAE,CAgKxE"}
1
+ {"version":3,"file":"js.d.ts","sourceRoot":"","sources":["../../presets/js.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAerE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAGhD,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAA;AAGrC;;;;;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;;;;;kCAK8B;IAC9B,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC;;;;gDAI4C;IAC5C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC9B;oDACgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;iBAGa;IACb,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;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;IAC7B;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,KAAK,CAAA;IAC3B;;wCAEoC;IACpC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;qEACiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;mCAG+B;IAC/B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,WAAW,EAAE,CAAA;IAC5B,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;oEACgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,SAAS,EAAE,CAwLxE"}
@@ -7,6 +7,8 @@
7
7
  * test-driven-development → enforceJsTdd (built-in enforceTdd + addendum)
8
8
  * ports-and-adapters → enforcePortsBoundary + forbidInternalModuleMocks
9
9
  * + a deterministic import screen
10
+ * + enforceThinDrivingAdapter on UI/inbound
11
+ * adapter files
10
12
  * acceptance-testing → enforceAcceptanceLanguage
11
13
  *
12
14
  * `jsRuleEntries(options?)` reproduces exactly what the shipped
@@ -22,6 +24,7 @@ import { forbidNewAmbientEffects, JS_AMBIENT_EFFECT_PATTERNS, requireGreenTestRu
22
24
  import { enforceJsTdd } from '../rules/js-tdd.js';
23
25
  import { enforcePortsBoundary, forbidInternalModuleMocks, } from '../rules/ports-and-adapters.js';
24
26
  import { withExcludeGlobs } from '../rules/scoping.js';
27
+ import { drivingAdapterBlock } from './driving-adapter.js';
25
28
  import { enforceSpecTestParity, JS_TEST_DECLARATION, requireSpecBackedAcceptanceTest, surfaceScenarioLinkBreakage, } from '../rules/spec-test-parity.js';
26
29
  import { surfaceGlossaryTermBreakage } from '../rules/ubiquitous-language.js';
27
30
  /**
@@ -44,6 +47,14 @@ export function jsRuleEntries(options = {}) {
44
47
  const tddGlobs = options.tddGlobs ?? ['src/**', 'test/**', 'tests/**'];
45
48
  const specGlobs = options.specGlobs ?? ['specs/**', 'acceptance/**', '**/*.feature'];
46
49
  const excludeGlobs = options.excludeGlobs ?? ['spikes/**', '**/build/**'];
50
+ const drivingAdapterGlobs = options.drivingAdapterGlobs ?? [
51
+ 'src/ui/**',
52
+ 'src/components/**',
53
+ 'src/**/*.tsx',
54
+ '!**/*.test.*',
55
+ '!**/*.spec.*',
56
+ '!**/*.stories.*',
57
+ ];
47
58
  const entries = [
48
59
  // ── Boundaries: ports-and-adapters ──────────────────────────────
49
60
  // Core purity. Point these globs at your core/domain/use-case
@@ -78,6 +89,22 @@ export function jsRuleEntries(options = {}) {
78
89
  rules: [forbidInternalModuleMocks()],
79
90
  },
80
91
  ];
92
+ // Driving adapters must be thin (issue #72). The core-purity block
93
+ // above stops vendors getting INTO core code; this stops business
94
+ // logic leaking OUT of it into UI components and handlers, which the
95
+ // TDD gate alone never questions (a component test makes the logic
96
+ // "tested"). The free discriminant screen runs first when
97
+ // configured; the judge runs before the TDD judge, so a denial here
98
+ // costs one AI call, not two.
99
+ const drivingAdapter = drivingAdapterBlock({
100
+ globs: drivingAdapterGlobs,
101
+ coreGlobs,
102
+ domainDiscriminants: options.domainDiscriminants,
103
+ domainHint: options.domainHint,
104
+ coreExports: options.coreExportsInJudge ? {} : undefined,
105
+ });
106
+ if (drivingAdapter)
107
+ entries.push(drivingAdapter);
81
108
  // Spec-to-test traceability (issue #18): OFF by default, so a
82
109
  // project that hasn't opted in sees no behavior change. Setting
83
110
  // `specsDir` wires the same set the KMP preset wires — deterministic
@@ -1 +1 @@
1
- {"version":3,"file":"js.js","sourceRoot":"","sources":["../../presets/js.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,EAAE,oBAAoB,EAAkB,MAAM,gBAAgB,CAAA;AAErE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAA;AAC3E,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EACL,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,gCAAgC,CAAA;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,+BAA+B,EAC/B,2BAA2B,GAE5B,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAA;AAE7E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,4BAA4B,GACvC,kRAAkR,CAAA;AAiEpR;;;;;;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;IAC3F,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAA;IAEzE,MAAM,OAAO,GAAgB;QAC3B,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;KACF,CAAA;IAED,8DAA8D;IAC9D,gEAAgE;IAChE,qEAAqE;IACrE,iEAAiE;IACjE,4DAA4D;IAC5D,+DAA+D;IAC/D,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QACjC,MAAM,mBAAmB,GAAU,OAAO,CAAC,mBAAmB,IAAI;YAChE,wBAAwB;YACxB,wBAAwB;SACzB,CAAA;QACD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAEtD,iEAAiE;QACjE,6DAA6D;QAC7D,iEAAiE;QACjE,iEAAiE;QACjE,sBAAsB;QACtB,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE;gBACL,2BAA2B,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC;aACrF;SACF,CAAC,CAAA;QAEF,gEAAgE;QAChE,mEAAmE;QACnE,mEAAmE;QACnE,0CAA0C;QAC1C,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,mBAAmB;YAC1B,KAAK,EAAE;gBACL,+BAA+B,CAAC;oBAC9B,QAAQ;oBACR,sBAAsB,EAAE,OAAO,CAAC,sBAAsB,IAAI,mBAAmB;iBAC9E,CAAC;aACH;SACF,CAAC,CAAA;QAEF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,6DAA6D;YAC7D,gEAAgE;YAChE,8DAA8D;YAC9D,wDAAwD;YACxD,8DAA8D;YAC9D,2DAA2D;YAC3D,4CAA4C;YAC5C,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC/C,KAAK,EAAE,CAAC,2BAA2B,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;aACjE,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,kEAAkE;IAClE,gEAAgE;IAChE,4DAA4D;IAC5D,4DAA4D;IAC5D,4DAA4D;IAC5D,oCAAoC;IACpC,OAAO,CAAC,IAAI,CAAC;QACX,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,CAAC,YAAY,EAAE,CAAC;KACxB,CAAC,CAAA;IAEF,mEAAmE;IACnE,iEAAiE;IACjE,8DAA8D;IAC9D,gEAAgE;IAChE,gEAAgE;IAChE,uBAAuB;IACvB,gCAAgC;IAChC,mFAAmF;IACnF,OAAO;IACP,OAAO,CAAC,IAAI,CAAC;QACX,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,CAAC,yBAAyB,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC3E,CAAC,CAAA;IAEF,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,mEAAmE;QACnE,iEAAiE;QACjE,+DAA+D;QAC/D,gEAAgE;QAChE,wBAAwB;QACxB,OAAO,CAAC,IAAI,CACV,qBAAqB,CAAC;YACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAC/C,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,YAAY,EAAE,OAAO,CAAC,kBAAkB;YACxC,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,aAAa,EAAE,OAAO,CAAC,aAAa;SACrC,CAAC,CACH,CAAA;IACH,CAAC;IAED,mEAAmE;IACnE,iEAAiE;IACjE,mEAAmE;IACnE,+DAA+D;IAC/D,+DAA+D;IAC/D,gEAAgE;IAChE,oBAAoB;IACpB,OAAO,CAAC,IAAI,CACV,mBAAmB,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,6BAA6B;QAC/D,cAAc,EACZ,OAAO,CAAC,oBAAoB,IAAI,iDAAiD;QACnF,cAAc,EAAE,OAAO,CAAC,oBAAoB,IAAI,mBAAmB;KACpE,CAAC,CACH,CAAA;IAED,OAAO,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;AAChD,CAAC"}
1
+ {"version":3,"file":"js.js","sourceRoot":"","sources":["../../presets/js.ts"],"names":[],"mappings":"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"}
@@ -48,6 +48,37 @@ export type KmpPresetOptions = {
48
48
  * clock/randomness/env screen's deny text (default: function-typed
49
49
  * providers such as `nowEpochMillis: () -> Long`). */
50
50
  seamHint?: string;
51
+ /** Driving (inbound) adapter files held thin by
52
+ * `enforceThinDrivingAdapter`: Compose screens, CLI commands, route
53
+ * handlers. OFF unless set — a core-only module has none, so a
54
+ * default glob would only be a dead scope. `coreGlobs` are always
55
+ * excluded (so `presentation/` ViewModels stay core). Starting
56
+ * points:
57
+ * - UI in this repo: `['**\/composeApp/src/**', '**\/src/*Main/**\/ui/**', '!**\/*Preview*.kt']`
58
+ * - a CLI module: `['cli/src/main/**\/commands/**']`
59
+ * - a UI-only app on a core SDK: its `ui/` packages, plus `coreApiPaths`.
60
+ * Every matching write costs an AI call, before the TDD judge. */
61
+ drivingAdapterGlobs?: readonly string[];
62
+ /** Fields whose comparison to a domain value in a driving adapter is
63
+ * a domain decision (e.g. `['role', 'status']`): net-new
64
+ * `role == Role.ADMIN`, `when (viewer.role)` or `status is
65
+ * Status.Draft` block free, before the AI call. No default. */
66
+ domainDiscriminants?: string[];
67
+ /** Appended to the discriminant block message, e.g. where permission
68
+ * rules live. */
69
+ domainHint?: string;
70
+ /** Give the thin-driving-adapter judge the public names declared in
71
+ * `coreGlobs` sources, so it can name the existing function a copy
72
+ * duplicates. Scans the tree on each judged write. */
73
+ coreExportsInJudge?: boolean;
74
+ /** Cap on the export list the judge is given (default 16000
75
+ * characters; the list is truncated beyond it). */
76
+ coreExportsMaxChars?: number;
77
+ /** For a repo that consumes the core as a library: binary-
78
+ * compatibility-validator dumps (`.api`, `.klib.api`), as files or
79
+ * directories relative to the root, whose public API the
80
+ * thin-driving-adapter judge is given. */
81
+ coreApiPaths?: string[];
51
82
  /** Names your telemetry convention for the adapter-observability
52
83
  * judge — how a boundary event is recorded in this codebase
53
84
  * (default: a :foundation `Logger.event` or port-tap convention). */
@@ -1 +1 @@
1
- {"version":3,"file":"kmp.d.ts","sourceRoot":"","sources":["../../presets/kmp.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAKrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAOhD,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAA;AAwBrC;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;uEACmE;IACnE,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;6CAEyC;IACzC,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,KAAK,CAAA;IAC3B,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;qEACiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;gEAC4D;IAC5D,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,WAAW,EAAE,CAAA;IAC5B,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;oEACgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;6BAGyB;IACzB,uBAAuB,CAAC,EAAE,KAAK,CAAA;IAC/B;;2DAEuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;0EAEsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS,EAAE,CAsRxF"}
1
+ {"version":3,"file":"kmp.d.ts","sourceRoot":"","sources":["../../presets/kmp.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAKrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAQhD,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAA;AA4BrC;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;uEACmE;IACnE,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;6CAEyC;IACzC,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,KAAK,CAAA;IAC3B,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;qEACiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;gEAC4D;IAC5D,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,WAAW,EAAE,CAAA;IAC5B,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;oEACgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;6BAGyB;IACzB,uBAAuB,CAAC,EAAE,KAAK,CAAA;IAC/B;;2DAEuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;;uEASmE;IACnE,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC;;;oEAGgE;IAChE,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC9B;sBACkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;2DAEuD;IACvD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;wDACoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;+CAG2C;IAC3C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;0EAEsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS,EAAE,CAySxF"}
@@ -22,9 +22,10 @@ import { enforceKotlinTdd } from '../internal/kotlin-tdd.js';
22
22
  import { withExtractionUnderGreen } from '../rules/gates.js';
23
23
  import { enforceAcceptanceLanguage, withAcceptanceLanguageFastPath, } from '../rules/acceptance-language.js';
24
24
  import { withExcludeGlobs } from '../rules/scoping.js';
25
+ import { drivingAdapterBlock } from './driving-adapter.js';
25
26
  import { enforceSpecTestParity, requireSpecBackedAcceptanceTest, surfaceScenarioLinkBreakage, } from '../rules/spec-test-parity.js';
26
27
  import { surfaceGlossaryTermBreakage } from '../rules/ubiquitous-language.js';
27
- import { enforceCharacterizationResolution, enforceProbeReversion, forbidNewAmbientEffects, GRADLE_TEST_COMMAND, KOTLIN_BOUNDARY_ADDENDUM, KOTLIN_INFRASTRUCTURE_IMPORTS, KOTLIN_PRODUCTION_SOURCE_PATTERN, KOTLIN_TEST_SOURCE_PATTERN, kotlinGreenRunOptions, MOCKING_LIBRARY_IMPORTS, requireGreenTestRun, withCharacterizationTest, withKotlinFastPath, withMutationProbe, withTelemetryFastPath, } from '../rules/kotlin.js';
28
+ import { enforceCharacterizationResolution, enforceProbeReversion, forbidNewAmbientEffects, GRADLE_TEST_COMMAND, KOTLIN_API_DUMP, KOTLIN_BOUNDARY_ADDENDUM, KOTLIN_DRIVING_ADAPTER_ADDENDUM, KOTLIN_EXPORTS, kotlinDomainDiscriminantPatterns, KOTLIN_INFRASTRUCTURE_IMPORTS, KOTLIN_PRODUCTION_SOURCE_PATTERN, KOTLIN_TEST_SOURCE_PATTERN, kotlinGreenRunOptions, MOCKING_LIBRARY_IMPORTS, requireGreenTestRun, withCharacterizationTest, withKotlinFastPath, withMutationProbe, withTelemetryFastPath, } from '../rules/kotlin.js';
28
29
  import { enforceAdapterObservability, enforcePortsBoundary, } from '../rules/ports-and-adapters.js';
29
30
  /**
30
31
  * The rule entries, as a factory over the project root. Probity only
@@ -77,6 +78,22 @@ export function kmpRuleEntries(root, options = {}) {
77
78
  // listed before any AI-validated rule (a model call per matching
78
79
  // write). A write with a vendor import in core code must be
79
80
  // rejected by the free import screen, not after a TDD model call.
81
+ // Driving adapters must be thin (issues #72, #76). Opt-in: listed
82
+ // before the TDD block, so a denial costs one AI call, not two.
83
+ const drivingAdapter = drivingAdapterBlock({
84
+ globs: options.drivingAdapterGlobs ?? [],
85
+ coreGlobs,
86
+ domainDiscriminants: options.domainDiscriminants,
87
+ domainHint: options.domainHint,
88
+ patternsFor: kotlinDomainDiscriminantPatterns,
89
+ coreExports: options.coreExportsInJudge
90
+ ? { root, language: KOTLIN_EXPORTS, maxChars: options.coreExportsMaxChars ?? 16000 }
91
+ : undefined,
92
+ publishedApi: options.coreApiPaths?.length
93
+ ? { paths: options.coreApiPaths, format: KOTLIN_API_DUMP, root }
94
+ : undefined,
95
+ instructions: (defaults) => defaults + KOTLIN_DRIVING_ADAPTER_ADDENDUM,
96
+ });
80
97
  const entries = [
81
98
  // ── Deterministic wall ───────────────────────────────────────────
82
99
  // Core import/effect screens. The import screen also catches Koin
@@ -162,6 +179,7 @@ export function kmpRuleEntries(root, options = {}) {
162
179
  // marked `// probity: characterization` passes, and
163
180
  // enforceCharacterizationResolution below blocks commits until the
164
181
  // marker comes off through a recorded red under a mutation probe.
182
+ ...(drivingAdapter ? [drivingAdapter] : []),
165
183
  {
166
184
  files: [
167
185
  '**/src/*Main/kotlin/**',
@@ -1 +1 @@
1
- {"version":3,"file":"kmp.js","sourceRoot":"","sources":["../../presets/kmp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kmp.js","sourceRoot":"","sources":["../../presets/kmp.ts"],"names":[],"mappings":"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"}
@@ -30,6 +30,38 @@ export type KotlinPresetOptions = {
30
30
  tddGlobs?: Globs;
31
31
  /** Adapter/data packages that must carry boundary observability. */
32
32
  adapterGlobs?: Globs;
33
+ /** Driving (inbound) adapter files held thin by
34
+ * `enforceThinDrivingAdapter`: Compose screens, CLI commands, route
35
+ * handlers. OFF unless set — a core-only module has none, so a
36
+ * default glob would only be a dead scope. `coreGlobs` are always
37
+ * excluded, so whether a ViewModel is an adapter or a presenter in
38
+ * the core is decided by which of the two scopes its package
39
+ * matches. Starting points:
40
+ * - UI in this repo: `['**\/composeApp/src/**', '**\/src/*Main/**\/ui/**', '!**\/*Preview*.kt']`
41
+ * - a CLI module: `['cli/src/main/**\/commands/**']`
42
+ * - a UI-only app on a core SDK: its `ui/` packages, plus `coreApiPaths`.
43
+ * Every matching write costs an AI call, before the TDD judge. */
44
+ drivingAdapterGlobs?: readonly string[];
45
+ /** Fields whose comparison to a domain value in a driving adapter is
46
+ * a domain decision (e.g. `['role', 'status']`): net-new
47
+ * `role == Role.ADMIN`, `when (viewer.role)` or `status is
48
+ * Status.Draft` block free, before the AI call. No default. */
49
+ domainDiscriminants?: string[];
50
+ /** Appended to the discriminant block message, e.g. where permission
51
+ * rules live. */
52
+ domainHint?: string;
53
+ /** Give the thin-driving-adapter judge the public names declared in
54
+ * `coreGlobs` sources, so it can name the existing function a copy
55
+ * duplicates. Scans the tree on each judged write. */
56
+ coreExportsInJudge?: boolean;
57
+ /** Cap on the export list the judge is given (default 16000
58
+ * characters; the list is truncated beyond it). */
59
+ coreExportsMaxChars?: number;
60
+ /** For a repo that consumes the core as a library: binary-
61
+ * compatibility-validator dumps (`.api`, `.klib.api`), as files or
62
+ * directories relative to the root, whose public API the
63
+ * thin-driving-adapter judge is given. */
64
+ coreApiPaths?: string[];
33
65
  /** The real Gradle test task your commit gate should look for. */
34
66
  commitCommand?: RegExp;
35
67
  /** Globs excluded (as `!`-negations) from every files-scoped block —
@@ -1 +1 @@
1
- {"version":3,"file":"kotlin.d.ts","sourceRoot":"","sources":["../../presets/kotlin.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AA+BrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAIhD,MAAM,MAAM,mBAAmB,GAAG;IAChC;;iDAE6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;kEAE8D;IAC9D,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,uEAAuE;IACvE,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;qBAGiB;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;oDACgD;IAChD,eAAe,CAAC,EAAE,KAAK,CAAA;IACvB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,KAAK,CAAA;IAC3B;sCACkC;IAClC,uBAAuB,CAAC,EAAE,KAAK,CAAA;IAC/B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,oEAAoE;IACpE,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;oEACgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,SAAS,EAAE,CA2L9F"}
1
+ {"version":3,"file":"kotlin.d.ts","sourceRoot":"","sources":["../../presets/kotlin.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAmCrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAKhD,MAAM,MAAM,mBAAmB,GAAG;IAChC;;iDAE6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;kEAE8D;IAC9D,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,uEAAuE;IACvE,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;qBAGiB;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;oDACgD;IAChD,eAAe,CAAC,EAAE,KAAK,CAAA;IACvB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,KAAK,CAAA;IAC3B;sCACkC;IAClC,uBAAuB,CAAC,EAAE,KAAK,CAAA;IAC/B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,oEAAoE;IACpE,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB;;;;;;;;;;uEAUmE;IACnE,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC;;;oEAGgE;IAChE,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC9B;sBACkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;2DAEuD;IACvD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;wDACoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;+CAG2C;IAC3C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;oEACgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,SAAS,EAAE,CA8M9F"}
@@ -18,10 +18,11 @@ import { forbidContentPattern } from '@nizos/probity';
18
18
  import { enforceKotlinTdd } from '../internal/kotlin-tdd.js';
19
19
  import { withExtractionUnderGreen } from '../rules/gates.js';
20
20
  import { enforceAcceptanceLanguage, withAcceptanceLanguageFastPath, } from '../rules/acceptance-language.js';
21
- import { enforceCharacterizationResolution, enforceProbeReversion, forbidNewAmbientEffects, forbidStaticMocks, GRADLE_TEST_COMMAND, KOTLIN_BOUNDARY_ADDENDUM, KOTLIN_INFRASTRUCTURE_IMPORTS, KOTLIN_PRODUCTION_SOURCE_PATTERN, KOTLIN_TEST_SOURCE_PATTERN, kotlinGreenRunOptions, requireGreenTestRun, withCharacterizationTest, withKotlinFastPath, withMutationProbe, withTelemetryFastPath, } from '../rules/kotlin.js';
21
+ import { enforceCharacterizationResolution, enforceProbeReversion, forbidNewAmbientEffects, forbidStaticMocks, GRADLE_TEST_COMMAND, KOTLIN_API_DUMP, KOTLIN_BOUNDARY_ADDENDUM, KOTLIN_DRIVING_ADAPTER_ADDENDUM, KOTLIN_EXPORTS, kotlinDomainDiscriminantPatterns, KOTLIN_INFRASTRUCTURE_IMPORTS, KOTLIN_PRODUCTION_SOURCE_PATTERN, KOTLIN_TEST_SOURCE_PATTERN, kotlinGreenRunOptions, requireGreenTestRun, withCharacterizationTest, withKotlinFastPath, withMutationProbe, withTelemetryFastPath, } from '../rules/kotlin.js';
22
22
  import { enforceAdapterObservability, enforcePortsBoundary, } from '../rules/ports-and-adapters.js';
23
23
  import { requireSpecBackedAcceptanceTest } from '../rules/spec-test-parity.js';
24
24
  import { withExcludeGlobs } from '../rules/scoping.js';
25
+ import { drivingAdapterBlock } from './driving-adapter.js';
25
26
  import { surfaceGlossaryTermBreakage } from '../rules/ubiquitous-language.js';
26
27
  /**
27
28
  * Rule entries for a Kotlin/JVM/Android project, as a factory over the
@@ -63,6 +64,22 @@ export function kotlinRuleEntries(root, options = {}) {
63
64
  '**/src/main/**/data/**',
64
65
  ];
65
66
  const excludeGlobs = options.excludeGlobs ?? ['spikes/**', '**/build/**'];
67
+ // Driving adapters must be thin (issues #72, #76). Opt-in: listed
68
+ // before the TDD block, so a denial costs one AI call, not two.
69
+ const drivingAdapter = drivingAdapterBlock({
70
+ globs: options.drivingAdapterGlobs ?? [],
71
+ coreGlobs,
72
+ domainDiscriminants: options.domainDiscriminants,
73
+ domainHint: options.domainHint,
74
+ patternsFor: kotlinDomainDiscriminantPatterns,
75
+ coreExports: options.coreExportsInJudge
76
+ ? { root, language: KOTLIN_EXPORTS, maxChars: options.coreExportsMaxChars ?? 16000 }
77
+ : undefined,
78
+ publishedApi: options.coreApiPaths?.length
79
+ ? { paths: options.coreApiPaths, format: KOTLIN_API_DUMP, root }
80
+ : undefined,
81
+ instructions: (defaults) => defaults + KOTLIN_DRIVING_ADAPTER_ADDENDUM,
82
+ });
66
83
  const entries = [
67
84
  // ── Deterministic wall ───────────────────────────────────────────
68
85
  // Core import/effect screens.
@@ -125,6 +142,7 @@ export function kotlinRuleEntries(root, options = {}) {
125
142
  // production already has (born green): a test-source write marked
126
143
  // `// probity: characterization` passes, and the commit gate below
127
144
  // holds the marker until a mutation probe shows that test failing.
145
+ ...(drivingAdapter ? [drivingAdapter] : []),
128
146
  {
129
147
  files: tddGlobs,
130
148
  // Telemetry-only additions pass deterministically — see the
@@ -1 +1 @@
1
- {"version":3,"file":"kotlin.js","sourceRoot":"","sources":["../../presets/kotlin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kotlin.js","sourceRoot":"","sources":["../../presets/kotlin.ts"],"names":[],"mappings":"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"}