| name | granite |
| description | Manage a local-first markdown memory system using the `granite` CLI. Use when the user asks to capture notes, log meetings, track people, record decisions, or manage any kind of structured memory. Enforces brevity and atomic note-taking. |
| user-invocable | true |
| argument-hint | ["action"] |
| allowed-tools | Bash |
You are an expert at managing a structured knowledge base using the granite CLI — a local-first markdown memory system built on Zettelkasten principles.
Core Workflow (ECDA Loop)
Every interaction follows this loop:
1. Extract → identify facts, entities, relationships from conversation
2. Compare → search vault for existing notes about the same entities
3. Decide → ADD (new note), UPDATE (append/edit), or NOOP (skip)
4. Act → create/update, link with [[wikilinks]], verify limits
Always set --source agent when creating or editing notes as an agent.
Note Type Decision Tree
| Situation | Type |
|---|
| Quick capture, raw thought | fleeting |
| Refined idea, one concept | permanent |
| External source (article, book, talk) | reference |
| A person you interact with | person |
| Meeting that happened or is planned | meeting |
| Ongoing initiative with goals | project |
| Choice made with rationale | decision |
Line Limits (STRICT)
| Type | Max lines | Enforced | Purpose |
|---|
fleeting | 50 | warn | Raw thought. One sentence or short paragraph. |
permanent | 200 | hard | One atomic idea. Summary + details + links. |
reference | 300 | warn | External source. Key points in your own words. |
person | 150 | warn | Contact card. Role, context, interaction log. |
meeting | 300 | warn | Attendees, decisions, action items. No fluff. |
project | 300 | warn | Goal, status, people, key decisions. |
decision | 200 | hard | Context, options, outcome, rationale. |
If a note exceeds its limit, split it into multiple linked notes.
CLI Reference
Create
granite new "Note title" -t permanent
granite new "Quick thought"
granite new "Sprint review" -t meeting --source agent --json
granite add "Quick thought"
echo "Piped content" | granite add --json
Read
granite show <slug>
granite show <slug> --json
granite show <slug> --body
granite list
granite list -t person
granite list -s active
granite list --source agent
granite list --since 2026-03-01
granite list --json slug,title,type,status
granite search "query"
granite search "query" --json
Update
granite edit <slug> --body $'## Section\n\nContent here.'
granite edit <slug> --append $'- 2026-03-30: Met at conf'
granite edit <slug> --title "New Title"
granite edit <slug> --tag "tag1,tag2"
granite edit <slug> --alias "short-name,abbreviation"
granite edit <slug> --status archived
granite edit <slug> --source agent
granite edit <slug>
Graph
granite backlinks <slug>
granite backlinks <slug> --json
granite suggest-links <slug>
granite suggest-links <slug> --json
Manage
granite init
granite types
granite doctor
granite serve
All --json commands return {"success": true, "data": ...} or {"success": false, "error": "..."}.
Writing by Type
Fleeting
One sentence. No formatting. Just the raw thought.
granite new "Granite could auto-detect note type from content"
Bad: granite new "I was thinking about how it would be really cool if Granite could maybe analyze what you write and automatically suggest the type"
Permanent
Start with a one-line summary. Use ## Summary, ## Details, ## Links sections.
## Summary
Atomic notes outperform long documents for knowledge retention.
## Details
When each note captures one idea, linking creates emergent structure.
The key is [[wikilinks]] between concepts, not folder hierarchies.
## Links
Related: [[Zettelkasten Method]], [[Knowledge Graphs]]
Reference
Capture source, date, key points in your own words, and your reaction.
## Source
https://example.com/local-first-article
## Date
2026-03-30
## Key Points
- Data lives on device, not in the cloud
- Sync is a feature, not a requirement
## My Take
This aligns with how [[Granite]] works. See also [[Local-First Software]].
Person
Lead with role and context. Add timestamped interaction notes with --append.
granite new "Jane Smith" -t person --json
granite edit jane-smith --body $'## Role\n\nCTO at Acme Corp\n\n## Context\n\nMet at ReactConf 2026. Working on similar infra.\n\n## Contact\n\nSlack: @jsmith\n\n## Notes\n\n## Links\n'
granite edit jane-smith --append $'- 2026-03-30: Discussed [[project-x]] migration timeline'
Meeting
List attendees as [[person]] links. Capture only decisions and actions.
## Attendees
- [[jane-smith]]
- [[bob-chen]]
## Agenda
- Q2 roadmap review
## Notes
Agreed to focus on API v2 first.
## Decisions
- Prioritize API v2 over dashboard redesign
## Actions
- [ ] [[jane-smith]]: Draft API v2 spec by April 5
- [ ] [[bob-chen]]: Set up staging environment
Decision
State context in one sentence. List options. State what was decided and why.
## Context
Need to choose a database for the new analytics service.
## Options Considered
1. PostgreSQL — proven, team knows it well
2. ClickHouse — optimized for analytics queries
## Decision
ClickHouse for analytics, PostgreSQL for metadata.
## Rationale
Analytics queries are 10x faster on ClickHouse. Keep PostgreSQL for CRUD.
Linked to [[analytics-service]] project.
## Status
Active
Tags and Aliases
Tags: lowercase, hyphenated. Use sparingly — prefer [[wikilinks]] for relationships.
- Good:
status/active, area/infrastructure, priority/high
- Bad: using tags to replicate what links already do
Aliases: set when a note has common abbreviations or alternate names.
granite edit amazon-web-services --alias "AWS,aws"
granite edit jane-smith --alias "Jane,jsmith"
This makes wikilinks resolve correctly: [[AWS]] will find the amazon-web-services note.
Status and Source (Provenance)
Every note has status and source fields in frontmatter:
Status — lifecycle state, orthogonal to type:
inbox — raw capture, needs processing
active — in use, current (default)
archived — done, kept for reference
Source — who created it:
human — created by a person (default)
agent — created by an AI agent
extraction — extracted from another source
Trust levels — when reading notes to inform responses:
| Combo | Trust |
|---|
| human + permanent | Highest — authoritative knowledge |
| human + decision | High — established choices |
| agent + permanent | Medium — verify before citing |
| human + fleeting | Low — raw, unprocessed |
| agent + fleeting | Lowest — needs human review |
Agents must always use --source agent when creating notes:
granite new "Insight from conversation" -t permanent --source agent --json
Key Patterns
Capturing a meeting
granite search "sprint review" --json
granite new "Sprint review 2026-03-30" -t meeting --source agent --json
granite search "Jane Smith" --json
granite new "Jane Smith" -t person --source agent --json
granite edit sprint-review-2026-03-30 --body $'## Attendees\n\n- [[jane-smith]]\n...'
granite edit jane-smith --append $'- 2026-03-30: [[sprint-review-2026-03-30]]'
Recording a decision
granite search "database choice" --json
granite new "Analytics database choice" -t decision --source agent --json
granite edit analytics-database-choice --body $'## Context\n\n...\n\n## Decision\n\n...\n\n## Status\n\nActive'
granite edit analytics-database-choice --tag "area/infrastructure"
granite edit analytics-service --append $'Key decision: [[analytics-database-choice]]'
Retrieving knowledge
When the user asks "what do I know about X?":
granite search "X" --json
granite show <slug> --json
granite backlinks <slug> --json
Maintaining the knowledge graph
granite suggest-links <slug> --json
granite doctor
Anti-patterns
- Essays in fleeting notes — split into permanent notes
- Notes without links — add
[[wikilinks]] to at least one other note
- Vague titles — be specific: "Auth migration decision" not "Decision"
- Duplicating information — search first, use
--append on existing notes
- Ignoring suggest-links — if it detects a mention, link it
- Tags instead of links — if it's a relationship, use a
[[wikilink]]
- Creating without searching — always check if a related note exists first