@vyuhlabs/dxkit 2.19.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 (100) hide show
  1. package/CHANGELOG.md +68 -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 +46 -13
  62. package/dist/cli.js.map +1 -1
  63. package/dist/dashboard/graph-adapter.d.ts.map +1 -1
  64. package/dist/dashboard/graph-adapter.js +1 -4
  65. package/dist/dashboard/graph-adapter.js.map +1 -1
  66. package/dist/explore/flow-graph.d.ts +62 -0
  67. package/dist/explore/flow-graph.d.ts.map +1 -0
  68. package/dist/explore/flow-graph.js +194 -0
  69. package/dist/explore/flow-graph.js.map +1 -0
  70. package/dist/explore/flow-view.d.ts +33 -0
  71. package/dist/explore/flow-view.d.ts.map +1 -0
  72. package/dist/explore/flow-view.js +85 -0
  73. package/dist/explore/flow-view.js.map +1 -0
  74. package/dist/explore/load.d.ts.map +1 -1
  75. package/dist/explore/load.js +16 -3
  76. package/dist/explore/load.js.map +1 -1
  77. package/dist/explore/queries.d.ts +92 -1
  78. package/dist/explore/queries.d.ts.map +1 -1
  79. package/dist/explore/queries.js +142 -0
  80. package/dist/explore/queries.js.map +1 -1
  81. package/dist/explore/types.d.ts +56 -3
  82. package/dist/explore/types.d.ts.map +1 -1
  83. package/dist/explore/types.js +10 -2
  84. package/dist/explore/types.js.map +1 -1
  85. package/dist/flow-cli.d.ts +32 -0
  86. package/dist/flow-cli.d.ts.map +1 -1
  87. package/dist/flow-cli.js +168 -21
  88. package/dist/flow-cli.js.map +1 -1
  89. package/dist/languages/index.d.ts +21 -0
  90. package/dist/languages/index.d.ts.map +1 -1
  91. package/dist/languages/index.js +41 -0
  92. package/dist/languages/index.js.map +1 -1
  93. package/dist/loop/policy.d.ts +4 -1
  94. package/dist/loop/policy.d.ts.map +1 -1
  95. package/dist/loop/policy.js +3 -0
  96. package/dist/loop/policy.js.map +1 -1
  97. package/dist/loop/stop-gate.d.ts.map +1 -1
  98. package/dist/loop/stop-gate.js +8 -2
  99. package/dist/loop/stop-gate.js.map +1 -1
  100. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,74 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.21.0] - 2026-07-01
11
+
12
+ ### Added — the integration gate (`flow refresh` + guardrail flow pass)
13
+
14
+ The Flow feature's third slice turns UI→API traceability into a guardrail: a PR
15
+ that net-new breaks an integration — a frontend call to an endpoint no backend
16
+ serves, or a backend route removal a consumer still binds to — fails the check,
17
+ the same way a net-new secret or CVE does.
18
+
19
+ - **Net-new broken-integration gate.** The guardrail check now runs an additive,
20
+ fail-open flow pass over its ref-based `base↔HEAD` comparison. One algorithm
21
+ covers both directions (dead frontend call / removed backend route), because
22
+ both reduce to "a consumed binding whose `(method, path)` is not served."
23
+ Pre-existing breakage is grandfathered — only what the diff *newly* breaks is
24
+ surfaced. It never touches the existing finding matcher.
25
+ - **Confidence-gated, false-positive-safe.** An exact, fully specified binding
26
+ blocks; a placeholder-only path (`/{var}`) warns. The gate self-skips when it
27
+ has no served-side truth to check against (a pure frontend with no committed
28
+ contract), so it can never false-block a repo it can't fully see, and it fails
29
+ open on any error.
30
+ - **`vyuh-dxkit flow refresh`** writes the cross-repo contract snapshots
31
+ (`.dxkit/flow/served.json` + `consumed.json`). A backend publishes what it
32
+ serves; a frontend commits the counterpart's snapshot and gates against it —
33
+ so a split-repo setup needs a cross-repo fetch only at refresh time, never on
34
+ a developer's machine or in the per-check gate. A monorepo gates live against
35
+ its own routes and needs no snapshot.
36
+ - **Posture.** `.dxkit/policy.json:flow.mode` (`block` / `warn` / `off`, default
37
+ `block`) governs the verdict; the loop preset overrides it (`security-only`
38
+ warns, `full-debt` blocks) so an unattended loop can't wedge on a cross-repo
39
+ false positive. Broken integrations render in the console, `--json`, and
40
+ PR-comment markdown, and count toward the verdict banner.
41
+ - Runs only in ref-based mode (committed mode has no base flow model to diff);
42
+ a diff that touches no client call, route, or spec is skipped up front.
43
+ Binding identity is line-independent and environment-independent, so a
44
+ committed contract keeps matching when the check moves from a laptop to CI.
45
+
46
+ ## [2.20.0] - 2026-07-01
47
+
48
+ ### Added — native flow map + blast radius (`flow`, `flow trace`)
49
+
50
+ The Flow feature's second slice makes UI→API traceability a first-class part of
51
+ the code graph, so a change's cross-boundary blast radius is a query, not a
52
+ guess.
53
+
54
+ - **Graph schema v2 — the endpoint overlay.** `graph.json` now carries
55
+ `http-endpoint` nodes (one per served `(method, path)`) and `calls-endpoint`
56
+ edges (a UI call site → the endpoint it hits) — the cross-boundary join the
57
+ structural graph could not previously express. The overlay is purely additive:
58
+ a v1 artifact migrates forward to an empty overlay, and every pre-flow query is
59
+ untouched. The consuming call site's coordinates ride on the edge, so the map
60
+ works even where graphify never ran (a pure-frontend repo) — the flow layer
61
+ stays graphify-independent.
62
+ - **`vyuh-dxkit flow`** writes the overlay and prints every endpoint with its
63
+ consuming UI surfaces, plus the served-but-unconsumed set (a dead-route or
64
+ cross-repo-consumer candidate — surfaced, not flagged as a defect).
65
+ - **`vyuh-dxkit flow trace "<METHOD> <path>"`** shows one endpoint's handler,
66
+ every UI call site, and the change blast radius — direct consumers extended
67
+ transitively through the structural call graph.
68
+ - Both take `--json`. New pure queries (`endpointCallers`, `flowTrace`,
69
+ `flowBlastRadius`, `flowMapQuery`) live in the canonical query module; the
70
+ overlay is regenerated each run (never accumulated).
71
+
72
+ ### Added — advisory file-size budget in the pre-commit slop check
73
+
74
+ A warn-only, diff-scoped 500-LoC budget nudges when a changed source file
75
+ sprawls, exempting the modules that are large by architectural mandate (language
76
+ packs, the canonical query/registry modules, the CLI dispatch). It never blocks.
77
+
10
78
  ## [2.19.0] - 2026-06-30
11
79
 
12
80
  ### Added — application-flow extraction (`flow extract`)
@@ -1 +1 @@
1
- {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/allowlist/categories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,kGAMjB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,iBAAiB,CAG7D,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,iBAAiB,CAItE,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,YAAY,CAO5D,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,CAAC,CA6C3F,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAErF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAE/F;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM,CAIhE"}
1
+ {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/allowlist/categories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,kGAMjB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,iBAAiB,CAG7D,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,iBAAiB,CAItE,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,YAAY,CAO5D,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,CAAC,CAkD3F,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAErF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAE/F;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM,CAIhE"}
@@ -130,6 +130,10 @@ exports.CATEGORIES_BY_KIND = {
130
130
  // TODO / FIXME / HACK / console-log / any-type markers: only
131
131
  // accepted-risk or deferred (the marker IS the hygiene issue)
132
132
  hygiene: ['accepted-risk', 'deferred'],
133
+ // Broken integration: false-positive (a cross-repo consumer exists that the
134
+ // scan didn't see, so the binding isn't actually dead); otherwise
135
+ // accepted-risk or deferred
136
+ 'flow-binding': ['false-positive', 'accepted-risk', 'deferred'],
133
137
  // Stale-allow (orphaned inline allowlist annotation): never
134
138
  // allowlisted. The right response is always "remove the stale
135
139
  // annotation" — allowlisting the warning that an annotation is
@@ -1 +1 @@
1
- {"version":3,"file":"categories.js","sourceRoot":"","sources":["../../src/allowlist/categories.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"categories.js","sourceRoot":"","sources":["../../src/allowlist/categories.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAyJH,oCAEC;AAMD,wCAEC;AAQD,wDAEC;AAmBD,8CAIC;AAhMD;;;;;;GAMG;AACU,QAAA,cAAc,GAAG;IAC5B,gBAAgB;IAChB,cAAc;IACd,sBAAsB;IACtB,eAAe;IACf,UAAU;CACF,CAAC;AAIX;;;;;;;;;;;GAWG;AACU,QAAA,mBAAmB,GAAmC,IAAI,GAAG,CAAC;IACzE,eAAe;IACf,UAAU;CACX,CAAC,CAAC;AAEH;;;;;;GAMG;AACU,QAAA,4BAA4B,GAAmC,IAAI,GAAG,CAAC;IAClF,gBAAgB;IAChB,cAAc;IACd,sBAAsB;CACvB,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACU,QAAA,uBAAuB,GAA8B,IAAI,GAAG,CAAe;IACtF,QAAQ;IACR,aAAa;IACb,MAAM;IACN,QAAQ;IACR,UAAU;IACV,SAAS;CACV,CAAC,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACU,QAAA,kBAAkB,GAAiE;IAC9F,yDAAyD;IACzD,MAAM,EAAE,CAAC,gBAAgB,EAAE,cAAc,EAAE,sBAAsB,EAAE,eAAe,EAAE,UAAU,CAAC;IAC/F,aAAa,EAAE;QACb,gBAAgB;QAChB,cAAc;QACd,sBAAsB;QACtB,eAAe;QACf,UAAU;KACX;IACD,IAAI,EAAE,CAAC,gBAAgB,EAAE,cAAc,EAAE,sBAAsB,EAAE,eAAe,EAAE,UAAU,CAAC;IAC7F,MAAM,EAAE,CAAC,gBAAgB,EAAE,cAAc,EAAE,sBAAsB,EAAE,eAAe,EAAE,UAAU,CAAC;IAE/F,uEAAuE;IACvE,+BAA+B;IAC/B,UAAU,EAAE,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,eAAe,EAAE,UAAU,CAAC;IAEnF,iEAAiE;IACjE,uDAAuD;IACvD,WAAW,EAAE,CAAC,gBAAgB,EAAE,eAAe,EAAE,UAAU,CAAC;IAE5D,qEAAqE;IACrE,iCAAiC;IACjC,cAAc,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IAC7C,UAAU,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACzC,uBAAuB,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IAEtD,oEAAoE;IACpE,kEAAkE;IAClE,UAAU,EAAE,CAAC,gBAAgB,EAAE,eAAe,EAAE,UAAU,CAAC;IAC3D,YAAY,EAAE,CAAC,gBAAgB,EAAE,eAAe,EAAE,UAAU,CAAC;IAC7D,YAAY,EAAE,CAAC,gBAAgB,EAAE,eAAe,EAAE,UAAU,CAAC;IAE7D,6DAA6D;IAC7D,8DAA8D;IAC9D,OAAO,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IAEtC,4EAA4E;IAC5E,kEAAkE;IAClE,4BAA4B;IAC5B,cAAc,EAAE,CAAC,gBAAgB,EAAE,eAAe,EAAE,UAAU,CAAC;IAE/D,4DAA4D;IAC5D,8DAA8D;IAC9D,+DAA+D;IAC/D,6DAA6D;IAC7D,iEAAiE;IACjE,8DAA8D;IAC9D,YAAY;IACZ,aAAa,EAAE,EAAE;CAClB,CAAC;AAEF;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAAC,IAAkB,EAAE,QAA2B;IAC1E,OAAO,+BAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,oCAA4B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACzF,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,QAA2B;IACxD,OAAO,2BAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,IAAkB,EAAE,QAA2B;IACpF,OAAO,0BAAkB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;GAMG;AACU,QAAA,mBAAmB,GAAG,EAAE,CAAC;AAEtC;;;;;;;GAOG;AACH,SAAgB,iBAAiB,CAAC,MAAY,IAAI,IAAI,EAAE;IACtD,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,2BAAmB,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC5C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"hint.d.ts","sourceRoot":"","sources":["../../src/allowlist/hint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGxE,OAAO,EAKL,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AAUtB,MAAM,WAAW,SAAS;IACxB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;oBAEgB;IAChB,QAAQ,CAAC,oBAAoB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5D;;;mCAG+B;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;4CAGwC;IACxC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC;2DACuD;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,CAyB3F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAwFlE"}
1
+ {"version":3,"file":"hint.d.ts","sourceRoot":"","sources":["../../src/allowlist/hint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGxE,OAAO,EAKL,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AAUtB,MAAM,WAAW,SAAS;IACxB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;oBAEgB;IAChB,QAAQ,CAAC,oBAAoB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5D;;;mCAG+B;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;4CAGwC;IACxC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC;2DACuD;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,CAyB3F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CA+FlE"}
@@ -179,6 +179,11 @@ function remediationFor(kind) {
179
179
  'suppressed is no longer present, so the annotation is dead code. ' +
180
180
  'Allowlisting THIS finding is not supported; the only remediation is ' +
181
181
  'to delete the annotation comment.');
182
+ case 'flow-binding':
183
+ return ('A UI call no longer resolves to a served route (or a route a consumer ' +
184
+ 'still binds to was removed). Restore the endpoint, fix the call to match ' +
185
+ 'the current route, or — if a cross-repo consumer the scan cannot see is ' +
186
+ 'intended — allowlist with category=false-positive.');
182
187
  }
183
188
  }
184
189
  // ─── Internals ───────────────────────────────────────────────────────────
@@ -202,6 +207,7 @@ function entryLocator(entry) {
202
207
  case 'config':
203
208
  case 'hygiene':
204
209
  case 'stale-allow':
210
+ case 'flow-binding':
205
211
  return { file: entry.file, line: entry.line };
206
212
  case 'coverage-gap':
207
213
  case 'test-gap':
@@ -1 +1 @@
1
- {"version":3,"file":"hint.js","sourceRoot":"","sources":["../../src/allowlist/hint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hint.js","sourceRoot":"","sources":["../../src/allowlist/hint.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DH,0CAyBC;AAQD,wCA+FC;AAxLD,2CAA6B;AAC7B,mDAAmD;AAEnD,4CAAyC;AAEzC,6CAMsB;AACtB,qCAA4C;AAC5C,wDAA8C;AAE9C;;;GAGG;AACH,MAAM,iBAAiB,GAAG,IAAA,0BAAQ,EAAC,eAAe,CAAC,CAAC;AA0BpD;;;;;;;;;;GAUG;AACH,SAAgB,eAAe,CAAC,KAAoB,EAAE,QAA0B;IAC9E,MAAM,oBAAoB,GAAG,+BAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,0BAA0B,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACnE,yCAA4B,CAAC,GAAG,CAAC,CAAC,CAAC,CACpC,CAAC;IACF,MAAM,aAAa,GACjB,CAAC,oCAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,0BAA0B,CAAC,MAAM,KAAK,CAAC,CAAC;IAEtF,MAAM,mBAAmB,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;IAChE,MAAM,aAAa,GAAG,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;IAE/D,kEAAkE;IAClE,wDAAwD;IACxD,KAAK,QAAQ,CAAC;IAEd,OAAO;QACL,WAAW,EAAE,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC;QACvC,oBAAoB;QACpB,aAAa;QACb,UAAU;QACV,aAAa;QACb,aAAa;KACd,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,IAA2B;IACxD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC;QACd,KAAK,aAAa;YAChB,OAAO,CACL,8EAA8E;gBAC9E,4EAA4E;gBAC5E,qEAAqE,CACtE,CAAC;QACJ,KAAK,MAAM;YACT,OAAO,CACL,6EAA6E;gBAC7E,6EAA6E;gBAC7E,wDAAwD,CACzD,CAAC;QACJ,KAAK,QAAQ;YACX,OAAO,CACL,+DAA+D;gBAC/D,oEAAoE;gBACpE,uEAAuE;gBACvE,iCAAiC,CAClC,CAAC;QACJ,KAAK,UAAU;YACb,OAAO,CACL,gEAAgE;gBAChE,GAAG;gBACH,IAAA,0BAAQ,EAAC,iBAAiB,CAAC;gBAC3B,yCAAyC;gBACzC,qBAAqB,CACtB,CAAC;QACJ,KAAK,aAAa;YAChB,OAAO,CACL,kEAAkE;gBAClE,uDAAuD;gBACvD,wEAAwE,CACzE,CAAC;QACJ,KAAK,cAAc;YACjB,OAAO,CACL,gEAAgE;gBAChE,sEAAsE;gBACtE,kEAAkE,CACnE,CAAC;QACJ,KAAK,UAAU;YACb,OAAO,CACL,sEAAsE;gBACtE,iEAAiE;gBACjE,sCAAsC,CACvC,CAAC;QACJ,KAAK,uBAAuB;YAC1B,OAAO,CACL,0EAA0E;gBAC1E,yEAAyE;gBACzE,0DAA0D,CAC3D,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO,CACL,uEAAuE;gBACvE,0EAA0E;gBAC1E,yEAAyE;gBACzE,+BAA+B,CAChC,CAAC;QACJ,KAAK,UAAU;YACb,OAAO,CACL,yEAAyE;gBACzE,uEAAuE;gBACvE,yEAAyE;gBACzE,+BAA+B,CAChC,CAAC;QACJ,KAAK,YAAY;YACf,OAAO,CACL,+DAA+D;gBAC/D,gEAAgE;gBAChE,uDAAuD,CACxD,CAAC;QACJ,KAAK,YAAY;YACf,OAAO,CACL,wEAAwE;gBACxE,wEAAwE;gBACxE,+CAA+C,CAChD,CAAC;QACJ,KAAK,aAAa;YAChB,OAAO,CACL,iEAAiE;gBACjE,mEAAmE;gBACnE,sEAAsE;gBACtE,mCAAmC,CACpC,CAAC;QACJ,KAAK,cAAc;YACjB,OAAO,CACL,wEAAwE;gBACxE,2EAA2E;gBAC3E,0EAA0E;gBAC1E,oDAAoD,CACrD,CAAC;IACN,CAAC;AACH,CAAC;AAED,4EAA4E;AAE5E;;;;;;;;;;GAUG;AACH,SAAS,YAAY,CAAC,KAAoB;IACxC,IAAI,IAAA,sBAAW,EAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,aAAa,CAAC;QACnB,KAAK,cAAc;YACjB,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QAChD,KAAK,cAAc,CAAC;QACpB,KAAK,UAAU,CAAC;QAChB,KAAK,uBAAuB,CAAC;QAC7B,KAAK,UAAU,CAAC;QAChB,KAAK,YAAY,CAAC;QAClB,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QAC9B,KAAK,aAAa,CAAC;QACnB,KAAK,UAAU,CAAC;QAChB,KAAK,aAAa;YAChB,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,qBAAS,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACvD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,kBAAkB,CACzB,KAAoB,EACpB,mBAAkD;IAElD,IAAI,CAAC,mBAAmB;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,CAAC,oCAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/D,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1D,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa;QAAE,OAAO,SAAS,CAAC;IACnD,OAAO,IAAA,yBAAgB,EAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,IAAI,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,eAAe,CACtB,KAAoB,EACpB,oBAAkD;IAElD,MAAM,aAAa,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,6BAA6B,CAAC;IAChD,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,cAAc,aAAa,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC;IAC5F,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAEhC,oEAAoE;IACpE,oEAAoE;IACpE,EAAE;IACF,qEAAqE;IACrE,kEAAkE;IAClE,qDAAqD;IACrD,iEAAiE;IACjE,kEAAkE;IAClE,kDAAkD;IAClD,IAAI,oCAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClF,OAAO,GAAG,iBAAiB,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,WAAW,IAAI,SAAS,EAAE,CAAC;IACpF,CAAC;IACD,OAAO,GAAG,iBAAiB,kBAAkB,KAAK,CAAC,EAAE,WAAW,KAAK,CAAC,IAAI,IAAI,WAAW,IAAI,SAAS,EAAE,CAAC;AAC3G,CAAC;AAED,SAAS,kBAAkB,CACzB,oBAAkD;IAElD,MAAM,mBAAmB,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gCAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzF,IAAI,CAAC,mBAAmB;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO,CACL,2EAA2E;QAC3E,iFAAiF;QACjF,yCAAyC,CAC1C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Flow configuration read from `.dxkit/policy.json:flow` — the single reader of
3
+ * that section (Rule 2). Kept out of the shared `BrownfieldPolicy` schema (the
4
+ * same way the loop preset is read separately): the flow concept stays
5
+ * self-contained, and every flow surface — the `flow` CLI, the `flow refresh`
6
+ * snapshot writer, and the guardrail gate pass — resolves its config here.
7
+ *
8
+ * All fields are optional in the file; a missing / malformed policy yields the
9
+ * conservative defaults (fail-open), never a throw.
10
+ */
11
+ /** How the guardrail treats a net-new broken integration.
12
+ * - `block` (default): honor the per-finding verdict — an exact, fully
13
+ * specified binding fails the build; a low-confidence (placeholder-only)
14
+ * one warns.
15
+ * - `warn`: every net-new break warns, never fails a build (soft launch, or
16
+ * a repo still tuning its served-side inventory).
17
+ * - `off`: the gate does not run at all. */
18
+ export type FlowGateMode = 'block' | 'warn' | 'off';
19
+ export interface FlowConfig {
20
+ /** Host-helper prefixes stripped during URL normalization (per-app config,
21
+ * e.g. `["https://api.example.com"]`). */
22
+ readonly stripUrlPrefixes: string[];
23
+ /** OpenAPI/spec files whose served routes union with static extraction. */
24
+ readonly specs: string[];
25
+ /** Guardrail posture for net-new broken integrations. */
26
+ readonly mode: FlowGateMode;
27
+ /** Confidence at/above which a net-new break BLOCKS (else warns). Default 1 —
28
+ * only exact, fully specified bindings can fail a build. */
29
+ readonly blockThreshold: number;
30
+ }
31
+ /**
32
+ * Read the `flow` section of `.dxkit/policy.json`. Fail-open — a read/parse
33
+ * error, or an absent `flow` block, returns the defaults so a repo without flow
34
+ * config behaves as "monorepo, block on exact net-new breaks".
35
+ */
36
+ export declare function readFlowConfig(cwd: string): FlowConfig;
37
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/analyzers/flow/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH;;;;;;8CAM8C;AAC9C,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB;+CAC2C;IAC3C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;iEAC6D;IAC7D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAwBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAiBtD"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ /**
3
+ * Flow configuration read from `.dxkit/policy.json:flow` — the single reader of
4
+ * that section (Rule 2). Kept out of the shared `BrownfieldPolicy` schema (the
5
+ * same way the loop preset is read separately): the flow concept stays
6
+ * self-contained, and every flow surface — the `flow` CLI, the `flow refresh`
7
+ * snapshot writer, and the guardrail gate pass — resolves its config here.
8
+ *
9
+ * All fields are optional in the file; a missing / malformed policy yields the
10
+ * conservative defaults (fail-open), never a throw.
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.readFlowConfig = readFlowConfig;
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ const DEFAULTS = {
50
+ stripUrlPrefixes: [],
51
+ specs: [],
52
+ mode: 'block',
53
+ blockThreshold: 1,
54
+ };
55
+ function stringList(v) {
56
+ return Array.isArray(v) ? v.filter((s) => typeof s === 'string') : [];
57
+ }
58
+ function isMode(v) {
59
+ return v === 'block' || v === 'warn' || v === 'off';
60
+ }
61
+ /**
62
+ * Read the `flow` section of `.dxkit/policy.json`. Fail-open — a read/parse
63
+ * error, or an absent `flow` block, returns the defaults so a repo without flow
64
+ * config behaves as "monorepo, block on exact net-new breaks".
65
+ */
66
+ function readFlowConfig(cwd) {
67
+ let raw;
68
+ try {
69
+ const text = fs.readFileSync(path.join(cwd, '.dxkit', 'policy.json'), 'utf8');
70
+ raw = (JSON.parse(text)?.flow ?? {});
71
+ }
72
+ catch {
73
+ return DEFAULTS;
74
+ }
75
+ return {
76
+ stripUrlPrefixes: stringList(raw.stripUrlPrefixes),
77
+ specs: stringList(raw.specs),
78
+ mode: isMode(raw.mode) ? raw.mode : DEFAULTS.mode,
79
+ blockThreshold: typeof raw.blockThreshold === 'number' && raw.blockThreshold > 0
80
+ ? raw.blockThreshold
81
+ : DEFAULTS.blockThreshold,
82
+ };
83
+ }
84
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/analyzers/flow/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDH,wCAiBC;AArED,uCAAyB;AACzB,2CAA6B;AAwB7B,MAAM,QAAQ,GAAe;IAC3B,gBAAgB,EAAE,EAAE;IACpB,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,OAAO;IACb,cAAc,EAAE,CAAC;CAClB,CAAC;AASF,SAAS,UAAU,CAAC,CAAU;IAC5B,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACrF,CAAC;AAED,SAAS,MAAM,CAAC,CAAU;IACxB,OAAO,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,GAAW;IACxC,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9E,GAAG,GAAG,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwB,EAAE,IAAI,IAAI,EAAE,CAAY,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO;QACL,gBAAgB,EAAE,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAClD,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;QAC5B,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI;QACjD,cAAc,EACZ,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ,IAAI,GAAG,CAAC,cAAc,GAAG,CAAC;YAC9D,CAAC,CAAC,GAAG,CAAC,cAAc;YACpB,CAAC,CAAC,QAAQ,CAAC,cAAc;KAC9B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Cross-repo flow contract snapshots under `.dxkit/flow/`.
3
+ *
4
+ * The integration gate is cross-repo: each side publishes its inventory as a
5
+ * committed artifact the OTHER side gates against (mirror of the ingest
6
+ * snapshot pattern, CLAUDE.md Rule 13). A backend refreshes `served.json`
7
+ * (every `(method, path)` it serves); a frontend refreshes `consumed.json`
8
+ * (every binding it depends on). A repo commits the COUNTERPART's snapshot (or
9
+ * a monorepo computes both live), so the gate needs a cross-repo fetch/token
10
+ * only at refresh time — never on the developer's machine or in the per-stop
11
+ * gate.
12
+ *
13
+ * This module is the single reader/writer of `.dxkit/flow/`: confining the path
14
+ * here (arch-check enforced) stops the "different modules pick different
15
+ * defaults" drift class and keeps a future cross-repo fetch composing on one
16
+ * primitive. Snapshots carry only finding data (normalized method/path/file) —
17
+ * no token, no account id — so they are safe to commit.
18
+ */
19
+ import { type FlowModel } from './model';
20
+ /** Directory (relative to repo root) where flow contract snapshots live. */
21
+ export declare const FLOW_DIR: string;
22
+ export declare const SERVED_SNAPSHOT = "served.json";
23
+ export declare const CONSUMED_SNAPSHOT = "consumed.json";
24
+ /** One served endpoint in the served-side inventory. */
25
+ export interface ServedRoute {
26
+ readonly method: string;
27
+ readonly path: string;
28
+ readonly handler: string | null;
29
+ readonly via: 'decorator' | 'router-call' | 'spec';
30
+ }
31
+ /** One binding in the consumed-side inventory — a UI call site's dependency on
32
+ * a served `(method, path)`. `file` + the normalized key are the flow-binding
33
+ * identity inputs; `line` is display metadata (never hashed). `confidence` in
34
+ * [0,1] is the path-specificity signal the gate thresholds on — a
35
+ * placeholder-only path (`/{var}`) is too generic to block a build. */
36
+ export interface ConsumedBinding {
37
+ readonly method: string;
38
+ readonly path: string;
39
+ readonly file: string;
40
+ readonly line: number;
41
+ readonly confidence: number;
42
+ }
43
+ interface SnapshotMeta {
44
+ readonly schemaVersion: 1;
45
+ /** ISO timestamp, stamped by the caller so this module stays clock-free
46
+ * (testability — mirror of ingest/snapshot.ts). */
47
+ readonly generatedAt: string;
48
+ /** Commit the snapshot was produced against, when known. */
49
+ readonly commitSha?: string;
50
+ }
51
+ export interface ServedContract extends SnapshotMeta {
52
+ readonly side: 'served';
53
+ readonly routes: ServedRoute[];
54
+ }
55
+ export interface ConsumedContract extends SnapshotMeta {
56
+ readonly side: 'consumed';
57
+ readonly bindings: ConsumedBinding[];
58
+ }
59
+ /** The `${method} ${path}` join key both sides meet on. */
60
+ export declare function contractKey(method: string, routePath: string): string;
61
+ /**
62
+ * The served inventory: every distinct `(method, path)` this repo serves,
63
+ * deduped via the shared helper (spec wins). Sorted for byte-stable snapshots
64
+ * across runs (a committed artifact should not churn on extraction order).
65
+ */
66
+ export declare function buildServedContract(model: FlowModel, meta: SnapshotMeta): ServedContract;
67
+ /**
68
+ * The consumed inventory: every internal binding this repo depends on — each
69
+ * client call that resolved to an internal path (external/absolute URLs, whose
70
+ * `path` is null, are not internal integrations). Deduped by
71
+ * `(method, path, file)` — the flow-binding identity — so multiple call sites
72
+ * for one dependency collapse to one entry (the earliest line kept for
73
+ * display). Sorted for byte-stability.
74
+ */
75
+ export declare function buildConsumedContract(model: FlowModel, meta: SnapshotMeta): ConsumedContract;
76
+ /** Write the served snapshot (overwrite). Returns the file path. */
77
+ export declare function writeServedContract(cwd: string, contract: ServedContract): string;
78
+ /** Write the consumed snapshot (overwrite). Returns the file path. */
79
+ export declare function writeConsumedContract(cwd: string, contract: ConsumedContract): string;
80
+ /**
81
+ * Read the served snapshot from a repo root (default `.dxkit/flow/served.json`,
82
+ * or an explicit path for a counterpart's committed snapshot). Fail-open: a
83
+ * missing / unreadable / malformed file yields `undefined`, never a throw — the
84
+ * gate degrades to "no contract to check against", never an error.
85
+ */
86
+ export declare function readServedContract(cwd: string, filePath?: string): ServedContract | undefined;
87
+ /** Read the consumed snapshot (see {@link readServedContract}). */
88
+ export declare function readConsumedContract(cwd: string, filePath?: string): ConsumedContract | undefined;
89
+ /** The `${method} ${path}` keys a served contract exposes — the O(1) lookup the
90
+ * gate uses to check whether a consumed binding still resolves. */
91
+ export declare function servedKeySet(contract: ServedContract): Set<string>;
92
+ export {};
93
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/analyzers/flow/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EAA6C,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpF,4EAA4E;AAC5E,eAAO,MAAM,QAAQ,QAA8B,CAAC;AACpD,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAC7C,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,GAAG,MAAM,CAAC;CACpD;AAED;;;;wEAIwE;AACxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B;wDACoD;IACpD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;CACtC;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErE;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,cAAc,CAKxF;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,gBAAgB,CAsB5F;AAWD,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,CAEjF;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAErF;AAgBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAG7F;AAED,mEAAmE;AACnE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAGjG;AAED;oEACoE;AACpE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAElE"}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * Cross-repo flow contract snapshots under `.dxkit/flow/`.
4
+ *
5
+ * The integration gate is cross-repo: each side publishes its inventory as a
6
+ * committed artifact the OTHER side gates against (mirror of the ingest
7
+ * snapshot pattern, CLAUDE.md Rule 13). A backend refreshes `served.json`
8
+ * (every `(method, path)` it serves); a frontend refreshes `consumed.json`
9
+ * (every binding it depends on). A repo commits the COUNTERPART's snapshot (or
10
+ * a monorepo computes both live), so the gate needs a cross-repo fetch/token
11
+ * only at refresh time — never on the developer's machine or in the per-stop
12
+ * gate.
13
+ *
14
+ * This module is the single reader/writer of `.dxkit/flow/`: confining the path
15
+ * here (arch-check enforced) stops the "different modules pick different
16
+ * defaults" drift class and keeps a future cross-repo fetch composing on one
17
+ * primitive. Snapshots carry only finding data (normalized method/path/file) —
18
+ * no token, no account id — so they are safe to commit.
19
+ */
20
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ var desc = Object.getOwnPropertyDescriptor(m, k);
23
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
24
+ desc = { enumerable: true, get: function() { return m[k]; } };
25
+ }
26
+ Object.defineProperty(o, k2, desc);
27
+ }) : (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ o[k2] = m[k];
30
+ }));
31
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
32
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
33
+ }) : function(o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = (this && this.__importStar) || (function () {
37
+ var ownKeys = function(o) {
38
+ ownKeys = Object.getOwnPropertyNames || function (o) {
39
+ var ar = [];
40
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
41
+ return ar;
42
+ };
43
+ return ownKeys(o);
44
+ };
45
+ return function (mod) {
46
+ if (mod && mod.__esModule) return mod;
47
+ var result = {};
48
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
49
+ __setModuleDefault(result, mod);
50
+ return result;
51
+ };
52
+ })();
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.CONSUMED_SNAPSHOT = exports.SERVED_SNAPSHOT = exports.FLOW_DIR = void 0;
55
+ exports.contractKey = contractKey;
56
+ exports.buildServedContract = buildServedContract;
57
+ exports.buildConsumedContract = buildConsumedContract;
58
+ exports.writeServedContract = writeServedContract;
59
+ exports.writeConsumedContract = writeConsumedContract;
60
+ exports.readServedContract = readServedContract;
61
+ exports.readConsumedContract = readConsumedContract;
62
+ exports.servedKeySet = servedKeySet;
63
+ const fs = __importStar(require("fs"));
64
+ const path = __importStar(require("path"));
65
+ const model_1 = require("./model");
66
+ /** Directory (relative to repo root) where flow contract snapshots live. */
67
+ exports.FLOW_DIR = path.join('.dxkit', 'flow');
68
+ exports.SERVED_SNAPSHOT = 'served.json';
69
+ exports.CONSUMED_SNAPSHOT = 'consumed.json';
70
+ /** The `${method} ${path}` join key both sides meet on. */
71
+ function contractKey(method, routePath) {
72
+ return `${method} ${routePath}`;
73
+ }
74
+ // ─── Build (from a flow model) ────────────────────────────────────────────────
75
+ /**
76
+ * The served inventory: every distinct `(method, path)` this repo serves,
77
+ * deduped via the shared helper (spec wins). Sorted for byte-stable snapshots
78
+ * across runs (a committed artifact should not churn on extraction order).
79
+ */
80
+ function buildServedContract(model, meta) {
81
+ const routes = (0, model_1.dedupeServedRoutes)(model.routes)
82
+ .map((r) => ({ method: r.method, path: r.path, handler: r.handler, via: r.via }))
83
+ .sort(byMethodPath);
84
+ return { ...meta, side: 'served', routes };
85
+ }
86
+ /**
87
+ * The consumed inventory: every internal binding this repo depends on — each
88
+ * client call that resolved to an internal path (external/absolute URLs, whose
89
+ * `path` is null, are not internal integrations). Deduped by
90
+ * `(method, path, file)` — the flow-binding identity — so multiple call sites
91
+ * for one dependency collapse to one entry (the earliest line kept for
92
+ * display). Sorted for byte-stability.
93
+ */
94
+ function buildConsumedContract(model, meta) {
95
+ const byKey = new Map();
96
+ for (const call of model.calls) {
97
+ if (call.path == null)
98
+ continue;
99
+ const key = `${call.method}\0${call.path}\0${call.file}`;
100
+ const existing = byKey.get(key);
101
+ if (!existing || call.line < existing.line) {
102
+ byKey.set(key, {
103
+ method: call.method,
104
+ path: call.path,
105
+ file: call.file,
106
+ line: call.line,
107
+ // A placeholder-only path carries no static signal → low confidence, so
108
+ // the gate warns rather than blocks on it.
109
+ confidence: (0, model_1.isPlaceholderOnlyPath)(call.path) ? 0.3 : 1,
110
+ });
111
+ }
112
+ }
113
+ const bindings = [...byKey.values()].sort((a, b) => byMethodPath(a, b) || a.file.localeCompare(b.file));
114
+ return { ...meta, side: 'consumed', bindings };
115
+ }
116
+ function byMethodPath(a, b) {
117
+ return a.method.localeCompare(b.method) || a.path.localeCompare(b.path);
118
+ }
119
+ // ─── Persist ──────────────────────────────────────────────────────────────────
120
+ /** Write the served snapshot (overwrite). Returns the file path. */
121
+ function writeServedContract(cwd, contract) {
122
+ return writeSnapshot(cwd, exports.SERVED_SNAPSHOT, contract);
123
+ }
124
+ /** Write the consumed snapshot (overwrite). Returns the file path. */
125
+ function writeConsumedContract(cwd, contract) {
126
+ return writeSnapshot(cwd, exports.CONSUMED_SNAPSHOT, contract);
127
+ }
128
+ function writeSnapshot(cwd, name, contract) {
129
+ const dir = path.join(cwd, exports.FLOW_DIR);
130
+ fs.mkdirSync(dir, { recursive: true });
131
+ const file = path.join(dir, name);
132
+ fs.writeFileSync(file, JSON.stringify(contract, null, 2) + '\n', 'utf-8');
133
+ return file;
134
+ }
135
+ // ─── Load (fail-open) ───────────────────────────────────────────────────────
136
+ /**
137
+ * Read the served snapshot from a repo root (default `.dxkit/flow/served.json`,
138
+ * or an explicit path for a counterpart's committed snapshot). Fail-open: a
139
+ * missing / unreadable / malformed file yields `undefined`, never a throw — the
140
+ * gate degrades to "no contract to check against", never an error.
141
+ */
142
+ function readServedContract(cwd, filePath) {
143
+ const raw = readJson(filePath ?? path.join(cwd, exports.FLOW_DIR, exports.SERVED_SNAPSHOT));
144
+ return isServed(raw) ? raw : undefined;
145
+ }
146
+ /** Read the consumed snapshot (see {@link readServedContract}). */
147
+ function readConsumedContract(cwd, filePath) {
148
+ const raw = readJson(filePath ?? path.join(cwd, exports.FLOW_DIR, exports.CONSUMED_SNAPSHOT));
149
+ return isConsumed(raw) ? raw : undefined;
150
+ }
151
+ /** The `${method} ${path}` keys a served contract exposes — the O(1) lookup the
152
+ * gate uses to check whether a consumed binding still resolves. */
153
+ function servedKeySet(contract) {
154
+ return new Set(contract.routes.map((r) => contractKey(r.method, r.path)));
155
+ }
156
+ function readJson(absPath) {
157
+ try {
158
+ return JSON.parse(fs.readFileSync(absPath, 'utf-8'));
159
+ }
160
+ catch {
161
+ return undefined;
162
+ }
163
+ }
164
+ function isServed(v) {
165
+ return (typeof v === 'object' &&
166
+ v !== null &&
167
+ v.side === 'served' &&
168
+ Array.isArray(v.routes));
169
+ }
170
+ function isConsumed(v) {
171
+ return (typeof v === 'object' &&
172
+ v !== null &&
173
+ v.side === 'consumed' &&
174
+ Array.isArray(v.bindings));
175
+ }
176
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../src/analyzers/flow/contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The integration-breakage gate — pure evaluation core.
3
+ *
4
+ * Answers "does this diff NET-NEW break a UI→API integration?" from a base↔HEAD
5
+ * contract comparison, with no running system. One algorithm covers both
6
+ * directions (CLAUDE.md design §6):
7
+ * - a FRONTEND PR that adds a call to an endpoint no backend serves, and
8
+ * - a BACKEND PR that removes/renames a route a frontend still calls,
9
+ * because both reduce to "a consumed binding whose (method, path) is not in the
10
+ * served set". The diff makes it net-new: a binding already broken BEFORE the
11
+ * PR (present at base and unresolved against the base served set) is
12
+ * grandfathered; only a binding the PR NEWLY breaks is surfaced.
13
+ *
14
+ * Pure over its inputs — the ref-based gather (base worktree via
15
+ * `withRefWorktree`, Rule 11) and the guardrail wiring live above this module;
16
+ * here we only diff two already-materialized contract sides. Identity is the
17
+ * flow-binding fingerprint (line-independent (method, path, file), Rule 9),
18
+ * computed through the canonical helper so an emitted finding shares one
19
+ * identity contract with the baseline + allowlist.
20
+ */
21
+ import { type ConsumedBinding } from './contract';
22
+ /** Why a binding is broken: the endpoint was never served (a new call to a
23
+ * non-existent route, or a typo), or a route that WAS served got removed. */
24
+ export type BrokenReason = 'no-route' | 'route-removed';
25
+ /** One net-new broken integration the gate surfaces. */
26
+ export interface BrokenIntegration {
27
+ /** Flow-binding fingerprint — the durable identity (Rule 9). */
28
+ readonly id: string;
29
+ readonly method: string;
30
+ readonly path: string;
31
+ readonly file: string;
32
+ readonly line: number;
33
+ readonly confidence: number;
34
+ readonly reason: BrokenReason;
35
+ /** `block` when confidence clears the threshold (a real, specific breakage),
36
+ * else `warn` — conservative by construction to protect the false-positive
37
+ * budget (fuzzy / placeholder-only paths never fail a build). */
38
+ readonly verdict: 'block' | 'warn';
39
+ }
40
+ export interface GateInputs {
41
+ /** Bindings this side depends on at HEAD (the consumed contract post-diff). */
42
+ readonly headConsumed: readonly ConsumedBinding[];
43
+ /** Bindings at the base ref — the grandfathering set. */
44
+ readonly baseConsumed: readonly ConsumedBinding[];
45
+ /** `${method} ${path}` keys served at HEAD (the counterpart's served
46
+ * contract, or this repo's own in a monorepo). */
47
+ readonly headServed: ReadonlySet<string>;
48
+ /** Served keys at the base ref. */
49
+ readonly baseServed: ReadonlySet<string>;
50
+ /** Confidence at/above which a net-new broken binding BLOCKS (else warns).
51
+ * Default 1 — only exact, fully-specified bindings can fail a build. */
52
+ readonly blockThreshold?: number;
53
+ }
54
+ /**
55
+ * Evaluate the gate. Returns every NET-NEW broken integration, most-severe
56
+ * (block before warn) first, then by location for stable output. Empty when the
57
+ * diff breaks nothing new.
58
+ */
59
+ export declare function evaluateFlowGate(inputs: GateInputs): BrokenIntegration[];
60
+ /** Does the gate result block? True when any finding's verdict is `block`. */
61
+ export declare function flowGateBlocks(findings: readonly BrokenIntegration[]): boolean;
62
+ /** Human-readable one-liner for a broken integration (report + Stop-gate). */
63
+ export declare function describeBrokenIntegration(f: BrokenIntegration): string;
64
+ //# sourceMappingURL=gate.d.ts.map