cue-ai 0.9.0 → 0.9.2

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 (310) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +82 -33
  3. package/bin/cue-review-progress +107 -0
  4. package/bin/cue-review-watch +98 -0
  5. package/dist/cue.js +7352 -3744
  6. package/package.json +16 -5
  7. package/profiles/_types.ts +9 -0
  8. package/profiles/backend/profile.yaml +2 -0
  9. package/profiles/blog-writer/profile.yaml +10 -0
  10. package/profiles/browser/profile.yaml +9 -2
  11. package/profiles/builder/profile.yaml +3 -6
  12. package/profiles/career/profile.yaml +13 -2
  13. package/profiles/claude-api/profile.yaml +1 -1
  14. package/profiles/commerce/profile.yaml +27 -3
  15. package/profiles/core/logo.png +0 -0
  16. package/profiles/core/profile.yaml +62 -2
  17. package/profiles/dash-merge-test/profile.yaml +109 -0
  18. package/profiles/designer/profile.yaml +2 -0
  19. package/profiles/designer-medusa-next/profile.yaml +4 -1
  20. package/profiles/designer-medusa-vite/profile.yaml +4 -1
  21. package/profiles/docs-writer/profile.yaml +3 -1
  22. package/profiles/eu-tender-research/README.md +48 -0
  23. package/profiles/eu-tender-research/logo.png +0 -0
  24. package/profiles/eu-tender-research/profile.yaml +108 -0
  25. package/profiles/finance/logo.png +0 -0
  26. package/profiles/finance/profile.yaml +46 -0
  27. package/profiles/frontend/profile.yaml +5 -9
  28. package/profiles/growth/profile.yaml +2 -3
  29. package/profiles/gstack/profile.yaml +15 -0
  30. package/profiles/higgsfield/profile.yaml +3 -0
  31. package/profiles/hyperframes/logo.png +0 -0
  32. package/profiles/hyperframes/profile.yaml +59 -0
  33. package/profiles/improver/profile.yaml +88 -0
  34. package/profiles/marketing/profile.yaml +0 -3
  35. package/profiles/medusa-dev/profile.yaml +2 -0
  36. package/profiles/medusa-next/profile.yaml +2 -3
  37. package/profiles/medusa-vite/profile.yaml +2 -3
  38. package/profiles/n8n/logo.png +0 -0
  39. package/profiles/n8n/profile.yaml +50 -0
  40. package/profiles/nextjs/profile.yaml +2 -3
  41. package/profiles/ops/profile.yaml +2 -0
  42. package/profiles/postizz/profile.yaml +13 -3
  43. package/profiles/python/profile.yaml +3 -0
  44. package/profiles/research/profile.yaml +3 -1
  45. package/profiles/schema.json +10 -0
  46. package/profiles/secops/profile.yaml +2 -0
  47. package/profiles/seo/profile.yaml +56 -0
  48. package/profiles/skill-writer/profile.yaml +8 -0
  49. package/profiles/ssh/profile.yaml +32 -0
  50. package/profiles/strapi/logo.png +0 -0
  51. package/profiles/strapi/profile.yaml +45 -0
  52. package/profiles/stripe/logo.png +0 -0
  53. package/profiles/stripe/profile.yaml +1 -0
  54. package/profiles/supabase/logo.png +0 -0
  55. package/profiles/supabase/profile.yaml +85 -0
  56. package/profiles/vercel/logo.png +0 -0
  57. package/profiles/vercel/profile.yaml +25 -1
  58. package/profiles/vite/profile.yaml +4 -3
  59. package/profiles/web-frontend-base/profile.yaml +5 -4
  60. package/profiles/webshop/profile.yaml +23 -5
  61. package/profiles/x-growth-bot/profile.yaml +44 -0
  62. package/resources/icons/generate-icons.py +128 -2
  63. package/resources/mcps/configs/claude.sanitized.json +42 -0
  64. package/resources/mcps/configs/codex.sanitized.json +7 -0
  65. package/resources/skills/skills/career/resume-version-manager/SKILL.md +351 -0
  66. package/resources/skills/skills/career/salary-negotiation-prep/SKILL.md +378 -0
  67. package/resources/skills/skills/content/pdf/SKILL.md +2 -0
  68. package/resources/skills/skills/content/postiz-cards/SKILL.md +48 -0
  69. package/resources/skills/skills/content/postiz-cards/scripts/analytics.sh +38 -0
  70. package/resources/skills/skills/content/postiz-cards/scripts/card.sh +42 -0
  71. package/resources/skills/skills/content/postiz-cards/scripts/lint.py +38 -0
  72. package/resources/skills/skills/design/headless-gif-demo/SKILL.md +1 -1
  73. package/resources/skills/skills/design/readme-svg-design/SKILL.md +1 -1
  74. package/resources/skills/skills/eu-funding/grant-outreach/SKILL.md +70 -0
  75. package/resources/skills/skills/eu-funding/hu-grant-finder/SKILL.md +114 -0
  76. package/resources/skills/skills/eu-funding/hu-grant-finder/evals.md +26 -0
  77. package/resources/skills/skills/eu-funding/ted-tender-search/SKILL.md +80 -0
  78. package/resources/skills/skills/eu-funding/ted-tender-search/evals.md +26 -0
  79. package/resources/skills/skills/eu-funding/ted-tender-search/scripts/ted-search.sh +46 -0
  80. package/resources/skills/skills/event-design/wedding-invitations/SKILL.md +1 -1
  81. package/resources/skills/skills/github/gx-agents/SKILL.md +96 -0
  82. package/resources/skills/skills/gstack/design-shotgun/SKILL.md +1 -1
  83. package/resources/skills/skills/marketing/ab-test-analyzer/SKILL.md +1 -1
  84. package/resources/skills/skills/marketing/ab-test-setup-and-analysis/SKILL.md +1 -1
  85. package/resources/skills/skills/marketing/account-structure-review/SKILL.md +1 -1
  86. package/resources/skills/skills/marketing/ad-copy-variant-generator/SKILL.md +1 -1
  87. package/resources/skills/skills/marketing/ad-extension-audit/SKILL.md +1 -1
  88. package/resources/skills/skills/marketing/ad-spend-allocator/SKILL.md +1 -1
  89. package/resources/skills/skills/marketing/anomaly-detection/SKILL.md +1 -1
  90. package/resources/skills/skills/marketing/attribution-model-comparison/SKILL.md +1 -1
  91. package/resources/skills/skills/marketing/audience-overlap-analysis/SKILL.md +7 -1
  92. package/resources/skills/skills/marketing/bid-strategy-recommendations/SKILL.md +7 -1
  93. package/resources/skills/skills/marketing/budget-scenario-planner/SKILL.md +6 -1
  94. package/resources/skills/skills/marketing/campaign-naming-convention-builder/SKILL.md +7 -1
  95. package/resources/skills/skills/marketing/channel-mix-optimizer/SKILL.md +7 -1
  96. package/resources/skills/skills/marketing/client-report-narratives/SKILL.md +6 -1
  97. package/resources/skills/skills/marketing/competitor-creative-analysis/SKILL.md +1 -1
  98. package/resources/skills/skills/marketing/competitor-teardown/SKILL.md +1 -1
  99. package/resources/skills/skills/marketing/content-repurposer/SKILL.md +1 -1
  100. package/resources/skills/skills/marketing/conversion-path-analysis/SKILL.md +1 -1
  101. package/resources/skills/skills/marketing/cpa-diagnostics/SKILL.md +1 -1
  102. package/resources/skills/skills/marketing/creative-fatigue-detection/SKILL.md +1 -1
  103. package/resources/skills/skills/marketing/day-hour-performance-breakdown/SKILL.md +1 -1
  104. package/resources/skills/skills/marketing/device-performance-split/SKILL.md +1 -1
  105. package/resources/skills/skills/marketing/e2e-seo-assistant/SKILL.md +1 -1
  106. package/resources/skills/skills/marketing/email-sequence-writer/SKILL.md +1 -1
  107. package/resources/skills/skills/marketing/frequency-cap-recommendations/SKILL.md +1 -1
  108. package/resources/skills/skills/marketing/geo-performance-analysis/SKILL.md +1 -1
  109. package/resources/skills/skills/marketing/google-ads-audit/SKILL.md +1 -1
  110. package/resources/skills/skills/marketing/icp-research-assistant/SKILL.md +1 -1
  111. package/resources/skills/skills/marketing/keyword-cannibalization-check/SKILL.md +1 -1
  112. package/resources/skills/skills/marketing/landing-page-audit/SKILL.md +1 -1
  113. package/resources/skills/skills/marketing/landing-page-audit-quick/SKILL.md +1 -1
  114. package/resources/skills/skills/marketing/linkedin-ads-audit/SKILL.md +1 -1
  115. package/resources/skills/skills/marketing/meta-ads-audit/SKILL.md +1 -1
  116. package/resources/skills/skills/marketing/pacing-monitor/SKILL.md +1 -1
  117. package/resources/skills/skills/marketing/performance-benchmarking/SKILL.md +1 -1
  118. package/resources/skills/skills/marketing/programmatic-seo-builder/SKILL.md +1 -1
  119. package/resources/skills/skills/marketing/quality-score-breakdown/SKILL.md +1 -1
  120. package/resources/skills/skills/marketing/reddit-ads-audit/SKILL.md +1 -1
  121. package/resources/skills/skills/marketing/retargeting-window-analysis/SKILL.md +1 -1
  122. package/resources/skills/skills/marketing/roas-forecasting/SKILL.md +1 -1
  123. package/resources/skills/skills/marketing/search-term-mining/SKILL.md +1 -1
  124. package/resources/skills/skills/marketing/utm-tracking-generator/SKILL.md +1 -1
  125. package/resources/skills/skills/marketing/wasted-spend-finder/SKILL.md +1 -1
  126. package/resources/skills/skills/marketing/weekly-account-summary/SKILL.md +1 -1
  127. package/resources/skills/skills/meta/awesome-list-submit/SKILL.md +4 -4
  128. package/resources/skills/skills/meta/cue-dashboard/SKILL.md +109 -0
  129. package/resources/skills/skills/meta/cue-developer/SKILL.md +161 -0
  130. package/resources/skills/skills/meta/cue-developer/evals/evals.json +57 -0
  131. package/resources/skills/skills/meta/cue-developer/references/architecture.md +65 -0
  132. package/resources/skills/skills/meta/cue-developer/references/build_and_test.md +72 -0
  133. package/resources/skills/skills/meta/cue-developer/references/contributing.md +75 -0
  134. package/resources/skills/skills/meta/cue-developer/references/conventions.md +57 -0
  135. package/resources/skills/skills/meta/cue-developer/references/first_time_setup.md +51 -0
  136. package/resources/skills/skills/meta/cue-developer/references/skill_and_mcp_authoring.md +84 -0
  137. package/resources/skills/skills/meta/cue-developer/references/troubleshooting.md +42 -0
  138. package/resources/skills/skills/meta/delegation-check/SKILL.md +148 -0
  139. package/resources/skills/skills/meta/delegation-check/specs/scan-algorithm.md +125 -0
  140. package/resources/skills/skills/meta/delegation-check/specs/separation-rules.md +190 -0
  141. package/resources/skills/skills/meta/focus/SKILL.md +62 -0
  142. package/resources/skills/skills/meta/help/SKILL.md +1 -1
  143. package/resources/skills/skills/meta/integrity-tags/SKILL.md +2 -0
  144. package/resources/skills/skills/meta/next-steps/SKILL.md +124 -0
  145. package/resources/skills/skills/meta/next-steps/evals/eval-set.json +92 -0
  146. package/resources/skills/skills/meta/profile-from-docs/SKILL.md +141 -0
  147. package/resources/skills/skills/meta/ralph-loop/SKILL.md +83 -0
  148. package/resources/skills/skills/meta/ralph-loop/scripts/loop.sh +73 -0
  149. package/resources/skills/skills/meta/skill-simplify/SKILL.md +136 -0
  150. package/resources/skills/skills/meta/skill-simplify/phases/01-analysis.md +173 -0
  151. package/resources/skills/skills/meta/skill-simplify/phases/02-optimize.md +104 -0
  152. package/resources/skills/skills/meta/skill-simplify/phases/03-check.md +145 -0
  153. package/resources/skills/skills/meta/smart-loader/scripts/smart-lookup.sh +13 -4
  154. package/resources/skills/skills/meta/verify-council/SKILL.md +182 -0
  155. package/resources/skills/skills/meta/verify-council/references/lane-prompts.md +103 -0
  156. package/resources/skills/skills/meta/verify-council/references/workflow.js +217 -0
  157. package/resources/skills/skills/nvidia/aiq-research/SKILL.md +1 -1
  158. package/resources/skills/skills/nvidia/cuopt-developer/SKILL.md +16 -1
  159. package/resources/skills/skills/nvidia/cuopt-developer/resources/contributing.md +2 -2
  160. package/resources/skills/skills/nvidia/cuopt-developer/resources/numerical_debugging.md +128 -0
  161. package/resources/skills/skills/nvidia/cuopt-developer/resources/python_bindings.md +2 -9
  162. package/resources/skills/skills/nvidia/cuopt-developer/resources/vrp_skills.md +166 -0
  163. package/resources/skills/skills/nvidia/cuopt-install/SKILL.md +2 -10
  164. package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-c/SKILL.md +3 -23
  165. package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-c/resources/examples.md +40 -20
  166. package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-python/SKILL.md +5 -1
  167. package/resources/skills/skills/nvidia/skill-evolution/SKILL.md +4 -5
  168. package/resources/skills/skills/research/trendradar/SKILL.md +1 -1
  169. package/resources/skills/skills/ssh/ssh-config/SKILL.md +94 -0
  170. package/resources/skills/skills/ssh/ssh-copy/SKILL.md +92 -0
  171. package/resources/skills/skills/ssh/ssh-harden/SKILL.md +108 -0
  172. package/resources/skills/skills/ssh/ssh-keys/SKILL.md +82 -0
  173. package/resources/skills/skills/ssh/ssh-paste-image/LICENSE +28 -0
  174. package/resources/skills/skills/ssh/ssh-paste-image/SKILL.md +149 -0
  175. package/resources/skills/skills/ssh/ssh-paste-image/scripts/build.sh +29 -0
  176. package/resources/skills/skills/ssh/ssh-paste-image/scripts/client/go.mod +3 -0
  177. package/resources/skills/skills/ssh/ssh-paste-image/scripts/client/main.go +79 -0
  178. package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/ccimgd.service +12 -0
  179. package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/com.ccimgd.plist +20 -0
  180. package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/go.mod +3 -0
  181. package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/main.go +98 -0
  182. package/resources/skills/skills/ssh/ssh-tunnel/SKILL.md +96 -0
  183. package/resources/skills/skills/strapi/building-with-strapi/SKILL.md +112 -0
  184. package/resources/skills/skills/strapi/strapi-cli/SKILL.md +93 -0
  185. package/resources/skills/skills/strapi/strapi-content-api/SKILL.md +115 -0
  186. package/resources/skills/skills/strapi/strapi-deploy/SKILL.md +89 -0
  187. package/resources/skills/skills/strapi/strapi-mcp-setup/SKILL.md +101 -0
  188. package/resources/skills/skills/strapi/strapi-plugins/SKILL.md +97 -0
  189. package/resources/skills/skills/tools/context7/SKILL.md +101 -0
  190. package/resources/skills/skills/tools/opensrc/SKILL.md +1 -1
  191. package/resources/skills/skills/tools/portless/SKILL.md +186 -0
  192. package/resources/skills/skills/xbot/operate/SKILL.md +229 -0
  193. package/src/commands/_index.ts +8 -0
  194. package/src/commands/ai-score.e2e.test.ts +11 -4
  195. package/src/commands/ai.ts +3 -4
  196. package/src/commands/auto-detect.ts +1 -1
  197. package/src/commands/cli.test.ts +1 -2
  198. package/src/commands/cli.ts +1 -1
  199. package/src/commands/cloud.ts +1 -1
  200. package/src/commands/current.ts +1 -4
  201. package/src/commands/dash.test.ts +110 -0
  202. package/src/commands/dash.ts +194 -0
  203. package/src/commands/dashboard.ts +26 -0
  204. package/src/commands/diff.ts +1 -1
  205. package/src/commands/discover.test.ts +1 -1
  206. package/src/commands/discover.ts +90 -40
  207. package/src/commands/doctor.test.ts +58 -0
  208. package/src/commands/doctor.ts +79 -3
  209. package/src/commands/eval-behavior.ts +1 -1
  210. package/src/commands/eval.ts +2 -2
  211. package/src/commands/evolve.ts +4 -3
  212. package/src/commands/failures.test.ts +1 -1
  213. package/src/commands/features-batch1.test.ts +6 -1
  214. package/src/commands/icon.ts +1 -5
  215. package/src/commands/import-profile.ts +1 -1
  216. package/src/commands/init.ts +50 -7
  217. package/src/commands/install-sh.e2e.test.ts +65 -0
  218. package/src/commands/launch-handoff.e2e.test.ts +88 -0
  219. package/src/commands/launch.e2e.test.ts +8 -1
  220. package/src/commands/launch.test.ts +29 -0
  221. package/src/commands/launch.ts +185 -131
  222. package/src/commands/lock.ts +0 -1
  223. package/src/commands/marketplace.ts +0 -4
  224. package/src/commands/materialize.ts +1 -1
  225. package/src/commands/mem.ts +341 -0
  226. package/src/commands/optimizer.ts +0 -3
  227. package/src/commands/playground.ts +1 -2
  228. package/src/commands/profile-draft-skill.ts +1 -1
  229. package/src/commands/replay-whatif.ts +1 -6
  230. package/src/commands/score.ts +2 -2
  231. package/src/commands/security.test.ts +88 -0
  232. package/src/commands/security.ts +74 -28
  233. package/src/commands/shell.test.ts +65 -4
  234. package/src/commands/shell.ts +67 -7
  235. package/src/commands/skills-test.ts +0 -1
  236. package/src/commands/skills.ts +28 -2
  237. package/src/commands/sources.ts +1 -2
  238. package/src/commands/status.ts +2 -6
  239. package/src/commands/submit-profile.ts +1 -1
  240. package/src/commands/suggest.ts +35 -10
  241. package/src/commands/trigger-gaps.test.ts +50 -0
  242. package/src/commands/trigger-gaps.ts +63 -29
  243. package/src/commands/update.ts +1 -1
  244. package/src/commands/validate.ts +16 -4
  245. package/src/commands/watch-live.ts +1 -1
  246. package/src/commands/workspace.ts +1 -1
  247. package/src/index.ts +26 -10
  248. package/src/lib/active-sessions.ts +1 -1
  249. package/src/lib/agent-adapters.test.ts +100 -0
  250. package/src/lib/agent-adapters.ts +2 -2
  251. package/src/lib/analytics.test.ts +88 -0
  252. package/src/lib/analytics.ts +82 -1
  253. package/src/lib/auto-detect.test.ts +10 -4
  254. package/src/lib/auto-detect.ts +19 -23
  255. package/src/lib/brand-icons.ts +0 -1
  256. package/src/lib/cache.ts +2 -3
  257. package/src/lib/claude-mem-env.test.ts +148 -0
  258. package/src/lib/claude-mem-env.ts +172 -0
  259. package/src/lib/combo-history.test.ts +53 -0
  260. package/src/lib/combo-history.ts +83 -0
  261. package/src/lib/companion-detect.test.ts +108 -0
  262. package/src/lib/companion-detect.ts +140 -0
  263. package/src/lib/companion-fetch.ts +4 -6
  264. package/src/lib/conditional-skills.test.ts +1 -1
  265. package/src/lib/config-paths.test.ts +53 -0
  266. package/src/lib/config-paths.ts +33 -0
  267. package/src/lib/dashboard-server.test.ts +351 -0
  268. package/src/lib/dashboard-server.ts +1476 -27
  269. package/src/lib/debug-log.test.ts +66 -0
  270. package/src/lib/debug-log.ts +45 -0
  271. package/src/lib/mcp-catalog.test.ts +102 -0
  272. package/src/lib/mcp-catalog.ts +193 -0
  273. package/src/lib/pair-suggestions.test.ts +111 -0
  274. package/src/lib/pair-suggestions.ts +98 -5
  275. package/src/lib/permissions.test.ts +76 -0
  276. package/src/lib/permissions.ts +125 -0
  277. package/src/lib/picker.test.ts +1106 -1
  278. package/src/lib/picker.ts +1230 -142
  279. package/src/lib/plugin-discovery.ts +126 -0
  280. package/src/lib/pr-poster.ts +1 -1
  281. package/src/lib/pr-throttle.ts +2 -6
  282. package/src/lib/profile-linter.test.ts +67 -1
  283. package/src/lib/profile-linter.ts +59 -14
  284. package/src/lib/profile-loader.test.ts +21 -0
  285. package/src/lib/profile-loader.ts +22 -3
  286. package/src/lib/profile-metrics.ts +2 -6
  287. package/src/lib/profile-names.test.ts +58 -0
  288. package/src/lib/repos.test.ts +57 -0
  289. package/src/lib/repos.ts +167 -0
  290. package/src/lib/resolver-npx.ts +10 -1
  291. package/src/lib/runtime-materializer.test.ts +200 -3
  292. package/src/lib/runtime-materializer.ts +129 -20
  293. package/src/lib/shared-profiles.ts +2 -3
  294. package/src/lib/skill-clis.test.ts +113 -0
  295. package/src/lib/skill-clis.ts +232 -0
  296. package/src/lib/skill-dependencies.ts +9 -1
  297. package/src/lib/skill-deps.ts +1 -1
  298. package/src/lib/skill-linter.ts +1 -1
  299. package/src/lib/skill-quality.ts +0 -1
  300. package/src/lib/skill-sandbox.test.ts +1 -1
  301. package/src/lib/skills-lock.test.ts +1 -1
  302. package/src/lib/telemetry-consent.ts +3 -5
  303. package/src/lib/telemetry-report.test.ts +2 -2
  304. package/src/lib/token-budget.ts +111 -0
  305. package/src/lib/trigger-gaps.test.ts +70 -0
  306. package/src/lib/trigger-gaps.ts +48 -6
  307. package/src/lib/tui/data.ts +1 -5
  308. package/src/lib/workflow-store.ts +150 -0
  309. package/src/lib/workspace-secrets.ts +0 -4
  310. package/src/lib/workspaces.ts +1 -1
@@ -0,0 +1,217 @@
1
+ export const meta = {
2
+ name: 'verify-council',
3
+ description: 'Token-scaled council of independent verifier lanes plus a real-screen visual lane; returns raw verdicts for the author to adjudicate.',
4
+ phases: [
5
+ { title: 'Council', detail: 'parallel verifier lanes over the diff + claims' },
6
+ ],
7
+ }
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // args (all passed by the orchestrating agent — scripts have no FS access):
11
+ // diff string capped unified diff of the change (inline)
12
+ // diffCmd string OR a scoped command the lane runs to get the diff,
13
+ // e.g. "git diff -- src/lib/picker.ts". Use this
14
+ // instead of `diff` for large diffs — same token cost,
15
+ // no giant string through args. One of diff/diffCmd.
16
+ // claims array [{ id, text, kind: 'logic'|'visual', file }]
17
+ // surface string 'code' | 'tui' | 'web' (default 'code')
18
+ // hardToReverse boolean add the skeptic lane when true
19
+ // appCmd string how the visual lane launches a TUI surface (optional)
20
+ // url string dev-server URL for a web surface (optional)
21
+ //
22
+ // The MECHANICAL gate (tests / typecheck / lint) runs in the orchestrator
23
+ // BEFORE this script — a failing gate means no council is spawned at all. This
24
+ // engine is only the agent fan-out; adjudication happens back in the orchestrator
25
+ // on the strong model, so the strong model never enters the parallel barrier.
26
+ // ---------------------------------------------------------------------------
27
+
28
+ // The harness may hand `args` to the script as a JSON STRING rather than a parsed
29
+ // object (verified: typeof args === 'string'). Parse it so a.claims / a.diff /
30
+ // a.hardToReverse resolve — otherwise every field reads undefined and the lanes
31
+ // run with no diff and no claims, which makes them roam the whole repo.
32
+ let a = args ?? {}
33
+ if (typeof a === 'string') {
34
+ try { a = JSON.parse(a) } catch { a = {} }
35
+ }
36
+ const diff = String(a.diff ?? '').slice(0, 60000)
37
+ const diffCmd = a.diffCmd ? String(a.diffCmd) : ''
38
+ const claims = Array.isArray(a.claims) ? a.claims : []
39
+ const surface = a.surface ?? 'code'
40
+ const isVisual = surface === 'tui' || surface === 'web'
41
+
42
+ // Each lane either gets the diff inline, or is told to run one scoped command to
43
+ // obtain it (kept scoped so the lane never roams the repo — the token discipline
44
+ // is the same either way).
45
+ const diffSection = diff
46
+ ? `The change under review is EXACTLY the diff below. Do not read or report on any
47
+ file outside it; discard any issue you cannot tie to a line shown here.
48
+ --- DIFF ---\n${diff}\n--- END DIFF ---`
49
+ : diffCmd
50
+ ? `The change under review is EXACTLY the output of this one command. Run it
51
+ verbatim and treat its output as the complete and only changeset:
52
+ ${diffCmd}
53
+ Hard scope: do NOT run \`git diff\` without these exact paths, do NOT open, read,
54
+ or report on any file outside this output, and discard any finding you cannot
55
+ tie to a line inside it. Reviewing the wider repo is a scope violation that wastes
56
+ the token budget.`
57
+ : '(no diff provided — audit the claims against the named files only)'
58
+
59
+ // When the caller lists claims, the lane must answer THOSE claims, not invent its
60
+ // own. Without this the lane drifts into a free-form repo review (more tokens, and
61
+ // the caller's actual claims go unverified).
62
+ const claimsDirective = claims.length
63
+ ? `Return exactly one verdict per claim id below, using these ids verbatim. Do not
64
+ add, rename, merge, or invent claim ids. If a claim cannot be judged from the
65
+ changeset, mark it NA with that reason.`
66
+ : `No claims were listed: derive the key correctness claims from the changeset itself.`
67
+
68
+ const claimsBlock = claims.length
69
+ ? claims.map((c, i) => `${c.id ?? i + 1}. [${c.kind ?? 'logic'}] ${c.text}${c.file ? ` (${c.file})` : ''}`).join('\n')
70
+ : '(no explicit claims listed — audit the diff for correctness)'
71
+
72
+ // Structured verdict every lane returns, so the orchestrator never parses prose.
73
+ const VERDICT = {
74
+ type: 'object',
75
+ additionalProperties: false,
76
+ required: ['lane', 'summary', 'claims', 'findings'],
77
+ properties: {
78
+ lane: { type: 'string' },
79
+ summary: { type: 'string', description: 'one line' },
80
+ claims: {
81
+ type: 'array',
82
+ items: {
83
+ type: 'object',
84
+ additionalProperties: false,
85
+ required: ['id', 'verdict', 'evidence'],
86
+ properties: {
87
+ id: { type: 'string' },
88
+ verdict: { type: 'string', enum: ['PASS', 'FAIL', 'PARTIAL', 'NA'] },
89
+ evidence: { type: 'string', description: 'quoted line or measured value — never a paraphrase' },
90
+ },
91
+ },
92
+ },
93
+ findings: {
94
+ type: 'array',
95
+ items: {
96
+ type: 'object',
97
+ additionalProperties: false,
98
+ required: ['severity', 'text'],
99
+ properties: {
100
+ severity: { type: 'string', enum: ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] },
101
+ text: { type: 'string' },
102
+ },
103
+ },
104
+ },
105
+ },
106
+ }
107
+
108
+ const NEUTRAL = `You are an INDEPENDENT verifier with no shared context. Do not edit anything.
109
+ Several assertions below may be false — do not assume they are correct.
110
+ For each claim return verdict PASS/FAIL/PARTIAL/NA with evidence that QUOTES the
111
+ exact line or MEASURES the value. A remembered or paraphrased line is not evidence.`
112
+
113
+ function correctnessPrompt() {
114
+ return `${NEUTRAL}
115
+
116
+ Lane: correctness. Re-derive each claim strictly from the change.
117
+ ${claimsDirective}
118
+
119
+ CLAIMS:
120
+ ${claimsBlock}
121
+
122
+ ${diffSection}`
123
+ }
124
+
125
+ function redteamPrompt() {
126
+ return `${NEUTRAL}
127
+
128
+ Lane: red-team. Review ONLY the change for blocking defects.
129
+ CRITICAL: security holes, data loss, crashes, injection, broken auth.
130
+ HIGH: real bugs, broken contracts, race conditions, wrong logic.
131
+ List each as a finding with its severity. Do not list LOW/style nits as blocking.
132
+ If there are no CRITICAL or HIGH defects, return an empty findings array and
133
+ summary "REVIEW_CLEAN". Map each claim's verdict to NA unless the change disproves it.
134
+
135
+ ${diffSection}`
136
+ }
137
+
138
+ function visualPrompt() {
139
+ const visualClaims = claims.filter((c) => c.kind === 'visual')
140
+ const vBlock = visualClaims.length
141
+ ? visualClaims.map((c, i) => `${c.id ?? i + 1}. ${c.text}`).join('\n')
142
+ : '(measure whatever the diff claims about the rendered surface)'
143
+ const driver = surface === 'web'
144
+ ? `Surface: WEB. Use the lightpanda MCP tools (search for them with ToolSearch:
145
+ goto ${a.url ?? '<dev-server-url>'} , then eval getComputedStyle() /
146
+ getBoundingClientRect() on the relevant selectors and return the MEASURED
147
+ pixel values.`
148
+ : `Surface: TUI. Use the cue-tty-watch MCP tools (search for them with ToolSearch):
149
+ launch the app in a tmux pane${a.appCmd ? ` with \`${a.appCmd}\`` : ''}, send_keys_tmux to
150
+ reach the target screen, screenshot it, then find_text / ask_about_image to
151
+ assert each claim against what is ACTUALLY on screen.`
152
+
153
+ return `${NEUTRAL}
154
+
155
+ Lane: visual proof. Drive the REAL rendered surface and report what you observe.
156
+ A code read is NOT acceptable evidence for a visual claim — only a measured or
157
+ screenshotted value counts.
158
+
159
+ ${driver}
160
+
161
+ VISUAL CLAIMS:
162
+ ${vBlock}`
163
+ }
164
+
165
+ function skepticPrompt() {
166
+ return `${NEUTRAL}
167
+
168
+ Lane: skeptic. Your job is to REFUTE the riskiest claim, not confirm it. Default
169
+ each claim to FAIL ("refuted") unless the change makes it undeniable. Be adversarial.
170
+ ${claimsDirective}
171
+
172
+ CLAIMS:
173
+ ${claimsBlock}
174
+
175
+ ${diffSection}`
176
+ }
177
+
178
+ // Adaptive lane set: 2 default, +visual when visual, +skeptic when hard to reverse.
179
+ const lanes = [
180
+ { key: 'correctness', prompt: correctnessPrompt() },
181
+ { key: 'redteam', prompt: redteamPrompt() },
182
+ ]
183
+ if (isVisual) lanes.push({ key: 'visual', prompt: visualPrompt() })
184
+ if (a.hardToReverse) lanes.push({ key: 'skeptic', prompt: skepticPrompt() })
185
+
186
+ // Surface the parsed inputs so a misdelivery (e.g. empty claims, no diff) is
187
+ // obvious in the run log instead of silently degrading into a repo-wide roam.
188
+ log(
189
+ `council: ${lanes.map((l) => l.key).join(' + ')} ` +
190
+ `(surface=${surface}, claims=${claims.length}, diff=${diff ? 'inline' : diffCmd ? 'cmd' : 'NONE'})`,
191
+ )
192
+
193
+ phase('Council')
194
+ const verdicts = await parallel(
195
+ lanes.map((l) => () =>
196
+ agent(l.prompt, { label: `lane:${l.key}`, phase: 'Council', schema: VERDICT, model: 'sonnet' })
197
+ .then((v) => ({ ...v, lane: l.key }))
198
+ ),
199
+ )
200
+
201
+ const ok = verdicts.filter(Boolean)
202
+ const blocking = ok.flatMap((v) =>
203
+ (v.findings ?? []).filter((f) => f.severity === 'CRITICAL' || f.severity === 'HIGH').map((f) => ({ lane: v.lane, ...f })),
204
+ )
205
+ const failed = ok.flatMap((v) =>
206
+ (v.claims ?? []).filter((c) => c.verdict === 'FAIL' || c.verdict === 'PARTIAL').map((c) => ({ lane: v.lane, ...c })),
207
+ )
208
+
209
+ // Raw material for the orchestrator's Phase-2 adjudication. No strong-model
210
+ // spend happened inside this script.
211
+ return {
212
+ lanes: lanes.map((l) => l.key),
213
+ verdicts: ok,
214
+ blocking,
215
+ disputedClaims: failed,
216
+ clean: blocking.length === 0 && failed.length === 0,
217
+ }
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "When user asks for deep research, multi-source synthesis, regulatory analysis, or enterprise document research, route through AI-Q server for structured reports with citations"
2
+ description: "Use when user says \"deep research this\", \"research the regulatory landscape\", \"synthesize findings from our docs\", \"produce a cited memo\", \"multi-source research\". Routes deep research, multi-source synthesis, regulatory analysis, or enterprise document research through the NVIDIA AI-Q server for structured reports with citations."
3
3
  tags: [research, nvidia, aiq, deep-research, enterprise]
4
4
  category: nvidia
5
5
  version: 2.0.0
@@ -3,7 +3,6 @@ name: cuopt-developer
3
3
  version: "26.08.00"
4
4
  description: Modify, build, test, debug, and contribute to NVIDIA cuOpt (C++/CUDA, Python, server, CI). Use for solver internals, PRs, DCO, and code conventions.
5
5
  ---
6
-
7
6
  # cuOpt Developer Skill
8
7
 
9
8
  Contribute to the NVIDIA cuOpt codebase. This skill is for modifying cuOpt itself, not for using it.
@@ -232,3 +231,19 @@ For build/test pitfalls (Cython rebuild, OOM, CUDA driver mismatch, missing `nvc
232
231
  - **Python binding architecture**: [resources/python_bindings.md](resources/python_bindings.md)
233
232
 
234
233
  _Shell-execution, install, sudo, and outside-workspace policies are covered by [Refusal Rules — Read First](#refusal-rules--read-first) at the top of this skill._
234
+
235
+ ## VRP dimension internals (routing engine)
236
+
237
+ When implementing or debugging **VRP dimensions** (constraints, objectives, forward/backward propagation, `combine`, local-search deltas), read:
238
+
239
+ - **`resources/vrp_skills.md`** — architecture contracts, required interfaces, and implementation checklist.
240
+
241
+ Read it **before** adding a new dimension or changing combine semantics.
242
+
243
+ ## Numerical issues in non-routing solver internals
244
+
245
+ When a bug surfaces as **wrong-but-plausible** solver output (invalid lower bound, unexpectedly large duals, 10× iteration blow-up after a small change) rather than a crash, read:
246
+
247
+ - **`resources/numerical_debugging.md`** — methodology for locating catastrophic-cancellation sites, the cancellation patterns endemic to cMIR / flow-cover / MIR-style cut construction, and threshold guidance for numerical guards.
248
+
249
+ Apply the *instrument-first, guard-at-the-exact-site* workflow it describes before patching — speculative fixes on these symptoms usually miss.
@@ -32,11 +32,11 @@ Never push branches directly to the main cuOpt repository. Use the fork workflow
32
32
 
33
33
  ```bash
34
34
  # 1. Clone the main repo
35
- git clone git@github.com:NVIDIA/cuopt.git
35
+ git clone https://github.com/NVIDIA/cuopt.git
36
36
  cd cuopt
37
37
 
38
38
  # 2. Add your fork as a remote
39
- git remote add fork git@github.com:<your-username>/cuopt.git
39
+ git remote add fork https://github.com/<your-username>/cuopt.git
40
40
 
41
41
  # 3. Create a branch from the appropriate base
42
42
  git checkout -b my-feature-branch
@@ -0,0 +1,128 @@
1
+ # Debugging Numerical Issues in Numerical Optimization Solver Internals
2
+
3
+ Read this when a solver bug surfaces as **wrong-but-plausible output** rather
4
+ than a crash or assertion.
5
+
6
+ ## Symptoms
7
+
8
+ - A lower bound that contradicts a known incumbent (LP claims a value the MIP
9
+ cannot reach).
10
+ - Dual values of order `1e10+` on a problem whose data is `O(1)`–`O(1e5)`.
11
+ - A 10× blow-up in simplex iterations after an algorithmic change that should
12
+ have been cheap.
13
+ - Bit-for-bit reproducibility of the wrong answer across runs — the bug is
14
+ deterministic, not a memory or race issue.
15
+
16
+ The root cause is often **catastrophic cancellation** in a
17
+ floating-point accumulator: `final = Σ(signed contributions)` collapses to a
18
+ value many orders of magnitude smaller than its constituents, leaving the
19
+ result dominated by floating-point noise.
20
+
21
+ ## Methodology — Instrument Before Patching
22
+
23
+ The classical mistake is to guess the cancellation site and apply a fix. There
24
+ are usually several candidates and you will guess wrong. Do this instead:
25
+
26
+ ### Locate the suspicious region
27
+
28
+ Usually a recent commit or a code path tied to the symptom. Read it end-to-end before adding any instrumentation.
29
+
30
+ ### Audit candidate cancellation sites by hand
31
+
32
+ Any floating-point accumulator whose result can be much smaller than its inputs is a candidate.
33
+ Write the list down before you instrument anything.
34
+
35
+ ### Instrument each site with a `cancel_ratio = |final| / max(1, Σ|delta|)`
36
+
37
+ Logged per event. A ratio of `1.0` means no cancellation; `1e-9` means ~7 decimal digits of precision lost; `1e-15` means the result is numerical noise.
38
+
39
+ ### Reproduce, log, read
40
+
41
+ Sort the log by `cancel_ratio` ascending; the worst offenders are at the top.
42
+
43
+ ### Guard at the exact site that's cancelling — not earlier, not later
44
+
45
+ A guard on an upstream accumulator does nothing if cancellation happens downstream; cut-generation paths typically have multiple sites in series.
46
+
47
+ ### Re-run and confirm
48
+
49
+ If the symptom persists, your instrumentation missed a site — return to step 2. The cancellation hypothesis is wrong only if every measured ratio is `≥ ~1e-6` and the symptom is still there.
50
+
51
+ ## Threshold Guidance
52
+
53
+ A cancellation ratio of `1e-9` leaves ~7 decimal digits of precision in a
54
+ double. Use this as the *machine-safety* floor — a guard at this level only
55
+ rejects results that are essentially noise.
56
+
57
+ A ratio of `1e-4` leaves ~12 digits, which is still numerically clean but
58
+ tight enough that downstream LP solves remain conditioned. Use this for guards
59
+ on quantities that feed back into a basis whose conditioning matters (cut
60
+ RHS, constraint accumulators, anything that becomes a row of `A` after
61
+ addition).
62
+
63
+ When in doubt, log the ratio *without* filtering first, observe the
64
+ distribution across a representative benchmark, and place the threshold at
65
+ least one order of magnitude below the cleanest "bad" case and at least one
66
+ order of magnitude above the cleanest "good" case. Single-instance threshold
67
+ choices tend to over-fit.
68
+
69
+ ## Cancellation Sites in Cut Generation
70
+
71
+ Cut-generation routines (Gomory, MIR, complemented-MIR, flow-cover) are
72
+ repeat offenders. They build a cut by combining row data with variable-bound
73
+ substitutions, each of which can introduce a large
74
+ `coefficient × bound_bias` shift. The shifts often sum to a small residual.
75
+
76
+ In a cMIR-style routine, expect **three accumulators in series**, each
77
+ capable of independent cancellation:
78
+
79
+ | # | Accumulator | Cancellation form |
80
+ |---|---|---|
81
+ | 1 | Substituted row RHS | `b − Σ (coef × variable_bound_bias)` |
82
+ | 2 | Cut-LHS constant | `Σ (multiplier × per_arc_constant)` across all arcs |
83
+ | 3 | Final cut RHS subtraction | `cut.rhs = lhs_constant − substituted_b` |
84
+
85
+ Two of the three can have well-behaved ratios individually while the third
86
+ still cancels — site (3) is especially insidious because both inputs can be
87
+ clean on their own and only their *difference* loses precision. A guard at
88
+ only one site is insufficient; instrument all three before deciding where to
89
+ clamp.
90
+
91
+ ## Scale-Mismatch Hazard
92
+
93
+ A cut that is mathematically valid by construction can still poison the LP
94
+ basis after addition. If `cut.rhs` is several orders of magnitude below the
95
+ original constraint matrix's typical row scale, the dual simplex needs to
96
+ produce dual values at the inverse scale to express dual feasibility, and
97
+ those duals propagate into the bound.
98
+
99
+ The diagnostic for this is **iteration count**, not the cut shape.
100
+ Re-optimization after cut addition should take `O(few ×)` the original root
101
+ iterations. If it suddenly takes `O(10×)`, the cuts are valid but
102
+ ill-conditioned for the LP.
103
+
104
+ Filters that help, in order of increasing aggressiveness:
105
+
106
+ - Reject cuts with high coefficient dynamism (`max|coef| / min|coef|`).
107
+ - Reject cuts with `|cut.rhs|` much smaller than the original row scale on
108
+ the source row.
109
+ - Suppress variable-bound substitutions whose bias term is itself huge —
110
+ root-cause filter, but rejects more cuts than necessary.
111
+
112
+ Pick the lowest-risk filter that removes the symptom on the failing instance.
113
+ Re-validate on the broader benchmark before declaring the fix done — a guard
114
+ that fixes one instance can quietly suppress healthy cuts on others.
115
+
116
+ ## Common Mistakes
117
+
118
+ - **Speculative fix before measurement.** "It's probably the MIR floor at
119
+ large ratios" is a guess. Instrument first; the data usually points
120
+ elsewhere.
121
+ - **Single global guard.** A guard at the first cancellation site won't catch
122
+ the rest. Cut paths typically have 2–3 distinct sites in series.
123
+ - **Confusing "small final value" with "cancellation."** A small `final`
124
+ derived from a small sum of small `delta_i` is healthy. The ratio
125
+ `|final| / Σ|delta_i|` is what distinguishes the two.
126
+ - **Picking the most aggressive (root-cause) filter when a narrow site-guard
127
+ would do.** Be surgical; the narrowest filter that recovers correctness is
128
+ the right one.
@@ -106,6 +106,8 @@ def Solve(py_data_model_obj, settings, mip=False):
106
106
  return create_solution(move(sol_ret_ptr), data_model_obj)
107
107
  ```
108
108
 
109
+ Always release the GIL around C++ calls that do GPU work — this allows other Python threads to run during solve.
110
+
109
111
  ### Step 6: C++ implementation receives the call
110
112
 
111
113
  `cpp/src/math_optimization/solver_settings.cu`:
@@ -145,15 +147,6 @@ settings.reset(new solver_settings_t[int, double]())
145
147
  # Auto-destroyed when scope exits
146
148
  ```
147
149
 
148
- ### Releasing the GIL for GPU work
149
-
150
- ```cython
151
- with nogil:
152
- result = move(call_solve(problem_ptr, settings_ptr))
153
- ```
154
-
155
- Always release the GIL around C++ calls that do GPU work. This allows other Python threads to run during solve.
156
-
157
150
  ### Bridging C++ enums to Python IntEnum
158
151
 
159
152
  ```python
@@ -0,0 +1,166 @@
1
+ # cuOpt VRP Dimension Developer Skills
2
+
3
+ ---
4
+
5
+ ## `cuopt-dimension-architecture`
6
+
7
+ **When to use**: Before implementing any new constraint or objective in cuOpt.
8
+
9
+ ### The forward/backward propagation model
10
+ Each node stores accumulated state (`fwd_X`, `bwd_X`) so that combining any two adjacent fragments is O(1). This is the core design contract that makes cuOpt fast:
11
+ - `fwd_X[k]` = contribution of the prefix `[0..k]`
12
+ - `bwd_X[k]` = contribution of the suffix `[k..n]`
13
+ - No recomputation is needed when a move splits a route at any point
14
+
15
+ ### The combine invariant
16
+ `combine(node[k], node[k+1])` must return the **same value for every split point `k`** in a route (within floating-point tolerance — small differences from order of operations are acceptable; large gaps indicate a bug). This is the fundamental correctness contract. Violating it breaks local search delta evaluation (the solver computes `cost_after - cost_before` using combine; if combine is materially inconsistent, deltas are wrong).
17
+
18
+ ### Why boundaries double-count
19
+ `fwd_excess[k]` accumulates violations from `[0..k]`. `bwd_excess[k+1]` accumulates violations from `[k+1..n]`. At the join point `k → k+1`, both sides have already "seen" the in-transit state at that boundary — so their sum overcounts the boundary contribution once. The correction term `excess(fwd_state[k])` subtracts the double-counted boundary:
20
+ ```
21
+ combine(k, k+1) = fwd_excess[k] + bwd_excess[k+1] - excess(fwd_state[k])
22
+ ```
23
+
24
+ ### Required interface for every dimension
25
+ | Method | Description |
26
+ |--------|-------------|
27
+ | `calculate_forward(next)` | Propagate fwd state from `this` to `next`; update `next.fwd_excess` |
28
+ | `calculate_backward(prev)` | Propagate bwd state from `this` to `prev`; update `prev.bwd_excess` |
29
+ | `combine(prev, next)` | O(1) total cost for joining two fragments; must satisfy the invariant |
30
+ | `get_cost(prev, this)` | Same formula as `combine`, called from `next`'s perspective |
31
+ | `compute_cost(n_nodes)` | Full-route cost; must equal `combine(last_node, return_depot)` |
32
+ | `forward_excess` | Returns `fwd_excess` as double |
33
+ | `backward_excess` | Returns `bwd_excess` as double |
34
+ | `forward_feasible` | True if `fwd_excess <= excess_limit` |
35
+ | `backward_feasible` | True if `bwd_excess <= excess_limit` |
36
+
37
+ ---
38
+
39
+ ## `cuopt-implement-dimension`
40
+
41
+ **When to use**: When given a constraint/objective description to implement as a new cuOpt dimension.
42
+
43
+ ### Step-by-step recipe
44
+
45
+ **Step 1 — Define per-node state**
46
+ Identify the minimal set of scalars needed for O(1) propagation:
47
+ - What is "in transit" at each route position? (e.g. load, type counts, time)
48
+ - What accumulated violation measure can be updated incrementally? (e.g. excess load, incompatibility excess)
49
+ - Separate: *fixed data* (set once from problem input), *forward data*, *backward data*
50
+
51
+ **Step 2 — Write `calculate_forward(next)`**
52
+ ```
53
+ propagate accumulated fwd_state from this → next
54
+ apply next node's demand to fwd_state
55
+ compute positional_excess = f(fwd_state_at_next)
56
+ next.fwd_excess = this.fwd_excess + positional_excess // depot nodes: no positional contribution
57
+ ```
58
+
59
+ **Step 3 — Write `calculate_backward(prev)`**
60
+ Mirror of forward, applied in reverse direction. Backward demand direction is opposite to forward (e.g. a pickup that adds +1 forward subtracts -1 backward).
61
+
62
+ **Step 4 — Derive `combine(prev, next)`**
63
+
64
+ `combine` is the **core cost computation for every local search move**: operators evaluate candidate edits by differencing combined fragment costs (`cost_after - cost_before`). It is called extremely often, so **keep it as fast as possible**.
65
+
66
+ - **Typical dimensions** (capacity, distance, simple time windows, etc.): `combine` is **O(1)** — only prefix/suffix scalars and a boundary correction. This is what all current VRP operators assume.
67
+ - **Richer dimensions** can be **much more expensive** — e.g. **O(log n)** in route size `n` when the join cost needs a non-trivial lookup (time-dependent travel times, multiple time windows, profile queries). Prefer precomputed tables or cached state so `combine` stays hot-path friendly; if it must be superlinear, document it and expect fewer applicable operators or higher move-evaluation cost.
68
+
69
+ Write out the invariant formula and verify it equals the total route cost for a complete route:
70
+ ```
71
+ total = prev.fwd_excess + next.bwd_excess - boundary_correction(prev.fwd_state)
72
+ ```
73
+ where `boundary_correction` removes the double-counted overlap at the join point.
74
+
75
+ **Step 5 — Derive `get_cost(prev, this)` from combine**
76
+
77
+ `get_cost` is on the **same hot path as `combine`**: local search operators call it constantly when scoring edges and fragments. It must stay **as fast as `combine`** — same **O(1)** target for typical dimensions, same risk of **O(log n)** or worse for time-dependent travel, multiple time windows, etc. **Do not** put a separate heavy computation here.
78
+
79
+ `get_cost` is called on the `next` node with `prev` passed in. It must be identical to `combine` — substitute `this` for `next`:
80
+ ```
81
+ get_cost(prev, this) == combine(prev, this)
82
+ ```
83
+ Implement by **delegating to `combine`** (or inlining the same formula). Do **not** derive an independent formula; any deviation breaks coherence assertions and can hide a slower code path.
84
+
85
+ **Step 6 — Write `compute_cost(n_nodes)`**
86
+ Must equal `combine(last_service_node, fresh_return_depot)` within the same floating-point tolerance:
87
+ ```
88
+ compute_cost = fwd_excess[n_nodes] - boundary_correction(fwd_state[n_nodes])
89
+ ```
90
+ (For a balanced route, `bwd_excess` at the return depot is 0 and `bwd_state` is 0, so the depot term drops out.)
91
+
92
+ **Step 7 — Create the node class**
93
+ File: `cpp/src/routing/node/your_node.cuh`
94
+ - Fixed data fields (problem input)
95
+ - `fwd_state[]`, `fwd_excess`, `bwd_state[]`, `bwd_excess`
96
+ - All 9 interface methods listed in `cuopt-dimension-architecture`
97
+
98
+ **Step 8 — Create the route class**
99
+ File: `cpp/src/routing/route/your_route.cuh`
100
+ - Host-side: `rmm::device_uvector` for each array (fixed, fwd, bwd)
101
+ - Device-side `view_t`: `raft::device_span` members, `get_node`, `set_node`, `set_forward_data`, `set_backward_data`, `copy_forward_data`, `copy_backward_data`, `copy_fixed_route_data`, `compute_cost`, `create_shared_route`, `get_shared_size`
102
+ - Stride layout: all arrays use `stride = n_nodes_route + 1`; multi-type arrays are row-major `[n_types * stride]`
103
+
104
+ ---
105
+
106
+ ## `cuopt-dimension-wiring-checklist`
107
+
108
+ **When to use**: After writing node/route logic, to ensure the dimension is fully integrated into the framework.
109
+
110
+ ### Files to create
111
+ - [ ] `cpp/src/routing/node/your_node.cuh`
112
+ - [ ] `cpp/src/routing/route/your_route.cuh`
113
+
114
+ ### Files to modify
115
+
116
+ **`cpp/src/routing/routing_helpers.cuh`** (or `dimensions_info`)
117
+ - [ ] Add new `dim_t` enum value
118
+ - [ ] `enabled_dimensions_t::has_dimension` covers it
119
+ - [ ] `enabled_dimensions_t::get_dimension<dim>` covers it
120
+ - [ ] `loop_over_dimensions` range covers it (check `Start`/`End` bounds)
121
+
122
+ **`cpp/src/routing/route/dimensions_route.cuh`**
123
+ - [ ] Add to `route_from_dim<I>` type alias chain
124
+ - [ ] Add member `your_route_t<i_t, f_t> your_dim` to `dimensions_route_t`
125
+ - [ ] Initialize in constructor: `your_dim(sol_handle_, dimensions_info_.get_dimension<dim_t::YOUR_DIM>())`
126
+ - [ ] Copy constructor copies `your_dim`
127
+ - [ ] `view_t` has `typename your_route_t<i_t, f_t>::view_t your_dim` member
128
+ - [ ] `view()` calls `get_dimension_of<I>(v) = get_dimension_of<I>(*this).view()` via loop — automatic if wired into enum
129
+
130
+ **`cpp/src/routing/node/node.cuh`**
131
+ - [ ] `get_dimension<dim_t::YOUR_DIM>()` returns `your_dim` member — add to the accessor chain
132
+
133
+ **`cpp/src/routing/problem/problem.cuh`**
134
+ - [ ] Add storage for input data (e.g. `std::vector<int> order_incompatible_types`)
135
+ - [ ] Add setter method
136
+
137
+ **`cpp/src/routing/problem/problem.cu`**
138
+ - [ ] `populate_dimensions_info()`: enable dimension when input data is non-empty
139
+
140
+ **`cpp/src/routing/util_kernels/set_nodes_data.cuh`**
141
+ - [ ] Depot boundary initialization in `set_route_data`: set `fwd_state[0] = 0`, `fwd_excess[0] = 0`, `bwd_state[n_nodes] = 0`, `bwd_excess[n_nodes] = 0`
142
+
143
+ **`cpp/src/routing/fleet_info.hpp`** (if dimension has vehicle-level parameters)
144
+ - [ ] Add vehicle-level constraint data
145
+
146
+ **Python/C API**
147
+ - [ ] Expose setter in C API header
148
+ - [ ] Python binding in the routing data class
149
+
150
+ ---
151
+
152
+ ## `cuopt-dimension-testing`
153
+
154
+ **When to use**: After implementing a new dimension, to write tests that validate correctness end-to-end.
155
+
156
+ ### C++ unit tests (`cpp/tests/routing/`)
157
+ - Add a simple unit test with less than 10 nodes/orders
158
+
159
+ ### Python integration tests (`python/cuopt/cuopt/tests/routing/`)
160
+ - Add a similar test in python to test the Python APIs and end-to-end testing
161
+
162
+ ### What every test should verify
163
+ - `is_feasible()` for the final solution when feasibility is expected
164
+ - Infeasibility cost for the new dimension is 0 in a feasible solution
165
+ - Optimal objective value is obtained for curated tests
166
+ - Edge cases: empty route, single-node route, all nodes same type/value
@@ -3,7 +3,6 @@ name: cuopt-install
3
3
  version: "26.08.00"
4
4
  description: Install cuOpt for Python, C, or as a server (pip, conda, Docker) — system requirements, install commands, and verification. Use when the user wants to install or verify cuOpt for any user-facing interface. For building cuOpt from source or contributing to cuOpt, see cuopt-developer.
5
5
  ---
6
-
7
6
  # cuOpt Install (user)
8
7
 
9
8
  Install cuOpt to *use* it from Python, C, or as a REST server. For building cuOpt from source to contribute or modify it, see `cuopt-developer`.
@@ -77,15 +76,8 @@ conda install -c rapidsai -c conda-forge -c nvidia libcuopt
77
76
 
78
77
  ### Verify
79
78
 
80
- ```bash
81
- # conda:
82
- find $CONDA_PREFIX -name "cuopt_c.h"
83
- find $CONDA_PREFIX -name "libcuopt.so"
84
-
85
- # pip (venv):
86
- find "$(python -c 'import sys; print(sys.prefix)')" -name "cuopt_c.h"
87
- find "$(python -c 'import sys; print(sys.prefix)')" -name "libcuopt.so"
88
- ```
79
+ See [`resources/verification_examples.md`](resources/verification_examples.md)
80
+ for the canonical C-API header/library `find` commands (conda and pip/venv variants).
89
81
 
90
82
  ## Server (REST)
91
83
 
@@ -4,7 +4,6 @@ version: "26.08.00"
4
4
  description: LP, MILP, and QP (beta) with cuOpt — C API only. Use when the user is embedding LP, MILP, or QP in C/C++.
5
5
  ---
6
6
 
7
-
8
7
  # cuOpt Numerical Optimization — C API
9
8
 
10
9
  Solve LP, MILP, and QP problems via the cuOpt C API. The same library, headers, build pattern, and core calls (`cuOptCreate*Problem`, `cuOptSolve`, `cuOptGetObjectiveValue`) apply across all three; QP extends the API with quadratic-objective creation calls.
@@ -13,28 +12,9 @@ Confirm problem type and formulation (variables, objective, constraints, variabl
13
12
 
14
13
  This skill is **C only**.
15
14
 
16
- ## Quick Reference: C API
17
-
18
- ```c
19
- #include <cuopt/linear_programming/cuopt_c.h>
20
-
21
- // CSR format for constraints
22
- cuopt_int_t row_offsets[] = {0, 2, 4};
23
- cuopt_int_t col_indices[] = {0, 1, 0, 1};
24
- cuopt_float_t values[] = {2.0, 3.0, 4.0, 2.0};
25
- char var_types[] = {CUOPT_CONTINUOUS, CUOPT_INTEGER};
26
-
27
- cuOptCreateRangedProblem(
28
- num_constraints, num_variables, CUOPT_MINIMIZE,
29
- 0.0, objective_coefficients,
30
- row_offsets, col_indices, values,
31
- constraint_lower, constraint_upper,
32
- var_lower, var_upper, var_types,
33
- &problem
34
- );
35
- cuOptSolve(problem, settings, &solution);
36
- cuOptGetObjectiveValue(solution, &obj_value);
37
- ```
15
+ ## API Call Sequence
16
+
17
+ For LP/MILP, the ordered C entry points are: `cuOptCreateRangedProblem` (sense `CUOPT_MINIMIZE` / `CUOPT_MAXIMIZE`, CSR constraint matrix as `row_offsets` / `col_indices` / `values`, `var_types` char array using `CUOPT_CONTINUOUS` / `CUOPT_INTEGER` macros) → `cuOptSolve(problem, settings, &solution)` → `cuOptGetObjectiveValue(solution, &obj_value)` → matching `cuOptDestroy*` calls. Include `<cuopt/linear_programming/cuopt_c.h>`. Full ordered code with build instructions in [resources/examples.md](resources/examples.md).
38
18
 
39
19
  ## QP via C API (beta)
40
20