@balpal4495/quorum 3.0.3 → 3.1.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 (243) hide show
  1. package/bin/commands/compass.js +4 -4
  2. package/bin/shared/llm.js +2 -2
  3. package/dist/advisor/ask.d.ts +13 -0
  4. package/dist/advisor/ask.d.ts.map +1 -0
  5. package/dist/advisor/ask.js +67 -0
  6. package/dist/advisor/ask.js.map +1 -0
  7. package/dist/advisor/index.d.ts +3 -0
  8. package/dist/advisor/index.d.ts.map +1 -0
  9. package/dist/advisor/index.js +2 -0
  10. package/dist/advisor/index.js.map +1 -0
  11. package/dist/advisor/prompt.d.ts +5 -0
  12. package/dist/advisor/prompt.d.ts.map +1 -0
  13. package/{modules/advisor/prompt.ts → dist/advisor/prompt.js} +22 -26
  14. package/dist/advisor/prompt.js.map +1 -0
  15. package/dist/advisor/types.d.ts +23 -0
  16. package/dist/advisor/types.d.ts.map +1 -0
  17. package/dist/advisor/types.js +2 -0
  18. package/dist/advisor/types.js.map +1 -0
  19. package/dist/compass/behavior.d.ts +4 -0
  20. package/dist/compass/behavior.d.ts.map +1 -0
  21. package/dist/compass/behavior.js +138 -0
  22. package/dist/compass/behavior.js.map +1 -0
  23. package/dist/compass/create.d.ts +3 -0
  24. package/dist/compass/create.d.ts.map +1 -0
  25. package/dist/compass/create.js +289 -0
  26. package/dist/compass/create.js.map +1 -0
  27. package/dist/compass/evidence/collect.d.ts +11 -0
  28. package/dist/compass/evidence/collect.d.ts.map +1 -0
  29. package/dist/compass/evidence/collect.js +86 -0
  30. package/dist/compass/evidence/collect.js.map +1 -0
  31. package/dist/compass/index.d.ts +8 -0
  32. package/dist/compass/index.d.ts.map +1 -0
  33. package/dist/compass/index.js +8 -0
  34. package/dist/compass/index.js.map +1 -0
  35. package/dist/compass/prompts/index.d.ts +28 -0
  36. package/dist/compass/prompts/index.d.ts.map +1 -0
  37. package/{modules/compass/prompts/index.ts → dist/compass/prompts/index.js} +13 -38
  38. package/dist/compass/prompts/index.js.map +1 -0
  39. package/dist/compass/prompts/system.d.ts +2 -0
  40. package/dist/compass/prompts/system.d.ts.map +1 -0
  41. package/{modules/compass/prompts/system.ts → dist/compass/prompts/system.js} +2 -1
  42. package/dist/compass/prompts/system.js.map +1 -0
  43. package/dist/compass/propose.d.ts +15 -0
  44. package/dist/compass/propose.d.ts.map +1 -0
  45. package/dist/compass/propose.js +128 -0
  46. package/dist/compass/propose.js.map +1 -0
  47. package/dist/compass/schemas.d.ts +1271 -0
  48. package/dist/compass/schemas.d.ts.map +1 -0
  49. package/dist/compass/schemas.js +113 -0
  50. package/dist/compass/schemas.js.map +1 -0
  51. package/dist/compass/score.d.ts +25 -0
  52. package/dist/compass/score.d.ts.map +1 -0
  53. package/dist/compass/score.js +89 -0
  54. package/dist/compass/score.js.map +1 -0
  55. package/dist/compass/sources/index.d.ts +9 -0
  56. package/dist/compass/sources/index.d.ts.map +1 -0
  57. package/dist/compass/sources/index.js +408 -0
  58. package/dist/compass/sources/index.js.map +1 -0
  59. package/dist/compass/types.d.ts +334 -0
  60. package/dist/compass/types.d.ts.map +1 -0
  61. package/dist/compass/types.js +2 -0
  62. package/dist/compass/types.js.map +1 -0
  63. package/dist/council/advisors.d.ts +15 -0
  64. package/dist/council/advisors.d.ts.map +1 -0
  65. package/dist/council/advisors.js +46 -0
  66. package/dist/council/advisors.js.map +1 -0
  67. package/dist/council/chairman.d.ts +13 -0
  68. package/dist/council/chairman.d.ts.map +1 -0
  69. package/dist/council/chairman.js +145 -0
  70. package/dist/council/chairman.js.map +1 -0
  71. package/dist/council/deliberate.d.ts +22 -0
  72. package/dist/council/deliberate.d.ts.map +1 -0
  73. package/dist/council/deliberate.js +99 -0
  74. package/dist/council/deliberate.js.map +1 -0
  75. package/dist/council/frame.d.ts +8 -0
  76. package/dist/council/frame.d.ts.map +1 -0
  77. package/dist/council/frame.js +40 -0
  78. package/dist/council/frame.js.map +1 -0
  79. package/dist/council/index.d.ts +6 -0
  80. package/dist/council/index.d.ts.map +1 -0
  81. package/dist/council/index.js +4 -0
  82. package/dist/council/index.js.map +1 -0
  83. package/dist/council/personas.d.ts +18 -0
  84. package/dist/council/personas.d.ts.map +1 -0
  85. package/dist/council/personas.js +44 -0
  86. package/dist/council/personas.js.map +1 -0
  87. package/dist/council/reviewers.d.ts +13 -0
  88. package/dist/council/reviewers.d.ts.map +1 -0
  89. package/dist/council/reviewers.js +59 -0
  90. package/dist/council/reviewers.js.map +1 -0
  91. package/dist/council/risk.d.ts +16 -0
  92. package/dist/council/risk.d.ts.map +1 -0
  93. package/dist/council/risk.js +74 -0
  94. package/dist/council/risk.js.map +1 -0
  95. package/dist/council/types.d.ts +95 -0
  96. package/dist/council/types.d.ts.map +1 -0
  97. package/dist/council/types.js +2 -0
  98. package/dist/council/types.js.map +1 -0
  99. package/dist/jury/evaluate.d.ts +13 -0
  100. package/dist/jury/evaluate.d.ts.map +1 -0
  101. package/{modules/jury/evaluate.ts → dist/jury/evaluate.js} +60 -84
  102. package/dist/jury/evaluate.js.map +1 -0
  103. package/dist/jury/index.d.ts +6 -0
  104. package/dist/jury/index.d.ts.map +1 -0
  105. package/dist/jury/index.js +4 -0
  106. package/dist/jury/index.js.map +1 -0
  107. package/dist/jury/preflight.d.ts +26 -0
  108. package/dist/jury/preflight.d.ts.map +1 -0
  109. package/dist/jury/preflight.js +71 -0
  110. package/dist/jury/preflight.js.map +1 -0
  111. package/dist/jury/schema.d.ts +57 -0
  112. package/dist/jury/schema.d.ts.map +1 -0
  113. package/dist/jury/schema.js +21 -0
  114. package/dist/jury/schema.js.map +1 -0
  115. package/dist/jury/types.d.ts +47 -0
  116. package/dist/jury/types.d.ts.map +1 -0
  117. package/dist/jury/types.js +2 -0
  118. package/dist/jury/types.js.map +1 -0
  119. package/dist/oracle/adapters/lance-db.d.ts +15 -0
  120. package/dist/oracle/adapters/lance-db.d.ts.map +1 -0
  121. package/dist/oracle/adapters/lance-db.js +68 -0
  122. package/dist/oracle/adapters/lance-db.js.map +1 -0
  123. package/dist/oracle/adapters/xenova-embedder.d.ts +21 -0
  124. package/dist/oracle/adapters/xenova-embedder.d.ts.map +1 -0
  125. package/dist/oracle/adapters/xenova-embedder.js +36 -0
  126. package/dist/oracle/adapters/xenova-embedder.js.map +1 -0
  127. package/dist/oracle/bm25.d.ts +20 -0
  128. package/dist/oracle/bm25.d.ts.map +1 -0
  129. package/dist/oracle/bm25.js +82 -0
  130. package/dist/oracle/bm25.js.map +1 -0
  131. package/dist/oracle/index.d.ts +21 -0
  132. package/dist/oracle/index.d.ts.map +1 -0
  133. package/dist/oracle/index.js +25 -0
  134. package/dist/oracle/index.js.map +1 -0
  135. package/dist/oracle/log.d.ts +6 -0
  136. package/dist/oracle/log.d.ts.map +1 -0
  137. package/dist/oracle/log.js +12 -0
  138. package/dist/oracle/log.js.map +1 -0
  139. package/dist/oracle/propose.d.ts +25 -0
  140. package/dist/oracle/propose.d.ts.map +1 -0
  141. package/dist/oracle/propose.js +133 -0
  142. package/dist/oracle/propose.js.map +1 -0
  143. package/dist/oracle/query.d.ts +17 -0
  144. package/dist/oracle/query.d.ts.map +1 -0
  145. package/dist/oracle/query.js +106 -0
  146. package/dist/oracle/query.js.map +1 -0
  147. package/dist/oracle/summary.d.ts +11 -0
  148. package/dist/oracle/summary.d.ts.map +1 -0
  149. package/dist/oracle/summary.js +102 -0
  150. package/dist/oracle/summary.js.map +1 -0
  151. package/dist/oracle/types.d.ts +31 -0
  152. package/dist/oracle/types.d.ts.map +1 -0
  153. package/dist/oracle/types.js +2 -0
  154. package/dist/oracle/types.js.map +1 -0
  155. package/dist/sentinel/assert.d.ts +28 -0
  156. package/dist/sentinel/assert.d.ts.map +1 -0
  157. package/dist/sentinel/assert.js +63 -0
  158. package/dist/sentinel/assert.js.map +1 -0
  159. package/dist/sentinel/coverage.d.ts +14 -0
  160. package/dist/sentinel/coverage.d.ts.map +1 -0
  161. package/dist/sentinel/coverage.js +96 -0
  162. package/dist/sentinel/coverage.js.map +1 -0
  163. package/dist/sentinel/drift.d.ts +12 -0
  164. package/dist/sentinel/drift.d.ts.map +1 -0
  165. package/dist/sentinel/drift.js +149 -0
  166. package/dist/sentinel/drift.js.map +1 -0
  167. package/dist/sentinel/index.d.ts +7 -0
  168. package/dist/sentinel/index.d.ts.map +1 -0
  169. package/dist/sentinel/index.js +5 -0
  170. package/dist/sentinel/index.js.map +1 -0
  171. package/dist/sentinel/review.d.ts +15 -0
  172. package/dist/sentinel/review.d.ts.map +1 -0
  173. package/dist/sentinel/review.js +177 -0
  174. package/dist/sentinel/review.js.map +1 -0
  175. package/dist/setup.d.ts +103 -0
  176. package/dist/setup.d.ts.map +1 -0
  177. package/dist/setup.js +87 -0
  178. package/dist/setup.js.map +1 -0
  179. package/dist/shared/types.d.ts +173 -0
  180. package/dist/shared/types.d.ts.map +1 -0
  181. package/dist/shared/types.js +16 -0
  182. package/dist/shared/types.js.map +1 -0
  183. package/package.json +13 -8
  184. package/.github/copilot-instructions.md +0 -117
  185. package/CLAUDE.md +0 -146
  186. package/GEMINI.md +0 -73
  187. package/SETUP.md +0 -264
  188. package/evals/__tests__/eval.test.ts +0 -31
  189. package/evals/cases/auth_hs256_rejected.json +0 -46
  190. package/evals/cases/auth_rs256_valid.json +0 -30
  191. package/evals/cases/cache_missing_lock.json +0 -31
  192. package/evals/cases/db_naive_not_null.json +0 -32
  193. package/evals/cases/logging_pii_leak.json +0 -32
  194. package/evals/cases/migration_with_rollback.json +0 -43
  195. package/evals/cases/no_evidence_novel_design.json +0 -16
  196. package/evals/cases/payment_no_idempotency.json +0 -33
  197. package/evals/cases/redis_session_rejected.json +0 -32
  198. package/evals/cases/safe_refactor.json +0 -17
  199. package/evals/runner.ts +0 -226
  200. package/modules/AGENTS.md +0 -78
  201. package/modules/CLAUDE.md +0 -93
  202. package/modules/README.md +0 -504
  203. package/modules/advisor/ask.ts +0 -87
  204. package/modules/advisor/index.ts +0 -2
  205. package/modules/advisor/types.ts +0 -26
  206. package/modules/compass/behavior.ts +0 -161
  207. package/modules/compass/create.ts +0 -365
  208. package/modules/compass/evidence/collect.ts +0 -109
  209. package/modules/compass/index.ts +0 -7
  210. package/modules/compass/propose.ts +0 -152
  211. package/modules/compass/schemas.ts +0 -121
  212. package/modules/compass/score.ts +0 -77
  213. package/modules/compass/sources/index.ts +0 -413
  214. package/modules/compass/types.ts +0 -431
  215. package/modules/council/advisors.ts +0 -71
  216. package/modules/council/chairman.ts +0 -183
  217. package/modules/council/deliberate.ts +0 -141
  218. package/modules/council/frame.ts +0 -54
  219. package/modules/council/index.ts +0 -9
  220. package/modules/council/personas.ts +0 -57
  221. package/modules/council/reviewers.ts +0 -82
  222. package/modules/council/risk.ts +0 -89
  223. package/modules/council/types.ts +0 -107
  224. package/modules/jury/index.ts +0 -5
  225. package/modules/jury/preflight.ts +0 -101
  226. package/modules/jury/schema.ts +0 -24
  227. package/modules/jury/types.ts +0 -50
  228. package/modules/oracle/adapters/lance-db.ts +0 -81
  229. package/modules/oracle/adapters/xenova-embedder.ts +0 -43
  230. package/modules/oracle/bm25.ts +0 -92
  231. package/modules/oracle/index.ts +0 -36
  232. package/modules/oracle/log.ts +0 -15
  233. package/modules/oracle/propose.ts +0 -164
  234. package/modules/oracle/query.ts +0 -146
  235. package/modules/oracle/summary.ts +0 -116
  236. package/modules/oracle/types.ts +0 -32
  237. package/modules/sentinel/assert.ts +0 -95
  238. package/modules/sentinel/coverage.ts +0 -106
  239. package/modules/sentinel/drift.ts +0 -163
  240. package/modules/sentinel/index.ts +0 -6
  241. package/modules/sentinel/review.ts +0 -208
  242. package/modules/setup.ts +0 -202
  243. package/modules/shared/types.ts +0 -193
@@ -1,152 +0,0 @@
1
- import type { OracleClient } from "../shared/types"
2
- import type {
3
- CompassProposalInput, CompassProposalResult,
4
- CompassOutcomeInput, CompassOutcomeResultPayload,
5
- ProductPathway, ProductBet, ProductPathwayPhase,
6
- } from "./types"
7
-
8
- /**
9
- * Stage a Compass-generated artifact as a Chronicle proposal.
10
- *
11
- * Writes to .chronicle/proposals/ ONLY via oracle.propose().
12
- * Never calls oracle.commit(). Human must approve.
13
- */
14
- export async function stageProposal(
15
- input: CompassProposalInput,
16
- oracle: OracleClient,
17
- ): Promise<CompassProposalResult> {
18
- const payload = input.payload as ProductPathway | ProductBet
19
-
20
- const decision = buildDecision(input)
21
- const key_insight = decision.slice(0, 200)
22
-
23
- const entry = {
24
- key_insight,
25
- decision,
26
- schema_version: 2 as const,
27
- topic: buildTopic(input),
28
- scope: buildScope(input),
29
- affected_areas: buildAffectedAreas(input),
30
- status: "open" as const,
31
- confidence: "confidence" in payload ? payload.confidence : 0.7,
32
- source_module: "compass",
33
- evidence_cited: [],
34
- alternatives_considered: "assumptions" in payload ? [] : [],
35
- rejected_reason: [],
36
- validation_plan: buildValidationPlan(input),
37
- review_after: reviewAfterDate(),
38
- }
39
-
40
- const result = await oracle.propose(entry)
41
-
42
- return {
43
- proposal_id: result.proposalId,
44
- message: `Staged Chronicle proposal ${result.proposalId.slice(0, 8)} — run 'quorum commit --list' to review.`,
45
- }
46
- }
47
-
48
- /**
49
- * Stage an outcome update for a prior product bet or pathway.
50
- * Creates a new proposal that supersedes the original entry.
51
- */
52
- export async function stageOutcome(
53
- input: CompassOutcomeInput,
54
- oracle: OracleClient,
55
- ): Promise<CompassOutcomeResultPayload> {
56
- const resultLabel: Record<string, string> = {
57
- "validated": "has been validated",
58
- "partially-validated": "has been partially validated",
59
- "invalidated": "has been invalidated",
60
- "unclear": "outcome is unclear — insufficient signal",
61
- "superseded": "has been superseded by a newer approach",
62
- }
63
-
64
- const label = resultLabel[input.result] ?? input.result
65
- const decision = `Product bet/pathway ${input.entry_id.slice(0, 8)} ${label}.${input.note ? " " + input.note : ""}`
66
-
67
- const entry = {
68
- key_insight: decision.slice(0, 200),
69
- decision,
70
- schema_version: 2 as const,
71
- topic: `product/outcome/${input.entry_id.slice(0, 8)}`,
72
- scope: ["product", "compass", "outcome"],
73
- affected_areas: [],
74
- status: "validated" as const,
75
- confidence: input.result === "validated" ? 0.9
76
- : input.result === "partially-validated" ? 0.7
77
- : input.result === "invalidated" ? 0.6
78
- : 0.5,
79
- source_module: "compass",
80
- evidence_cited: [input.entry_id],
81
- alternatives_considered: [],
82
- rejected_reason: [],
83
- validation_plan: [],
84
- post_merge_result: (input.result === "validated" ? "successful"
85
- : input.result === "invalidated" ? "rolled-back"
86
- : input.result === "partially-validated" ? "partial"
87
- : undefined) as "successful" | "bug" | "partial" | "rolled-back" | undefined,
88
- }
89
-
90
- const result = await oracle.propose(entry)
91
- return {
92
- proposal_id: result.proposalId,
93
- message: `Staged outcome proposal ${result.proposalId.slice(0, 8)} — run 'quorum commit --list' to review.`,
94
- }
95
- }
96
-
97
- // ── Helpers ───────────────────────────────────────────────────────────────────
98
-
99
- function buildDecision(input: CompassProposalInput): string {
100
- const p = input.payload as ProductPathway | ProductBet
101
- if (input.artifact_kind === "product_pathway" && "smallest_useful_version" in p) {
102
- return `Compass identified '${(p as ProductPathway).title}' as a product pathway: ${(p as ProductPathway).smallest_useful_version}`
103
- }
104
- if (input.artifact_kind === "product_bet" && "thesis" in p) {
105
- return `Product bet: ${(p as ProductBet).thesis}`
106
- }
107
- if ("title" in p) {
108
- return `Compass ${input.artifact_kind.replace("_", " ")}: ${(p as { title: string }).title}`
109
- }
110
- return `Compass generated ${input.artifact_kind} artifact.`
111
- }
112
-
113
- function buildTopic(input: CompassProposalInput): string {
114
- const p = input.payload
115
- if ("title" in p) return `product/${input.artifact_kind.replace("product_", "")}/${slugify((p as { title: string }).title)}`
116
- return `product/${input.artifact_kind}`
117
- }
118
-
119
- function buildScope(input: CompassProposalInput): string[] {
120
- const base = ["product", "compass", input.artifact_kind.replace("product_", "")]
121
- const p = input.payload
122
- if ("goal" in p && (p as ProductPathway).goal) base.push(slugify((p as ProductPathway).goal).slice(0, 20))
123
- return base
124
- }
125
-
126
- function buildAffectedAreas(input: CompassProposalInput): string[] {
127
- const p = input.payload
128
- if ("phases" in p) {
129
- return (p as ProductPathway).phases
130
- .flatMap((ph: ProductPathwayPhase) => ph.dependencies)
131
- .filter(Boolean)
132
- .slice(0, 5)
133
- }
134
- return []
135
- }
136
-
137
- function buildValidationPlan(input: CompassProposalInput): string[] {
138
- const p = input.payload
139
- if ("validation_signals" in p) return (p as ProductBet).validation_signals.slice(0, 3)
140
- if ("suggested_next_step" in p) return [(p as ProductPathway).suggested_next_step]
141
- return []
142
- }
143
-
144
- function reviewAfterDate(): string {
145
- const d = new Date()
146
- d.setDate(d.getDate() + 45)
147
- return d.toISOString().slice(0, 10)
148
- }
149
-
150
- function slugify(s: string): string {
151
- return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 40)
152
- }
@@ -1,121 +0,0 @@
1
- import { z } from "zod"
2
-
3
- export const CompassEvidenceRefSchema = z.object({
4
- id: z.string(),
5
- kind: z.enum([
6
- "chronicle", "advisor", "sentinel", "code", "docs", "tests",
7
- "config", "cli", "package", "issue", "analytics", "support",
8
- "inference", "assumption", "unknown",
9
- ]),
10
- source: z.string(),
11
- path: z.string().optional(),
12
- line: z.number().optional(),
13
- entry_id: z.string().optional(),
14
- summary: z.string().min(1),
15
- quote: z.string().optional(),
16
- confidence: z.number().min(0).max(1),
17
- })
18
-
19
- export const ProductScoreBreakdownSchema = z.object({
20
- strategic_fit: z.number().min(0).max(1),
21
- user_problem_clarity: z.number().min(0).max(1),
22
- evidence_strength: z.number().min(0).max(1),
23
- leverage: z.number().min(0).max(1),
24
- feasibility: z.number().min(0).max(1),
25
- time_to_signal: z.number().min(0).max(1),
26
- reversibility: z.number().min(0).max(1),
27
- complexity_penalty: z.number().min(0).max(1),
28
- dependency_penalty: z.number().min(0).max(1),
29
- contradiction_penalty: z.number().min(0).max(1),
30
- evidence_gap_penalty: z.number().min(0).max(1),
31
- total: z.number().min(0).max(100),
32
- })
33
-
34
- export const ProductPathwayPhaseSchema = z.object({
35
- name: z.string().min(1),
36
- outcome: z.string().min(1),
37
- user_value: z.string().min(1),
38
- build_notes: z.array(z.string()).optional(),
39
- dependencies: z.array(z.string()),
40
- risks: z.array(z.string()),
41
- })
42
-
43
- export const ProductPathwaySchema = z.object({
44
- id: z.string(),
45
- kind: z.literal("product_pathway"),
46
- title: z.string().min(1),
47
- goal: z.string().min(1),
48
- target_user: z.string().optional(),
49
- problem: z.string().optional(),
50
- current_behaviors: z.array(z.string()).min(1),
51
- opportunity: z.string().min(1),
52
- why_now: z.string().min(1),
53
- smallest_useful_version: z.string().min(1),
54
- phases: z.array(ProductPathwayPhaseSchema),
55
- dependencies: z.array(z.string()),
56
- risks: z.array(z.string()),
57
- assumptions: z.array(z.string()).min(1),
58
- open_questions: z.array(z.string()),
59
- evidence: z.array(CompassEvidenceRefSchema).min(1),
60
- scores: ProductScoreBreakdownSchema,
61
- confidence: z.number().min(0).max(1),
62
- time_to_signal: z.string().min(1),
63
- reversibility: z.enum(["high", "medium", "low"]),
64
- suggested_next_step: z.string().min(1),
65
- })
66
-
67
- export const ProductBetSchema = z.object({
68
- id: z.string(),
69
- kind: z.literal("product_bet"),
70
- title: z.string().min(1),
71
- thesis: z.string().min(1),
72
- why_now: z.string().min(1),
73
- target_user: z.string().optional(),
74
- upside: z.string().min(1),
75
- downside: z.string().min(1),
76
- assumptions: z.array(z.string()).min(1),
77
- validation_signals: z.array(z.string()).min(1),
78
- invalidation_signals: z.array(z.string()).min(1),
79
- kill_criteria: z.array(z.string()).min(1),
80
- first_experiment: z.string().min(1),
81
- build_path: z.array(z.string()),
82
- evidence: z.array(CompassEvidenceRefSchema).min(1),
83
- scores: ProductScoreBreakdownSchema,
84
- confidence: z.number().min(0).max(1),
85
- time_to_signal: z.string().min(1),
86
- reversibility: z.enum(["high", "medium", "low"]),
87
- appetite: z.enum(["small", "medium", "large"]),
88
- })
89
-
90
- export const ProductIdeaScoreSchema = z.object({
91
- idea: z.string().min(1),
92
- summary: z.string().min(1),
93
- recommendation: z.enum(["pursue", "pursue-small-test", "investigate-more", "defer", "avoid"]),
94
- scores: ProductScoreBreakdownSchema,
95
- evidence: z.array(CompassEvidenceRefSchema),
96
- supporting_reasons: z.array(z.string()),
97
- risks: z.array(z.string()),
98
- assumptions: z.array(z.string()),
99
- open_questions: z.array(z.string()),
100
- suggested_next_step: z.string().min(1),
101
- })
102
-
103
- export const CompassBriefLLMSchema = z.object({
104
- product_direction: z.string().min(1),
105
- known_from_chronicle: z.array(z.string()),
106
- known_from_behavior: z.array(z.string()),
107
- inferred: z.array(z.string()),
108
- assumptions: z.array(z.string()),
109
- unknowns: z.array(z.string()),
110
- missing_evidence: z.array(z.string()),
111
- recommended_next_step: z.string().min(1),
112
- confidence: z.number().min(0).max(1),
113
- })
114
-
115
- export const PathwaysLLMSchema = z.object({
116
- pathways: z.array(ProductPathwaySchema),
117
- })
118
-
119
- export const BetsLLMSchema = z.object({
120
- bets: z.array(ProductBetSchema),
121
- })
@@ -1,77 +0,0 @@
1
- import type { ProductScoreBreakdown } from "./types"
2
-
3
- /**
4
- * Compute a directional product score from raw dimension values.
5
- *
6
- * Each dimension is 0–1. Penalty dimensions reduce the total.
7
- * Final score is clamped to 0–100.
8
- *
9
- * Interpretation:
10
- * 85–100 Very strong; build or spec next
11
- * 70–84 Strong; pursue a small test
12
- * 55–69 Plausible; investigate more
13
- * 40–54 Weak; defer unless strategic
14
- * 0–39 Avoid for now
15
- */
16
- export function computeScore(dims: Omit<ProductScoreBreakdown, "total">): ProductScoreBreakdown {
17
- const raw =
18
- dims.strategic_fit * 20 +
19
- dims.user_problem_clarity * 15 +
20
- dims.evidence_strength * 20 +
21
- dims.leverage * 10 +
22
- dims.feasibility * 15 +
23
- dims.time_to_signal * 10 +
24
- dims.reversibility * 10 -
25
- dims.complexity_penalty * 10 -
26
- dims.dependency_penalty * 8 -
27
- dims.contradiction_penalty * 15 -
28
- dims.evidence_gap_penalty * 12
29
-
30
- const total = Math.max(0, Math.min(100, Math.round(raw)))
31
- return { ...dims, total }
32
- }
33
-
34
- export function scoreToRecommendation(
35
- total: number,
36
- ): "pursue" | "pursue-small-test" | "investigate-more" | "defer" | "avoid" {
37
- if (total >= 85) return "pursue"
38
- if (total >= 70) return "pursue-small-test"
39
- if (total >= 55) return "investigate-more"
40
- if (total >= 40) return "defer"
41
- return "avoid"
42
- }
43
-
44
- export function scoreToLabel(total: number): string {
45
- if (total >= 85) return "Very strong"
46
- if (total >= 70) return "Strong"
47
- if (total >= 55) return "Plausible"
48
- if (total >= 40) return "Weak"
49
- return "Avoid"
50
- }
51
-
52
- /**
53
- * Build a human-readable explanation for a score.
54
- */
55
- export function explainScore(scores: ProductScoreBreakdown): { strengths: string[]; weaknesses: string[] } {
56
- const strengths: string[] = []
57
- const weaknesses: string[] = []
58
-
59
- if (scores.strategic_fit >= 0.7) strengths.push("Strong strategic fit with current product direction")
60
- if (scores.evidence_strength >= 0.7) strengths.push("Well-supported by Chronicle or code evidence")
61
- if (scores.feasibility >= 0.7) strengths.push("Technically feasible given current architecture")
62
- if (scores.reversibility >= 0.7) strengths.push("Highly reversible — easy to change course")
63
- if (scores.leverage >= 0.7) strengths.push("High leverage — small build unlocks significant value")
64
- if (scores.time_to_signal >= 0.7) strengths.push("Fast time-to-signal — team learns quickly")
65
- if (scores.user_problem_clarity >= 0.7) strengths.push("Clear user problem and target")
66
-
67
- if (scores.evidence_strength < 0.4) weaknesses.push("Weak evidence — mostly inference or assumption")
68
- if (scores.evidence_gap_penalty > 0.5) weaknesses.push("Significant evidence gaps — needs more investigation")
69
- if (scores.contradiction_penalty > 0.3) weaknesses.push("May conflict with prior Chronicle decisions")
70
- if (scores.dependency_penalty > 0.4) weaknesses.push("High dependency burden — external services or platform work required")
71
- if (scores.complexity_penalty > 0.4) weaknesses.push("Adds significant complexity — UI, infrastructure, or support burden")
72
- if (scores.time_to_signal < 0.4) weaknesses.push("Long time-to-signal — hard to validate quickly")
73
- if (scores.strategic_fit < 0.4) weaknesses.push("Weak strategic fit with current product direction")
74
- if (scores.user_problem_clarity < 0.4) weaknesses.push("User problem or target not yet clearly defined")
75
-
76
- return { strengths, weaknesses }
77
- }