@balpal4495/quorum 1.0.0 → 3.0.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.
@@ -0,0 +1,431 @@
1
+ import type { LLMProvider, OracleClient } from "../shared/types"
2
+ import type { AdvisorOutput } from "../advisor/types"
3
+
4
+ // ── Evidence ──────────────────────────────────────────────────────────────────
5
+
6
+ export type CompassEvidenceKind =
7
+ | "chronicle"
8
+ | "advisor"
9
+ | "sentinel"
10
+ | "code"
11
+ | "docs"
12
+ | "tests"
13
+ | "config"
14
+ | "cli"
15
+ | "package"
16
+ | "issue"
17
+ | "analytics"
18
+ | "support"
19
+ | "inference"
20
+ | "assumption"
21
+ | "unknown"
22
+
23
+ export interface CompassEvidenceRef {
24
+ id: string
25
+ kind: CompassEvidenceKind
26
+ source: string
27
+ path?: string
28
+ line?: number
29
+ entry_id?: string
30
+ summary: string
31
+ quote?: string
32
+ confidence: number
33
+ }
34
+
35
+ // ── Source scanner interface ──────────────────────────────────────────────────
36
+
37
+ export interface ProductSourceFinding {
38
+ id: string
39
+ kind: CompassEvidenceKind
40
+ source: string
41
+ path?: string
42
+ line?: number
43
+ title: string
44
+ summary: string
45
+ raw?: string
46
+ confidence: number
47
+ tags: string[]
48
+ }
49
+
50
+ export interface ProductSourceScanInput {
51
+ rootDir: string
52
+ area?: string
53
+ include?: string[]
54
+ exclude?: string[]
55
+ }
56
+
57
+ export interface ProductSource {
58
+ id: string
59
+ kind: "docs" | "code" | "tests" | "config" | "cli" | "package" | "issue" | "analytics" | "support"
60
+ scan(input: ProductSourceScanInput): Promise<ProductSourceFinding[]>
61
+ }
62
+
63
+ // ── Bearings ──────────────────────────────────────────────────────────────────
64
+
65
+ export interface ProductBearing {
66
+ id: string
67
+ title: string
68
+ summary: string
69
+ area?: string
70
+ evidence: CompassEvidenceRef[]
71
+ confidence: number
72
+ }
73
+
74
+ // ── Terrain / behaviour map ───────────────────────────────────────────────────
75
+
76
+ export type BehaviorBasis = "documented" | "implemented" | "tested" | "observed" | "inferred"
77
+
78
+ export interface ProductBehavior {
79
+ id: string
80
+ area: string
81
+ name: string
82
+ description: string
83
+ current_behavior: string
84
+ evidence: CompassEvidenceRef[]
85
+ basis: BehaviorBasis[]
86
+ confidence: number
87
+ notes?: string[]
88
+ }
89
+
90
+ export interface ProductBehaviorGap {
91
+ id: string
92
+ area: string
93
+ gap: string
94
+ why_it_matters: string
95
+ evidence: CompassEvidenceRef[]
96
+ confidence: number
97
+ }
98
+
99
+ export interface ProductBehaviorContradiction {
100
+ id: string
101
+ area: string
102
+ docs_claim: string
103
+ implementation_claim: string
104
+ evidence: CompassEvidenceRef[]
105
+ severity: "low" | "medium" | "high"
106
+ }
107
+
108
+ export interface BehaviorMap {
109
+ generated_at: string
110
+ area?: string
111
+ behaviors: ProductBehavior[]
112
+ gaps: ProductBehaviorGap[]
113
+ contradictions: ProductBehaviorContradiction[]
114
+ confidence: number
115
+ }
116
+
117
+ export interface BehaviorMapInput {
118
+ area?: string
119
+ source?: string
120
+ }
121
+
122
+ export interface BehaviorQuestionInput {
123
+ question: string
124
+ area?: string
125
+ deterministic?: boolean
126
+ }
127
+
128
+ export interface BehaviorAnswer {
129
+ question: string
130
+ what_exists: string[]
131
+ what_appears_missing: string[]
132
+ product_implication: string
133
+ evidence: CompassEvidenceRef[]
134
+ confidence: number
135
+ }
136
+
137
+ // ── Observations ──────────────────────────────────────────────────────────────
138
+
139
+ export interface ProductObservation {
140
+ id: string
141
+ kind: "product_observation"
142
+ title: string
143
+ observation: string
144
+ area: string
145
+ evidence: CompassEvidenceRef[]
146
+ implications: string[]
147
+ confidence: number
148
+ }
149
+
150
+ // ── Hypotheses ────────────────────────────────────────────────────────────────
151
+
152
+ export interface ProductHypothesis {
153
+ id: string
154
+ kind: "product_hypothesis"
155
+ title: string
156
+ hypothesis: string
157
+ target_user?: string
158
+ problem?: string
159
+ assumptions: string[]
160
+ validation_signals: string[]
161
+ invalidation_signals: string[]
162
+ evidence: CompassEvidenceRef[]
163
+ confidence: number
164
+ }
165
+
166
+ // ── Scoring ───────────────────────────────────────────────────────────────────
167
+
168
+ export interface ProductScoreBreakdown {
169
+ strategic_fit: number
170
+ user_problem_clarity: number
171
+ evidence_strength: number
172
+ leverage: number
173
+ feasibility: number
174
+ time_to_signal: number
175
+ reversibility: number
176
+ complexity_penalty: number
177
+ dependency_penalty: number
178
+ contradiction_penalty: number
179
+ evidence_gap_penalty: number
180
+ total: number
181
+ }
182
+
183
+ // ── Opportunities ─────────────────────────────────────────────────────────────
184
+
185
+ export interface ProductOpportunity {
186
+ id: string
187
+ title: string
188
+ area: string
189
+ why_it_matters: string
190
+ evidence_strength: "strong" | "medium" | "weak" | "inferred"
191
+ suggested_next_step: string
192
+ evidence: CompassEvidenceRef[]
193
+ confidence: number
194
+ }
195
+
196
+ export interface OpportunitiesInput {
197
+ goal?: string
198
+ area?: string
199
+ limit?: number
200
+ }
201
+
202
+ // ── Pathways ──────────────────────────────────────────────────────────────────
203
+
204
+ export interface ProductPathwayPhase {
205
+ name: string
206
+ outcome: string
207
+ user_value: string
208
+ build_notes?: string[]
209
+ dependencies: string[]
210
+ risks: string[]
211
+ }
212
+
213
+ export interface ProductPathway {
214
+ id: string
215
+ kind: "product_pathway"
216
+ title: string
217
+ goal: string
218
+ target_user?: string
219
+ problem?: string
220
+ current_behaviors: string[]
221
+ opportunity: string
222
+ why_now: string
223
+ smallest_useful_version: string
224
+ phases: ProductPathwayPhase[]
225
+ dependencies: string[]
226
+ risks: string[]
227
+ assumptions: string[]
228
+ open_questions: string[]
229
+ evidence: CompassEvidenceRef[]
230
+ scores: ProductScoreBreakdown
231
+ confidence: number
232
+ time_to_signal: string
233
+ reversibility: "high" | "medium" | "low"
234
+ suggested_next_step: string
235
+ }
236
+
237
+ export interface PathwaysInput {
238
+ goal: string
239
+ horizon?: string
240
+ appetite?: "small" | "medium" | "large"
241
+ area?: string
242
+ limit?: number
243
+ }
244
+
245
+ // ── Bets ──────────────────────────────────────────────────────────────────────
246
+
247
+ export interface ProductBet {
248
+ id: string
249
+ kind: "product_bet"
250
+ title: string
251
+ thesis: string
252
+ why_now: string
253
+ target_user?: string
254
+ upside: string
255
+ downside: string
256
+ assumptions: string[]
257
+ validation_signals: string[]
258
+ invalidation_signals: string[]
259
+ kill_criteria: string[]
260
+ first_experiment: string
261
+ build_path: string[]
262
+ evidence: CompassEvidenceRef[]
263
+ scores: ProductScoreBreakdown
264
+ confidence: number
265
+ time_to_signal: string
266
+ reversibility: "high" | "medium" | "low"
267
+ appetite: "small" | "medium" | "large"
268
+ }
269
+
270
+ export interface BigBetsInput {
271
+ horizon?: string
272
+ goal?: string
273
+ appetite?: "small" | "medium" | "large"
274
+ }
275
+
276
+ // ── Idea scoring ──────────────────────────────────────────────────────────────
277
+
278
+ export interface ProductIdeaScore {
279
+ idea: string
280
+ summary: string
281
+ recommendation: "pursue" | "pursue-small-test" | "investigate-more" | "defer" | "avoid"
282
+ scores: ProductScoreBreakdown
283
+ evidence: CompassEvidenceRef[]
284
+ supporting_reasons: string[]
285
+ risks: string[]
286
+ assumptions: string[]
287
+ open_questions: string[]
288
+ suggested_next_step: string
289
+ }
290
+
291
+ export interface ScoreIdeaInput {
292
+ idea: string
293
+ context?: string
294
+ }
295
+
296
+ // ── Product brief ─────────────────────────────────────────────────────────────
297
+
298
+ export interface ProductBrief {
299
+ title: string
300
+ problem: string
301
+ target_user?: string
302
+ current_behavior: string[]
303
+ product_opportunity: string
304
+ recommended_solution: string
305
+ smallest_useful_version: string
306
+ non_goals: string[]
307
+ user_flow: string[]
308
+ implementation_notes: string[]
309
+ dependencies: string[]
310
+ risks: string[]
311
+ open_questions: string[]
312
+ assumptions: string[]
313
+ validation_signals: string[]
314
+ invalidation_signals: string[]
315
+ evidence: CompassEvidenceRef[]
316
+ suggested_quorum_checks: string[]
317
+ }
318
+
319
+ export interface ProductBriefInput {
320
+ title: string
321
+ pathway_id?: string
322
+ idea?: string
323
+ context?: string
324
+ }
325
+
326
+ // ── Compass brief ─────────────────────────────────────────────────────────────
327
+
328
+ export interface CompassBrief {
329
+ generated_at: string
330
+ area?: string
331
+ product_direction: string
332
+ known_from_chronicle: string[]
333
+ known_from_behavior: string[]
334
+ inferred: string[]
335
+ assumptions: string[]
336
+ unknowns: string[]
337
+ opportunities: ProductOpportunity[]
338
+ missing_evidence: string[]
339
+ recommended_next_step: string
340
+ confidence: number
341
+ }
342
+
343
+ export interface CompassBriefInput {
344
+ area?: string
345
+ }
346
+
347
+ // ── Proposals ─────────────────────────────────────────────────────────────────
348
+
349
+ export type CompassArtifactKind =
350
+ | "product_observation"
351
+ | "product_hypothesis"
352
+ | "product_pathway"
353
+ | "product_bet"
354
+ | "product_idea_score"
355
+ | "product_outcome"
356
+
357
+ export interface CompassProposalInput {
358
+ artifact_kind: CompassArtifactKind
359
+ artifact_id: string
360
+ payload: ProductPathway | ProductBet | ProductObservation | ProductIdeaScore
361
+ }
362
+
363
+ export interface CompassProposalResult {
364
+ proposal_id: string
365
+ message: string
366
+ }
367
+
368
+ // ── Outcomes ──────────────────────────────────────────────────────────────────
369
+
370
+ export type CompassOutcomeResult =
371
+ | "validated"
372
+ | "partially-validated"
373
+ | "invalidated"
374
+ | "unclear"
375
+ | "superseded"
376
+
377
+ export interface CompassOutcomeInput {
378
+ entry_id: string
379
+ result: CompassOutcomeResult
380
+ note?: string
381
+ }
382
+
383
+ export interface CompassOutcomeResultPayload {
384
+ proposal_id: string
385
+ message: string
386
+ }
387
+
388
+ // ── Main Compass interface ────────────────────────────────────────────────────
389
+
390
+ export interface Compass {
391
+ brief(input?: CompassBriefInput): Promise<CompassBrief>
392
+ mapBehaviors(input?: BehaviorMapInput): Promise<BehaviorMap>
393
+ behavior(input: BehaviorQuestionInput): Promise<BehaviorAnswer>
394
+ opportunities(input?: OpportunitiesInput): Promise<ProductOpportunity[]>
395
+ pathways(input: PathwaysInput): Promise<ProductPathway[]>
396
+ bigBets(input: BigBetsInput): Promise<ProductBet[]>
397
+ scoreIdea(input: ScoreIdeaInput): Promise<ProductIdeaScore>
398
+ productBrief(input: ProductBriefInput): Promise<ProductBrief>
399
+ propose(input: CompassProposalInput): Promise<CompassProposalResult>
400
+ outcome(input: CompassOutcomeInput): Promise<CompassOutcomeResultPayload>
401
+ }
402
+
403
+ // ── Options ───────────────────────────────────────────────────────────────────
404
+
405
+ export interface CreateCompassOptions {
406
+ oracle: OracleClient
407
+ advisor?: {
408
+ ask: (question: string) => Promise<AdvisorOutput>
409
+ }
410
+ /**
411
+ * Required for LLM-backed commands: brief (with synthesis), pathways,
412
+ * bigBets, scoreIdea, productBrief, behavior (non-deterministic).
413
+ * Not required for deterministic mapBehaviors.
414
+ */
415
+ llm?: LLMProvider
416
+ rootDir?: string
417
+ chronicleDir?: string
418
+ sources?: ProductSource[]
419
+ models?: {
420
+ brief?: string
421
+ pathways?: string
422
+ bets?: string
423
+ score?: string
424
+ }
425
+ /**
426
+ * How aggressively to surface low-evidence recommendations.
427
+ * "strict" penalises more. "exploratory" allows weaker evidence through.
428
+ * Default: "balanced"
429
+ */
430
+ minimumEvidence?: "strict" | "balanced" | "exploratory"
431
+ }
package/modules/setup.ts CHANGED
@@ -11,6 +11,9 @@ import { entryText } from "./shared/types"
11
11
  import type { JuryInput, JuryOutput, JuryDeps } from "./jury/types"
12
12
  import type { CouncilInput, CouncilOutput, CouncilDeps, CouncilModels } from "./council/types"
13
13
  import type { AdvisorOutput } from "./advisor/types"
14
+ import { createCompass } from "./compass/create"
15
+ import { defaultSources } from "./compass/sources/index"
16
+ import type { Compass, CreateCompassOptions } from "./compass/types"
14
17
 
15
18
  export interface SetupOptions {
16
19
  /**
@@ -33,8 +36,20 @@ export interface SetupOptions {
33
36
  models?: {
34
37
  jury?: string
35
38
  council?: CouncilModels
39
+ compass?: {
40
+ brief?: string
41
+ pathways?: string
42
+ bets?: string
43
+ score?: string
44
+ }
36
45
  }
37
46
 
47
+ /**
48
+ * Root directory for scanning source files (used by Compass).
49
+ * Default: process.cwd()
50
+ */
51
+ rootDir?: string
52
+
38
53
  /**
39
54
  * Pre-warm the local ONNX embedder during setup so the first query
40
55
  * is not slow. Set to false to skip (e.g. in test environments).
@@ -79,6 +94,14 @@ export interface Modules {
79
94
  * the confidence threshold (≥ 0.7, no blockers) or the retry budget runs out.
80
95
  */
81
96
  ask: (question: string) => Promise<AdvisorOutput>
97
+
98
+ /**
99
+ * Product-direction module.
100
+ * Synthesises Chronicle memory and current codebase behaviour into
101
+ * pathways, bets, briefs, and opportunities.
102
+ * All writes go through oracle.propose() — never auto-committed.
103
+ */
104
+ compass: Compass
82
105
  }
83
106
 
84
107
  /**
@@ -103,6 +126,7 @@ export async function setup(options: SetupOptions): Promise<Modules> {
103
126
  const {
104
127
  llm,
105
128
  chronicleDir = ".chronicle",
129
+ rootDir = process.cwd(),
106
130
  models = {},
107
131
  warmEmbedder: shouldWarm = true,
108
132
  embedder = xenovaEmbed,
@@ -165,5 +189,14 @@ export async function setup(options: SetupOptions): Promise<Modules> {
165
189
  const evidence = await oracle.query(question)
166
190
  return advisorAsk({ question, evidence }, { llm })
167
191
  },
192
+
193
+ compass: createCompass({
194
+ oracle,
195
+ llm,
196
+ rootDir,
197
+ chronicleDir,
198
+ sources: defaultSources(),
199
+ models: models.compass,
200
+ }),
168
201
  }
169
202
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@balpal4495/quorum",
3
- "version": "1.0.0",
4
- "description": "Portable reasoning layer for agentic codebases Oracle, Jury, Council, Sentinel",
3
+ "version": "3.0.0",
4
+ "description": "Git-backed memory and design review for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -10,20 +10,30 @@
10
10
  },
11
11
  "homepage": "https://github.com/balpal4495/Quorum#readme",
12
12
  "keywords": [
13
- "ai",
14
- "agents",
15
- "agentic",
16
- "reasoning",
17
- "knowledge",
18
- "chronicle",
19
- "oracle",
20
- "llm"
13
+ "ai-agents",
14
+ "coding-agents",
15
+ "agent-memory",
16
+ "claude-code",
17
+ "cursor",
18
+ "codex",
19
+ "copilot",
20
+ "llm",
21
+ "developer-tools",
22
+ "typescript"
21
23
  ],
22
24
  "bin": {
23
25
  "quorum": "bin/quorum.js"
24
26
  },
27
+ "exports": {
28
+ ".": "./modules/setup.ts",
29
+ "./oracle": "./modules/oracle/index.ts",
30
+ "./advisor": "./modules/advisor/index.ts",
31
+ "./jury": "./modules/jury/index.ts",
32
+ "./council": "./modules/council/index.ts",
33
+ "./sentinel": "./modules/sentinel/index.ts",
34
+ "./compass": "./modules/compass/index.ts"
35
+ },
25
36
  "scripts": {
26
- "init": "node bin/init.js",
27
37
  "test": "vitest run modules/ evals/",
28
38
  "test:watch": "vitest modules/",
29
39
  "typecheck": "tsc --noEmit"