@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.
@@ -1,3 +1,7 @@
1
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import { isAbsolute, join, relative, sep } from 'node:path';
3
+ import { introducedPatterns } from './gates.js';
4
+ import { buildMatcher } from './scoping.js';
1
5
  // reason comes FIRST in the shape: an autoregressive model commits to
2
6
  // each field in order, so kind-first forces the verdict before the
3
7
  // analysis — observed live producing a "violation" whose reason
@@ -372,4 +376,381 @@ export function forbidInternalModuleMocks(options = {}) {
372
376
  };
373
377
  };
374
378
  }
379
+ function escapeRegExp(text) {
380
+ return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
381
+ }
382
+ /**
383
+ * One pattern per discriminant: the field compared to a string literal
384
+ * with `===`, `!==`, `==` or `!=`, in either order
385
+ * (`viewer.role === 'SuperUser'`, `'Draft' !== order.status`).
386
+ */
387
+ export function domainDiscriminantPatterns(discriminants) {
388
+ return discriminants.map((name) => {
389
+ const field = escapeRegExp(name);
390
+ const literal = String.raw `(['"\x60])[^'"\x60\n]*\1`;
391
+ return {
392
+ label: `${name} compared to a literal`,
393
+ pattern: new RegExp(String.raw `\b${field}\s*[!=]==?\s*['"\x60]|${literal}\s*[!=]==?\s*[\w$.?!]*\b${field}\b`, 'g'),
394
+ };
395
+ });
396
+ }
397
+ /**
398
+ * Deterministic first screen for thin driving adapters (issue #72): a
399
+ * UI component or other inbound adapter that compares a domain
400
+ * discriminant — a role, a status, a plan — to a literal is deciding a
401
+ * business rule itself. The domain should export that decision
402
+ * (`canApprove(actor)`, `isEditable(order)`) and the adapter call
403
+ * it.
404
+ *
405
+ * Delta-based, like `forbidNewAmbientEffects`: only a write that adds
406
+ * comparisons beyond what the file on disk already has blocks, so an
407
+ * existing thick component doesn't freeze. No AI call.
408
+ *
409
+ * There is no default list. `status === 'loading'` is ordinary local
410
+ * view state in a UI, so the discriminants must be the fields that
411
+ * carry domain meaning in YOUR model.
412
+ *
413
+ * Applies to: write actions. Scope it to driving-adapter files (UI
414
+ * components, route handlers, CLI commands).
415
+ *
416
+ * @param options.discriminants — field names whose literal comparisons
417
+ * are domain decisions, e.g. `['role', 'plan']`.
418
+ * @param options.domainHint — appended to the block message to name
419
+ * where the decision should go, e.g. "permission rules live in
420
+ * src/domain/permissions.ts".
421
+ * @param options.patternsFor — builds the patterns from the
422
+ * discriminants (default {@link domainDiscriminantPatterns}, JS/TS
423
+ * string literals). The Kotlin presets pass
424
+ * `kotlinDomainDiscriminantPatterns`, which also matches enum
425
+ * entries, `when` subjects and `is` checks.
426
+ *
427
+ * @example
428
+ * { files: ['src/ui/**'], rules: [forbidNewDomainDiscriminantChecks({ discriminants: ['role'] })] }
429
+ */
430
+ export function forbidNewDomainDiscriminantChecks(options) {
431
+ const patterns = (options.patternsFor ?? domainDiscriminantPatterns)(options.discriminants);
432
+ return async function forbidNewDomainDiscriminantChecks(action, ctx) {
433
+ if (action.kind !== 'write' || patterns.length === 0)
434
+ return { kind: 'pass' };
435
+ const introduced = await introducedPatterns(action, ctx, patterns);
436
+ if (introduced.length === 0)
437
+ return { kind: 'pass' };
438
+ const hint = options.domainHint ? ` ${options.domainHint}.` : '';
439
+ return {
440
+ kind: 'violation',
441
+ reason: `This write adds a domain decision to a driving adapter (${introduced.join(', ')}). Driving adapters (UI components, route handlers, CLI commands) render ` +
442
+ 'core-supplied state and forward user intent; they do not decide ' +
443
+ 'business rules. Add a function to the domain that makes this ' +
444
+ 'decision (e.g. `canApprove(actor)`, `isEditable(order)`), ' +
445
+ `test it without the UI framework, and call it here.${hint} ` +
446
+ 'Existing comparisons in the file are untouched by this rule — ' +
447
+ 'only new ones are blocked.',
448
+ };
449
+ };
450
+ }
451
+ const EXPORT_DECLARATION = /^\s*export\s+(?:default\s+)?(?:declare\s+)?(?:async\s+)?(?:abstract\s+)?(?:function\*?|const|let|var|class|type|interface|enum)\s+([A-Za-z_$][\w$]*)/gm;
452
+ const EXPORT_LIST = /^\s*export\s+(?:type\s+)?\{([^}]*)\}/gm;
453
+ const EXPORT_SCAN_SKIP_DIRS = new Set([
454
+ 'node_modules',
455
+ '.git',
456
+ 'build',
457
+ 'dist',
458
+ 'out',
459
+ 'coverage',
460
+ ]);
461
+ /** Names a JS/TS module exports, from its source text. */
462
+ export function exportedNames(content) {
463
+ const names = new Set();
464
+ for (const match of content.matchAll(EXPORT_DECLARATION)) {
465
+ if (match[1])
466
+ names.add(match[1]);
467
+ }
468
+ for (const match of content.matchAll(EXPORT_LIST)) {
469
+ for (const part of (match[1] ?? '').split(',')) {
470
+ const name = part.trim().split(/\s+as\s+/).pop()?.replace(/^type\s+/, '').trim();
471
+ if (name && /^[A-Za-z_$][\w$]*$/.test(name))
472
+ names.add(name);
473
+ }
474
+ }
475
+ return [...names];
476
+ }
477
+ /** JS/TS exports: `export function|const|class|type…` and `export { … }`. */
478
+ export const JS_EXPORTS = {
479
+ sourceFile: /\.(?:[cm]?[jt]sx?)$/,
480
+ testFile: /\.(?:test|spec)\.[^./]+$/,
481
+ exportedNames,
482
+ };
483
+ function sourceFiles(dir, pattern, out = [], top = true) {
484
+ // A directory holding a `.git` FILE is another working tree (a
485
+ // linked worktree under .claude/worktrees/, or a submodule): its
486
+ // copies of the core are not this checkout's exports (cf. #55).
487
+ if (!top) {
488
+ try {
489
+ if (statSync(join(dir, '.git')).isFile())
490
+ return out;
491
+ }
492
+ catch {
493
+ // no .git entry: an ordinary directory
494
+ }
495
+ }
496
+ let entries;
497
+ try {
498
+ entries = readdirSync(dir, { withFileTypes: true });
499
+ }
500
+ catch {
501
+ return out;
502
+ }
503
+ for (const entry of entries) {
504
+ if (entry.isDirectory()) {
505
+ if (!EXPORT_SCAN_SKIP_DIRS.has(entry.name))
506
+ sourceFiles(join(dir, entry.name), pattern, out, false);
507
+ }
508
+ else if (entry.isFile() && pattern.test(entry.name)) {
509
+ out.push(join(dir, entry.name));
510
+ }
511
+ }
512
+ return out;
513
+ }
514
+ /**
515
+ * The core's export list, one line per module (`src/domain/roles.ts:
516
+ * canApprove, canEdit`), for the thin-driving-adapter judge. Test files
517
+ * are skipped. Truncated beyond `maxChars`.
518
+ */
519
+ export function listCoreExports(options) {
520
+ const language = options.language ?? JS_EXPORTS;
521
+ const matches = buildMatcher(options.globs);
522
+ const modules = [];
523
+ for (const file of sourceFiles(options.root, language.sourceFile).sort()) {
524
+ const rel = relative(options.root, file).split(sep).join('/');
525
+ if (!matches(rel) || language.testFile.test(rel))
526
+ continue;
527
+ let content;
528
+ try {
529
+ content = readFileSync(file, 'utf8');
530
+ }
531
+ catch {
532
+ continue;
533
+ }
534
+ const names = language.exportedNames(content);
535
+ if (names.length > 0)
536
+ modules.push([rel, names]);
537
+ }
538
+ // Paths relative to the directory every module shares, so a deep
539
+ // package path isn't repeated on every line of a capped list.
540
+ const prefix = commonDirectory(modules.map(([rel]) => rel));
541
+ const lines = modules.map(([rel, names]) => `${rel.slice(prefix.length)}: ${names.join(', ')}`);
542
+ if (prefix && modules.length > 1)
543
+ lines.unshift(`(paths under ${prefix})`);
544
+ return capped(lines.join('\n'), options.maxChars);
545
+ }
546
+ function commonDirectory(paths) {
547
+ if (paths.length < 2)
548
+ return '';
549
+ const split = paths.map((path) => path.split('/').slice(0, -1));
550
+ const shared = [];
551
+ for (let i = 0; split.every((parts) => i < parts.length && parts[i] === split[0][i]); i++) {
552
+ shared.push(split[0][i]);
553
+ }
554
+ return shared.length ? `${shared.join('/')}/` : '';
555
+ }
556
+ function capped(text, maxChars) {
557
+ return text.length > maxChars
558
+ ? `${text.slice(0, maxChars)}\n(...export list truncated...)`
559
+ : text;
560
+ }
561
+ /**
562
+ * The core's public API from published dumps, for a repo that consumes
563
+ * the core as a library and has no core source to scan. Each path is a
564
+ * dump file or a directory of them, relative to `root` or absolute.
565
+ * Missing paths are skipped. Truncated beyond `maxChars`.
566
+ */
567
+ export function listPublishedApi(options) {
568
+ const files = [];
569
+ for (const path of options.paths) {
570
+ const full = isAbsolute(path) ? path : join(options.root, path);
571
+ let stat;
572
+ try {
573
+ stat = statSync(full);
574
+ }
575
+ catch {
576
+ continue;
577
+ }
578
+ if (stat.isDirectory())
579
+ files.push(...sourceFiles(full, options.format.file).sort());
580
+ else
581
+ files.push(full);
582
+ }
583
+ const lines = [];
584
+ for (const file of files) {
585
+ try {
586
+ lines.push(...options.format.read(readFileSync(file, 'utf8')));
587
+ }
588
+ catch {
589
+ continue;
590
+ }
591
+ }
592
+ return capped(lines.join('\n'), options.maxChars);
593
+ }
594
+ const THIN_DRIVING_ADAPTER_INSTRUCTIONS = `## Role
595
+
596
+ You are a driving-adapter thinness validator. A driving (inbound)
597
+ adapter is the code the outside world calls first: a UI component, a
598
+ page, a route handler, a CLI command. In this codebase it renders
599
+ core-supplied state and forwards user intent to the core. Business
600
+ logic in it can only be tested through the framework, drifts when it
601
+ is copied, and is invisible to headless and acceptance tests. Judge
602
+ whether the pending write keeps this adapter thin, per the rules below.
603
+
604
+ ## Inputs
605
+
606
+ 1. "Current file content" — what's on disk right now (may be a marker
607
+ like \`(file does not exist)\`).
608
+ 2. "Pending action" — the file path and the file content after the
609
+ write.
610
+ 3. Optionally, "Core exports" — what the domain and use-case modules
611
+ already export, one module per line.
612
+
613
+ ## What you judge
614
+
615
+ Judge only what this write adds (before → after), never pre-existing
616
+ code: an existing thick component is migrated incrementally, so a
617
+ write that leaves old logic in place but adds none passes. A transient
618
+ state (an unresolved import, a half-built component) is never itself a
619
+ violation. A block recorded earlier in the session is a past verdict,
620
+ not a rule; when the user says to let a change through, treat that as
621
+ authoritative and pass. The bar is a clear violation; when genuinely
622
+ ambiguous, pass.
623
+
624
+ ## Block a write that adds any of these
625
+
626
+ (a) **A decision expressed in domain terms**: eligibility, permission,
627
+ a state transition, a validation rule, or a derived value used to
628
+ make one (who may approve, which approver a request is routed to,
629
+ whether an order can still be edited). Comparing a role, status or plan
630
+ to a literal is the usual shape. Extraction target: a domain
631
+ function the adapter calls.
632
+ (b) **Coordination of more than one port or use-case call in one
633
+ handler**, or a policy about their outcomes (call the domain, then
634
+ save, then notify; "a failed notification must never fail the
635
+ submit"). That is a use case. Extraction target: a use-case
636
+ function, tested headless with fakes at its ports, which the
637
+ handler calls once.
638
+ (c) **A re-implementation of something the core already exports**, or
639
+ a copy of a domain rule that already lives elsewhere (a
640
+ display-name rule, a permission check). When "Core exports" lists
641
+ a matching name, block and name it. Extraction target: call the
642
+ existing export, or move the rule into the domain once and call it.
643
+ (d) **A use case filed as an adapter**: a module under a driving-
644
+ adapter path that uses no UI or framework API and coordinates
645
+ ports (e.g. \`startCheckout(billing, logger)\`). Extraction target:
646
+ move it to the use-case layer.
647
+
648
+ ## Always pass
649
+
650
+ - Rendering and layout, styling, accessibility attributes.
651
+ - Formatting for display: dates, currency, pluralization, truncation.
652
+ - Local view state: open/closed, loading/error flags, form field
653
+ values, the selected tab, input focus.
654
+ - Parsing and shaping user input into the arguments of a call.
655
+ - Calling ONE use case or port per user intent and showing its
656
+ result or error.
657
+ - Calling a domain function to make a decision (\`canApprove(actor)\`)
658
+ — that is the intended pattern.
659
+ - Wiring/composition (providers, DI, routing tables), test code, and
660
+ deleting code.
661
+ - Files that are clearly not driving adapters despite the path.
662
+
663
+ ## When you block
664
+
665
+ Name the exact logic the write adds and its extraction target: a
666
+ domain function (for a decision or a duplicated rule) or a use case
667
+ (for coordination). Name the existing core export to call when there
668
+ is one. Remind the agent that under this codebase's TDD gate the
669
+ extracted function gets its failing test first, written without the UI
670
+ framework.`;
671
+ /**
672
+ * AI-validated rule for thin driving adapters (issue #72): UI
673
+ * components, pages, route handlers and CLI commands must not add
674
+ * business logic. The judge blocks a write that adds (a) a decision in
675
+ * domain terms, (b) coordination of more than one port/use-case call,
676
+ * (c) a re-implementation of something the core already exports, or
677
+ * (d) a framework-free use case filed as an adapter — naming the
678
+ * extraction target (domain function or use case) in the deny.
679
+ * Rendering, display formatting, local view state and one call per
680
+ * user intent pass. Delta-based: only what a write adds is judged.
681
+ *
682
+ * The other ports-and-adapters rules stop vendors getting INTO core
683
+ * code; this one stops logic leaking OUT of it.
684
+ *
685
+ * Applies to: write actions. Scope it to driving-adapter files — every
686
+ * matching write costs an AI call. Pair it with
687
+ * `forbidNewDomainDiscriminantChecks` so the obvious cases block free.
688
+ *
689
+ * @param options.coreExports — when set, the judge is given the
690
+ * export names of every source file matching `globs` under `root`
691
+ * (default `process.cwd()`), truncated beyond `maxChars` (default
692
+ * 8000), so it can spot a copy of an existing domain rule. Costs a
693
+ * directory scan per judged write.
694
+ * `language` picks how exports are read (default {@link JS_EXPORTS};
695
+ * the Kotlin presets pass `KOTLIN_EXPORTS`).
696
+ * @param options.publishedApi — for a repo that consumes the core as
697
+ * a library: the judge is given the public API read from published
698
+ * dumps at `paths` (files or directories, relative to `root`), in
699
+ * `format` (e.g. `KOTLIN_API_DUMP` for binary-compatibility-validator
700
+ * `.api` files). Combined with `coreExports` when both are set.
701
+ * @param options.instructions — replaces or extends the default rules
702
+ * text (string, or `(defaults) => ...`).
703
+ *
704
+ * @example
705
+ * { files: ['src/ui/**', '!**\/*.test.*'], rules: [enforceThinDrivingAdapter()] }
706
+ */
707
+ export function enforceThinDrivingAdapter(options = {}) {
708
+ const rules = typeof options.instructions === 'function'
709
+ ? options.instructions(THIN_DRIVING_ADAPTER_INSTRUCTIONS)
710
+ : (options.instructions ?? THIN_DRIVING_ADAPTER_INSTRUCTIONS);
711
+ return async function enforceThinDrivingAdapter(action, ctx) {
712
+ if (action.kind !== 'write')
713
+ return { kind: 'pass' };
714
+ if (!ctx?.agent) {
715
+ return {
716
+ kind: 'violation',
717
+ reason: 'enforceThinDrivingAdapter: no AI agent available; configure Config.ai or use a vendor that ships one.',
718
+ };
719
+ }
720
+ const before = (await ctx.readFile?.(action.path)) ?? {
721
+ kind: 'unknown',
722
+ };
723
+ const sections = [
724
+ rules,
725
+ `## Current file content\n\n${formatBefore(before)}`,
726
+ `## Pending action\n\nFile: ${action.path}\n\n${action.content}`,
727
+ ];
728
+ const exports = [];
729
+ if (options.coreExports) {
730
+ exports.push(listCoreExports({
731
+ globs: options.coreExports.globs,
732
+ root: options.coreExports.root ?? process.cwd(),
733
+ maxChars: options.coreExports.maxChars ?? 8000,
734
+ language: options.coreExports.language,
735
+ }));
736
+ }
737
+ if (options.publishedApi) {
738
+ exports.push(listPublishedApi({
739
+ paths: options.publishedApi.paths,
740
+ root: options.publishedApi.root ?? process.cwd(),
741
+ maxChars: options.publishedApi.maxChars ?? 8000,
742
+ format: options.publishedApi.format,
743
+ }));
744
+ }
745
+ const exportList = exports.filter(Boolean).join('\n');
746
+ if (exportList)
747
+ sections.push(`## Core exports\n\n${exportList}`);
748
+ sections.push(RESPONSE_SPEC);
749
+ const verdict = await ctx.agent.reason(sections.join('\n\n'));
750
+ if (verdict.kind === 'violation') {
751
+ return { kind: 'violation', reason: verdict.reason };
752
+ }
753
+ return { kind: 'pass', reason: verdict.reason };
754
+ };
755
+ }
375
756
  //# sourceMappingURL=ports-and-adapters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ports-and-adapters.js","sourceRoot":"","sources":["../../rules/ports-and-adapters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ports-and-adapters.js","sourceRoot":"","sources":["../../rules/ports-and-adapters.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjchill/probity-rules",
3
- "version": "0.4.15",
3
+ "version": "0.4.17",
4
4
  "description": "Versioned Probity rule presets and CLI tooling for the agent-skills catalog (test-driven-development, ports-and-adapters, acceptance-testing, spec-test parity, ubiquitous-language) — see hooks/PROBITY.md.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,6 +27,11 @@
27
27
  * to your layout. The optional `parity` second argument turns on the
28
28
  * per-scenario driver mapping; see the commented example in
29
29
  * presets/kmp.ts.
30
+ *
31
+ * Thin driving adapters are opt-in: set `drivingAdapterGlobs` to your
32
+ * Compose screens or CLI commands (e.g. `['cli/src/main/**\/commands/**']`)
33
+ * to have each write there judged before the TDD gate. See
34
+ * hooks/PROBITY.md "Driving adapters by project layout".
30
35
  */
31
36
  import { dirname } from 'node:path'
32
37
  import { fileURLToPath } from 'node:url'
@@ -23,6 +23,11 @@
23
23
  * - acceptanceTestGlobs / acceptanceLanguageGlobs — your spec layer
24
24
  * - seamHint — your ambient-effect port(s)
25
25
  * - commitCommand — your real Gradle test task
26
+ * - drivingAdapterGlobs — your Compose screens / CLI commands, held
27
+ * thin (opt-in; an AI call per write), with
28
+ * domainDiscriminants / coreExportsInJudge /
29
+ * coreApiPaths — see hooks/PROBITY.md
30
+ * "Driving adapters by project layout"
26
31
  */
27
32
  import { dirname } from 'node:path'
28
33
  import { fileURLToPath } from 'node:url'
package/probity.config.ts CHANGED
@@ -14,6 +14,11 @@
14
14
  * - coreGlobs — where your core/domain code lives
15
15
  * - infrastructureImports — your stack's known vendor/framework imports
16
16
  * - specGlobs — where your acceptance specs live
17
+ * - drivingAdapterGlobs — your UI components / route handlers, held
18
+ * thin (an AI call per write; [] = off)
19
+ * - domainDiscriminants — fields whose literal comparison in UI code
20
+ * is a domain decision, e.g. ['role'] (off
21
+ * until set; blocks free, before the AI call)
17
22
  * - glossaryPath — absolute path to a ubiquitous-language glossary
18
23
  * - commitCommand / commitSuccessPattern / commitFailurePattern
19
24
  * — your real test command and its output shapes
@@ -36,5 +41,7 @@ import { jsRuleEntries } from '@jjchill/probity-rules/presets/js'
36
41
  export default defineConfig({
37
42
  rules: jsRuleEntries({
38
43
  // glossaryPath: fileURLToPath(new URL('./docs/GLOSSARY.md', import.meta.url)),
44
+ // domainDiscriminants: ['role'],
45
+ // coreExportsInJudge: true,
39
46
  }),
40
47
  })