@eduardbar/drift 1.3.0 → 1.5.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 (198) hide show
  1. package/.gga +50 -0
  2. package/.github/actions/drift-review/README.md +62 -0
  3. package/.github/actions/drift-review/action.yml +148 -0
  4. package/.github/actions/drift-scan/README.md +28 -32
  5. package/.github/actions/drift-scan/action.yml +78 -14
  6. package/.github/workflows/publish-vscode.yml +1 -3
  7. package/.github/workflows/publish.yml +8 -0
  8. package/.github/workflows/quality.yml +15 -0
  9. package/.github/workflows/reusable-quality-checks.yml +95 -0
  10. package/.github/workflows/review-pr.yml +33 -41
  11. package/AGENTS.md +75 -251
  12. package/CHANGELOG.md +41 -0
  13. package/README.md +177 -43
  14. package/benchmarks/fixtures/critical/drift.config.ts +21 -0
  15. package/benchmarks/fixtures/critical/src/app/user-service.ts +30 -0
  16. package/benchmarks/fixtures/critical/src/domain/entities.ts +19 -0
  17. package/benchmarks/fixtures/critical/src/domain/policies.ts +22 -0
  18. package/benchmarks/fixtures/critical/src/index.ts +10 -0
  19. package/benchmarks/fixtures/critical/src/infra/memory-user-repo.ts +14 -0
  20. package/benchmarks/perf-budget.v1.json +27 -0
  21. package/dist/benchmark.d.ts +1 -1
  22. package/dist/benchmark.js +83 -52
  23. package/dist/cli.js +243 -8
  24. package/dist/config.js +16 -2
  25. package/dist/diff.js +42 -50
  26. package/dist/doctor.d.ts +26 -0
  27. package/dist/doctor.js +140 -0
  28. package/dist/format.d.ts +17 -0
  29. package/dist/format.js +45 -0
  30. package/dist/guard-baseline.d.ts +12 -0
  31. package/dist/guard-baseline.js +57 -0
  32. package/dist/guard-metrics.d.ts +6 -0
  33. package/dist/guard-metrics.js +39 -0
  34. package/dist/guard-types.d.ts +58 -0
  35. package/dist/guard-types.js +2 -0
  36. package/dist/guard.d.ts +16 -0
  37. package/dist/guard.js +178 -0
  38. package/dist/index.d.ts +10 -3
  39. package/dist/index.js +4 -1
  40. package/dist/init.d.ts +15 -0
  41. package/dist/init.js +273 -0
  42. package/dist/map-cycles.d.ts +2 -0
  43. package/dist/map-cycles.js +34 -0
  44. package/dist/map-svg.d.ts +19 -0
  45. package/dist/map-svg.js +97 -0
  46. package/dist/map.js +78 -138
  47. package/dist/metrics.js +70 -55
  48. package/dist/output-metadata.d.ts +15 -0
  49. package/dist/output-metadata.js +19 -0
  50. package/dist/plugins-capabilities.d.ts +4 -0
  51. package/dist/plugins-capabilities.js +21 -0
  52. package/dist/plugins-messages.d.ts +10 -0
  53. package/dist/plugins-messages.js +16 -0
  54. package/dist/plugins-rules.d.ts +9 -0
  55. package/dist/plugins-rules.js +137 -0
  56. package/dist/plugins.d.ts +1 -1
  57. package/dist/plugins.js +45 -142
  58. package/dist/reporter-constants.d.ts +16 -0
  59. package/dist/reporter-constants.js +39 -0
  60. package/dist/reporter.d.ts +3 -3
  61. package/dist/reporter.js +35 -55
  62. package/dist/review.d.ts +2 -1
  63. package/dist/review.js +2 -1
  64. package/dist/rules/phase3-configurable.js +23 -15
  65. package/dist/saas/constants.d.ts +15 -0
  66. package/dist/saas/constants.js +48 -0
  67. package/dist/saas/dashboard.d.ts +8 -0
  68. package/dist/saas/dashboard.js +132 -0
  69. package/dist/saas/errors.d.ts +19 -0
  70. package/dist/saas/errors.js +37 -0
  71. package/dist/saas/helpers.d.ts +21 -0
  72. package/dist/saas/helpers.js +110 -0
  73. package/dist/saas/ingest.d.ts +3 -0
  74. package/dist/saas/ingest.js +249 -0
  75. package/dist/saas/organization.d.ts +5 -0
  76. package/dist/saas/organization.js +82 -0
  77. package/dist/saas/plan-change.d.ts +10 -0
  78. package/dist/saas/plan-change.js +15 -0
  79. package/dist/saas/store.d.ts +21 -0
  80. package/dist/saas/store.js +159 -0
  81. package/dist/saas/types.d.ts +191 -0
  82. package/dist/saas/types.js +2 -0
  83. package/dist/saas.d.ts +8 -218
  84. package/dist/saas.js +7 -761
  85. package/dist/sarif.d.ts +74 -0
  86. package/dist/sarif.js +122 -0
  87. package/dist/trust-advanced.d.ts +14 -0
  88. package/dist/trust-advanced.js +65 -0
  89. package/dist/trust-kpi-fs.d.ts +3 -0
  90. package/dist/trust-kpi-fs.js +141 -0
  91. package/dist/trust-kpi-parse.d.ts +7 -0
  92. package/dist/trust-kpi-parse.js +186 -0
  93. package/dist/trust-kpi-types.d.ts +16 -0
  94. package/dist/trust-kpi-types.js +2 -0
  95. package/dist/trust-kpi.d.ts +1 -3
  96. package/dist/trust-kpi.js +6 -266
  97. package/dist/trust-policy.d.ts +32 -0
  98. package/dist/trust-policy.js +160 -0
  99. package/dist/trust-render.d.ts +9 -0
  100. package/dist/trust-render.js +54 -0
  101. package/dist/trust-scoring.d.ts +9 -0
  102. package/dist/trust-scoring.js +208 -0
  103. package/dist/trust.d.ts +5 -32
  104. package/dist/trust.js +29 -432
  105. package/dist/types/app.d.ts +30 -0
  106. package/dist/types/app.js +2 -0
  107. package/dist/types/config.d.ts +25 -0
  108. package/dist/types/config.js +2 -0
  109. package/dist/types/core.d.ts +100 -0
  110. package/dist/types/core.js +2 -0
  111. package/dist/types/diff.d.ts +55 -0
  112. package/dist/types/diff.js +2 -0
  113. package/dist/types/plugin.d.ts +41 -0
  114. package/dist/types/plugin.js +2 -0
  115. package/dist/types/trust.d.ts +120 -0
  116. package/dist/types/trust.js +2 -0
  117. package/dist/types.d.ts +8 -365
  118. package/docs/AGENTS.md +1 -1
  119. package/docs/release-notes-draft.md +40 -0
  120. package/docs/rules-catalog.md +49 -0
  121. package/docs/trust-core-release-checklist.md +37 -5
  122. package/package.json +11 -4
  123. package/packages/vscode-drift/src/code-actions.ts +1 -1
  124. package/schemas/drift-ai-output.v1.json +162 -0
  125. package/schemas/drift-doctor.v1.json +57 -0
  126. package/schemas/drift-guard.v1.json +298 -0
  127. package/schemas/drift-report.v1.json +151 -0
  128. package/schemas/drift-trust.v1.json +131 -0
  129. package/scripts/check-docs-drift.mjs +154 -0
  130. package/scripts/check-performance-budget.mjs +360 -0
  131. package/scripts/check-runtime-policy.mjs +66 -0
  132. package/scripts/smoke-repo.mjs +394 -0
  133. package/src/benchmark.ts +92 -53
  134. package/src/cli.ts +285 -13
  135. package/src/config.ts +19 -2
  136. package/src/diff.ts +57 -48
  137. package/src/doctor.ts +185 -0
  138. package/src/format.ts +81 -0
  139. package/src/guard-baseline.ts +74 -0
  140. package/src/guard-metrics.ts +52 -0
  141. package/src/guard-types.ts +66 -0
  142. package/src/guard.ts +248 -0
  143. package/src/index.ts +36 -0
  144. package/src/init.ts +298 -0
  145. package/src/map-cycles.ts +38 -0
  146. package/src/map-svg.ts +124 -0
  147. package/src/map.ts +111 -142
  148. package/src/metrics.ts +78 -59
  149. package/src/output-metadata.ts +32 -0
  150. package/src/plugins-capabilities.ts +36 -0
  151. package/src/plugins-messages.ts +35 -0
  152. package/src/plugins-rules.ts +296 -0
  153. package/src/plugins.ts +76 -283
  154. package/src/reporter-constants.ts +46 -0
  155. package/src/reporter.ts +64 -65
  156. package/src/review.ts +4 -2
  157. package/src/rules/phase3-configurable.ts +39 -26
  158. package/src/saas/constants.ts +56 -0
  159. package/src/saas/dashboard.ts +172 -0
  160. package/src/saas/errors.ts +45 -0
  161. package/src/saas/helpers.ts +140 -0
  162. package/src/saas/ingest.ts +278 -0
  163. package/src/saas/organization.ts +99 -0
  164. package/src/saas/plan-change.ts +19 -0
  165. package/src/saas/store.ts +172 -0
  166. package/src/saas/types.ts +216 -0
  167. package/src/saas.ts +49 -1031
  168. package/src/sarif.ts +232 -0
  169. package/src/trust-advanced.ts +99 -0
  170. package/src/trust-kpi-fs.ts +169 -0
  171. package/src/trust-kpi-parse.ts +219 -0
  172. package/src/trust-kpi-types.ts +19 -0
  173. package/src/trust-kpi.ts +8 -316
  174. package/src/trust-policy.ts +246 -0
  175. package/src/trust-render.ts +61 -0
  176. package/src/trust-scoring.ts +231 -0
  177. package/src/trust.ts +62 -576
  178. package/src/types/app.ts +30 -0
  179. package/src/types/config.ts +27 -0
  180. package/src/types/core.ts +105 -0
  181. package/src/types/diff.ts +61 -0
  182. package/src/types/plugin.ts +46 -0
  183. package/src/types/trust.ts +134 -0
  184. package/src/types.ts +79 -409
  185. package/tests/ci-quality-matrix.test.ts +37 -0
  186. package/tests/ci-smoke-gate.test.ts +26 -0
  187. package/tests/ci-version-alignment.test.ts +93 -0
  188. package/tests/cli-sarif.test.ts +92 -0
  189. package/tests/docs-drift-check.test.ts +115 -0
  190. package/tests/format.test.ts +157 -0
  191. package/tests/new-features.test.ts +11 -3
  192. package/tests/perf-budget-check.test.ts +146 -0
  193. package/tests/phase1-init-doctor-guard.test.ts +301 -0
  194. package/tests/runtime-policy-alignment.test.ts +46 -0
  195. package/tests/sarif.test.ts +160 -0
  196. package/tests/trust-kpi.test.ts +31 -4
  197. package/tests/trust.test.ts +18 -0
  198. package/vitest.config.ts +2 -0
@@ -0,0 +1,49 @@
1
+ # drift rules catalog (current)
2
+
3
+ Source of truth: `RULE_WEIGHTS` in `src/analyzer.ts`.
4
+
5
+ This catalog reflects the current repository state and includes all rule IDs currently weighted/scored by drift.
6
+
7
+ | id | severity | weight | phase/origin | note |
8
+ |---|---|---:|---|---|
9
+ | `large-file` | error | 20 | phase0-basic | file exceeds size threshold |
10
+ | `large-function` | error | 15 | phase0-basic | function exceeds line threshold |
11
+ | `debug-leftover` | warning | 10 | phase0-basic | debug console calls / TODO-like leftovers |
12
+ | `dead-code` | warning | 8 | phase0-basic | unused named imports in file |
13
+ | `duplicate-function-name` | error | 18 | phase0-basic | repeated function names in same file |
14
+ | `comment-contradiction` | warning | 12 | comments rule | comment restates obvious code intent |
15
+ | `no-return-type` | info | 5 | phase0-basic | missing explicit return type |
16
+ | `catch-swallow` | warning | 10 | phase0-basic | empty catch blocks |
17
+ | `magic-number` | info | 3 | magic rule | numeric literals used directly |
18
+ | `any-abuse` | warning | 8 | phase0-basic | explicit `any` usage |
19
+ | `high-complexity` | error | 15 | phase1-complexity | high cyclomatic complexity |
20
+ | `deep-nesting` | warning | 12 | nesting rule | nested control flow too deep |
21
+ | `too-many-params` | warning | 8 | nesting rule | function has too many parameters |
22
+ | `high-coupling` | warning | 10 | coupling rule | too many module dependencies |
23
+ | `promise-style-mix` | warning | 7 | promise rule | mixed async/await and then/catch styles |
24
+ | `unused-export` | warning | 8 | phase2-crossfile | export not imported elsewhere |
25
+ | `dead-file` | warning | 10 | phase2-crossfile | file not imported by project |
26
+ | `unused-dependency` | warning | 6 | phase2-crossfile | package.json dependency unused in sources |
27
+ | `circular-dependency` | error | 14 | phase3-arch | circular import graph edges |
28
+ | `layer-violation` | error | 16 | phase3-arch (config-driven) | invalid import direction across configured layers |
29
+ | `cross-boundary-import` | warning | 10 | phase3-arch (config-driven) | invalid import across configured modules/boundaries |
30
+ | `controller-no-db` | warning | 11 | phase3-configurable | controller imports DB/repository concerns directly |
31
+ | `service-no-http` | warning | 11 | phase3-configurable | service imports/uses HTTP transport concerns |
32
+ | `max-function-lines` | warning | 9 | phase3-configurable | function/method exceeds configured max lines |
33
+ | `over-commented` | info | 4 | phase5-ai | excessive comments heuristic |
34
+ | `hardcoded-config` | warning | 10 | phase5-ai | hardcoded URLs/secrets/config literals |
35
+ | `inconsistent-error-handling` | warning | 8 | phase5-ai | mixed error-handling styles |
36
+ | `unnecessary-abstraction` | warning | 7 | phase5-ai | wrappers/abstractions with little value |
37
+ | `naming-inconsistency` | warning | 6 | phase5-ai | mixed naming conventions |
38
+ | `ai-code-smell` | warning | 12 | analyzer meta-rule | aggregated AI-smell signal from multiple heuristics |
39
+ | `semantic-duplication` | warning | 12 | phase8-semantic | AST fingerprint identifies equivalent functions |
40
+ | `plugin-error` | warning | 4 | plugin diagnostics | plugin load/contract/runtime failure surfaced as issue |
41
+ | `plugin-warning` | info | 0 | plugin diagnostics | non-fatal plugin validation warning |
42
+ | `analysis-skip-max-files` | info | 0 | analysis guardrail diagnostics | file skipped due to `maxFiles` limit |
43
+ | `analysis-skip-file-size` | info | 0 | analysis guardrail diagnostics | file skipped due to `maxFileSizeKb` limit |
44
+
45
+ ## Notes
46
+
47
+ - Config-driven rules require matching config blocks to execute (`layers`, `modules`/legacy aliases, `architectureRules`).
48
+ - `plugin-*` and `analysis-skip-*` are diagnostic rules emitted as issues and included in scoring with their configured weights.
49
+ - Total rule IDs currently defined: **35**.
@@ -8,7 +8,7 @@ Use this checklist before releasing the trust-core milestone.
8
8
  - [x] `npm test`
9
9
  - [x] `npx --no-install tsx ./src/cli.ts trust . --base origin/master --markdown`
10
10
  - [x] `npx --no-install tsx ./src/cli.ts trust . --base origin/master --json-output drift-trust.json`
11
- - [x] `npx --no-install tsx ./src/cli.ts trust-gate drift-trust.json --min-trust 40 --max-risk HIGH`
11
+ - [x] `npx --no-install tsx ./src/cli.ts trust-gate drift-trust.json --min-trust 45 --max-risk HIGH`
12
12
  - [x] `npx --no-install tsx ./src/cli.ts review --base origin/master --comment`
13
13
 
14
14
  ## 2) CI workflow validation
@@ -36,16 +36,16 @@ Smoke PR runbook:
36
36
 
37
37
  Default trust gate for this milestone:
38
38
 
39
- - `--min-trust 40`
39
+ - `--min-trust 45`
40
40
  - `--max-risk HIGH`
41
41
 
42
42
  Checks:
43
43
 
44
- - [x] PR fails when trust score is below 40.
44
+ - [x] PR fails when trust score is below 45.
45
45
  - [x] PR fails when merge risk is `CRITICAL`.
46
- - [x] PR passes when trust score is 40+ and merge risk is `LOW`, `MEDIUM`, or `HIGH`.
46
+ - [x] PR passes when trust score is 45+ and merge risk is `LOW`, `MEDIUM`, or `HIGH`.
47
47
 
48
- Calibration evidence from docs-only smoke runs: trust score 49 (PR #11), 46 (PR #12), 41 (PR #13). Gate floor set to 40 to avoid false negatives while still blocking `CRITICAL` risk.
48
+ Calibration evidence from docs-only smoke runs: trust score 49 (PR #11), 46 (PR #12), 41 (PR #13). Gate floor set to 45 to reduce false positives while still blocking weak trust outcomes and `CRITICAL` risk.
49
49
 
50
50
  ## 4) Narrative and docs acceptance
51
51
 
@@ -53,3 +53,35 @@ Calibration evidence from docs-only smoke runs: trust score 49 (PR #11), 46 (PR
53
53
  - [x] `package.json` description matches the same positioning.
54
54
  - [x] `src/cli.ts` program description matches the same positioning.
55
55
  - [x] `ROADMAP.md` no longer contradicts PRD on core vs premium direction.
56
+
57
+ ## 5) SARIF and action v2 readiness
58
+
59
+ - [x] `scan --format sarif` emits valid SARIF payload with drift rule mapping.
60
+ - [x] `ci --format sarif` emits SARIF without requiring GitHub annotation mode.
61
+ - [x] `diff --format sarif` emits SARIF from `DriftDiff` output.
62
+ - [x] `review --format sarif` emits SARIF from review diff context.
63
+ - [x] `trust --format sarif` emits SARIF based on current trust scan report.
64
+ - [x] CI workflow uploads SARIF artifact in PR runs.
65
+ - [x] Action v2 contracts are aligned with SARIF-capable commands and outputs.
66
+
67
+ ## 6) Trust artifacts and KPI readiness
68
+
69
+ - [x] Trust command supports split outputs (`--json-output` + selected stdout format).
70
+ - [x] Artifact bundle includes trust JSON, gate result, and trust KPI aggregate.
71
+ - [x] `drift kpi` parses trust artifacts and prints JSON plus optional summary.
72
+ - [x] Trust gate policy behavior documented and calibrated for current milestone.
73
+
74
+ ## 7) Quick smoke runbook (no build)
75
+
76
+ Run from repository root:
77
+
78
+ - [x] `node --import tsx ./src/cli.ts scan . --format sarif > .tmp/smoke-scan.sarif`
79
+ - [x] `node --import tsx ./src/cli.ts ci . --format sarif > .tmp/smoke-ci.sarif`
80
+ - [x] `node --import tsx ./src/cli.ts trust . --format sarif > .tmp/smoke-trust.sarif`
81
+ - [x] `node --import tsx ./src/cli.ts review --base HEAD~1 --format sarif > .tmp/smoke-review.sarif`
82
+
83
+ Validation hints:
84
+
85
+ - Check each command exits with code `0`.
86
+ - Check each `.sarif` file starts with `{"$schema"` and contains `"runs"`.
87
+ - Keep smoke artifacts out of release commit unless explicitly needed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eduardbar/drift",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "AI Code Audit CLI for merge trust in AI-assisted PRs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,7 +15,11 @@
15
15
  "test": "vitest run",
16
16
  "test:watch": "vitest",
17
17
  "test:coverage": "vitest run --coverage",
18
- "benchmark": "node --import tsx src/benchmark.ts"
18
+ "benchmark": "node --import tsx src/benchmark.ts",
19
+ "smoke:repo": "node ./scripts/smoke-repo.mjs",
20
+ "check:runtime-policy": "node ./scripts/check-runtime-policy.mjs",
21
+ "check:docs-drift": "node ./scripts/check-docs-drift.mjs",
22
+ "check:perf-budget": "node ./scripts/check-performance-budget.mjs"
19
23
  },
20
24
  "keywords": [
21
25
  "vibe-coding",
@@ -27,6 +31,9 @@
27
31
  ],
28
32
  "author": "eduardbar",
29
33
  "license": "MIT",
34
+ "engines": {
35
+ "node": "^20.0.0 || ^22.0.0"
36
+ },
30
37
  "homepage": "https://github.com/eduardbar/drift#readme",
31
38
  "repository": {
32
39
  "type": "git",
@@ -42,9 +49,9 @@
42
49
  },
43
50
  "devDependencies": {
44
51
  "@types/node": "^25.3.0",
45
- "@vitest/coverage-v8": "^4.0.18",
52
+ "@vitest/coverage-v8": "^4.1.2",
46
53
  "tsx": "^4.21.0",
47
54
  "typescript": "^5.9.3",
48
- "vitest": "^4.0.18"
55
+ "vitest": "^4.1.2"
49
56
  }
50
57
  }
@@ -16,7 +16,7 @@ function buildCatchTodoEdit(document: vscode.TextDocument, line: number): vscode
16
16
  const targetLine = document.lineAt(line)
17
17
  const baseIndent = targetLine.text.match(/^\s*/)?.[0] ?? ''
18
18
  const indent = `${baseIndent} `
19
- edit.insert(document.uri, new vscode.Position(line + 1, 0), `${indent}// TODO: handle error\n`)
19
+ edit.insert(document.uri, new vscode.Position(line + 1, 0), `${indent}// handle error\n`)
20
20
  return edit
21
21
  }
22
22
 
@@ -0,0 +1,162 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "schemas/drift-ai-output.v1.json",
4
+ "title": "drift ai output v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "$schema",
9
+ "toolVersion",
10
+ "summary",
11
+ "files_suspected",
12
+ "priority_order",
13
+ "maintenance_risk",
14
+ "quality",
15
+ "context_for_ai"
16
+ ],
17
+ "properties": {
18
+ "$schema": {
19
+ "const": "schemas/drift-ai-output.v1.json"
20
+ },
21
+ "toolVersion": {
22
+ "type": "string"
23
+ },
24
+ "summary": {
25
+ "type": "object",
26
+ "additionalProperties": false,
27
+ "required": [
28
+ "score",
29
+ "grade",
30
+ "total_issues",
31
+ "files_affected",
32
+ "files_clean",
33
+ "ai_likelihood",
34
+ "ai_code_smell_score"
35
+ ],
36
+ "properties": {
37
+ "score": { "type": "number" },
38
+ "grade": { "type": "string" },
39
+ "total_issues": { "type": "number" },
40
+ "files_affected": { "type": "number" },
41
+ "files_clean": { "type": "number" },
42
+ "ai_likelihood": { "type": "number" },
43
+ "ai_code_smell_score": { "type": "number" }
44
+ }
45
+ },
46
+ "files_suspected": {
47
+ "type": "array",
48
+ "items": {
49
+ "type": "object",
50
+ "additionalProperties": false,
51
+ "required": ["path", "ai_likelihood", "triggers"],
52
+ "properties": {
53
+ "path": { "type": "string" },
54
+ "ai_likelihood": { "type": "number" },
55
+ "triggers": {
56
+ "type": "array",
57
+ "items": { "type": "string" }
58
+ }
59
+ }
60
+ }
61
+ },
62
+ "priority_order": {
63
+ "type": "array",
64
+ "items": {
65
+ "type": "object",
66
+ "additionalProperties": false,
67
+ "required": ["rank", "file", "line", "rule", "severity", "message", "snippet", "fix_suggestion", "effort"],
68
+ "properties": {
69
+ "rank": { "type": "number" },
70
+ "file": { "type": "string" },
71
+ "line": { "type": "number" },
72
+ "rule": { "type": "string" },
73
+ "severity": { "type": "string" },
74
+ "message": { "type": "string" },
75
+ "snippet": { "type": "string" },
76
+ "fix_suggestion": { "type": "string" },
77
+ "effort": { "enum": ["low", "medium", "high"] }
78
+ }
79
+ }
80
+ },
81
+ "maintenance_risk": {
82
+ "type": "object",
83
+ "additionalProperties": false,
84
+ "required": ["score", "level", "hotspots", "signals"],
85
+ "properties": {
86
+ "score": { "type": "number" },
87
+ "level": { "enum": ["low", "medium", "high", "critical"] },
88
+ "hotspots": {
89
+ "type": "array",
90
+ "items": {
91
+ "type": "object",
92
+ "additionalProperties": false,
93
+ "required": [
94
+ "file",
95
+ "driftScore",
96
+ "complexityIssues",
97
+ "hasNearbyTests",
98
+ "changeFrequency",
99
+ "risk",
100
+ "reasons"
101
+ ],
102
+ "properties": {
103
+ "file": { "type": "string" },
104
+ "driftScore": { "type": "number" },
105
+ "complexityIssues": { "type": "number" },
106
+ "hasNearbyTests": { "type": "boolean" },
107
+ "changeFrequency": { "type": "number" },
108
+ "risk": { "type": "number" },
109
+ "reasons": {
110
+ "type": "array",
111
+ "items": { "type": "string" }
112
+ }
113
+ }
114
+ }
115
+ },
116
+ "signals": {
117
+ "type": "object",
118
+ "additionalProperties": false,
119
+ "required": ["highComplexityFiles", "filesWithoutNearbyTests", "frequentChangeFiles"],
120
+ "properties": {
121
+ "highComplexityFiles": { "type": "number" },
122
+ "filesWithoutNearbyTests": { "type": "number" },
123
+ "frequentChangeFiles": { "type": "number" }
124
+ }
125
+ }
126
+ }
127
+ },
128
+ "quality": {
129
+ "type": "object",
130
+ "additionalProperties": false,
131
+ "required": ["overall", "dimensions"],
132
+ "properties": {
133
+ "overall": { "type": "number" },
134
+ "dimensions": {
135
+ "type": "object",
136
+ "additionalProperties": false,
137
+ "required": ["architecture", "complexity", "ai-patterns", "testing"],
138
+ "properties": {
139
+ "architecture": { "type": "number" },
140
+ "complexity": { "type": "number" },
141
+ "ai-patterns": { "type": "number" },
142
+ "testing": { "type": "number" }
143
+ }
144
+ }
145
+ }
146
+ },
147
+ "context_for_ai": {
148
+ "type": "object",
149
+ "additionalProperties": false,
150
+ "required": ["project_type", "scan_path", "rules_detected", "recommended_action"],
151
+ "properties": {
152
+ "project_type": { "type": "string" },
153
+ "scan_path": { "type": "string" },
154
+ "rules_detected": {
155
+ "type": "array",
156
+ "items": { "type": "string" }
157
+ },
158
+ "recommended_action": { "type": "string" }
159
+ }
160
+ }
161
+ }
162
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "schemas/drift-doctor.v1.json",
4
+ "title": "drift doctor v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "$schema",
9
+ "toolVersion",
10
+ "targetPath",
11
+ "node",
12
+ "project"
13
+ ],
14
+ "properties": {
15
+ "$schema": {
16
+ "const": "schemas/drift-doctor.v1.json"
17
+ },
18
+ "toolVersion": {
19
+ "type": "string"
20
+ },
21
+ "targetPath": {
22
+ "type": "string"
23
+ },
24
+ "node": {
25
+ "type": "object",
26
+ "additionalProperties": false,
27
+ "required": ["version", "major", "supported"],
28
+ "properties": {
29
+ "version": { "type": "string" },
30
+ "major": { "type": "number" },
31
+ "supported": { "type": "boolean" }
32
+ }
33
+ },
34
+ "project": {
35
+ "type": "object",
36
+ "additionalProperties": false,
37
+ "required": [
38
+ "packageJsonFound",
39
+ "esm",
40
+ "tsconfigFound",
41
+ "sourceFilesCount",
42
+ "lowMemorySuggested",
43
+ "driftConfigFile"
44
+ ],
45
+ "properties": {
46
+ "packageJsonFound": { "type": "boolean" },
47
+ "esm": { "type": "boolean" },
48
+ "tsconfigFound": { "type": "boolean" },
49
+ "sourceFilesCount": { "type": "number" },
50
+ "lowMemorySuggested": { "type": "boolean" },
51
+ "driftConfigFile": {
52
+ "type": ["string", "null"]
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }