@vyuhlabs/dxkit 2.20.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/allowlist/categories.d.ts.map +1 -1
  3. package/dist/allowlist/categories.js +4 -0
  4. package/dist/allowlist/categories.js.map +1 -1
  5. package/dist/allowlist/hint.d.ts.map +1 -1
  6. package/dist/allowlist/hint.js +6 -0
  7. package/dist/allowlist/hint.js.map +1 -1
  8. package/dist/analyzers/flow/config.d.ts +37 -0
  9. package/dist/analyzers/flow/config.d.ts.map +1 -0
  10. package/dist/analyzers/flow/config.js +84 -0
  11. package/dist/analyzers/flow/config.js.map +1 -0
  12. package/dist/analyzers/flow/contract.d.ts +93 -0
  13. package/dist/analyzers/flow/contract.d.ts.map +1 -0
  14. package/dist/analyzers/flow/contract.js +176 -0
  15. package/dist/analyzers/flow/contract.js.map +1 -0
  16. package/dist/analyzers/flow/gate.d.ts +64 -0
  17. package/dist/analyzers/flow/gate.d.ts.map +1 -0
  18. package/dist/analyzers/flow/gate.js +84 -0
  19. package/dist/analyzers/flow/gate.js.map +1 -0
  20. package/dist/analyzers/flow/gather.d.ts +11 -0
  21. package/dist/analyzers/flow/gather.d.ts.map +1 -1
  22. package/dist/analyzers/flow/gather.js +10 -9
  23. package/dist/analyzers/flow/gather.js.map +1 -1
  24. package/dist/analyzers/flow/model.d.ts +12 -0
  25. package/dist/analyzers/flow/model.d.ts.map +1 -1
  26. package/dist/analyzers/flow/model.js +25 -3
  27. package/dist/analyzers/flow/model.js.map +1 -1
  28. package/dist/analyzers/tools/fingerprint.d.ts +32 -0
  29. package/dist/analyzers/tools/fingerprint.d.ts.map +1 -1
  30. package/dist/analyzers/tools/fingerprint.js +37 -1
  31. package/dist/analyzers/tools/fingerprint.js.map +1 -1
  32. package/dist/baseline/check-renderers.d.ts +21 -0
  33. package/dist/baseline/check-renderers.d.ts.map +1 -1
  34. package/dist/baseline/check-renderers.js +93 -3
  35. package/dist/baseline/check-renderers.js.map +1 -1
  36. package/dist/baseline/check.d.ts +18 -0
  37. package/dist/baseline/check.d.ts.map +1 -1
  38. package/dist/baseline/check.js +21 -2
  39. package/dist/baseline/check.js.map +1 -1
  40. package/dist/baseline/entry-to-located.d.ts.map +1 -1
  41. package/dist/baseline/entry-to-located.js +7 -0
  42. package/dist/baseline/entry-to-located.js.map +1 -1
  43. package/dist/baseline/finding-identity.d.ts.map +1 -1
  44. package/dist/baseline/finding-identity.js +5 -0
  45. package/dist/baseline/finding-identity.js.map +1 -1
  46. package/dist/baseline/flow-gate-check.d.ts +60 -0
  47. package/dist/baseline/flow-gate-check.d.ts.map +1 -0
  48. package/dist/baseline/flow-gate-check.js +171 -0
  49. package/dist/baseline/flow-gate-check.js.map +1 -0
  50. package/dist/baseline/migrate.d.ts.map +1 -1
  51. package/dist/baseline/migrate.js +3 -0
  52. package/dist/baseline/migrate.js.map +1 -1
  53. package/dist/baseline/producers/index.d.ts.map +1 -1
  54. package/dist/baseline/producers/index.js +9 -0
  55. package/dist/baseline/producers/index.js.map +1 -1
  56. package/dist/baseline/show.js +2 -0
  57. package/dist/baseline/show.js.map +1 -1
  58. package/dist/baseline/types.d.ts +32 -2
  59. package/dist/baseline/types.d.ts.map +1 -1
  60. package/dist/cli.d.ts.map +1 -1
  61. package/dist/cli.js +8 -0
  62. package/dist/cli.js.map +1 -1
  63. package/dist/explore/flow-graph.d.ts +1 -1
  64. package/dist/explore/flow-graph.d.ts.map +1 -1
  65. package/dist/explore/flow-graph.js +4 -12
  66. package/dist/explore/flow-graph.js.map +1 -1
  67. package/dist/flow-cli.d.ts +10 -0
  68. package/dist/flow-cli.d.ts.map +1 -1
  69. package/dist/flow-cli.js +63 -18
  70. package/dist/flow-cli.js.map +1 -1
  71. package/dist/languages/index.d.ts +21 -0
  72. package/dist/languages/index.d.ts.map +1 -1
  73. package/dist/languages/index.js +41 -0
  74. package/dist/languages/index.js.map +1 -1
  75. package/dist/loop/policy.d.ts +4 -1
  76. package/dist/loop/policy.d.ts.map +1 -1
  77. package/dist/loop/policy.js +3 -0
  78. package/dist/loop/policy.js.map +1 -1
  79. package/dist/loop/stop-gate.d.ts.map +1 -1
  80. package/dist/loop/stop-gate.js +8 -2
  81. package/dist/loop/stop-gate.js.map +1 -1
  82. package/package.json +1 -1
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ /**
3
+ * The integration-breakage gate — pure evaluation core.
4
+ *
5
+ * Answers "does this diff NET-NEW break a UI→API integration?" from a base↔HEAD
6
+ * contract comparison, with no running system. One algorithm covers both
7
+ * directions (CLAUDE.md design §6):
8
+ * - a FRONTEND PR that adds a call to an endpoint no backend serves, and
9
+ * - a BACKEND PR that removes/renames a route a frontend still calls,
10
+ * because both reduce to "a consumed binding whose (method, path) is not in the
11
+ * served set". The diff makes it net-new: a binding already broken BEFORE the
12
+ * PR (present at base and unresolved against the base served set) is
13
+ * grandfathered; only a binding the PR NEWLY breaks is surfaced.
14
+ *
15
+ * Pure over its inputs — the ref-based gather (base worktree via
16
+ * `withRefWorktree`, Rule 11) and the guardrail wiring live above this module;
17
+ * here we only diff two already-materialized contract sides. Identity is the
18
+ * flow-binding fingerprint (line-independent (method, path, file), Rule 9),
19
+ * computed through the canonical helper so an emitted finding shares one
20
+ * identity contract with the baseline + allowlist.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.evaluateFlowGate = evaluateFlowGate;
24
+ exports.flowGateBlocks = flowGateBlocks;
25
+ exports.describeBrokenIntegration = describeBrokenIntegration;
26
+ const fingerprint_1 = require("../tools/fingerprint");
27
+ const contract_1 = require("./contract");
28
+ /** The flow-binding identity tuple as a map key (method, path, file). */
29
+ function identityKey(b) {
30
+ return `${b.method}\0${b.path}\0${b.file}`;
31
+ }
32
+ /**
33
+ * Evaluate the gate. Returns every NET-NEW broken integration, most-severe
34
+ * (block before warn) first, then by location for stable output. Empty when the
35
+ * diff breaks nothing new.
36
+ */
37
+ function evaluateFlowGate(inputs) {
38
+ const blockThreshold = inputs.blockThreshold ?? 1;
39
+ const baseByIdentity = new Map();
40
+ for (const b of inputs.baseConsumed)
41
+ baseByIdentity.set(identityKey(b), b);
42
+ const out = [];
43
+ for (const b of inputs.headConsumed) {
44
+ const key = (0, contract_1.contractKey)(b.method, b.path);
45
+ if (inputs.headServed.has(key))
46
+ continue; // resolves at HEAD → not broken
47
+ // Broken at HEAD. Was the SAME binding already broken at base? (present at
48
+ // base AND unresolved against the base served set) → grandfathered.
49
+ const base = baseByIdentity.get(identityKey(b));
50
+ const brokenBefore = base !== undefined && !inputs.baseServed.has(key);
51
+ if (brokenBefore)
52
+ continue;
53
+ // Net-new. `route-removed` when the binding existed at base and WAS served
54
+ // then (the PR removed the route); otherwise the call itself is new or
55
+ // never resolved (`no-route`).
56
+ const reason = base !== undefined && inputs.baseServed.has(key) ? 'route-removed' : 'no-route';
57
+ out.push({
58
+ id: (0, fingerprint_1.computeFlowBindingFingerprint)(b.method, b.path, b.file),
59
+ method: b.method,
60
+ path: b.path,
61
+ file: b.file,
62
+ line: b.line,
63
+ confidence: b.confidence,
64
+ reason,
65
+ verdict: b.confidence >= blockThreshold ? 'block' : 'warn',
66
+ });
67
+ }
68
+ out.sort((a, z) => Number(z.verdict === 'block') - Number(a.verdict === 'block') ||
69
+ a.file.localeCompare(z.file) ||
70
+ a.path.localeCompare(z.path));
71
+ return out;
72
+ }
73
+ /** Does the gate result block? True when any finding's verdict is `block`. */
74
+ function flowGateBlocks(findings) {
75
+ return findings.some((f) => f.verdict === 'block');
76
+ }
77
+ /** Human-readable one-liner for a broken integration (report + Stop-gate). */
78
+ function describeBrokenIntegration(f) {
79
+ const what = f.reason === 'route-removed'
80
+ ? `removed ${f.method} ${f.path} still called by`
81
+ : `${f.method} ${f.path} matches no served route —`;
82
+ return `net-new broken integration: ${what} ${f.file}:${f.line}`;
83
+ }
84
+ //# sourceMappingURL=gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../../src/analyzers/flow/gate.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,17 @@ export interface GatherFlowOptions {
18
18
  readonly specs?: readonly string[];
19
19
  /** Host-helper prefixes to strip during URL normalization (per-app config). */
20
20
  readonly stripUrlPrefixes?: readonly string[];
21
+ /**
22
+ * Relabel every extracted call / route `file` relative to this directory.
23
+ * Off by default (files keep their scanned absolute path — the M2 map/trace
24
+ * display form). The flow-binding identity contract (Rule 9) requires an
25
+ * environment-INDEPENDENT locator, so the gate and `flow refresh` set this to
26
+ * the repo root: a binding gathered from the working tree and the same file
27
+ * gathered from a detached worktree then share one relative `file`, and the
28
+ * committed `consumed.json` carries repo-relative paths that mean the same
29
+ * thing on any machine.
30
+ */
31
+ readonly relativeTo?: string;
21
32
  }
22
33
  /** Walk + extract + assemble. Files that don't parse are skipped, never fatal. */
23
34
  export declare function gatherFlowModel(opts: GatherFlowOptions): Promise<FlowModel>;
@@ -1 +1 @@
1
- {"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../../../src/analyzers/flow/gather.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAIzD,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,+EAA+E;IAC/E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAaD,kFAAkF;AAClF,wBAAsB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,CAgBjF"}
1
+ {"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../../../src/analyzers/flow/gather.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAIzD,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,+EAA+E;IAC/E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAgBD,kFAAkF;AAClF,wBAAsB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,CAgBjF"}
@@ -21,14 +21,15 @@ const model_1 = require("./model");
21
21
  const spec_source_1 = require("./spec-source");
22
22
  /** Extensions of packs that can contribute flow (httpFlow + a grammar). */
23
23
  function flowExtensions() {
24
- const exts = new Set();
25
- for (const pack of languages_1.LANGUAGES) {
26
- if (pack.httpFlow && pack.treeSitterGrammars) {
27
- for (const ext of Object.keys(pack.treeSitterGrammars))
28
- exts.add(ext);
29
- }
30
- }
31
- return [...exts];
24
+ return (0, languages_1.allFlowSourceExtensions)(languages_1.LANGUAGES);
25
+ }
26
+ /** Relabel a file surface's call/route paths relative to `base`. */
27
+ function relabelFileFlow(flow, base) {
28
+ const rel = (f) => (0, path_1.relative)(base, f);
29
+ return {
30
+ calls: flow.calls.map((c) => ({ ...c, file: rel(c.file) })),
31
+ routes: flow.routes.map((r) => ({ ...r, file: rel(r.file) })),
32
+ };
32
33
  }
33
34
  /** Walk + extract + assemble. Files that don't parse are skipped, never fatal. */
34
35
  async function gatherFlowModel(opts) {
@@ -39,7 +40,7 @@ async function gatherFlowModel(opts) {
39
40
  for (const rel of (0, walk_source_files_1.walkSourceFiles)(root, { extensions })) {
40
41
  const flow = await (0, extract_1.extractFileFlow)((0, path_1.join)(root, rel), config);
41
42
  if (flow)
42
- fileFlows.push(flow);
43
+ fileFlows.push(opts.relativeTo ? relabelFileFlow(flow, opts.relativeTo) : flow);
43
44
  }
44
45
  }
45
46
  // Served side = extracted routes UNION spec routes (dedup is implicit: the
@@ -1 +1 @@
1
- {"version":3,"file":"gather.js","sourceRoot":"","sources":["../../../src/analyzers/flow/gather.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AA+BH,0CAgBC;AA7CD,+BAA4B;AAC5B,+CAA4C;AAC5C,kEAA6D;AAC7D,uCAA2D;AAC3D,mCAAyD;AACzD,+CAAkD;AAYlD,2EAA2E;AAC3E,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,qBAAS,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC7C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;gBAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,kFAAkF;AAC3E,KAAK,UAAU,eAAe,CAAC,IAAuB;IAC3D,MAAM,MAAM,GAAoB,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5E,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,MAAM,SAAS,GAAe,EAAE,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAA,mCAAe,EAAC,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,GAAG,MAAM,IAAA,yBAAe,EAAC,IAAA,WAAI,EAAC,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;YAC5D,IAAI,IAAI;gBAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,oEAAoE;IACpE,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,+BAAiB,EAAC,IAAI,CAAC,CAAC,CAAC;IACjF,OAAO,IAAA,sBAAc,EAAC,CAAC,GAAG,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;AAC3E,CAAC"}
1
+ {"version":3,"file":"gather.js","sourceRoot":"","sources":["../../../src/analyzers/flow/gather.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AA6CH,0CAgBC;AA3DD,+BAAsC;AACtC,+CAAqE;AACrE,kEAA6D;AAC7D,uCAA2D;AAC3D,mCAAyD;AACzD,+CAAkD;AAuBlD,2EAA2E;AAC3E,SAAS,cAAc;IACrB,OAAO,IAAA,mCAAuB,EAAC,qBAAS,CAAC,CAAC;AAC5C,CAAC;AAED,oEAAoE;AACpE,SAAS,eAAe,CAAC,IAAc,EAAE,IAAY;IACnD,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,IAAA,eAAQ,EAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACrD,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3D,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KAC9D,CAAC;AACJ,CAAC;AAED,kFAAkF;AAC3E,KAAK,UAAU,eAAe,CAAC,IAAuB;IAC3D,MAAM,MAAM,GAAoB,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5E,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,MAAM,SAAS,GAAe,EAAE,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAA,mCAAe,EAAC,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,GAAG,MAAM,IAAA,yBAAe,EAAC,IAAA,WAAI,EAAC,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;YAC5D,IAAI,IAAI;gBAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,oEAAoE;IACpE,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,+BAAiB,EAAC,IAAI,CAAC,CAAC,CAAC;IACjF,OAAO,IAAA,sBAAc,EAAC,CAAC,GAAG,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;AAC3E,CAAC"}
@@ -39,11 +39,23 @@ export interface FlowModel {
39
39
  readonly routes: readonly RouteEndpoint[];
40
40
  readonly bindings: readonly FlowBinding[];
41
41
  }
42
+ /** A path made up entirely of `{var}` segments carries no static signal. One
43
+ * source of truth (Rule 2) for both the join's confidence and the gate's
44
+ * confidence gating (a placeholder-only path is too generic to block on). */
45
+ export declare function isPlaceholderOnlyPath(path: string): boolean;
42
46
  /**
43
47
  * Bind each client call to the route it targets, on the normalized
44
48
  * `(method, path)` key. Routes are indexed once; each call resolves in O(1).
45
49
  */
46
50
  export declare function joinFlow(calls: readonly ClientCall[], routes: readonly RouteEndpoint[]): FlowBinding[];
51
+ /**
52
+ * Dedup served routes to one per distinct `(method, path)` — the canonical
53
+ * "what this repo serves" set. A route surfaced by both a spec and static
54
+ * extraction collapses to one, spec winning (authoritative handler +
55
+ * provenance). One source of truth (Rule 2) for the graph overlay's endpoint
56
+ * nodes AND the served contract snapshot.
57
+ */
58
+ export declare function dedupeServedRoutes(routes: readonly RouteEndpoint[]): RouteEndpoint[];
47
59
  /** Flatten per-file surfaces into one model + its bindings. */
48
60
  export declare function buildFlowModel(fileFlows: readonly FileFlow[]): FlowModel;
49
61
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/analyzers/flow/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,kBAAkB,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnF,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAChC;AAED,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAC3C;AAOD;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,WAAW,EAAE,CAaf;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,CAIxE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,SAAS,CAAC,CAOpB;AAED,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CAUvD"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/analyzers/flow/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,kBAAkB,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnF,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAChC;AAED,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAC3C;AAED;;8EAE8E;AAC9E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,WAAW,EAAE,CAaf;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,aAAa,EAAE,CAUpF;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,CAIxE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,SAAS,CAAC,CAOpB;AAED,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CAUvD"}
@@ -16,13 +16,17 @@
16
16
  * the I/O); this module just structures + joins.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.isPlaceholderOnlyPath = isPlaceholderOnlyPath;
19
20
  exports.joinFlow = joinFlow;
21
+ exports.dedupeServedRoutes = dedupeServedRoutes;
20
22
  exports.buildFlowModel = buildFlowModel;
21
23
  exports.extractFlowModel = extractFlowModel;
22
24
  exports.summarize = summarize;
23
25
  const extract_1 = require("./extract");
24
- /** A path made up entirely of `{var}` segments carries no static signal. */
25
- function isPlaceholderOnly(path) {
26
+ /** A path made up entirely of `{var}` segments carries no static signal. One
27
+ * source of truth (Rule 2) for both the join's confidence and the gate's
28
+ * confidence gating (a placeholder-only path is too generic to block on). */
29
+ function isPlaceholderOnlyPath(path) {
26
30
  return /^(\/\{var\})+$/.test(path);
27
31
  }
28
32
  /**
@@ -39,12 +43,30 @@ function joinFlow(calls, routes) {
39
43
  const route = routeIndex.get(`${call.method} ${call.path}`) ?? null;
40
44
  if (!route)
41
45
  return { call, route: null, confidence: 0, reason: 'no-route' };
42
- if (isPlaceholderOnly(call.path)) {
46
+ if (isPlaceholderOnlyPath(call.path)) {
43
47
  return { call, route, confidence: 0.3, reason: 'placeholder-only' };
44
48
  }
45
49
  return { call, route, confidence: 1, reason: 'exact' };
46
50
  });
47
51
  }
52
+ /**
53
+ * Dedup served routes to one per distinct `(method, path)` — the canonical
54
+ * "what this repo serves" set. A route surfaced by both a spec and static
55
+ * extraction collapses to one, spec winning (authoritative handler +
56
+ * provenance). One source of truth (Rule 2) for the graph overlay's endpoint
57
+ * nodes AND the served contract snapshot.
58
+ */
59
+ function dedupeServedRoutes(routes) {
60
+ const byKey = new Map();
61
+ for (const route of routes) {
62
+ const key = `${route.method} ${route.path}`;
63
+ const existing = byKey.get(key);
64
+ if (!existing || (existing.via !== 'spec' && route.via === 'spec')) {
65
+ byKey.set(key, route);
66
+ }
67
+ }
68
+ return [...byKey.values()];
69
+ }
48
70
  /** Flatten per-file surfaces into one model + its bindings. */
49
71
  function buildFlowModel(fileFlows) {
50
72
  const calls = fileFlows.flatMap((f) => f.calls);
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/analyzers/flow/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/analyzers/flow/model.ts"],"names":[],"mappings":"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"}
@@ -212,6 +212,38 @@ export declare const SECRET_CANONICAL_RULE = "canonical:secret";
212
212
  * matched content (or, for code, its enclosing symbol) changes.
213
213
  */
214
214
  export declare function computeContentFingerprint(canonicalRule: string, file: string, contentAnchor: string): string;
215
+ /**
216
+ * Tool-independent canonical rule for a flow binding — a UI call site's
217
+ * dependency on a served `(method, path)`. Every flow binding shares this
218
+ * constant (like secrets share `SECRET_CANONICAL_RULE`) because the finding is
219
+ * intrinsic ("this component depends on this endpoint"), never a per-tool
220
+ * classification.
221
+ */
222
+ export declare const FLOW_BINDING_CANONICAL_RULE = "canonical:flow-binding";
223
+ /**
224
+ * Durable identity for a flow binding (the `flow-binding` kind — the unit the
225
+ * integration gate grandfathers). A binding IS "this consumer file depends on
226
+ * this `(method, path)`", so identity is exactly that triple — and nothing
227
+ * else. It is fully LINE-INDEPENDENT by construction (no line, no line-window
228
+ * bucket), which is strictly more robust than the v1 line-window scheme: the
229
+ * call can move anywhere in the file, be reformatted, or gain siblings above
230
+ * it, and the binding keeps its identity. Motion within a file simply is not a
231
+ * change to which endpoint the file depends on.
232
+ *
233
+ * Hashes only inputs dxkit derives itself (Rule 9) — the NORMALIZED join key
234
+ * (`GET`, `/articles/{var}`, never a tool's raw URL capture) and the consuming
235
+ * file dxkit read from its own AST pass — so a committed baseline keeps
236
+ * matching when the scan moves to CI. Multiple calls to the same endpoint from
237
+ * one file collapse to one identity, which is correct: the file depends on the
238
+ * endpoint once, however many call sites express it. A pure file rename is
239
+ * relocated by the matcher's whole-file rename pass (the file locator in
240
+ * `entryToLocated`), not by the hash.
241
+ *
242
+ * Deliberately NOT the graph's enclosing symbol: that would couple identity to
243
+ * graphify, and the flow layer is graphify-independent by design. Reusing
244
+ * `computeContentFingerprint` keeps every SHA-1 scheme in this one module.
245
+ */
246
+ export declare function computeFlowBindingFingerprint(method: string, path: string, file: string): string;
215
247
  /**
216
248
  * HMAC-SHA256 of a detected secret value, keyed by a per-repo salt.
217
249
  * The output is 16-char lowercase hex (first 8 bytes of the 32-byte
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC,GAAG,MAAM,CAST;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC,GAAG,MAAM,CAGT;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAGT;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAIlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,MAAM,EAAE,CAMrF;AAID;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAmBzD,CAAC;AAEH,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhG;AAwCD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,qDAAqD;AACrD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,GACpB,MAAM,CAGR;AAID;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtE"}
1
+ {"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":"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"}
@@ -35,7 +35,7 @@
35
35
  * repo scale. Producers may render either inline interchangeably.
36
36
  */
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.SECRET_CANONICAL_RULE = exports.CODE_FINGERPRINT_LINE_WINDOW = exports.CANONICAL_RULE_MAP = void 0;
38
+ exports.FLOW_BINDING_CANONICAL_RULE = exports.SECRET_CANONICAL_RULE = exports.CODE_FINGERPRINT_LINE_WINDOW = exports.CANONICAL_RULE_MAP = void 0;
39
39
  exports.canonicalAdvisoryId = canonicalAdvisoryId;
40
40
  exports.computeFingerprint = computeFingerprint;
41
41
  exports.computeFingerprintV1 = computeFingerprintV1;
@@ -50,6 +50,7 @@ exports.codeContentAnchor = codeContentAnchor;
50
50
  exports.codeContentAnchorFromHash = codeContentAnchorFromHash;
51
51
  exports.secretContentAnchor = secretContentAnchor;
52
52
  exports.computeContentFingerprint = computeContentFingerprint;
53
+ exports.computeFlowBindingFingerprint = computeFlowBindingFingerprint;
53
54
  exports.computeSecretHmac = computeSecretHmac;
54
55
  const crypto_1 = require("crypto");
55
56
  /**
@@ -322,6 +323,41 @@ function computeContentFingerprint(canonicalRule, file, contentAnchor) {
322
323
  const input = `${canonicalRule}\0${file}\0${contentAnchor}`;
323
324
  return (0, crypto_1.createHash)('sha1').update(input).digest('hex').slice(0, 16);
324
325
  }
326
+ // ─── Flow-binding identity (the integration gate, Rule 9) ─────────────────────
327
+ /**
328
+ * Tool-independent canonical rule for a flow binding — a UI call site's
329
+ * dependency on a served `(method, path)`. Every flow binding shares this
330
+ * constant (like secrets share `SECRET_CANONICAL_RULE`) because the finding is
331
+ * intrinsic ("this component depends on this endpoint"), never a per-tool
332
+ * classification.
333
+ */
334
+ exports.FLOW_BINDING_CANONICAL_RULE = 'canonical:flow-binding';
335
+ /**
336
+ * Durable identity for a flow binding (the `flow-binding` kind — the unit the
337
+ * integration gate grandfathers). A binding IS "this consumer file depends on
338
+ * this `(method, path)`", so identity is exactly that triple — and nothing
339
+ * else. It is fully LINE-INDEPENDENT by construction (no line, no line-window
340
+ * bucket), which is strictly more robust than the v1 line-window scheme: the
341
+ * call can move anywhere in the file, be reformatted, or gain siblings above
342
+ * it, and the binding keeps its identity. Motion within a file simply is not a
343
+ * change to which endpoint the file depends on.
344
+ *
345
+ * Hashes only inputs dxkit derives itself (Rule 9) — the NORMALIZED join key
346
+ * (`GET`, `/articles/{var}`, never a tool's raw URL capture) and the consuming
347
+ * file dxkit read from its own AST pass — so a committed baseline keeps
348
+ * matching when the scan moves to CI. Multiple calls to the same endpoint from
349
+ * one file collapse to one identity, which is correct: the file depends on the
350
+ * endpoint once, however many call sites express it. A pure file rename is
351
+ * relocated by the matcher's whole-file rename pass (the file locator in
352
+ * `entryToLocated`), not by the hash.
353
+ *
354
+ * Deliberately NOT the graph's enclosing symbol: that would couple identity to
355
+ * graphify, and the flow layer is graphify-independent by design. Reusing
356
+ * `computeContentFingerprint` keeps every SHA-1 scheme in this one module.
357
+ */
358
+ function computeFlowBindingFingerprint(method, path, file) {
359
+ return computeContentFingerprint(exports.FLOW_BINDING_CANONICAL_RULE, file, `${method} ${path}`);
360
+ }
325
361
  // ─── Secret HMAC primitive ───────────────────────────────────────────────────
326
362
  /**
327
363
  * HMAC-SHA256 of a detected secret value, keyed by a per-repo salt.
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;AAeH,kDAYC;AAYD,gDAOC;AAYD,oDAOC;AAYD,8CAIC;AAYD,kDAMC;AAqCD,4CAEC;AAqBD,sCAEC;AAQD,wDAGC;AA+CD,sCAEC;AAGD,4BAEC;AAUD,8CAEC;AAYD,8DAMC;AAqBD,kDAEC;AAwBD,8DAOC;AA6BD,8CAEC;AAnVD,mCAAgD;AAGhD;;;;;;;;;GASG;AACH,SAAgB,mBAAmB,CAAC,OAGnC;IACC,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;SACxD,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;SACxE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;IAClC,OAAO,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,kBAAkB,CAAC,OAIlC;IACC,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,OAAO,KAAK,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;IACpE,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,oBAAoB,CAAC,OAIpC;IACC,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,gBAAgB,IAAI,EAAE,KAAK,OAAO,CAAC,EAAE,EAAE,CAAC;IACrF,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,iBAAiB,CAAC,QAA0B;IAC1D,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,CAAC,CAAC,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,mBAAmB,CAAC,QAAuC;IACzE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,WAAW;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;GAUG;AACU,QAAA,kBAAkB,GAAgC,IAAI,GAAG,CAAiB;IACrF,sEAAsE;IACtE,qEAAqE;IACrE,kEAAkE;IAClE,+DAA+D;IAC/D,CAAC,6CAA6C,EAAE,sBAAsB,CAAC;IACvE,CAAC,iCAAiC,EAAE,sBAAsB,CAAC;IAC3D,CAAC,iDAAiD,EAAE,sBAAsB,CAAC;IAC3E,CAAC,wCAAwC,EAAE,sBAAsB,CAAC;IAElE,iEAAiE;IACjE,oEAAoE;IACpE,mCAAmC;IACnC,CAAC,yBAAyB,EAAE,0BAA0B,CAAC;IACvD,CAAC,oCAAoC,EAAE,0BAA0B,CAAC;IAElE,8DAA8D;IAC9D,CAAC,uBAAuB,EAAE,+BAA+B,CAAC;IAC1D,CAAC,sBAAsB,EAAE,+BAA+B,CAAC;CAC1D,CAAC,CAAC;AAEH,kEAAkE;AAClE,SAAgB,gBAAgB,CAAC,IAAY,EAAE,IAAY;IACzD,OAAO,0BAAkB,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,IAAI,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;GAMG;AACU,QAAA,4BAA4B,GAAG,CAAC,CAAC;AAE9C;;;;;;;;;GASG;AACH,SAAgB,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,oCAA4B,CAAC,GAAG,oCAA4B,CAAC;AACxF,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,aAAqB,EAAE,IAAY,EAAE,IAAY;IACtF,MAAM,KAAK,GAAG,GAAG,aAAa,KAAK,IAAI,KAAK,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;IAClE,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,0EAA0E;AAC1E,wEAAwE;AACxE,qEAAqE;AACrE,+DAA+D;AAC/D,qEAAqE;AACrE,uDAAuD;AACvD,EAAE;AACF,uEAAuE;AACvE,yEAAyE;AACzE,0EAA0E;AAC1E,wEAAwE;AACxE,sEAAsE;AACtE,mEAAmE;AACnE,0EAA0E;AAC1E,oEAAoE;AACpE,iEAAiE;AACjE,8DAA8D;AAC9D,0DAA0D;AAC1D,8CAA8C;AAC9C,mEAAmE;AACnE,8DAA8D;AAC9D,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,+CAA+C;AAC/C,EAAE;AACF,yEAAyE;AACzE,mEAAmE;AACnE,yEAAyE;AACzE,uEAAuE;AACvE,wEAAwE;AACxE,0EAA0E;AAC1E,mEAAmE;AACnE,mEAAmE;AACnE,mEAAmE;AACnE,oEAAoE;AACpE,sEAAsE;AAEtE;;;;;;GAMG;AACH,SAAgB,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED,qDAAqD;AACrD,SAAgB,QAAQ,CAAC,IAAY;IACnC,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,iBAAiB,CAAC,KAAa,EAAE,IAAY,EAAE,OAAe;IAC5E,OAAO,yBAAyB,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,yBAAyB,CACvC,KAAa,EACb,WAAmB,EACnB,OAAe;IAEf,OAAO,GAAG,KAAK,KAAK,WAAW,KAAK,OAAO,EAAE,CAAC;AAChD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,mBAAmB,CAAC,OAAe;IACjD,OAAO,WAAW,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;GAWG;AACU,QAAA,qBAAqB,GAAG,kBAAkB,CAAC;AAExD;;;;;;;GAOG;AACH,SAAgB,yBAAyB,CACvC,aAAqB,EACrB,IAAY,EACZ,aAAqB;IAErB,MAAM,KAAK,GAAG,GAAG,aAAa,KAAK,IAAI,KAAK,aAAa,EAAE,CAAC;IAC5D,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAgB,iBAAiB,CAAC,MAAc,EAAE,IAAY;IAC5D,OAAO,IAAA,mBAAU,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC9E,CAAC"}
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":"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"}
@@ -115,6 +115,27 @@ export interface GuardrailJsonPayload {
115
115
  };
116
116
  readonly reasons: ReadonlyArray<MatchReason>;
117
117
  }>;
118
+ /** The flow integration gate — net-new UI→API breakages from the base↔HEAD
119
+ * contract diff. Absent in committed modes (the gate runs only ref-based).
120
+ * When present but `ran` is false, `skipped` says why (e.g. no flow-surface
121
+ * change, no served-side truth). */
122
+ readonly flowGate?: {
123
+ readonly ran: boolean;
124
+ readonly skipped?: string;
125
+ readonly mode: string;
126
+ readonly blocks: boolean;
127
+ readonly warns: boolean;
128
+ readonly findings: ReadonlyArray<{
129
+ readonly id: string;
130
+ readonly method: string;
131
+ readonly path: string;
132
+ readonly file: string;
133
+ readonly line: number;
134
+ readonly confidence: number;
135
+ readonly reason: string;
136
+ readonly verdict: 'block' | 'warn';
137
+ }>;
138
+ };
118
139
  }
119
140
  export declare function renderJson(result: GuardrailCheckResult): GuardrailJsonPayload;
120
141
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"check-renderers.d.ts","sourceRoot":"","sources":["../../src/baseline/check-renderers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check-renderers.d.ts","sourceRoot":"","sources":["../../src/baseline/check-renderers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAkB,aAAa,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AA0B1D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAoGlE;AAkID,eAAO,MAAM,qBAAqB,EAAG,0BAAmC,CAAC;AAEzE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,OAAO,qBAAqB,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;KAC1B,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE;QACjB;8BACsB;QACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B;;;oEAG4D;QAC5D,QAAQ,CAAC,IAAI,EAAE;YACb,QAAQ,CAAC,KAAK,EAAE,gBAAgB,GAAG,qBAAqB,GAAG,WAAW,CAAC;YACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;YAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;SACvB,CAAC;KACH,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;KAChC,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;KAClC,CAAC;IACF,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACxC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;QAC7C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;QAC5C,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACpD,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;KACrD,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B;qEAC6D;QAC7D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;QAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;QAC/B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;QACxC;;;gEAGwD;QACxD,QAAQ,CAAC,qBAAqB,CAAC,EAAE;YAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;YAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;YAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;SAC7B,CAAC;QACF,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;KAC9C,CAAC,CAAC;IACH;;;yCAGqC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;QACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;YAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;SACpC,CAAC,CAAC;KACJ,CAAC;CACH;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,oBAAoB,CAmG7E;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAoHnE"}
@@ -64,6 +64,7 @@ exports.renderConsole = renderConsole;
64
64
  exports.renderJson = renderJson;
65
65
  exports.renderMarkdown = renderMarkdown;
66
66
  const logger = __importStar(require("../logger"));
67
+ const gate_1 = require("../analyzers/flow/gate");
67
68
  // ─── Shared verdict predicates ────────────────────────────────────────────
68
69
  /**
69
70
  * Whether a pair was accepted by an active allowlist entry. Such a
@@ -146,6 +147,7 @@ function renderConsole(result) {
146
147
  lines.push(...formatPairLines(p, ' '));
147
148
  lines.push('');
148
149
  }
150
+ lines.push(...formatFlowGate(result.flowGate));
149
151
  // Always show a summary footer — sets expectations for what
150
152
  // happens next (exit code, what to read on a fail).
151
153
  lines.push(logger.bold('Summary'));
@@ -168,13 +170,40 @@ function renderConsole(result) {
168
170
  }
169
171
  return lines.join('\n');
170
172
  }
173
+ /**
174
+ * Console lines for the flow integration gate. Silent unless the gate produced
175
+ * findings — a skipped or clean gate adds no noise. Blocking breakages are
176
+ * grouped separately from warnings so the actionable set surfaces first.
177
+ */
178
+ function formatFlowGate(flow) {
179
+ if (!flow || flow.findings.length === 0)
180
+ return [];
181
+ const out = [];
182
+ const blocking = flow.findings.filter((f) => f.verdict === 'block');
183
+ const warning = flow.findings.filter((f) => f.verdict === 'warn');
184
+ if (blocking.length > 0) {
185
+ out.push(logger.bold(`Flow breakage — blocking (${blocking.length})`));
186
+ for (const f of blocking)
187
+ out.push(` ${(0, gate_1.describeBrokenIntegration)(f)}`);
188
+ out.push('');
189
+ }
190
+ if (warning.length > 0) {
191
+ out.push(logger.bold(`Flow breakage — warning (${warning.length})`));
192
+ for (const f of warning)
193
+ out.push(` ${(0, gate_1.describeBrokenIntegration)(f)}`);
194
+ out.push('');
195
+ }
196
+ return out;
197
+ }
171
198
  function verdictBanner(result) {
199
+ const flow = result.flowGate?.findings ?? [];
172
200
  if (result.blocks) {
173
- const count = result.pairs.filter(isBlocking).length;
201
+ const count = result.pairs.filter(isBlocking).length + flow.filter((f) => f.verdict === 'block').length;
174
202
  return logger.bold(`Guardrail BLOCKED — ${count} new regression${count === 1 ? '' : 's'}`);
175
203
  }
176
204
  if (result.warns) {
177
- const count = result.pairs.filter((p) => p.classification.warns).length;
205
+ const count = result.pairs.filter((p) => p.classification.warns).length +
206
+ flow.filter((f) => f.verdict === 'warn').length;
178
207
  return logger.bold(`Guardrail PASSED — ${count} warning${count === 1 ? '' : 's'}`);
179
208
  }
180
209
  return logger.bold('Guardrail PASSED');
@@ -332,6 +361,27 @@ function renderJson(result) {
332
361
  : {}),
333
362
  reasons: p.classification.reasons,
334
363
  })),
364
+ ...(result.flowGate !== undefined
365
+ ? {
366
+ flowGate: {
367
+ ran: result.flowGate.ran,
368
+ ...(result.flowGate.skipped !== undefined ? { skipped: result.flowGate.skipped } : {}),
369
+ mode: result.flowGate.mode,
370
+ blocks: result.flowGate.blocks,
371
+ warns: result.flowGate.warns,
372
+ findings: result.flowGate.findings.map((f) => ({
373
+ id: f.id,
374
+ method: f.method,
375
+ path: f.path,
376
+ file: f.file,
377
+ line: f.line,
378
+ confidence: f.confidence,
379
+ reason: f.reason,
380
+ verdict: f.verdict,
381
+ })),
382
+ },
383
+ }
384
+ : {}),
335
385
  };
336
386
  }
337
387
  // ─── Markdown renderer ────────────────────────────────────────────────────
@@ -355,7 +405,10 @@ function renderMarkdown(result) {
355
405
  const verdict = result.blocks ? 'BLOCKED' : result.warns ? 'PASSED (with warnings)' : 'PASSED';
356
406
  lines.push(`## Guardrail: ${verdict}`);
357
407
  lines.push('');
358
- lines.push(summarySentence(result, blocking.length, warning.length, resolved.length));
408
+ const flow = result.flowGate?.findings ?? [];
409
+ const flowBlocking = flow.filter((f) => f.verdict === 'block').length;
410
+ const flowWarning = flow.filter((f) => f.verdict === 'warn').length;
411
+ lines.push(summarySentence(result, blocking.length + flowBlocking, warning.length + flowWarning, resolved.length));
359
412
  lines.push('');
360
413
  if (result.refExcludedKinds.length > 0) {
361
414
  const detail = result.refExcludedKinds.map((e) => `${e.currentCount} ${e.kind}`).join(', ');
@@ -373,6 +426,7 @@ function renderMarkdown(result) {
373
426
  lines.push(markdownPairRow(p));
374
427
  lines.push('');
375
428
  }
429
+ lines.push(...markdownFlowGate(result.flowGate));
376
430
  if (suppressed.length > 0) {
377
431
  lines.push('<details>');
378
432
  lines.push(`<summary>Suppressed by allowlist (${suppressed.length})</summary>`);
@@ -437,6 +491,42 @@ function renderMarkdown(result) {
437
491
  `_dxkit_: ${escapeMd(result.current.analysisMeta.dxkitVersion)}`);
438
492
  return lines.join('\n');
439
493
  }
494
+ /**
495
+ * Markdown for the flow integration gate. Blocking breakages render as a
496
+ * top-level table (they fail the PR); warnings collapse into a `<details>`.
497
+ * Silent when the gate produced no findings.
498
+ */
499
+ function markdownFlowGate(flow) {
500
+ if (!flow || flow.findings.length === 0)
501
+ return [];
502
+ const out = [];
503
+ const blocking = flow.findings.filter((f) => f.verdict === 'block');
504
+ const warning = flow.findings.filter((f) => f.verdict === 'warn');
505
+ const row = (f) => `| ${escapeMd(`${f.method} ${f.path}`)} | ${escapeMd(f.reason)} | ` +
506
+ `${escapeMd(`${f.file}:${f.line}`)} | ${f.confidence.toFixed(2)} |`;
507
+ if (blocking.length > 0) {
508
+ out.push('### Broken integrations');
509
+ out.push('');
510
+ out.push('| Endpoint | Reason | Consumer | Confidence |');
511
+ out.push('|---|---|---|---|');
512
+ for (const f of blocking)
513
+ out.push(row(f));
514
+ out.push('');
515
+ }
516
+ if (warning.length > 0) {
517
+ out.push('<details>');
518
+ out.push(`<summary>Integration warnings (${warning.length})</summary>`);
519
+ out.push('');
520
+ out.push('| Endpoint | Reason | Consumer | Confidence |');
521
+ out.push('|---|---|---|---|');
522
+ for (const f of warning)
523
+ out.push(row(f));
524
+ out.push('');
525
+ out.push('</details>');
526
+ out.push('');
527
+ }
528
+ return out;
529
+ }
440
530
  /** Append ` (ref: <ref>)` to the mode label when running ref-based,
441
531
  * so PR reviewers see WHICH ref the diff anchored to. Empty for
442
532
  * committed modes. */