@promptci/core 0.0.1 → 0.2.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 (253) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +29 -30
  3. package/dist/action-pinning.d.ts +37 -0
  4. package/dist/action-pinning.d.ts.map +1 -0
  5. package/dist/action-pinning.js +277 -0
  6. package/dist/action-pinning.js.map +1 -0
  7. package/dist/agent-practices.d.ts +3 -1
  8. package/dist/agent-practices.d.ts.map +1 -1
  9. package/dist/agent-practices.js +198 -94
  10. package/dist/agent-practices.js.map +1 -1
  11. package/dist/ai-config.d.ts +178 -0
  12. package/dist/ai-config.d.ts.map +1 -0
  13. package/dist/ai-config.js +721 -0
  14. package/dist/ai-config.js.map +1 -0
  15. package/dist/alias-files.d.ts +33 -0
  16. package/dist/alias-files.d.ts.map +1 -0
  17. package/dist/alias-files.js +60 -0
  18. package/dist/alias-files.js.map +1 -0
  19. package/dist/baseline.d.ts +17 -1
  20. package/dist/baseline.d.ts.map +1 -1
  21. package/dist/baseline.js +5 -1
  22. package/dist/baseline.js.map +1 -1
  23. package/dist/buried-critical.d.ts +17 -0
  24. package/dist/buried-critical.d.ts.map +1 -0
  25. package/dist/buried-critical.js +107 -0
  26. package/dist/buried-critical.js.map +1 -0
  27. package/dist/canonical-owner.d.ts.map +1 -1
  28. package/dist/canonical-owner.js +60 -30
  29. package/dist/canonical-owner.js.map +1 -1
  30. package/dist/ci-alignment.d.ts.map +1 -1
  31. package/dist/ci-alignment.js +3 -2
  32. package/dist/ci-alignment.js.map +1 -1
  33. package/dist/command-validity.d.ts +16 -0
  34. package/dist/command-validity.d.ts.map +1 -1
  35. package/dist/command-validity.js +387 -134
  36. package/dist/command-validity.js.map +1 -1
  37. package/dist/conflicts.d.ts.map +1 -1
  38. package/dist/conflicts.js +4 -44
  39. package/dist/conflicts.js.map +1 -1
  40. package/dist/context-analysis.d.ts.map +1 -1
  41. package/dist/context-analysis.js +13 -2
  42. package/dist/context-analysis.js.map +1 -1
  43. package/dist/context-bloat.d.ts +20 -1
  44. package/dist/context-bloat.d.ts.map +1 -1
  45. package/dist/context-bloat.js +99 -15
  46. package/dist/context-bloat.js.map +1 -1
  47. package/dist/context-optimizer.d.ts.map +1 -1
  48. package/dist/context-optimizer.js +18 -54
  49. package/dist/context-optimizer.js.map +1 -1
  50. package/dist/copilot-instructions-detector.d.ts +24 -0
  51. package/dist/copilot-instructions-detector.d.ts.map +1 -0
  52. package/dist/copilot-instructions-detector.js +145 -0
  53. package/dist/copilot-instructions-detector.js.map +1 -0
  54. package/dist/cursor-rules-detector.d.ts +17 -0
  55. package/dist/cursor-rules-detector.d.ts.map +1 -0
  56. package/dist/cursor-rules-detector.js +110 -0
  57. package/dist/cursor-rules-detector.js.map +1 -0
  58. package/dist/custom-rules.d.ts +52 -0
  59. package/dist/custom-rules.d.ts.map +1 -0
  60. package/dist/custom-rules.js +303 -0
  61. package/dist/custom-rules.js.map +1 -0
  62. package/dist/dead-references.d.ts +8 -2
  63. package/dist/dead-references.d.ts.map +1 -1
  64. package/dist/dead-references.js +315 -68
  65. package/dist/dead-references.js.map +1 -1
  66. package/dist/dependency-staleness.d.ts +35 -0
  67. package/dist/dependency-staleness.d.ts.map +1 -0
  68. package/dist/dependency-staleness.js +1001 -0
  69. package/dist/dependency-staleness.js.map +1 -0
  70. package/dist/detectors.d.ts +1 -3
  71. package/dist/detectors.d.ts.map +1 -1
  72. package/dist/detectors.js +74 -56
  73. package/dist/detectors.js.map +1 -1
  74. package/dist/duplicates.d.ts.map +1 -1
  75. package/dist/duplicates.js +15 -9
  76. package/dist/duplicates.js.map +1 -1
  77. package/dist/evidence.d.ts +39 -0
  78. package/dist/evidence.d.ts.map +1 -0
  79. package/dist/evidence.js +78 -0
  80. package/dist/evidence.js.map +1 -0
  81. package/dist/finding-id.d.ts +21 -0
  82. package/dist/finding-id.d.ts.map +1 -0
  83. package/dist/finding-id.js +31 -0
  84. package/dist/finding-id.js.map +1 -0
  85. package/dist/fix-engine.d.ts +11 -0
  86. package/dist/fix-engine.d.ts.map +1 -1
  87. package/dist/fix-engine.js +88 -71
  88. package/dist/fix-engine.js.map +1 -1
  89. package/dist/frameworks/dotnet.js +2 -2
  90. package/dist/frameworks/dotnet.js.map +1 -1
  91. package/dist/frameworks/python.d.ts.map +1 -1
  92. package/dist/frameworks/python.js +5 -2
  93. package/dist/frameworks/python.js.map +1 -1
  94. package/dist/frameworks/rust.d.ts.map +1 -1
  95. package/dist/frameworks/rust.js +2 -1
  96. package/dist/frameworks/rust.js.map +1 -1
  97. package/dist/git-symlinks.d.ts +30 -0
  98. package/dist/git-symlinks.d.ts.map +1 -0
  99. package/dist/git-symlinks.js +161 -0
  100. package/dist/git-symlinks.js.map +1 -0
  101. package/dist/gitignore.d.ts +22 -0
  102. package/dist/gitignore.d.ts.map +1 -0
  103. package/dist/gitignore.js +157 -0
  104. package/dist/gitignore.js.map +1 -0
  105. package/dist/health-score.d.ts.map +1 -1
  106. package/dist/health-score.js +35 -5
  107. package/dist/health-score.js.map +1 -1
  108. package/dist/hooks-settings-detector.d.ts +17 -0
  109. package/dist/hooks-settings-detector.d.ts.map +1 -0
  110. package/dist/hooks-settings-detector.js +228 -0
  111. package/dist/hooks-settings-detector.js.map +1 -0
  112. package/dist/index.d.ts +29 -8
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +21 -6
  115. package/dist/index.js.map +1 -1
  116. package/dist/makefile.d.ts +37 -0
  117. package/dist/makefile.d.ts.map +1 -0
  118. package/dist/makefile.js +156 -0
  119. package/dist/makefile.js.map +1 -0
  120. package/dist/manifest-consistency.d.ts +6 -0
  121. package/dist/manifest-consistency.d.ts.map +1 -1
  122. package/dist/manifest-consistency.js +75 -10
  123. package/dist/manifest-consistency.js.map +1 -1
  124. package/dist/markdown-fences.d.ts +112 -0
  125. package/dist/markdown-fences.d.ts.map +1 -0
  126. package/dist/markdown-fences.js +174 -0
  127. package/dist/markdown-fences.js.map +1 -0
  128. package/dist/mcp-config-detector.d.ts +20 -0
  129. package/dist/mcp-config-detector.d.ts.map +1 -0
  130. package/dist/mcp-config-detector.js +237 -0
  131. package/dist/mcp-config-detector.js.map +1 -0
  132. package/dist/missing-context.d.ts.map +1 -1
  133. package/dist/missing-context.js +2 -52
  134. package/dist/missing-context.js.map +1 -1
  135. package/dist/model-budgets.d.ts +69 -0
  136. package/dist/model-budgets.d.ts.map +1 -0
  137. package/dist/model-budgets.js +110 -0
  138. package/dist/model-budgets.js.map +1 -0
  139. package/dist/negative-instructions.d.ts +26 -0
  140. package/dist/negative-instructions.d.ts.map +1 -0
  141. package/dist/negative-instructions.js +169 -0
  142. package/dist/negative-instructions.js.map +1 -0
  143. package/dist/path-containment.d.ts +41 -0
  144. package/dist/path-containment.d.ts.map +1 -0
  145. package/dist/path-containment.js +123 -0
  146. package/dist/path-containment.js.map +1 -0
  147. package/dist/project-type.d.ts +12 -2
  148. package/dist/project-type.d.ts.map +1 -1
  149. package/dist/project-type.js +25 -12
  150. package/dist/project-type.js.map +1 -1
  151. package/dist/prompt-cache.d.ts.map +1 -1
  152. package/dist/prompt-cache.js +33 -24
  153. package/dist/prompt-cache.js.map +1 -1
  154. package/dist/promptci-gitignore.d.ts +34 -0
  155. package/dist/promptci-gitignore.d.ts.map +1 -0
  156. package/dist/promptci-gitignore.js +42 -0
  157. package/dist/promptci-gitignore.js.map +1 -0
  158. package/dist/repo-context.d.ts +80 -0
  159. package/dist/repo-context.d.ts.map +1 -1
  160. package/dist/repo-context.js +170 -16
  161. package/dist/repo-context.js.map +1 -1
  162. package/dist/report.d.ts +8 -0
  163. package/dist/report.d.ts.map +1 -1
  164. package/dist/report.js +163 -63
  165. package/dist/report.js.map +1 -1
  166. package/dist/scan.d.ts.map +1 -1
  167. package/dist/scan.js +47 -4
  168. package/dist/scan.js.map +1 -1
  169. package/dist/scanner.d.ts +61 -1
  170. package/dist/scanner.d.ts.map +1 -1
  171. package/dist/scanner.js +367 -70
  172. package/dist/scanner.js.map +1 -1
  173. package/dist/security-pack.d.ts +20 -0
  174. package/dist/security-pack.d.ts.map +1 -1
  175. package/dist/security-pack.js +33 -14
  176. package/dist/security-pack.js.map +1 -1
  177. package/dist/skill-supply-chain.d.ts +132 -0
  178. package/dist/skill-supply-chain.d.ts.map +1 -0
  179. package/dist/skill-supply-chain.js +2954 -0
  180. package/dist/skill-supply-chain.js.map +1 -0
  181. package/dist/skills-detector.d.ts +23 -0
  182. package/dist/skills-detector.d.ts.map +1 -0
  183. package/dist/skills-detector.js +279 -0
  184. package/dist/skills-detector.js.map +1 -0
  185. package/dist/stale-instructions.d.ts +4 -1
  186. package/dist/stale-instructions.d.ts.map +1 -1
  187. package/dist/stale-instructions.js +53 -55
  188. package/dist/stale-instructions.js.map +1 -1
  189. package/dist/subagents-detector.d.ts +19 -0
  190. package/dist/subagents-detector.d.ts.map +1 -0
  191. package/dist/subagents-detector.js +155 -0
  192. package/dist/subagents-detector.js.map +1 -0
  193. package/dist/suppression.d.ts +2 -0
  194. package/dist/suppression.d.ts.map +1 -1
  195. package/dist/suppression.js +16 -47
  196. package/dist/suppression.js.map +1 -1
  197. package/dist/types.d.ts +62 -4
  198. package/dist/types.d.ts.map +1 -1
  199. package/dist/types.js +47 -1
  200. package/dist/types.js.map +1 -1
  201. package/dist/vague-guidance.d.ts +15 -2
  202. package/dist/vague-guidance.d.ts.map +1 -1
  203. package/dist/vague-guidance.js +44 -41
  204. package/dist/vague-guidance.js.map +1 -1
  205. package/dist/windsurf-detector.d.ts +22 -0
  206. package/dist/windsurf-detector.d.ts.map +1 -0
  207. package/dist/windsurf-detector.js +96 -0
  208. package/dist/windsurf-detector.js.map +1 -0
  209. package/dist/within-section-dedup.d.ts +16 -0
  210. package/dist/within-section-dedup.d.ts.map +1 -0
  211. package/dist/within-section-dedup.js +148 -0
  212. package/dist/within-section-dedup.js.map +1 -0
  213. package/dist/workspace-manifests.d.ts +80 -0
  214. package/dist/workspace-manifests.d.ts.map +1 -0
  215. package/dist/workspace-manifests.js +333 -0
  216. package/dist/workspace-manifests.js.map +1 -0
  217. package/package.json +11 -8
  218. package/dist/cheap-model-routing.d.ts +0 -4
  219. package/dist/cheap-model-routing.d.ts.map +0 -1
  220. package/dist/cheap-model-routing.js +0 -43
  221. package/dist/cheap-model-routing.js.map +0 -1
  222. package/dist/cli-output-filter.d.ts +0 -16
  223. package/dist/cli-output-filter.d.ts.map +0 -1
  224. package/dist/cli-output-filter.js +0 -88
  225. package/dist/cli-output-filter.js.map +0 -1
  226. package/dist/context-cost.d.ts +0 -4
  227. package/dist/context-cost.d.ts.map +0 -1
  228. package/dist/context-cost.js +0 -70
  229. package/dist/context-cost.js.map +0 -1
  230. package/dist/context-recommender.d.ts +0 -3
  231. package/dist/context-recommender.d.ts.map +0 -1
  232. package/dist/context-recommender.js +0 -329
  233. package/dist/context-recommender.js.map +0 -1
  234. package/dist/llm.d.ts +0 -6
  235. package/dist/llm.d.ts.map +0 -1
  236. package/dist/llm.js +0 -67
  237. package/dist/llm.js.map +0 -1
  238. package/dist/mcp-detector.d.ts +0 -4
  239. package/dist/mcp-detector.d.ts.map +0 -1
  240. package/dist/mcp-detector.js +0 -131
  241. package/dist/mcp-detector.js.map +0 -1
  242. package/dist/native-tool-preference.d.ts +0 -20
  243. package/dist/native-tool-preference.d.ts.map +0 -1
  244. package/dist/native-tool-preference.js +0 -94
  245. package/dist/native-tool-preference.js.map +0 -1
  246. package/dist/output-verbosity.d.ts +0 -3
  247. package/dist/output-verbosity.d.ts.map +0 -1
  248. package/dist/output-verbosity.js +0 -83
  249. package/dist/output-verbosity.js.map +0 -1
  250. package/dist/product-boundary.d.ts +0 -11
  251. package/dist/product-boundary.d.ts.map +0 -1
  252. package/dist/product-boundary.js +0 -301
  253. package/dist/product-boundary.js.map +0 -1
@@ -1,301 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import * as crypto from 'node:crypto';
4
- /**
5
- * Product-Boundary Drift Detector
6
- *
7
- * Detects when instruction files contain stale "X does not exist" or
8
- * "do not build X" guidance that contradicts clear filesystem evidence of X
9
- * already existing in the repo.
10
- *
11
- * Philosophy:
12
- * - Require STRONG filesystem evidence before flagging (multiple corroborating
13
- * signals where possible).
14
- * - Matched text from the instruction file is shown in evidence — the raw
15
- * regex source is never exposed to users.
16
- * - One finding per (capability × file), regardless of how many patterns match.
17
- * - Wording is cautious throughout ("appears to", "may be stale").
18
- *
19
- * Findings are heuristic — cautious wording is intentional.
20
- */
21
- function issueId(key) {
22
- const hash = crypto.createHash('sha1').update(key).digest('hex').slice(0, 12);
23
- return `prod-bound-${hash}`;
24
- }
25
- // ── Filesystem helpers ────────────────────────────────────────────────────────
26
- /** Returns true when at least one of the repo-relative paths exists on disk. */
27
- function anyPathExists(repoRoot, relativePaths) {
28
- return relativePaths.some((p) => fs.existsSync(path.join(repoRoot, p)));
29
- }
30
- const CAPABILITIES = [
31
- // ── Web App ───────────────────────────────────────────────────────────────
32
- {
33
- name: 'Web App',
34
- fsPaths: [
35
- 'apps/web',
36
- 'next.config.ts',
37
- 'next.config.js',
38
- 'next.config.mjs',
39
- 'next.config.cjs',
40
- ],
41
- depPrefixes: ['next'],
42
- contradictoryPatterns: [
43
- // "do not add web app" / "don't add web app"
44
- /\b(?:do\s+not|don'?t)\s+add\s+(?:a\s+)?web\s+app\b/i,
45
- // "no web app exists yet" / "no web app yet"
46
- /\bno\s+web\s+app\s+(?:exists?\s+)?yet\b/i,
47
- // "no web app" as a standalone factual claim (not "no web app logic" etc.)
48
- /\bno\s+web\s+app\b(?!\s+(?:logic|code|component|route|page|specific))/i,
49
- // "web app pending" / "web app not yet built"
50
- /\bweb\s+app\s+(?:pending|not\s+(?:yet\s+)?(?:built|implemented|created))\b/i,
51
- ],
52
- severity: 'high',
53
- title: 'Possible stale boundary: instruction appears to deny a web app that exists',
54
- evidenceLabel: 'web app (apps/web or next.config.*)',
55
- recommendation: 'Update the instruction file to reflect that the web app is now present. ' +
56
- 'Replace the stale non-goal statement with current guidance about the web app.',
57
- },
58
- // ── Supabase ──────────────────────────────────────────────────────────────
59
- {
60
- name: 'Supabase',
61
- fsPaths: ['supabase/migrations', 'supabase'],
62
- depPrefixes: ['@supabase/'],
63
- contradictoryPatterns: [
64
- /\bno\s+supabase\b/i,
65
- /\bsupabase\s+(?:pending|not\s+(?:yet\s+)?(?:set\s+up|configured|added|integrated))\b/i,
66
- /\bno\s+(?:supabase\s+)?(?:database|db)\s+yet\b/i,
67
- ],
68
- severity: 'high',
69
- title: 'Possible stale boundary: instruction appears to deny Supabase that is configured',
70
- evidenceLabel: 'Supabase (supabase/ directory or @supabase/* dependency)',
71
- recommendation: 'Update the instruction file to reflect that Supabase is now configured. ' +
72
- 'Replace the stale non-goal statement with current guidance about the database.',
73
- },
74
- // ── Database ──────────────────────────────────────────────────────────────
75
- {
76
- name: 'Database',
77
- fsPaths: ['supabase/migrations', 'drizzle', 'prisma', 'prisma/schema.prisma'],
78
- depPrefixes: ['drizzle-orm', 'prisma', '@prisma/'],
79
- contradictoryPatterns: [
80
- /\bno\s+database\b/i,
81
- /\bdatabase\s+pending\b/i,
82
- /\bno\s+db\b/i,
83
- /\bwithout\s+a\s+database\b/i,
84
- ],
85
- severity: 'high',
86
- title: 'Possible stale boundary: instruction appears to deny a database that exists',
87
- evidenceLabel: 'database schema/migrations (supabase/migrations, drizzle, or prisma)',
88
- recommendation: 'Update the instruction file to reflect the current database setup. ' +
89
- 'Replace the stale non-goal statement with current guidance about data access.',
90
- },
91
- // ── Dashboard ─────────────────────────────────────────────────────────────
92
- {
93
- name: 'Dashboard',
94
- fsPaths: [
95
- 'apps/web/src/app/dashboard',
96
- 'apps/web/src/app/(dashboard)',
97
- 'apps/web/src/app/api/upload/route.ts',
98
- 'src/app/dashboard',
99
- 'src/app/(dashboard)',
100
- 'app/dashboard',
101
- 'app/(dashboard)',
102
- 'src/pages/dashboard',
103
- 'pages/dashboard',
104
- ],
105
- contradictoryPatterns: [
106
- /\bdashboard\s+(?:pending|not\s+(?:yet\s+)?(?:built|implemented|created|started))\b/i,
107
- /\bno\s+dashboard\b/i,
108
- /\bdashboard\s+does\s+not\s+exist\b/i,
109
- ],
110
- severity: 'warning',
111
- title: 'Possible stale boundary: instruction appears to deny a dashboard that exists',
112
- evidenceLabel: 'dashboard routes (apps/web/src/app/dashboard or upload API route)',
113
- recommendation: 'Update the instruction file to reflect that the dashboard is now implemented.',
114
- },
115
- // ── Upload API ────────────────────────────────────────────────────────────
116
- {
117
- name: 'Upload API',
118
- fsPaths: [
119
- 'apps/web/src/app/api/upload/route.ts',
120
- 'apps/web/src/app/api/upload',
121
- 'src/app/api/upload/route.ts',
122
- 'src/app/api/upload',
123
- 'app/api/upload/route.ts',
124
- 'app/api/upload',
125
- 'pages/api/upload.ts',
126
- ],
127
- contradictoryPatterns: [
128
- /\bupload\s+not\s+(?:yet\s+)?implemented\b/i,
129
- /\bno\s+upload\s+(?:route|api|endpoint)\b/i,
130
- /\bupload\s+(?:api|route|endpoint)\s+(?:pending|does\s+not\s+exist)\b/i,
131
- ],
132
- severity: 'warning',
133
- title: 'Possible stale boundary: instruction appears to deny an upload API that exists',
134
- evidenceLabel: 'upload API route (apps/web/src/app/api/upload/route.ts)',
135
- recommendation: 'Update the instruction file to reflect that the upload API is implemented. ' +
136
- 'Document what data is uploaded and any relevant security guidance.',
137
- },
138
- // ── Playwright / E2E ──────────────────────────────────────────────────────
139
- {
140
- name: 'Playwright/E2E',
141
- fsPaths: [
142
- 'playwright.config.ts',
143
- 'playwright.config.js',
144
- 'playwright.config.mjs',
145
- 'playwright.config.cjs',
146
- ],
147
- depPrefixes: ['@playwright/test'],
148
- contradictoryPatterns: [
149
- /\bno\s+(?:e2e|end.to.end)\s+tests?\b/i,
150
- /\bno\s+playwright\b/i,
151
- /\bplaywright\s+(?:pending|not\s+(?:yet\s+)?(?:set\s+up|configured|added))\b/i,
152
- ],
153
- severity: 'warning',
154
- title: 'Possible stale boundary: instruction appears to deny E2E tests that are configured',
155
- evidenceLabel: 'Playwright config (playwright.config.*)',
156
- recommendation: 'Update the instruction file to include E2E testing guidance. ' +
157
- 'Document how to run Playwright tests and any relevant setup steps.',
158
- },
159
- // ── GitHub OAuth ──────────────────────────────────────────────────────────
160
- {
161
- name: 'GitHub OAuth',
162
- fsPaths: [
163
- 'apps/web/src/app/auth',
164
- 'apps/web/src/app/api/auth',
165
- 'apps/web/src/app/(auth)',
166
- 'src/app/auth',
167
- 'src/app/api/auth',
168
- 'src/app/(auth)',
169
- 'app/auth',
170
- 'app/api/auth',
171
- 'app/(auth)',
172
- 'pages/api/auth',
173
- ],
174
- contradictoryPatterns: [
175
- // PB1: exclude scoped prose like "no auth required for public
176
- // endpoints" — that's a SCOPING statement about a specific route, not
177
- // a claim that auth doesn't exist anywhere in the project. Without
178
- // this exclusion, any repo with auth routes AND a scoped "no auth
179
- // required" note anywhere would always get flagged.
180
- /\bno\s+(?:github\s+)?(?:oauth|auth(?:entication)?)\b(?!\s+(?:is\s+)?(?:required|needed|necessary)\b)/i,
181
- /\bauth(?:entication)?\s+(?:pending|not\s+(?:yet\s+)?(?:built|implemented|added))\b/i,
182
- /\bno\s+login\b(?!\s+(?:is\s+)?(?:required|needed|necessary)\b)/i,
183
- ],
184
- severity: 'warning',
185
- title: 'Possible stale boundary: instruction appears to deny auth that is implemented',
186
- evidenceLabel: 'auth routes (apps/web/src/app/auth or apps/web/src/app/api/auth)',
187
- recommendation: 'Update the instruction file to reflect that authentication is now implemented.',
188
- },
189
- ];
190
- // ── Capability presence check ─────────────────────────────────────────────────
191
- /**
192
- * Returns true when the repo shows strong evidence of the capability, either
193
- * via filesystem paths or via package.json dependencies.
194
- */
195
- function capabilityIsPresent(cap, context) {
196
- if (anyPathExists(context.repoRoot, cap.fsPaths))
197
- return true;
198
- if (cap.depPrefixes && cap.depPrefixes.length > 0) {
199
- const allDeps = {
200
- ...context.packageJson.dependencies,
201
- ...context.packageJson.devDependencies,
202
- };
203
- return cap.depPrefixes.some((prefix) => Object.keys(allDeps).some((dep) => dep === prefix || dep.startsWith(prefix)));
204
- }
205
- return false;
206
- }
207
- // ── First-match evidence extraction ──────────────────────────────────────────
208
- /**
209
- * PB2: strips fenced code blocks (``` or ~~~, matching fence char/length per
210
- * CommonMark) and inline `code spans` before contradiction matching. Without
211
- * this, a fenced example that QUOTES a contradictory phrase (e.g.
212
- * documenting the OLD wording of a non-goal statement as a "before" example)
213
- * was read as a live claim and flagged — the same class of bug fixed for
214
- * vague-guidance.ts, stale-instructions.ts, and conflicts.ts.
215
- */
216
- function stripCodeBlocks(text) {
217
- const lines = text.split('\n');
218
- const kept = [];
219
- let inBlock = false;
220
- let fenceChar = null;
221
- let fenceLen = 0;
222
- for (const line of lines) {
223
- if (!inBlock) {
224
- const openMatch = /^ {0,3}([`~]{3,})/.exec(line);
225
- if (openMatch) {
226
- inBlock = true;
227
- fenceChar = openMatch[1][0] ?? null;
228
- fenceLen = openMatch[1].length;
229
- continue;
230
- }
231
- kept.push(line);
232
- }
233
- else {
234
- const closeMatch = /^ {0,3}([`~]{3,})\s*$/.exec(line);
235
- if (closeMatch && closeMatch[1][0] === fenceChar && closeMatch[1].length >= fenceLen) {
236
- inBlock = false;
237
- fenceChar = null;
238
- fenceLen = 0;
239
- }
240
- // else: still inside the fence — drop the line
241
- }
242
- }
243
- return kept.join('\n').replace(/`[^`\n]+`/g, '');
244
- }
245
- /**
246
- * Finds the first contradictory phrase in `content` and returns the matched
247
- * text (the actual instruction wording), or undefined if none match.
248
- */
249
- function findFirstContradiction(content, patterns) {
250
- for (const pattern of patterns) {
251
- // Use a fresh non-global copy to find the first match position
252
- const re = new RegExp(pattern.source, pattern.flags.replace('g', ''));
253
- const m = re.exec(content);
254
- if (m)
255
- return { pattern, matched: m[0] };
256
- }
257
- return undefined;
258
- }
259
- // ── Public detector ───────────────────────────────────────────────────────────
260
- /**
261
- * Detects stale product-boundary instructions that contradict filesystem
262
- * evidence of a feature already existing in the repo.
263
- *
264
- * One finding is emitted per (capability × file) regardless of how many
265
- * contradictory patterns match in that file, to keep the report actionable.
266
- */
267
- export function detectProductBoundary(context) {
268
- const issues = [];
269
- const { repoRoot, files } = context;
270
- for (const cap of CAPABILITIES) {
271
- if (!capabilityIsPresent(cap, context))
272
- continue;
273
- // Collect all existing evidence paths for the finding
274
- const existingPaths = cap.fsPaths.filter((p) => fs.existsSync(path.join(repoRoot, p)));
275
- const evidencePaths = existingPaths.length > 0 ? existingPaths : [cap.evidenceLabel];
276
- for (const file of files) {
277
- const contradiction = findFirstContradiction(stripCodeBlocks(file.content), cap.contradictoryPatterns);
278
- if (!contradiction)
279
- continue;
280
- issues.push({
281
- id: issueId(`${cap.name}:${file.path}`),
282
- severity: cap.severity,
283
- category: 'stale_instruction',
284
- title: cap.title,
285
- summary: `The instruction file appears to contain a stale product-boundary statement ` +
286
- `that contradicts ${cap.evidenceLabel} found in the repository. ` +
287
- `The phrase "${contradiction.matched}" may no longer reflect the current state of the project.`,
288
- filePaths: [file.path],
289
- locations: [{ filePath: file.path }],
290
- evidence: [
291
- `Contradictory phrase found: "${contradiction.matched}"`,
292
- `Repository evidence: ${evidencePaths.join(', ')}`,
293
- ],
294
- recommendation: cap.recommendation,
295
- confidence: 0.85,
296
- });
297
- }
298
- }
299
- return issues;
300
- }
301
- //# sourceMappingURL=product-boundary.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"product-boundary.js","sourceRoot":"","sources":["../src/product-boundary.ts"],"names":[],"mappings":"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"}