@balpal4495/quorum 0.1.8 → 0.1.10
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.
- package/README.md +132 -136
- package/bin/init.js +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,202 +1,198 @@
|
|
|
1
1
|
# Quorum
|
|
2
2
|
|
|
3
|
-
Quorum
|
|
3
|
+
**Quorum gives your AI coding assistant memory and judgment.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
When Claude Code, Copilot, or Cursor works in your codebase, it forgets everything between sessions. It retries approaches that already failed. It contradicts decisions made last week. It has no idea what the team has already learned.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Quorum fixes this. It installs a persistent knowledge store into your project and gives your AI a structured workflow for querying it before proposing solutions, validating designs before acting, and writing new knowledge back — with you approving every write.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Get started in one command
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Run this from your project root:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| **Oracle** | Query and write interface to Chronicle. No LLM required. |
|
|
18
|
-
| **Jury** | Evaluates a proposed design against Oracle evidence. Returns a confidence score. |
|
|
19
|
-
| **Council** | Adversarial validation via a parallel panel of advisors and reviewers. Returns a verdict. |
|
|
20
|
-
| **Sentinel** | Chronicle coverage and drift detection. Surfaces gaps and stale knowledge as Vitest assertions. |
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
oracle.query() → jury.evaluate() → council.deliberate() → human gate → Executor
|
|
24
|
-
sentinel.coverage() + sentinel.detectDrift() → advisory test output
|
|
15
|
+
```bash
|
|
16
|
+
npx @balpal4495/quorum@latest init
|
|
25
17
|
```
|
|
26
18
|
|
|
19
|
+
Then run `npm install`.
|
|
20
|
+
|
|
21
|
+
That's the whole setup. Quorum copies its modules into `quorum/`, merges instruction files for your AI (`CLAUDE.md`, `AGENTS.md`, `.github/copilot-instructions.md`), and creates the Chronicle knowledge store at `.chronicle/`.
|
|
22
|
+
|
|
27
23
|
---
|
|
28
24
|
|
|
29
|
-
##
|
|
25
|
+
## Then just talk to your AI
|
|
30
26
|
|
|
31
|
-
|
|
27
|
+
Once initialized, open your AI in agent mode and tell it:
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
flowchart LR
|
|
35
|
-
Agent[AI Agent] -->|query| Oracle
|
|
36
|
-
Oracle -->|evidence| Jury
|
|
37
|
-
Jury -->|scores| Council
|
|
38
|
-
Council -->|verdict| Gate[Human Gate]
|
|
39
|
-
Oracle -. reads .-> Chronicle[(Chronicle)]
|
|
40
|
-
Gate -. approved commit .-> Chronicle
|
|
41
|
-
Chronicle -. coverage + drift .-> Sentinel
|
|
42
|
-
Sentinel -. advisory report .-> CI([CI / Developer])
|
|
43
|
-
```
|
|
29
|
+
> "Follow quorum/SETUP.md"
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
participant Council
|
|
53
|
-
participant Human
|
|
54
|
-
participant Chronicle
|
|
55
|
-
|
|
56
|
-
Agent->>Oracle: query(text)
|
|
57
|
-
Oracle->>Chronicle: vector search
|
|
58
|
-
Chronicle-->>Oracle: ranked entries
|
|
59
|
-
Oracle-->>Agent: OracleResult[]
|
|
60
|
-
|
|
61
|
-
Agent->>Jury: evaluate(design, evidence)
|
|
62
|
-
Jury-->>Agent: score, flags, passed
|
|
63
|
-
|
|
64
|
-
Agent->>Council: deliberate(design, evaluations)
|
|
65
|
-
Council-->>Agent: satisfied, verdict, proposal
|
|
66
|
-
|
|
67
|
-
alt Council not satisfied
|
|
68
|
-
Note over Agent: revise design and retry
|
|
69
|
-
else Council satisfied
|
|
70
|
-
Agent->>Human: surface verdict and proposal
|
|
71
|
-
Human->>Oracle: commit(proposalId)
|
|
72
|
-
Oracle->>Chronicle: upsert entry
|
|
73
|
-
Oracle-->>Human: ChronicleEntry
|
|
74
|
-
end
|
|
75
|
-
```
|
|
31
|
+
Your AI reads the instruction files, wires the modules into your project's entry point, runs the tests, and reports what it did. From that point it operates under Quorum — querying Chronicle before every proposal, running designs through Jury and Council, and staging entries for your approval.
|
|
32
|
+
|
|
33
|
+
**Works with:**
|
|
34
|
+
- Claude Code (`claude` CLI or VS Code extension)
|
|
35
|
+
- GitHub Copilot (agent mode)
|
|
36
|
+
- Cursor
|
|
37
|
+
- Any other AI that can read files and run terminal commands
|
|
76
38
|
|
|
77
39
|
---
|
|
78
40
|
|
|
79
|
-
##
|
|
41
|
+
## What changes after setup
|
|
80
42
|
|
|
81
|
-
|
|
43
|
+
### Your AI now has a memory
|
|
82
44
|
|
|
83
|
-
|
|
84
|
-
npx @balpal4495/quorum@latest init
|
|
85
|
-
```
|
|
45
|
+
Before proposing anything, your AI queries Chronicle — the project's knowledge store. If a similar approach was tried and rejected, it knows. If a design decision was made last month, it knows.
|
|
86
46
|
|
|
87
|
-
|
|
47
|
+
> *"I queried Chronicle before proposing the Redis session approach. Entry `[abc-123]` shows we rejected this in March — key rotation wasn't viable. I'm proposing JWT with RS256 instead."*
|
|
88
48
|
|
|
89
|
-
|
|
49
|
+
### Your AI validates designs before acting
|
|
90
50
|
|
|
91
|
-
|
|
51
|
+
Every proposal goes through Jury (confidence scoring against evidence) and Council (adversarial panel review) before it reaches you. Low-confidence or contested ideas get challenged internally first.
|
|
92
52
|
|
|
93
|
-
|
|
53
|
+
> *"Jury scored this 0.41 — gaps in lock strategy and rollback plan. Council flagged the same issue. I've revised the migration plan to use a shadow column approach before bringing it to you."*
|
|
94
54
|
|
|
95
|
-
|
|
55
|
+
### You approve what gets remembered
|
|
96
56
|
|
|
97
|
-
|
|
57
|
+
When a decision is made, your AI stages a Chronicle entry using `oracle.propose()`. You approve it with `oracle.commit(proposalId)`. Nothing is indexed without your explicit sign-off.
|
|
98
58
|
|
|
99
59
|
```
|
|
100
60
|
.chronicle/
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
SUMMARY.md ← auto-generated
|
|
61
|
+
proposals/ ← AI-staged entries waiting for your approval
|
|
62
|
+
committed/ ← approved entries, indexed and searchable
|
|
63
|
+
SUMMARY.md ← auto-generated weekly context for your AI to read
|
|
104
64
|
```
|
|
105
65
|
|
|
106
|
-
|
|
66
|
+
Commit `.chronicle/committed/` to git. Future sessions — and your teammates' sessions — start with that context.
|
|
107
67
|
|
|
108
68
|
---
|
|
109
69
|
|
|
110
|
-
##
|
|
70
|
+
## Real examples
|
|
111
71
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
72
|
+
### An agent that remembers a past failure
|
|
73
|
+
|
|
74
|
+
Your AI is about to propose symmetric JWT signing. Oracle returns:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
[abc-123] Tried HS256 JWT in March. Rejected — no way to rotate keys without
|
|
78
|
+
invalidating all active sessions. Decision: RS256 with short-lived tokens.
|
|
79
|
+
status: committed · confidence: 0.91
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Jury flags it as a direct conflict. The agent revises before Council even sees it.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### Onboarding a new session to an established project
|
|
87
|
+
|
|
88
|
+
Day one of a new Claude Code session. Before touching anything:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
> query Chronicle for: authentication, session handling, token strategy
|
|
92
|
+
|
|
93
|
+
6 entries found:
|
|
94
|
+
- HS256 rejected (key rotation problem) → use RS256
|
|
95
|
+
- Redis sessions tried and removed (memory overhead at scale)
|
|
96
|
+
- Current approach: RS256 JWT, 15-min expiry, refresh rotation in httpOnly cookies
|
|
97
|
+
- Upcoming: OAuth migration planned for Q3
|
|
98
|
+
```
|
|
117
99
|
|
|
118
|
-
The
|
|
100
|
+
The AI works with full project context from the first message — no archaeology through git history.
|
|
119
101
|
|
|
120
102
|
---
|
|
121
103
|
|
|
122
|
-
|
|
104
|
+
### Validating a risky database change
|
|
105
|
+
|
|
106
|
+
An agent proposes adding a `NOT NULL` column to a 50M-row table. Jury returns:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
confidence: 0.41
|
|
110
|
+
gaps: ["no lock strategy documented", "no rollback plan"]
|
|
111
|
+
council_brief: challenge
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Council's Chairman gives a verdict:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
satisfied: false
|
|
118
|
+
verdict: "On a table this size, a naive ALTER TABLE takes an exclusive lock for minutes.
|
|
119
|
+
Specify a shadow column pattern or pg_repack. No rollback plan documented."
|
|
120
|
+
```
|
|
123
121
|
|
|
124
|
-
|
|
122
|
+
The agent revises the plan. You approve the Chronicle entry once it's solid. The reasoning is on record for the next time someone touches that table.
|
|
125
123
|
|
|
126
124
|
---
|
|
127
125
|
|
|
128
|
-
##
|
|
126
|
+
## What's inside
|
|
127
|
+
|
|
128
|
+
Four portable TypeScript modules installed into `quorum/modules/`:
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
| Module | What it does |
|
|
131
|
+
|---|---|
|
|
132
|
+
| **Oracle** | Query and write interface to Chronicle. No LLM required. |
|
|
133
|
+
| **Jury** | Evaluates a proposed design against Chronicle evidence. Returns a confidence score. |
|
|
134
|
+
| **Council** | A panel of advisors challenges the design independently, reviewers critique anonymously, a Chairman gives a final verdict. |
|
|
135
|
+
| **Sentinel** | Shows which files the AI knows nothing about, flags stale knowledge, and posts a coverage map on every PR. |
|
|
131
136
|
|
|
132
|
-
|
|
137
|
+
The modules live in your repo — readable by any AI working in the codebase. Nothing is hidden in `node_modules`.
|
|
133
138
|
|
|
134
|
-
|
|
139
|
+
---
|
|
135
140
|
|
|
136
|
-
|
|
141
|
+
## Sentinel — coverage and drift
|
|
137
142
|
|
|
138
|
-
Sentinel
|
|
143
|
+
Sentinel surfaces two things Chronicle can't tell you about itself.
|
|
139
144
|
|
|
140
|
-
|
|
145
|
+
**Coverage** — which parts of your codebase has the AI never documented?
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
import { describe } from "vitest"
|
|
144
|
-
import { sentinelAssertions } from "./modules/sentinel/assert"
|
|
147
|
+
**Drift** — do existing Chronicle entries still accurately describe the code, or have they gone stale?
|
|
145
148
|
|
|
146
|
-
|
|
147
|
-
chronicleDir: ".chronicle",
|
|
148
|
-
codebasePath: "src", // path to your source tree — defaults to "."
|
|
149
|
-
llm: myLLMProvider, // optional — drift tests skip gracefully when absent
|
|
150
|
-
minCoveragePercent: 50, // optional — 0 (default) = advisory only, never fails CI
|
|
151
|
-
})
|
|
149
|
+
Add `sentinel-pr.yml` (included in `quorum/`) to your GitHub Actions and every PR gets a comment showing a full-project coverage table and a colour-coded heatmap. Changed modules are highlighted. Reviewers see exactly where knowledge is solid and where it goes dark.
|
|
152
150
|
|
|
153
|
-
|
|
154
|
-
```
|
|
151
|
+
---
|
|
155
152
|
|
|
156
|
-
|
|
153
|
+
## For custom agent pipelines
|
|
157
154
|
|
|
158
|
-
|
|
155
|
+
If you're building your own agent workflow programmatically, the modules expose a clean TypeScript API. Wire your LLM provider and call directly:
|
|
159
156
|
|
|
160
|
-
|
|
157
|
+
```typescript
|
|
158
|
+
import { setup } from "./quorum/modules/setup"
|
|
161
159
|
|
|
162
|
-
|
|
160
|
+
const { oracle, evaluate, deliberate } = await setup({ llm: myLLMProvider })
|
|
163
161
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
| Module | Coverage | Entries | Files | PR Changes | Risk |
|
|
168
|
-
|----------|----------|---------|-------|-------------|--------|
|
|
169
|
-
| council/ | 0% | 0 | 8 | — | high |
|
|
170
|
-
| jury/ | 0% | 0 | 4 | — | high |
|
|
171
|
-
| oracle/ | 22% | 4 | 9 | — | medium |
|
|
172
|
-
| scripts/ | 0% | 0 | 1 | **1 files** | high |
|
|
173
|
-
| sentinel/| 0% | 0 | 5 | **2 files** | high |
|
|
174
|
-
| shared/ | 100% | 2 | 1 | — | low |
|
|
175
|
-
|
|
176
|
-
[mermaid heatmap — Chronicle root → all modules, nodes coloured red/yellow/green by risk,
|
|
177
|
-
changed modules labelled with file count]
|
|
178
|
-
|
|
179
|
-
### Chronicle context for changed modules
|
|
180
|
-
**oracle/**
|
|
181
|
-
- `[30bdc1c1]` schema constraints not LLM self-evaluation — validated (0.88)
|
|
162
|
+
const evidence = await oracle.query("authentication patterns")
|
|
163
|
+
const jury = await evaluate({ outcome, design, evidence })
|
|
164
|
+
const verdict = await deliberate({ outcome, design, evidence, jury_output: jury })
|
|
182
165
|
```
|
|
183
166
|
|
|
184
|
-
|
|
167
|
+
The `LLMProvider` type is a simple function — wire OpenAI, Anthropic, or anything else:
|
|
185
168
|
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
169
|
+
```typescript
|
|
170
|
+
// Anthropic
|
|
171
|
+
const llm = async (messages, model = "claude-3-5-sonnet-20241022") => {
|
|
172
|
+
const res = await anthropic.messages.create({ model, messages, max_tokens: 2048 })
|
|
173
|
+
return res.content[0].type === "text" ? res.content[0].text : ""
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// OpenAI
|
|
177
|
+
const llm = async (messages, model = "gpt-4o") => {
|
|
178
|
+
const res = await openai.chat.completions.create({ model, messages })
|
|
179
|
+
return res.choices[0].message.content ?? ""
|
|
180
|
+
}
|
|
193
181
|
```
|
|
194
182
|
|
|
183
|
+
Full API reference: [modules/README.md](modules/README.md)
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Releases
|
|
188
|
+
|
|
189
|
+
Quorum is published as `@balpal4495/quorum`. New versions release automatically when a semver tag is pushed — via GitHub Actions and OIDC Trusted Publishing, no stored tokens.
|
|
190
|
+
|
|
195
191
|
---
|
|
196
192
|
|
|
197
|
-
##
|
|
193
|
+
## Docs
|
|
198
194
|
|
|
199
|
-
- [
|
|
200
|
-
- [modules/
|
|
201
|
-
- [modules/
|
|
202
|
-
- [
|
|
195
|
+
- [SETUP.md](SETUP.md) — full bootstrap sequence (the file you point your AI at)
|
|
196
|
+
- [modules/README.md](modules/README.md) — TypeScript API reference
|
|
197
|
+
- [modules/AGENTS.md](modules/AGENTS.md) — file ownership map
|
|
198
|
+
- [modules/CLAUDE.md](modules/CLAUDE.md) — design decisions and invariants
|
package/bin/init.js
CHANGED
|
@@ -15,6 +15,10 @@ import { promises as fs } from "fs"
|
|
|
15
15
|
import path from "path"
|
|
16
16
|
import { fileURLToPath } from "url"
|
|
17
17
|
import { execSync } from "child_process"
|
|
18
|
+
import { createRequire } from "module"
|
|
19
|
+
|
|
20
|
+
const _require = createRequire(import.meta.url)
|
|
21
|
+
const PKG_VERSION = _require("../package.json").version
|
|
18
22
|
|
|
19
23
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
20
24
|
const QUORUM_ROOT = path.resolve(__dirname, "..")
|
|
@@ -346,7 +350,7 @@ async function cli() {
|
|
|
346
350
|
}
|
|
347
351
|
|
|
348
352
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
349
|
-
console.log(
|
|
353
|
+
console.log(PKG_VERSION)
|
|
350
354
|
return
|
|
351
355
|
}
|
|
352
356
|
|