@llm-dev-ops/agentics-cli 2.4.0 → 2.5.1

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.
Files changed (51) hide show
  1. package/dist/adapters/base-adapter.d.ts +5 -1
  2. package/dist/adapters/base-adapter.d.ts.map +1 -1
  3. package/dist/adapters/base-adapter.js +13 -0
  4. package/dist/adapters/base-adapter.js.map +1 -1
  5. package/dist/agents/repo-agent-runner.d.ts +2 -0
  6. package/dist/agents/repo-agent-runner.d.ts.map +1 -1
  7. package/dist/agents/repo-agent-runner.js +4 -2
  8. package/dist/agents/repo-agent-runner.js.map +1 -1
  9. package/dist/agents/system-prompts.d.ts.map +1 -1
  10. package/dist/agents/system-prompts.js +19 -0
  11. package/dist/agents/system-prompts.js.map +1 -1
  12. package/dist/commands/agents.d.ts +25 -0
  13. package/dist/commands/agents.d.ts.map +1 -1
  14. package/dist/commands/agents.js +186 -3
  15. package/dist/commands/agents.js.map +1 -1
  16. package/dist/config/endpoints.d.ts.map +1 -1
  17. package/dist/config/endpoints.js +8 -0
  18. package/dist/config/endpoints.js.map +1 -1
  19. package/dist/config/qe-gating.d.ts +81 -0
  20. package/dist/config/qe-gating.d.ts.map +1 -0
  21. package/dist/config/qe-gating.js +138 -0
  22. package/dist/config/qe-gating.js.map +1 -0
  23. package/dist/pipeline/phase5-build/qe-gating-executor.d.ts +73 -0
  24. package/dist/pipeline/phase5-build/qe-gating-executor.d.ts.map +1 -0
  25. package/dist/pipeline/phase5-build/qe-gating-executor.js +134 -0
  26. package/dist/pipeline/phase5-build/qe-gating-executor.js.map +1 -0
  27. package/dist/promotion/graph-diff.d.ts +39 -0
  28. package/dist/promotion/graph-diff.d.ts.map +1 -0
  29. package/dist/promotion/graph-diff.js +60 -0
  30. package/dist/promotion/graph-diff.js.map +1 -0
  31. package/dist/promotion/sampler-lib.d.ts +45 -0
  32. package/dist/promotion/sampler-lib.d.ts.map +1 -0
  33. package/dist/promotion/sampler-lib.js +96 -0
  34. package/dist/promotion/sampler-lib.js.map +1 -0
  35. package/dist/routing/domain-boundary.d.ts +92 -0
  36. package/dist/routing/domain-boundary.d.ts.map +1 -0
  37. package/dist/routing/domain-boundary.js +208 -0
  38. package/dist/routing/domain-boundary.js.map +1 -0
  39. package/dist/routing/graph-router.d.ts +31 -1
  40. package/dist/routing/graph-router.d.ts.map +1 -1
  41. package/dist/routing/graph-router.js +91 -4
  42. package/dist/routing/graph-router.js.map +1 -1
  43. package/dist/routing/index.d.ts +13 -3
  44. package/dist/routing/index.d.ts.map +1 -1
  45. package/dist/routing/index.js +9 -4
  46. package/dist/routing/index.js.map +1 -1
  47. package/dist/types/index.d.ts +1 -0
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/types/index.js.map +1 -1
  50. package/docs/ecosystem.graph.json +87 -14
  51. package/package.json +1 -1
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Pure logic for the promotion sampler (ADR-PIPELINE-084 §2.1).
3
+ *
4
+ * Parses, filters, and samples domain agent findings for human FP-rate review.
5
+ * The CLI wrapper lives in tools/promotion-sampler.ts and handles I/O + args;
6
+ * all deterministic logic is here and independently testable.
7
+ */
8
+ export interface Finding {
9
+ id: string;
10
+ timestamp: string;
11
+ domain: string;
12
+ agent: string;
13
+ severity: 'low' | 'medium' | 'high' | 'critical' | string;
14
+ blocking: boolean;
15
+ summary: string;
16
+ }
17
+ export interface SampleOptions {
18
+ /** Random seed for reproducibility in tests. */
19
+ seed?: number;
20
+ }
21
+ /**
22
+ * Parse a blob that is either JSON array of findings or newline-delimited
23
+ * JSON (JSONL). Returns [] for empty input.
24
+ */
25
+ export declare function parseFindings(raw: string): Finding[];
26
+ /**
27
+ * Keep findings from the specified domain whose timestamps fall within
28
+ * [now - windowDays, now].
29
+ */
30
+ export declare function filterInWindow(findings: Finding[], domain: string, windowDays: number, now?: Date): Finding[];
31
+ /**
32
+ * Keep only blocking findings (ADR-084 §2 — FP rate is computed against
33
+ * findings the agent marked blocking).
34
+ */
35
+ export declare function filterBlocking(findings: Finding[]): Finding[];
36
+ /**
37
+ * Draw a random sample. Size = max(floor(0.1 * N), 30), capped at 200.
38
+ * If N ≤ 30, returns everything.
39
+ */
40
+ export declare function drawSample(findings: Finding[], options?: SampleOptions): Finding[];
41
+ /**
42
+ * Emit a CSV with a blank fp_label column for the reviewer.
43
+ */
44
+ export declare function toCsv(sample: Finding[]): string;
45
+ //# sourceMappingURL=sampler-lib.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampler-lib.d.ts","sourceRoot":"","sources":["../../src/promotion/sampler-lib.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IAC1D,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAcpD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,IAAiB,GACrB,OAAO,EAAE,CAOX;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAE7D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,EAAE,CAmBtF;AAcD;;GAEG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAO/C"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Pure logic for the promotion sampler (ADR-PIPELINE-084 §2.1).
3
+ *
4
+ * Parses, filters, and samples domain agent findings for human FP-rate review.
5
+ * The CLI wrapper lives in tools/promotion-sampler.ts and handles I/O + args;
6
+ * all deterministic logic is here and independently testable.
7
+ */
8
+ /**
9
+ * Parse a blob that is either JSON array of findings or newline-delimited
10
+ * JSON (JSONL). Returns [] for empty input.
11
+ */
12
+ export function parseFindings(raw) {
13
+ const trimmed = raw.trim();
14
+ if (!trimmed)
15
+ return [];
16
+ if (trimmed.startsWith('[')) {
17
+ const arr = JSON.parse(trimmed);
18
+ return Array.isArray(arr) ? arr : [];
19
+ }
20
+ return trimmed
21
+ .split('\n')
22
+ .map(l => l.trim())
23
+ .filter(l => l.length > 0)
24
+ .map(l => JSON.parse(l));
25
+ }
26
+ /**
27
+ * Keep findings from the specified domain whose timestamps fall within
28
+ * [now - windowDays, now].
29
+ */
30
+ export function filterInWindow(findings, domain, windowDays, now = new Date()) {
31
+ const cutoff = new Date(now.getTime() - windowDays * 24 * 60 * 60 * 1000);
32
+ return findings.filter(f => {
33
+ if (f.domain !== domain)
34
+ return false;
35
+ const ts = new Date(f.timestamp);
36
+ return ts >= cutoff && ts <= now;
37
+ });
38
+ }
39
+ /**
40
+ * Keep only blocking findings (ADR-084 §2 — FP rate is computed against
41
+ * findings the agent marked blocking).
42
+ */
43
+ export function filterBlocking(findings) {
44
+ return findings.filter(f => f.blocking === true);
45
+ }
46
+ /**
47
+ * Draw a random sample. Size = max(floor(0.1 * N), 30), capped at 200.
48
+ * If N ≤ 30, returns everything.
49
+ */
50
+ export function drawSample(findings, options = {}) {
51
+ const n = findings.length;
52
+ if (n === 0)
53
+ return [];
54
+ if (n <= 30)
55
+ return [...findings];
56
+ const tenPercent = Math.floor(n * 0.1);
57
+ const targetSize = Math.min(Math.max(tenPercent, 30), 200);
58
+ const rng = makeRng(options.seed ?? Date.now());
59
+ const copy = [...findings];
60
+ for (let i = 0; i < targetSize; i++) {
61
+ const j = i + Math.floor(rng() * (copy.length - i));
62
+ const tmp = copy[i];
63
+ copy[i] = copy[j];
64
+ copy[j] = tmp;
65
+ }
66
+ return copy.slice(0, targetSize);
67
+ }
68
+ function makeRng(seed) {
69
+ // Mulberry32 — deterministic, seedable PRNG for reproducible tests.
70
+ let a = seed >>> 0;
71
+ return () => {
72
+ a = (a + 0x6d2b79f5) >>> 0;
73
+ let t = a;
74
+ t = Math.imul(t ^ (t >>> 15), t | 1);
75
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
76
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
77
+ };
78
+ }
79
+ /**
80
+ * Emit a CSV with a blank fp_label column for the reviewer.
81
+ */
82
+ export function toCsv(sample) {
83
+ const header = 'id,timestamp,domain,agent,severity,blocking,summary,fp_label';
84
+ const rows = sample.map(f => {
85
+ const summary = escapeCsv(f.summary ?? '');
86
+ return [f.id, f.timestamp, f.domain, f.agent, f.severity, f.blocking, summary, ''].join(',');
87
+ });
88
+ return [header, ...rows].join('\n') + '\n';
89
+ }
90
+ function escapeCsv(value) {
91
+ if (/[,"\n]/.test(value)) {
92
+ return `"${value.replace(/"/g, '""')}"`;
93
+ }
94
+ return value;
95
+ }
96
+ //# sourceMappingURL=sampler-lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampler-lib.js","sourceRoot":"","sources":["../../src/promotion/sampler-lib.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Domain Boundary Resolution (ADR-PIPELINE-082)
3
+ *
4
+ * Disambiguation rules for overlapping capability keywords and tie-break rules
5
+ * for domain ownership. Used to resolve which domain should handle a query
6
+ * when multiple domains could legitimately claim the same tag.
7
+ *
8
+ * Two rule types:
9
+ * 1. DISAMBIGUATION_RULES — modifier-based routing (ADR-082 §3).
10
+ * "regression" alone → test_bench; "regression test" → quality_engineering.
11
+ * 2. TIE_BREAK_RULES — priority resolution (ADR-082 §4).
12
+ * "security" always goes to safety (shield), never quality_engineering.
13
+ *
14
+ * This module is declarative; callers (capability classifier, agentics ask)
15
+ * consult it to refine routing decisions. It performs no I/O and is safe to
16
+ * import anywhere.
17
+ */
18
+ /**
19
+ * A disambiguation rule for a keyword that could route to multiple domains
20
+ * depending on nearby modifiers in the prompt.
21
+ */
22
+ export interface DisambiguationRule {
23
+ /** Trigger keyword that activates this rule (lowercase). */
24
+ readonly trigger: string;
25
+ /** Ordered modifier patterns. First match wins. */
26
+ readonly modifiers: readonly {
27
+ pattern: RegExp;
28
+ domain: string;
29
+ }[];
30
+ /** Domain used when no modifier matches. */
31
+ readonly defaultDomain: string;
32
+ /** Human-readable rationale tied to ADR-082. */
33
+ readonly note: string;
34
+ }
35
+ /**
36
+ * A tie-break rule declaring that one domain always wins a keyword over
37
+ * another. Used to enforce the capability ownership boundary from ADR-082 §1.
38
+ */
39
+ export interface TieBreakRule {
40
+ /** Keyword that triggers this rule (lowercase). */
41
+ readonly keyword: string;
42
+ /** The domain that wins — its capabilities stay. */
43
+ readonly winner: string;
44
+ /**
45
+ * Domains whose capabilities are suppressed when this keyword is present
46
+ * AND they would otherwise match. Empty means "both stay" (complementary).
47
+ */
48
+ readonly suppress: readonly string[];
49
+ /** Human-readable rationale. */
50
+ readonly note: string;
51
+ }
52
+ /** Result of resolving a prompt against the boundary rules. */
53
+ export interface BoundaryResolution {
54
+ /** Disambiguation resolutions: keyword → winning domain. */
55
+ readonly disambiguations: ReadonlyMap<string, string>;
56
+ /** Suppressed domains — their capabilities should be filtered from routing. */
57
+ readonly suppressedDomains: ReadonlySet<string>;
58
+ /** Applied rules for explain/debug. */
59
+ readonly appliedRules: readonly string[];
60
+ }
61
+ /**
62
+ * Modifier-based disambiguation rules. Order within modifiers[] matters:
63
+ * the first matching modifier wins, so more specific patterns come first.
64
+ */
65
+ export declare const DISAMBIGUATION_RULES: readonly DisambiguationRule[];
66
+ /**
67
+ * Priority resolution: certain keywords always belong to one domain regardless
68
+ * of what other domains might tag. Enforces the capability ownership boundary
69
+ * declared in ADR-082 §1 (Shield owns security, Latency-Lens owns perf, etc.).
70
+ *
71
+ * Note on domain names: ecosystem.graph.json uses underscores
72
+ * ("quality_engineering"), the CLI runner uses hyphens ("quality-engineering").
73
+ * These rules use the graph names (underscored) to match what the classifier
74
+ * emits.
75
+ */
76
+ export declare const TIE_BREAK_RULES: readonly TieBreakRule[];
77
+ /**
78
+ * Apply ADR-082 boundary rules to a user prompt.
79
+ * Returns disambiguation decisions and suppressed domains.
80
+ */
81
+ export declare function resolveDomainBoundary(prompt: string): BoundaryResolution;
82
+ /**
83
+ * Check whether a domain should be filtered from routing given the prompt.
84
+ * Convenience wrapper over resolveDomainBoundary.
85
+ */
86
+ export declare function isDomainSuppressed(domain: string, prompt: string): boolean;
87
+ /**
88
+ * Resolve a single keyword to its routing domain, applying both disambiguation
89
+ * and tie-break rules. Returns null if the keyword is not governed by any rule.
90
+ */
91
+ export declare function routeKeyword(keyword: string, prompt: string): string | null;
92
+ //# sourceMappingURL=domain-boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-boundary.d.ts","sourceRoot":"","sources":["../../src/routing/domain-boundary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnE,4CAA4C;IAC5C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtD,+EAA+E;IAC/E,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,uCAAuC;IACvC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAMD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,kBAAkB,EAqC7D,CAAC;AAMF;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EA0BlD,CAAC;AAMF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CA2CxE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkB3E"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Domain Boundary Resolution (ADR-PIPELINE-082)
3
+ *
4
+ * Disambiguation rules for overlapping capability keywords and tie-break rules
5
+ * for domain ownership. Used to resolve which domain should handle a query
6
+ * when multiple domains could legitimately claim the same tag.
7
+ *
8
+ * Two rule types:
9
+ * 1. DISAMBIGUATION_RULES — modifier-based routing (ADR-082 §3).
10
+ * "regression" alone → test_bench; "regression test" → quality_engineering.
11
+ * 2. TIE_BREAK_RULES — priority resolution (ADR-082 §4).
12
+ * "security" always goes to safety (shield), never quality_engineering.
13
+ *
14
+ * This module is declarative; callers (capability classifier, agentics ask)
15
+ * consult it to refine routing decisions. It performs no I/O and is safe to
16
+ * import anywhere.
17
+ */
18
+ // ============================================================================
19
+ // Rules — ADR-082 §3
20
+ // ============================================================================
21
+ /**
22
+ * Modifier-based disambiguation rules. Order within modifiers[] matters:
23
+ * the first matching modifier wins, so more specific patterns come first.
24
+ */
25
+ export const DISAMBIGUATION_RULES = [
26
+ {
27
+ trigger: 'regression',
28
+ modifiers: [
29
+ { pattern: /\btests?\b/i, domain: 'quality_engineering' },
30
+ { pattern: /\b(models?|qualit(?:y|ies))\b/i, domain: 'test_bench' },
31
+ ],
32
+ defaultDomain: 'test_bench',
33
+ note: 'ADR-082 §3: "regression test" → QE; "model regression" → test_bench',
34
+ },
35
+ {
36
+ trigger: 'quality',
37
+ modifiers: [
38
+ { pattern: /\b(code|tests?)\s+qualit(?:y|ies)\b/i, domain: 'quality_engineering' },
39
+ { pattern: /\b(models?|outputs?)\s+qualit(?:y|ies)\b/i, domain: 'test_bench' },
40
+ ],
41
+ defaultDomain: 'quality_engineering',
42
+ note: 'ADR-082 §3: code/test quality → QE; model/output quality → test_bench',
43
+ },
44
+ {
45
+ trigger: 'evaluation',
46
+ modifiers: [
47
+ { pattern: /\b(code|tests?|coverage|defects?)\b/i, domain: 'quality_engineering' },
48
+ { pattern: /\b(models?|prompts?|llms?)\b/i, domain: 'test_bench' },
49
+ ],
50
+ defaultDomain: 'test_bench',
51
+ note: 'ADR-082 §3: code/test evaluation → QE; model/prompt evaluation → test_bench',
52
+ },
53
+ {
54
+ trigger: 'synthetic',
55
+ modifiers: [
56
+ { pattern: /\b(tests?|fixtures?|mocks?)\b/i, domain: 'quality_engineering' },
57
+ { pattern: /\b(benchmarks?|datasets?|training)\b/i, domain: 'test_bench' },
58
+ ],
59
+ defaultDomain: 'test_bench',
60
+ note: 'ADR-082 §3: synthetic test data → QE; synthetic benchmark data → test_bench',
61
+ },
62
+ ];
63
+ // ============================================================================
64
+ // Rules — ADR-082 §4
65
+ // ============================================================================
66
+ /**
67
+ * Priority resolution: certain keywords always belong to one domain regardless
68
+ * of what other domains might tag. Enforces the capability ownership boundary
69
+ * declared in ADR-082 §1 (Shield owns security, Latency-Lens owns perf, etc.).
70
+ *
71
+ * Note on domain names: ecosystem.graph.json uses underscores
72
+ * ("quality_engineering"), the CLI runner uses hyphens ("quality-engineering").
73
+ * These rules use the graph names (underscored) to match what the classifier
74
+ * emits.
75
+ */
76
+ export const TIE_BREAK_RULES = [
77
+ // Safety (Shield) owns security (ADR-082 §1 + §4)
78
+ { keyword: 'security', winner: 'safety', suppress: ['quality_engineering'], note: 'Shield owns security per ADR-082 §1' },
79
+ { keyword: 'sast', winner: 'safety', suppress: ['quality_engineering'], note: 'Shield owns SAST per ADR-082 §1' },
80
+ { keyword: 'dast', winner: 'safety', suppress: ['quality_engineering'], note: 'Shield owns DAST per ADR-082 §1' },
81
+ { keyword: 'vulnerability', winner: 'safety', suppress: ['quality_engineering'], note: 'Shield owns vulnerability scanning per ADR-082 §1' },
82
+ { keyword: 'penetration', winner: 'safety', suppress: ['quality_engineering'], note: 'Shield owns pentest per ADR-082 §1' },
83
+ // Performance Profiling (Latency-Lens) owns perf measurement, QE complements with chaos stressing
84
+ { keyword: 'latency', winner: 'performance_profiling', suppress: [], note: 'Latency-Lens owns perf measurement; QE complements via chaos. Both stay.' },
85
+ { keyword: 'cold-start', winner: 'performance_profiling', suppress: [], note: 'Latency-Lens owns cold-start; ADR-082 §4' },
86
+ // Data Privacy (Data-Vault) owns anonymization
87
+ { keyword: 'anonymize', winner: 'data_security', suppress: ['quality_engineering'], note: 'Data-Vault owns anonymization per ADR-082 §1' },
88
+ { keyword: 'pii', winner: 'safety', suppress: ['quality_engineering'], note: 'Shield owns PII detection per ADR-082 §1' },
89
+ { keyword: 'redaction', winner: 'safety', suppress: ['quality_engineering'], note: 'Shield owns redaction per ADR-082 §1' },
90
+ // ERP boundary (connector-hub + ERP-Surface, ADR-074)
91
+ { keyword: 'sap', winner: 'connector_hub', suppress: ['quality_engineering'], note: 'ERP surface boundary — connector-hub owns SAP integration per ADR-082 §1 + ADR-074' },
92
+ { keyword: 'oracle', winner: 'connector_hub', suppress: ['quality_engineering'], note: 'ERP surface boundary per ADR-074' },
93
+ { keyword: 'workday', winner: 'connector_hub', suppress: ['quality_engineering'], note: 'ERP surface boundary per ADR-074' },
94
+ { keyword: 'soap', winner: 'connector_hub', suppress: ['quality_engineering'], note: 'Enterprise integration surface per ADR-082 §1' },
95
+ { keyword: 'odata', winner: 'connector_hub', suppress: ['quality_engineering'], note: 'Enterprise integration surface per ADR-082 §1' },
96
+ // Memory/learning (Memory-Graph)
97
+ { keyword: 'learning', winner: 'memory_context', suppress: ['quality_engineering'], note: 'Memory-Graph owns cross-session learning per ADR-082 §1' },
98
+ ];
99
+ // ============================================================================
100
+ // Resolvers
101
+ // ============================================================================
102
+ /**
103
+ * Apply ADR-082 boundary rules to a user prompt.
104
+ * Returns disambiguation decisions and suppressed domains.
105
+ */
106
+ export function resolveDomainBoundary(prompt) {
107
+ const promptLower = prompt.toLowerCase();
108
+ const disambiguations = new Map();
109
+ const suppressedDomains = new Set();
110
+ const appliedRules = [];
111
+ // Disambiguation rules
112
+ for (const rule of DISAMBIGUATION_RULES) {
113
+ if (!wordPresent(promptLower, rule.trigger))
114
+ continue;
115
+ let matched = false;
116
+ for (const mod of rule.modifiers) {
117
+ if (mod.pattern.test(prompt)) {
118
+ disambiguations.set(rule.trigger, mod.domain);
119
+ appliedRules.push(`disambiguation:${rule.trigger}→${mod.domain} (${rule.note})`);
120
+ matched = true;
121
+ break;
122
+ }
123
+ }
124
+ if (!matched) {
125
+ disambiguations.set(rule.trigger, rule.defaultDomain);
126
+ appliedRules.push(`disambiguation:${rule.trigger}→${rule.defaultDomain} (default, ${rule.note})`);
127
+ }
128
+ }
129
+ // Tie-break rules
130
+ for (const rule of TIE_BREAK_RULES) {
131
+ if (!wordPresent(promptLower, rule.keyword))
132
+ continue;
133
+ for (const loser of rule.suppress) {
134
+ suppressedDomains.add(loser);
135
+ }
136
+ if (rule.suppress.length > 0) {
137
+ appliedRules.push(`tie-break:${rule.keyword}→${rule.winner} (suppress: ${rule.suppress.join(', ')})`);
138
+ }
139
+ else {
140
+ appliedRules.push(`tie-break:${rule.keyword}→${rule.winner} (complementary, no suppression)`);
141
+ }
142
+ }
143
+ return {
144
+ disambiguations,
145
+ suppressedDomains,
146
+ appliedRules,
147
+ };
148
+ }
149
+ /**
150
+ * Check whether a domain should be filtered from routing given the prompt.
151
+ * Convenience wrapper over resolveDomainBoundary.
152
+ */
153
+ export function isDomainSuppressed(domain, prompt) {
154
+ return resolveDomainBoundary(prompt).suppressedDomains.has(domain);
155
+ }
156
+ /**
157
+ * Resolve a single keyword to its routing domain, applying both disambiguation
158
+ * and tie-break rules. Returns null if the keyword is not governed by any rule.
159
+ */
160
+ export function routeKeyword(keyword, prompt) {
161
+ const keywordLower = keyword.toLowerCase();
162
+ // Disambiguation takes precedence when a modifier matches
163
+ for (const rule of DISAMBIGUATION_RULES) {
164
+ if (rule.trigger !== keywordLower)
165
+ continue;
166
+ for (const mod of rule.modifiers) {
167
+ if (mod.pattern.test(prompt))
168
+ return mod.domain;
169
+ }
170
+ return rule.defaultDomain;
171
+ }
172
+ // Fall through to tie-break rules
173
+ for (const rule of TIE_BREAK_RULES) {
174
+ if (rule.keyword === keywordLower)
175
+ return rule.winner;
176
+ }
177
+ return null;
178
+ }
179
+ // ============================================================================
180
+ // Internals
181
+ // ============================================================================
182
+ /**
183
+ * Test whether a keyword appears in the prompt as a whole word, allowing
184
+ * common English inflections at the end (plural -s/-es/-ies, participle
185
+ * -ed/-ing).
186
+ *
187
+ * Matches: "security", "securities", "regression", "regressions"
188
+ * "vulnerability", "vulnerabilities", "cold-start", "cold-started"
189
+ * Does not match: "insecurity" (no preceding word boundary)
190
+ */
191
+ function wordPresent(promptLower, keyword) {
192
+ const escaped = keyword.replace(/[-\s]/g, '[-\\s]').replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
193
+ // Allow up to 4 trailing letters to catch common stems (s, es, ed, ing, ies)
194
+ // without matching unrelated long words. The leading boundary remains strict.
195
+ const re = new RegExp(`(?:^|[^a-z0-9_])${escaped}[a-z]{0,4}(?:$|[^a-z0-9_])`, 'i');
196
+ if (re.test(promptLower))
197
+ return true;
198
+ // Handle -y → -ies plurals explicitly (e.g., "vulnerability" → "vulnerabilities")
199
+ if (keyword.endsWith('y')) {
200
+ const stem = keyword.slice(0, -1);
201
+ const escapedStem = stem.replace(/[-\s]/g, '[-\\s]').replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
202
+ const iesRe = new RegExp(`(?:^|[^a-z0-9_])${escapedStem}ies(?:$|[^a-z0-9_])`, 'i');
203
+ if (iesRe.test(promptLower))
204
+ return true;
205
+ }
206
+ return false;
207
+ }
208
+ //# sourceMappingURL=domain-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-boundary.js","sourceRoot":"","sources":["../../src/routing/domain-boundary.ts"],"names":[],"mappings":"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"}
@@ -93,11 +93,41 @@ export interface DomainAgentRef {
93
93
  * Returns undefined for unknown agents.
94
94
  */
95
95
  export declare function resolveAgentRef(agentName: string): DomainAgentRef | undefined;
96
+ /**
97
+ * A classifier-selected agent whose display name did not resolve to a
98
+ * domain/agent pair. ADR-PIPELINE-087 §4 surfaces these instead of dropping
99
+ * them silently.
100
+ */
101
+ export interface UnresolvedAgent {
102
+ readonly stage: StageName;
103
+ readonly agentName: string;
104
+ readonly capability: string;
105
+ }
106
+ /**
107
+ * Result of projecting a RoutingResult onto the dispatch layer. The
108
+ * `unresolved` list is the ADR-PIPELINE-087 §4 signal: agents the graph
109
+ * selected but the resolver could not map. An empty array is the healthy state.
110
+ */
111
+ export interface DispatchProjection {
112
+ readonly refs: readonly DomainAgentRef[];
113
+ readonly unresolved: readonly UnresolvedAgent[];
114
+ }
115
+ /**
116
+ * Convert a routing result into a flat list of domain/agent pairs
117
+ * ready for dispatch via the existing executeAgentsInvokeCommand, along with
118
+ * the list of agents that failed to resolve.
119
+ *
120
+ * ADR-PIPELINE-087 §4: unresolved agents are logged at WARN (stderr) and
121
+ * returned to the caller so they can be surfaced in the JSON envelope
122
+ * (`routing.unresolved`) and in the MCP tool response.
123
+ */
124
+ export declare function projectDispatch(result: RoutingResult): DispatchProjection;
96
125
  /**
97
126
  * Convert a routing result into a flat list of domain/agent pairs
98
127
  * ready for dispatch via the existing executeAgentsInvokeCommand.
99
128
  *
100
- * Agents that cannot be mapped are logged and skipped.
129
+ * Agents that cannot be mapped are logged and skipped. Prefer
130
+ * {@link projectDispatch} when the caller needs the unresolved list.
101
131
  */
102
132
  export declare function toDomainAgentList(result: RoutingResult): DomainAgentRef[];
103
133
  //# sourceMappingURL=graph-router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph-router.d.ts","sourceRoot":"","sources":["../../src/routing/graph-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAmB,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEpF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAMjE,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAC9C,gDAAgD;IAChD,QAAQ,CAAC,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAC;IACjD,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IACzC,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6CAA6C;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CAChD;AAMD,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,yDAAyD;IACzD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,yDAAyD;IACzD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAaD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,oBAAoB,EACpC,KAAK,EAAE,cAAc,EACrB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,aAAa,CAmHf;AAgKD;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AA2ID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,EAAE,CAkBzE"}
1
+ {"version":3,"file":"graph-router.d.ts","sourceRoot":"","sources":["../../src/routing/graph-router.ts"],"names":[],"mappings":"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"}