granite-mem 0.1.11 → 0.1.13
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 +189 -107
- package/dist/index.js +3522 -2502
- package/dist/public/app.js +9 -9
- package/dist/public/index.html +1 -0
- package/dist/public/markdown-renderer.js +5 -1
- package/dist/public/style.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,19 +9,21 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
> **The personal OS your agent runs on.**
|
|
12
|
-
>
|
|
12
|
+
> Give your agent a memory it can't hallucinate: plain markdown + SQLite full-text search + a typed contract it already knows how to operate. No LLM inside. Your agent brings the intelligence; Granite holds the ground truth.
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
15
|
<img src="docs/screenshots/granite-graph.png" alt="Granite constellation graph" width="720">
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
|
-
<
|
|
19
|
+
<code>npm install -g granite-mem</code>
|
|
20
20
|
</p>
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
**Jump to:** [The 60-second setup](#the-60-second-setup) · [Install it yourself](#or-install-it-yourself) · [How it works](#how-it-works) · [Why not Obsidian, Notion, or a vector store?](#why-not-obsidian-notion-or-a-vector-store) · [See it](#see-it) · [Types are contracts](#types-are-contracts-not-folders) · [The MCP server](#wired-for-agents-the-mcp-server) · [What Granite will never do](#what-granite-will-never-do) · [Beyond one machine](#beyond-one-machine) · [The full CLI](#the-full-cli) · [FAQ](#faq) · [Philosophy](#philosophy)
|
|
25
|
+
|
|
26
|
+
## The 60-second setup
|
|
25
27
|
|
|
26
28
|
Paste this into **Claude Code**, **Cursor**, or any MCP-capable agent:
|
|
27
29
|
|
|
@@ -37,9 +39,69 @@ Install Granite as my personal OS.
|
|
|
37
39
|
drafts with --source agent.
|
|
38
40
|
````
|
|
39
41
|
|
|
40
|
-
Sixty seconds later
|
|
42
|
+
Sixty seconds later: a live vault, an agent that knows how to operate it, and its first three notes on disk in `~/.granite/notes/`. No system prompt. No config. No cloud.
|
|
43
|
+
|
|
44
|
+
That's the thesis of this project. No agent handy? Granite is a complete tool on its own:
|
|
45
|
+
|
|
46
|
+
## Or install it yourself
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install -g granite-mem
|
|
50
|
+
granite init # note / source / synthesis / output
|
|
51
|
+
granite new "Ideas worth stealing"
|
|
52
|
+
granite search "steal"
|
|
53
|
+
granite serve # web UI + constellation graph
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Add `--template founder-os` to `init` when you want a full personal OS from the start: `person`, `organization`, `meeting`, and `learning` on top of the four defaults — eight types already wired with hooks, indexed fields, and lifecycles, in [150 lines of pure YAML](templates/founder-os.yml).
|
|
57
|
+
|
|
58
|
+
Everything Granite writes is a plain `.md` file with YAML frontmatter. Close the laptop, `git init` the vault, open the folder in any editor — it's just files.
|
|
59
|
+
|
|
60
|
+
## How it works
|
|
61
|
+
|
|
62
|
+
Granite is a **deterministic substrate** for knowledge: markdown files as the source of truth, a SQLite index as derived state, and one fixed loop imposed on top. The intelligence is not in Granite — it's in whatever agent (or human) operates it.
|
|
41
63
|
|
|
42
|
-
|
|
64
|
+
```
|
|
65
|
+
┌──────────────────────────────────────────┐
|
|
66
|
+
│ your agent · the brains │
|
|
67
|
+
└────────────────────┬─────────────────────┘
|
|
68
|
+
│ MCP · CLI · web UI
|
|
69
|
+
┌────────────────────▼─────────────────────┐
|
|
70
|
+
│ GRANITE │
|
|
71
|
+
│ │
|
|
72
|
+
│ capture ─▶ compile ─▶ query ─▶ output │
|
|
73
|
+
│ ▲ │ │
|
|
74
|
+
│ └──────────── lint ◀──────────┘ │
|
|
75
|
+
│ │
|
|
76
|
+
│ .md files SQLite FTS5 wikilinks │
|
|
77
|
+
│ (truth) (derived) (graph) │
|
|
78
|
+
└──────────────────────────────────────────┘
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- **Markdown is truth.** Every note is `<folder>/<slug>.md` with YAML frontmatter. Nothing you can't read in `cat`.
|
|
82
|
+
- **The index is disposable.** Full-text search, backlinks, and typed queries live in `.granite/index.db` — rebuilt from the files at any time.
|
|
83
|
+
- **Wikilinks are the graph.** `[[a-note]]` in any body resolves slug → title → alias, and the backlink graph falls out for free.
|
|
84
|
+
|
|
85
|
+
> Karpathy asked for *"an incredible new product instead of a hacky collection of scripts"* for [LLM knowledge bases](https://x.com/karpathy/status/2039805659525644595).
|
|
86
|
+
>
|
|
87
|
+
> This is our answer.
|
|
88
|
+
|
|
89
|
+
## Why not Obsidian, Notion, or a vector store?
|
|
90
|
+
|
|
91
|
+
Granite doesn't compete with your note app. It competes with the pile of scripts you were about to write.
|
|
92
|
+
|
|
93
|
+
| | **Granite** | Obsidian | Notion | Vector memory | Plain files |
|
|
94
|
+
| ---------------------------------------------- | :---------: | :-------: | :-------: | :-----------: | :---------: |
|
|
95
|
+
| Plain markdown on disk | ✅ | ✅ | ❌ | ❌ | ✅ |
|
|
96
|
+
| Typed schemas with hooks & lifecycles | ✅ | plugins | databases | ❌ | ❌ |
|
|
97
|
+
| Agent-native MCP workflow | ✅ | community | limited | ✅ | ❌ |
|
|
98
|
+
| Deterministic retrieval (no embeddings) | ✅ | ✅ | ❌ | ❌ | `grep` |
|
|
99
|
+
| Structured queries over indexed fields | ✅ | plugins | ✅ | ❌ | ❌ |
|
|
100
|
+
| Provenance on every note | ✅ | ❌ | ❌ | partial | ❌ |
|
|
101
|
+
| Offline, no account, no telemetry | ✅ | ✅ | ❌ | ❌ | ✅ |
|
|
102
|
+
| Git-friendly | ✅ | ✅ | ❌ | ❌ | ✅ |
|
|
103
|
+
|
|
104
|
+
Obsidian is a great editor for humans. Vector memory is a great cache for agents. Granite is the shared substrate both can operate.
|
|
43
105
|
|
|
44
106
|
## See it
|
|
45
107
|
|
|
@@ -70,47 +132,11 @@ That's the thesis of this project.
|
|
|
70
132
|
</tr>
|
|
71
133
|
</table>
|
|
72
134
|
|
|
73
|
-
##
|
|
74
|
-
|
|
75
|
-
A local-first markdown store with an opinionated flow. **No AI inside** — just plain files on disk, indexed by SQLite, queried deterministically.
|
|
76
|
-
|
|
77
|
-
- **Imposed flow.** Capture, compile, query, output, lint. The shape is fixed; the content is yours.
|
|
78
|
-
- **Four default note types** — `note`, `source`, `synthesis`, `output`. Add your own in `granite.yml` when your life grows a new shape.
|
|
79
|
-
- **A specialized MCP** that teaches your agent how to use the vault. Drop any MCP-capable agent on it and it knows how to operate, no system prompt required.
|
|
135
|
+
## Types are contracts, not folders
|
|
80
136
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
## Try it standalone
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
npm install -g granite-mem
|
|
87
|
-
granite init
|
|
88
|
-
granite serve
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
That starts with the default knowledge model: `note`, `source`, `synthesis`, and `output`. Add `--template founder-os` when you want people, organizations, meetings, and learnings wired in from the start.
|
|
92
|
-
|
|
93
|
-
## Agent-native MCP
|
|
94
|
-
|
|
95
|
-
> "A thin MCP server exposes capabilities. A strong MCP server shapes behavior."
|
|
96
|
-
|
|
97
|
-
Granite's MCP surface is intention-first:
|
|
98
|
-
|
|
99
|
-
- `granite_wakeup` to orient
|
|
100
|
-
- `granite_research_topic` to inspect existing knowledge before writing
|
|
101
|
-
- `granite_query` for structured filters over typed notes
|
|
102
|
-
- `granite_compile_context` to assemble a graph-aware brief
|
|
103
|
-
- `granite_plan_garden` to decide what to improve next
|
|
104
|
-
- `granite_capture_knowledge` to write with protocol fields and type contracts
|
|
105
|
-
|
|
106
|
-
The point is not to give an agent a file browser. The point is to give it a workflow it can follow.
|
|
107
|
-
|
|
108
|
-
## Types as active contracts
|
|
109
|
-
|
|
110
|
-
This is what makes the agent feel native rather than bolted-on.
|
|
137
|
+
This is what makes an agent feel native rather than bolted-on. Every note type in `granite.yml` is an executable contract:
|
|
111
138
|
|
|
112
139
|
```yaml
|
|
113
|
-
# granite.yml — every note type is an executable contract
|
|
114
140
|
note_types:
|
|
115
141
|
meeting:
|
|
116
142
|
folder: notes/meetings
|
|
@@ -122,114 +148,164 @@ note_types:
|
|
|
122
148
|
- { action: set_default, field: date, value: "${today}" }
|
|
123
149
|
- { action: resolve_wikilinks, fields: [organization, attendees], auto_stub: true }
|
|
124
150
|
indexed_fields: [date, organization]
|
|
125
|
-
lifecycle:
|
|
126
|
-
states: [active, archived]
|
|
127
|
-
transitions:
|
|
128
|
-
- { from: active, to: archived, trigger: stale_days, days: 180 }
|
|
129
151
|
```
|
|
130
152
|
|
|
131
153
|
- `set_default` — fills `${today}` automatically
|
|
132
154
|
- `resolve_wikilinks + auto_stub` — turns `organization: Acme Corp` into the slug `acme-corp`, creating the org note if missing (with a globally-unique slug so nothing gets silently overwritten)
|
|
133
|
-
- `indexed_fields` — makes `granite_query { type: meeting, where: { date: { gte: "2026-01-01" } } }`
|
|
134
|
-
- `lifecycle` — `granite doctor` surfaces
|
|
155
|
+
- `indexed_fields` — makes `granite_query { type: meeting, where: { date: { gte: "2026-01-01" } } }` fast and deterministic
|
|
156
|
+
- `lifecycle` — declare states and stale-days transitions, and `granite doctor` surfaces drift before it rots
|
|
135
157
|
|
|
136
|
-
|
|
158
|
+
On top of its type, **every note carries five protocol fields**, so humans and agents share ground truth:
|
|
137
159
|
|
|
138
|
-
|
|
160
|
+
| Field | Values | Purpose |
|
|
161
|
+
|----------------|---------------------------------------|--------------------------------------|
|
|
162
|
+
| `status` | `inbox` · `active` · `archived` | operational state |
|
|
163
|
+
| `source` | `human` · `agent` · `extraction` | who wrote it |
|
|
164
|
+
| `review_state` | `draft` · `reviewed` · `locked` | editorial state |
|
|
165
|
+
| `durability` | `canonical` · `working` · `ephemeral` | keep / may drift / throwaway |
|
|
166
|
+
| `derived_from` | `[slug, …]` | provenance for syntheses and outputs |
|
|
167
|
+
|
|
168
|
+
Your agent reads these before writing and sets them as it works. You inherit a fully auditable trail. Add a type when your life grows a new shape — the core stays small. For the formal protocol, see [docs/GRANITE_OBJECT_STANDARD.md](docs/GRANITE_OBJECT_STANDARD.md).
|
|
169
|
+
|
|
170
|
+
## Wired for agents: the MCP server
|
|
171
|
+
|
|
172
|
+
> "A thin MCP server exposes capabilities. A strong MCP server shapes behavior."
|
|
173
|
+
|
|
174
|
+
One line connects any MCP-capable agent to your vault:
|
|
139
175
|
|
|
140
176
|
```bash
|
|
141
|
-
|
|
142
|
-
granite init --template founder-os # + person / organization / meeting / learning
|
|
177
|
+
claude mcp add granite -- granite mcp --vault ~/.granite
|
|
143
178
|
```
|
|
144
179
|
|
|
145
|
-
|
|
180
|
+
The surface is intention-first — fourteen tools organized around the workflow, not around files:
|
|
181
|
+
|
|
182
|
+
| Intent | Tools |
|
|
183
|
+
|------------|----------------------------------------------------------------------------------------------------------------|
|
|
184
|
+
| **Orient** | `granite_wakeup` · `granite_research_topic` · `granite_resolve` |
|
|
185
|
+
| **Read** | `granite_query` · `granite_compile_context` · `granite_understand_note` · `granite_extract_document` |
|
|
186
|
+
| **Write** | `granite_capture_knowledge` · `granite_import_document` · `granite_revise_note` · `granite_dispose_note` |
|
|
187
|
+
| **Garden** | `granite_plan_garden` · `granite_adjudicate_garden_opportunity` · `granite_list_garden_adjudications` |
|
|
146
188
|
|
|
147
|
-
|
|
189
|
+
Plus three prompts for the higher-level workflows (`granite_refine_note`, `granite_process_inbox`, `granite_compile_topic`), and resources for raw note and type-contract access. Start the server with `--role read` when an agent should inspect without mutating. An HTTP transport with bearer-token auth is available for remote setups — see [docs/DEPLOY.md](docs/DEPLOY.md).
|
|
190
|
+
|
|
191
|
+
The point is not to give an agent a file browser. The point is to give it a workflow it can follow.
|
|
192
|
+
|
|
193
|
+
## What Granite will never do
|
|
148
194
|
|
|
149
195
|
Granite will **never**:
|
|
150
196
|
|
|
151
197
|
- embed an LLM, run prompts, or hold an API key
|
|
152
198
|
- compute embeddings or ship a vector store
|
|
153
199
|
- run background agents or a scheduler
|
|
200
|
+
- phone home — no telemetry, no account, no cloud dependency
|
|
154
201
|
- add overlapping CLI/MCP endpoints that blur the loop
|
|
155
202
|
|
|
156
|
-
This is why your agent can be trusted with write access. The vault is a
|
|
157
|
-
|
|
158
|
-
## Protocol fields
|
|
159
|
-
|
|
160
|
-
Every note carries five shared fields so humans and agents share ground truth:
|
|
203
|
+
This is why your agent can be trusted with write access. The vault is a deterministic substrate. The intelligence is yours (or Claude's, or GPT's, or whoever you pay this quarter).
|
|
161
204
|
|
|
162
|
-
|
|
163
|
-
|----------------|---------------------------------------|--------------------------------------|
|
|
164
|
-
| `status` | `inbox` · `active` · `archived` | operational state |
|
|
165
|
-
| `source` | `human` · `agent` · `extraction` | who wrote it |
|
|
166
|
-
| `review_state` | `draft` · `reviewed` · `locked` | editorial state |
|
|
167
|
-
| `durability` | `canonical` · `working` · `ephemeral` | keep / may drift / throwaway |
|
|
168
|
-
| `derived_from` | `[slug, …]` | provenance for syntheses and outputs |
|
|
205
|
+
## Beyond one machine
|
|
169
206
|
|
|
170
|
-
|
|
207
|
+
**Cloud, if you want it.** One command deploys a personal serverless Granite on [Fly.io Sprites](https://sprites.dev): wakes on request in 100–500 ms, sleeps when idle, costs cents per month at rest. You own the sprite — there is no Granite cloud, no central admin, no relay.
|
|
171
208
|
|
|
172
|
-
|
|
209
|
+
```bash
|
|
210
|
+
granite deploy login --token <sprites-token> # or export SPRITES_TOKEN=…
|
|
211
|
+
granite deploy # prints an MCP URL + bearer token
|
|
173
212
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
- `granite serve` gives you a local web UI — browse, search, explore the graph
|
|
178
|
-
- `granite daemon start` runs MCP + web UI in one background process
|
|
213
|
+
claude mcp add --transport http granite https://<your-sprite>.sprites.app/mcp \
|
|
214
|
+
--header "Authorization: Bearer <token>"
|
|
215
|
+
```
|
|
179
216
|
|
|
180
|
-
|
|
217
|
+
Multiple named instances, bulk upgrades, token rotation, and self-hosting the HTTP MCP server (a generic `Dockerfile` is included) are covered in [docs/DEPLOY.md](docs/DEPLOY.md).
|
|
181
218
|
|
|
182
|
-
|
|
219
|
+
**Sync, without a relay.** Direct machine-to-machine over LAN, Tailscale, or a private DNS name — with per-device read/write tokens:
|
|
183
220
|
|
|
184
221
|
```bash
|
|
185
|
-
#
|
|
186
|
-
granite sync access grant ipad --role read
|
|
187
|
-
granite sync access grant desktop --role write
|
|
222
|
+
granite sync access grant ipad --role read # on the serving machine
|
|
188
223
|
granite sync serve --host 0.0.0.0 --port 8765
|
|
189
224
|
|
|
190
|
-
# Read-only Machine B
|
|
191
225
|
granite sync remote add macbook http://100.x.y.z:8765 --token <read-token>
|
|
192
|
-
granite sync pull macbook
|
|
193
226
|
granite sync watch macbook --direction pull --interval 30
|
|
194
|
-
|
|
195
|
-
# Write-capable Machine C
|
|
196
|
-
granite sync remote add macbook http://100.x.y.z:8765 --token <write-token>
|
|
197
|
-
granite sync run macbook
|
|
198
|
-
granite sync watch macbook --interval 30
|
|
199
227
|
```
|
|
200
228
|
|
|
201
|
-
|
|
229
|
+
Conflict policies, push/pull details, and access management live in [docs/SYNC.md](docs/SYNC.md).
|
|
202
230
|
|
|
203
|
-
|
|
204
|
-
granite sync config --policy primary-wins --primary-this-device
|
|
205
|
-
```
|
|
231
|
+
## The full CLI
|
|
206
232
|
|
|
207
|
-
|
|
233
|
+
<details>
|
|
234
|
+
<summary><b>Every command, one line each</b></summary>
|
|
208
235
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
granite
|
|
212
|
-
|
|
236
|
+
| Layer | Command | What it does |
|
|
237
|
+
|------------|----------------------------|------------------------------------------------------------------|
|
|
238
|
+
| setup | `granite init` | create a vault (optionally from a `--template`) |
|
|
239
|
+
| setup | `granite status` | vault health and what to do next |
|
|
240
|
+
| capture | `granite new <title>` | create a typed note |
|
|
241
|
+
| capture | `granite add [text]` | quick raw capture (arg or stdin) into the inbox |
|
|
242
|
+
| capture | `granite attach <file>` | attach an image/video/PDF and get markdown to embed |
|
|
243
|
+
| capture | `granite extract <file>` | raw text from PDF/DOCX/XLSX/PPTX without importing |
|
|
244
|
+
| capture | `granite import <file> --content <text>` | attach a document and create a linked source note |
|
|
245
|
+
| query | `granite list` | browse notes by type, status, source, date |
|
|
246
|
+
| query | `granite show <slug>` | read a full note |
|
|
247
|
+
| query | `granite search <query>` | full-text search across the vault |
|
|
248
|
+
| query | `granite open <slug>` | open a note in `$EDITOR` |
|
|
249
|
+
| query | `granite wakeup` | compact vault snapshot for loading agent context |
|
|
250
|
+
| compile | `granite edit <slug>` | update fields, body, tags, protocol state |
|
|
251
|
+
| compile | `granite backlinks <slug>` | inbound links to a note |
|
|
252
|
+
| compile | `granite suggest-links <slug>` | unlinked mentions worth linking |
|
|
253
|
+
| compile | `granite recommend <slug>` | what to link, tag, or write next |
|
|
254
|
+
| lint | `granite doctor` | broken links, missing fields, stale notes, line violations |
|
|
255
|
+
| lint | `granite types` | show note types and the flow between them |
|
|
256
|
+
| serve | `granite serve` | local web UI with the constellation graph (port 4321) |
|
|
257
|
+
| serve | `granite mcp` | MCP server (stdio or HTTP; `--role read\|write`) |
|
|
258
|
+
| serve | `granite daemon start` | MCP + web UI as one background process |
|
|
259
|
+
| cloud | `granite deploy …` | serverless instances on Fly.io Sprites ([docs](docs/DEPLOY.md)) |
|
|
260
|
+
| sync | `granite sync …` | direct multi-device sync ([docs](docs/SYNC.md)) |
|
|
213
261
|
|
|
214
|
-
|
|
262
|
+
Run `granite --help` for every flag.
|
|
215
263
|
|
|
216
|
-
|
|
264
|
+
</details>
|
|
217
265
|
|
|
218
|
-
|
|
266
|
+
## FAQ
|
|
219
267
|
|
|
220
|
-
|
|
268
|
+
<details>
|
|
269
|
+
<summary><b>Is this an Obsidian replacement?</b></summary>
|
|
221
270
|
|
|
222
|
-
|
|
271
|
+
No. Your vault is plain markdown with `[[wikilinks]]` — Obsidian opens it just fine. Granite adds the typed contracts, the deterministic index, and the MCP surface on top of files any editor can read.
|
|
223
272
|
|
|
224
|
-
|
|
273
|
+
</details>
|
|
225
274
|
|
|
226
|
-
|
|
275
|
+
<details>
|
|
276
|
+
<summary><b>Where's the AI?</b></summary>
|
|
227
277
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
>
|
|
231
|
-
|
|
232
|
-
>
|
|
278
|
+
In your agent. Granite is deliberately deterministic — that's precisely why an agent can be trusted with write access to it.
|
|
279
|
+
|
|
280
|
+
</details>
|
|
281
|
+
|
|
282
|
+
<details>
|
|
283
|
+
<summary><b>No embeddings — how does search work?</b></summary>
|
|
284
|
+
|
|
285
|
+
SQLite FTS5 for full text, typed queries over indexed fields, and the wikilink graph for structure. Deterministic, explainable, and rebuildable from the files.
|
|
286
|
+
|
|
287
|
+
</details>
|
|
288
|
+
|
|
289
|
+
<details>
|
|
290
|
+
<summary><b>Can I use it without an agent?</b></summary>
|
|
291
|
+
|
|
292
|
+
Yes. The full CLI and the web UI work standalone. The MCP server is one door among three.
|
|
293
|
+
|
|
294
|
+
</details>
|
|
295
|
+
|
|
296
|
+
<details>
|
|
297
|
+
<summary><b>What happens to my data if Granite disappears?</b></summary>
|
|
298
|
+
|
|
299
|
+
Nothing. It's a folder of markdown files. The index is derived and disposable; `git init` the vault and you have versioning and backup for free.
|
|
300
|
+
|
|
301
|
+
</details>
|
|
302
|
+
|
|
303
|
+
<details>
|
|
304
|
+
<summary><b>Does anything phone home?</b></summary>
|
|
305
|
+
|
|
306
|
+
No. No telemetry, no account, no network calls — unless you explicitly deploy to your own sprite, sync to your own machines, or run `granite serve` with cloud credentials configured (use `--no-cloud` to stay fully offline).
|
|
307
|
+
|
|
308
|
+
</details>
|
|
233
309
|
|
|
234
310
|
## Philosophy
|
|
235
311
|
|
|
@@ -240,6 +316,12 @@ For local development, read [CLAUDE.md](CLAUDE.md). The key product rule is simp
|
|
|
240
316
|
- protocol belongs in the core; **agent policy belongs outside it**
|
|
241
317
|
- a personal OS is a thing you own — not a thing you rent
|
|
242
318
|
|
|
319
|
+
## Status & contributing
|
|
320
|
+
|
|
321
|
+
Granite is pre-1.0 and moving fast — see [CHANGELOG.md](CHANGELOG.md) for release history. The product boundary stays fixed: Granite stores and indexes local knowledge; agents bring the intelligence.
|
|
322
|
+
|
|
323
|
+
Issues and focused PRs are welcome. For local development, read [CLAUDE.md](CLAUDE.md). The key product rule is simple: no embedded LLM, no vector store, no autonomous scheduler inside Granite.
|
|
324
|
+
|
|
243
325
|
---
|
|
244
326
|
|
|
245
327
|
<p align="center">
|