@imunitic/synapse 0.4.1 → 0.4.3
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/Index.md.template +4 -4
- package/commands/synapse-design-note.md +22 -15
- package/commands/synapse-init.md +3 -3
- package/commands/synapse-note.md +1 -1
- package/commands/synapse-rebuild-diff.md +16 -16
- package/commands/synapse-rebuild-full.md +2 -2
- package/commands/synapse-task-note.md +6 -6
- package/commands/synapse-vault-tidy.md +10 -12
- package/harness/codex/skills/synapse-design-note/SKILL.md +27 -14
- package/harness/codex/skills/synapse-init/SKILL.md +3 -3
- package/harness/codex/skills/synapse-note/SKILL.md +3 -2
- package/harness/codex/skills/synapse-rebuild-diff/SKILL.md +15 -15
- package/harness/codex/skills/synapse-rebuild-full/SKILL.md +2 -2
- package/harness/codex/skills/synapse-task-note/SKILL.md +4 -4
- package/harness/codex/skills/synapse-vault-tidy/SKILL.md +10 -11
- package/package.json +5 -5
- package/skills/synapse-node/SKILL.md +14 -14
- package/skills/synapse-node-authoring/SKILL.md +2 -2
- package/skills/synapse-node-format/SKILL.md +10 -12
- package/skills/synapse-orientation/SKILL.md +2 -2
- package/skills/synapse-query/SKILL.md +4 -4
- package/skills/synapse-task/SKILL.md +3 -3
- package/skills/synapse-vault/SKILL.md +23 -0
- package/synapse-claude.md +20 -28
- package/synapse-ignore-files.conf.template +6 -2
- package/synapse-module-boilerplate.conf.template +6 -3
- package/synapse-projects.conf.template +5 -1
- package/synapse-prompt-stopwords.conf.template +6 -2
- package/synapse.conf.template +6 -9
package/Index.md.template
CHANGED
|
@@ -3,20 +3,20 @@ title: "Index"
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Index
|
|
6
|
-
Map of the note folders and what each is for. This is the
|
|
6
|
+
Map of the note folders and what each is for. This is the second-brain vault, reached through the `synapse` CLI (see the Synapse repo's `CLAUDE.md`).
|
|
7
7
|
|
|
8
8
|
This index is agent-maintained: whenever an agent creates a new top-level folder (folder depth is capped at two levels, i.e. `folder/subfolder`), it must add a one-line section for it here in the same edit. Treat this file as out of date if a folder exists on disk with no matching section below -- fix the drift rather than working around it.
|
|
9
9
|
|
|
10
10
|
This is a starter index, not a fixed schema. `research/`, `scratchpad/`, and `inbox/` below are yours to rename, restructure, or drop -- an agent reads this file as the authority on what your folders are and mean, not the other way around. `designs/`, `tasks/`, and `synapse/` aren't listed yet because nothing has created one on this vault -- `/synapse-design-note`, `/synapse-task-note`, and `/synapse-init` each add their own section here the first time they actually create that folder.
|
|
11
11
|
|
|
12
12
|
## research/
|
|
13
|
-
Standalone research/reading notes -- general research about a topic, project-related or not: language features, library evaluations, design patterns, reference material. Filenames are plain, human-readable titles.
|
|
13
|
+
Standalone research/reading notes -- general research about a topic, project-related or not: language features, library evaluations, design patterns, reference material. Filenames are plain, human-readable titles. Created via `/synapse-note` (bare mode), which declares `schema: vault-note/v1`.
|
|
14
14
|
|
|
15
15
|
## scratchpad/
|
|
16
|
-
Notes for iterating on an idea just to see whether it works -- high-churn and exploratory, not yet worth filing under a settled category. A note here has a high chance of either being moved into a proper folder once it solidifies, or being deleted wholesale once the idea is settled one way or the other. Filenames are plain, human-readable titles.
|
|
16
|
+
Notes for iterating on an idea just to see whether it works -- high-churn and exploratory, not yet worth filing under a settled category. A note here has a high chance of either being moved into a proper folder once it solidifies, or being deleted wholesale once the idea is settled one way or the other. Filenames are plain, human-readable titles. Created via `/synapse-note` (bare mode), which declares `schema: vault-note/v1`.
|
|
17
17
|
|
|
18
18
|
## inbox/
|
|
19
|
-
A staging area for notes that need more input or reflection before they're settled -- most often the result of being asked to find something and write it down as a note, without yet knowing where it properly belongs, or that otherwise don't cleanly fit `research/` or `scratchpad/`. Filenames are plain, human-readable titles, same as every other folder -- no numbering scheme. Review periodically and move settled notes into a proper category; this folder is meant to stay small.
|
|
19
|
+
A staging area for notes that need more input or reflection before they're settled -- most often the result of being asked to find something and write it down as a note, without yet knowing where it properly belongs, or that otherwise don't cleanly fit `research/` or `scratchpad/`. Filenames are plain, human-readable titles, same as every other folder -- no numbering scheme. Created via `/synapse-note` (bare mode), which declares `schema: vault-note/v1`. Review periodically and move settled notes into a proper category; this folder is meant to stay small.
|
|
20
20
|
|
|
21
21
|
A second kind of note also lives here: standalone ideas that surface mid-discussion (with you, or an agent reasoning out loud) and are worth keeping without yet warranting a full design note of their own -- a small, self-contained "worth doing someday" item rather than an open question tied to a bigger design. Filenames are plain, human-readable titles like any other inbox note. Loosely ticket-shaped (a one-line summary, why it came up, rough acceptance criteria) is a fine, optional format for these -- not a requirement, just a convenient shape for something meant to be picked up and acted on later.
|
|
22
22
|
|
|
@@ -31,10 +31,10 @@ Not every design discussion ends with something to build. See `Status: Reference
|
|
|
31
31
|
|
|
32
32
|
## Determining the project
|
|
33
33
|
|
|
34
|
-
Every design note
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
Every design note records the project it belongs to as `project: {prefix}` in frontmatter (the
|
|
35
|
+
same short prefix `/synapse-note --task` uses for task IDs) — that field also decides the note's
|
|
36
|
+
`designs/{project}/` subfolder, so design notes and task notes can be filtered together via
|
|
37
|
+
`synapse vault-search`. The title itself is plain `{Topic}` — no project prefix, no id.
|
|
38
38
|
|
|
39
39
|
Same resolution `/synapse-note` uses for a missing task ID (its "Resolving a missing task ID"),
|
|
40
40
|
reading the same file:
|
|
@@ -56,7 +56,7 @@ reading the same file:
|
|
|
56
56
|
check both fields (`synapse vault-search --fields frontmatter.task_id,frontmatter.note_id`, filter
|
|
57
57
|
both for `{prefix}-\d+`, take the highest number found across both, add 1; start at 1 if none exist
|
|
58
58
|
yet). This is frontmatter only — unlike a task note, a design note's title and filename stay
|
|
59
|
-
exactly `{
|
|
59
|
+
exactly `{Topic}`, with no id and no project prefix prepended.
|
|
60
60
|
|
|
61
61
|
Never hardcode a specific project/prefix pair in this command's own instructions — the conf file is
|
|
62
62
|
machine-local and deliberately outside the portable Synapse package, so projects from
|
|
@@ -156,11 +156,11 @@ judgment call, not the automatic result of an `## Approach` section existing. Be
|
|
|
156
156
|
blocking question is fine to carry forward), but a note with a *blocking* open question is not
|
|
157
157
|
`Ready`, no matter how developed the rest of it is.
|
|
158
158
|
|
|
159
|
-
- **Both hold** → `Status: Ready`. Confirm: "Design note ready: `designs/{title}.md`.
|
|
159
|
+
- **Both hold** → `Status: Ready`. Confirm: "Design note ready: `designs/{project}/{title}.md`.
|
|
160
160
|
Whenever you're ready to implement, generate the task with
|
|
161
161
|
`/synapse-task-note \"{topic}\"` — no rush, nothing here expires."
|
|
162
162
|
- **Genuinely nothing to build** → `Status: Reference`. Confirm: "Design note concluded as
|
|
163
|
-
Reference: `designs/{title}.md`. No task note needed."
|
|
163
|
+
Reference: `designs/{project}/{title}.md`. No task note needed."
|
|
164
164
|
- **Anything else** (the approach is still hedged, or an open question blocks it) → stays
|
|
165
165
|
`Status: Discussing`. This is the default outcome, not a fallback to apologize for — most
|
|
166
166
|
conversations end here, and that's fine; nothing here expires either.
|
|
@@ -178,7 +178,7 @@ so the `## Status` line is the only lifecycle marker that matters. It simply sta
|
|
|
178
178
|
```
|
|
179
179
|
---
|
|
180
180
|
schema: vault-design-note/v1
|
|
181
|
-
title: "{
|
|
181
|
+
title: "{Topic}"
|
|
182
182
|
project: {prefix}
|
|
183
183
|
note_id: {id}
|
|
184
184
|
created: "{now}"
|
|
@@ -186,7 +186,7 @@ updated: "{now}"
|
|
|
186
186
|
tags: [{comma-separated configured tags, or empty}]
|
|
187
187
|
---
|
|
188
188
|
|
|
189
|
-
# {
|
|
189
|
+
# {Topic}
|
|
190
190
|
|
|
191
191
|
## Status
|
|
192
192
|
Discussing | Ready | Reference
|
|
@@ -197,16 +197,21 @@ Discussing | Ready | Reference
|
|
|
197
197
|
## Approach
|
|
198
198
|
{Chosen approach}
|
|
199
199
|
|
|
200
|
-
### Alternatives considered
|
|
200
|
+
### Alternatives considered
|
|
201
201
|
- {Option}: why not
|
|
202
202
|
|
|
203
203
|
## Constraints
|
|
204
204
|
{Hard constraints, non-negotiables}
|
|
205
205
|
|
|
206
|
-
## Open Questions
|
|
206
|
+
## Open Questions
|
|
207
207
|
- {Anything deferred or unresolved}
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
+
`### Alternatives considered` and `## Open Questions` are both optional per the schema — omit
|
|
211
|
+
either section entirely rather than leaving it as an empty heading, and never write it as `##
|
|
212
|
+
Open Questions (optional)`: the schema and `/synapse-status`'s own query both match this exact
|
|
213
|
+
heading text, and a suffixed one is invisible to both.
|
|
214
|
+
|
|
210
215
|
Any string scalar that is all digits (e.g. a numeric-looking title) must be quoted: an
|
|
211
216
|
unquoted all-digit value is parsed as an integer, which fails a `type: string` schema
|
|
212
217
|
field. `title`, `project`, `note_id`, and both timestamps are quoted above.
|
|
@@ -220,8 +225,10 @@ edit history here worth tracking separately.
|
|
|
220
225
|
|
|
221
226
|
## Filename
|
|
222
227
|
|
|
223
|
-
`designs/{
|
|
224
|
-
|
|
228
|
+
`designs/{project}/{Topic}.md` — grouped one level deeper into a per-project
|
|
229
|
+
subfolder named by the note's own `project:` frontmatter value (e.g. `designs/eon/`,
|
|
230
|
+
`designs/synapse/`), the same mapping `tasks/{project}/` uses. Sanitize filesystem-illegal
|
|
231
|
+
characters (`/ : * ? " < > |`). No slug, no numbering — vault filenames are the title itself.
|
|
225
232
|
|
|
226
233
|
---
|
|
227
234
|
|
|
@@ -242,12 +249,12 @@ Claude: [searches designs/ for existing matches — none found]
|
|
|
242
249
|
|
|
243
250
|
User: Replacing the AggregatingMergeTree rollup resolution with direct-value storage.
|
|
244
251
|
|
|
245
|
-
Claude: [creates designs/{
|
|
252
|
+
Claude: [creates designs/{project}/Rollup direct storage.md, Status: Discussing]
|
|
246
253
|
|
|
247
254
|
What's driving this over just tuning the current argMaxMerge query?
|
|
248
255
|
...
|
|
249
256
|
User: The resolution cost alone dominates the query, tuning won't fix that. Mark it ready.
|
|
250
257
|
|
|
251
|
-
Claude: Design note ready: designs/{
|
|
258
|
+
Claude: Design note ready: designs/{project}/Rollup direct storage.md.
|
|
252
259
|
Generate the task with /synapse-task-note "rollup direct storage" whenever you're ready.
|
|
253
260
|
```
|
package/commands/synapse-init.md
CHANGED
|
@@ -100,7 +100,7 @@ yours and cannot be scripted because what counts as signal differs per codebase.
|
|
|
100
100
|
**The work directory** defaults to `~/.cache/synapse/work/{repo}@{branch}/`, created on demand, and
|
|
101
101
|
holds `manifest.tsv`, `all.txt`, `lists/`, the authored `b-NN.md` bodies and the coverage files. Override with `$SYNAPSE_WORK_DIR` if you need to. Two things never to do: point it
|
|
102
102
|
at the repo (`synapse` runs from inside the repo, so its working files would land in the user's
|
|
103
|
-
checkout) or at the vault (
|
|
103
|
+
checkout) or at the vault (a file list that runs to six figures of lines has no business inside it).
|
|
104
104
|
It is deliberately persistent rather than a temp dir, so a later run finds the previous manifest
|
|
105
105
|
instead of re-deriving the clustering.
|
|
106
106
|
- **Interpretation (only you can do this):** deciding what the nodes *are*, and writing their prose.
|
|
@@ -289,8 +289,8 @@ emit into tool calls than read into a window. Never hand-author those.
|
|
|
289
289
|
**Then verify, before reporting success.** Three checks, all cheap:
|
|
290
290
|
- `synapse query stale` must print nothing. (40s for a 125k-file namespace.)
|
|
291
291
|
- Every `[[wikilink]]` in the namespace must resolve to a file that exists — extract them all and
|
|
292
|
-
test `-f "$link.md"`. Nothing else catches a broken link
|
|
293
|
-
|
|
292
|
+
test `-f "$link.md"`. Nothing else catches a broken link -- a wikilink to a note that does not
|
|
293
|
+
exist yet just fails silently.
|
|
294
294
|
- Every node file must appear in `Index.md`. An unlisted node exists but is invisible to a reader.
|
|
295
295
|
|
|
296
296
|
```yaml
|
package/commands/synapse-note.md
CHANGED
|
@@ -13,7 +13,7 @@ If `$ARGUMENTS` starts with `--search` → **search mode**: see "Search mode" be
|
|
|
13
13
|
Otherwise, split `$ARGUMENTS` on `--task`:
|
|
14
14
|
|
|
15
15
|
- If `--task` is present → **task mode**: scaffold the note as a tracked task, following the `synapse-task` skill's conventions. Task notes always live under `tasks/`.
|
|
16
|
-
- Otherwise → **bare mode**: create an empty node (title + frontmatter only). Which category folder it lands in is resolved from `Index.md`, per "Choosing a category (bare mode only)" below — not a fixed set.
|
|
16
|
+
- Otherwise → **bare mode**: create an empty node (title + frontmatter only). Which category folder it lands in is resolved from `Index.md`, per "Choosing a category (bare mode only)" below — not a fixed set. The typical categories are `research/`, `scratchpad/`, or `inbox/` — any plain note that isn't a task or design note.
|
|
17
17
|
|
|
18
18
|
The title is everything before `--task` (trimmed). Example:
|
|
19
19
|
|
|
@@ -97,8 +97,8 @@ this command when it does. What no longer happens is arriving here merely becaus
|
|
|
97
97
|
### 1. Size the job before doing any of it
|
|
98
98
|
|
|
99
99
|
```sh
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
synapse query drift
|
|
101
|
+
synapse query grounding
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
Report what it says, in the human's terms, **before** touching anything: how far the baseline is from
|
|
@@ -118,7 +118,7 @@ Two answers change the plan:
|
|
|
118
118
|
### 2. Mechanical phase — always, and cheap
|
|
119
119
|
|
|
120
120
|
```sh
|
|
121
|
-
|
|
121
|
+
synapse build-lists --reenumerate
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
`--reenumerate` matters here: without it an existing `all.txt` is reused, so a branch switch would be
|
|
@@ -136,7 +136,7 @@ move a lot and some may reach zero.
|
|
|
136
136
|
Then rebuild the reverse index so the hook and the read path agree with the new enumeration:
|
|
137
137
|
|
|
138
138
|
```sh
|
|
139
|
-
|
|
139
|
+
synapse build-index
|
|
140
140
|
```
|
|
141
141
|
|
|
142
142
|
### 3. Triage each flagged node — reseat, patch, or re-orient
|
|
@@ -193,8 +193,8 @@ straight back stores a quote of a file as it looked at the old baseline, present
|
|
|
193
193
|
current. So rebuild the directive from the pointer the writer recorded:
|
|
194
194
|
|
|
195
195
|
```sh
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
synapse query field "{Node}" crux_path
|
|
197
|
+
synapse query field "{Node}" crux_lines
|
|
198
198
|
```
|
|
199
199
|
|
|
200
200
|
and replace the fenced block with `<!-- crux: <crux_path> <crux_lines> -->` so it is cut from the
|
|
@@ -208,7 +208,7 @@ its directives are stripped from the body, so a recovered body contains none —
|
|
|
208
208
|
the node's provenance is gone with no error. Recover the pointers per node:
|
|
209
209
|
|
|
210
210
|
```sh
|
|
211
|
-
|
|
211
|
+
synapse query grounding "{Node}" --list # path<TAB>lines
|
|
212
212
|
```
|
|
213
213
|
|
|
214
214
|
and re-emit a `<!-- grounded_in: <path> <lines> -->` for each. Run `synapse query grounding` before
|
|
@@ -256,7 +256,7 @@ selection. Never pipe an unbounded `git diff <commit>..HEAD` into a context wind
|
|
|
256
256
|
### 4. Write each rebuilt node
|
|
257
257
|
|
|
258
258
|
```sh
|
|
259
|
-
|
|
259
|
+
synapse write-node --title "{Node}" --summary "{one line}" \
|
|
260
260
|
--paths "$W/lists/NN.txt" --body "$W/body.md"
|
|
261
261
|
```
|
|
262
262
|
|
|
@@ -267,17 +267,17 @@ not merely stale, if the subsystem's shape differs on this line.
|
|
|
267
267
|
### 5. Rebuild the projections and verify
|
|
268
268
|
|
|
269
269
|
```sh
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
270
|
+
synapse build-index
|
|
271
|
+
synapse build-project-index
|
|
272
|
+
synapse query drift # expect silence
|
|
273
|
+
synapse query stale # expect silence
|
|
274
|
+
synapse query grounding # expect silence: re-pointed, not dropped
|
|
275
|
+
synapse query links --check # expect silence: no dangling targets
|
|
276
276
|
```
|
|
277
277
|
|
|
278
278
|
`links --check` covers what used to be a manual instruction here: a broken `[[wikilink]]` is a valid
|
|
279
|
-
link to a not-yet-existing note,
|
|
280
|
-
|
|
279
|
+
link to a not-yet-existing note, silently, and nothing else in the system notices. It now reports
|
|
280
|
+
`Node<TAB>relation -> Target (no such node)` per dangling edge.
|
|
281
281
|
|
|
282
282
|
One check is still yours, because no command performs it: **every node file appears in `Index.md`**. An
|
|
283
283
|
unlisted node exists and is reachable by search, but is invisible to anyone reading the map.
|
|
@@ -54,7 +54,7 @@ Check whether `synapse/{repo}@{branch}/Index.md` exists.
|
|
|
54
54
|
### 2. Preview the wipe and get explicit confirmation
|
|
55
55
|
|
|
56
56
|
```sh
|
|
57
|
-
|
|
57
|
+
synapse graph-wipe --dry-run
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Report its output plainly: node count, and — the one thing this step exists to surface — how many
|
|
@@ -75,7 +75,7 @@ notes attached, which the human hasn't seen a number for yet.
|
|
|
75
75
|
Once confirmed:
|
|
76
76
|
|
|
77
77
|
```sh
|
|
78
|
-
|
|
78
|
+
synapse graph-wipe
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
This deletes `synapse/{repo}@{branch}/` and, if any node had non-empty `## Notes`, first dumps that
|
|
@@ -26,7 +26,7 @@ Use those instead of reinventing a parallel view.
|
|
|
26
26
|
|
|
27
27
|
## Prerequisites
|
|
28
28
|
|
|
29
|
-
- Requires a matching
|
|
29
|
+
- Requires a matching design note (`designs/`) with `Status: Ready`.
|
|
30
30
|
- No matching note → "No Ready design note found for '{topic}'. Run
|
|
31
31
|
`/synapse-design-note \"{topic}\"` first." Never generate a checklist from scratch.
|
|
32
32
|
- Matching note but `Status: Discussing` → "Design note for '{topic}' is still in Discussing. Finish
|
|
@@ -99,8 +99,8 @@ printf '> Compiled task: [[%s]]\n\n' "{task note title}" | \
|
|
|
99
99
|
|
|
100
100
|
A small annotation line, same idea as any other cross-reference you'd drop near a note's title. This
|
|
101
101
|
is a one-time link; the design note's `Status` itself does not change and does not need to track the
|
|
102
|
-
task's progress —
|
|
103
|
-
note's title
|
|
102
|
+
task's progress — a plain `synapse vault-search-text` for the task
|
|
103
|
+
note's title already surfaces the live task note from the design note, and
|
|
104
104
|
the task's `status:` frontmatter is the authoritative progress signal from here on.
|
|
105
105
|
|
|
106
106
|
## Confirm
|
|
@@ -122,7 +122,7 @@ command doesn't set or watch that field itself.
|
|
|
122
122
|
```
|
|
123
123
|
User: /synapse-task-note "rollup direct storage"
|
|
124
124
|
|
|
125
|
-
Claude: [reads designs/{
|
|
125
|
+
Claude: [reads designs/{project}/Rollup direct storage.md, Status: Ready]
|
|
126
126
|
[no existing linked task note]
|
|
127
127
|
|
|
128
128
|
Compiled checklist:
|
|
@@ -133,8 +133,8 @@ Claude: [reads designs/{PROJECT} — Rollup direct storage.md, Status: Ready]
|
|
|
133
133
|
|
|
134
134
|
Project already known: {PROJECT} → {prefix}-005.
|
|
135
135
|
|
|
136
|
-
Created: tasks/{
|
|
137
|
-
Linked back from designs/{
|
|
136
|
+
Created: tasks/{project}/Rollup direct storage implementation.md (task_id: {prefix}-005)
|
|
137
|
+
Linked back from designs/{project}/Rollup direct storage.md.
|
|
138
138
|
|
|
139
139
|
Status transitions happen automatically via the synapse-task skill once you start work.
|
|
140
140
|
```
|
|
@@ -29,15 +29,14 @@ of scope — foundational files, not taxonomy notes.
|
|
|
29
29
|
## Prerequisites
|
|
30
30
|
|
|
31
31
|
Requires the `synapse` CLI on `PATH`, resolving a vault with a working `LinkGraph`
|
|
32
|
-
(`synapse vault-backlinks`/`vault-links`/`vault-unresolved`/`vault-orphans`/`vault-deadends`
|
|
33
|
-
`
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
saying so; stop and report that rather than falling back to anything else.
|
|
32
|
+
(`synapse vault-backlinks`/`vault-links`/`vault-unresolved`/`vault-orphans`/`vault-deadends`).
|
|
33
|
+
`DiskStore`, the one real backend, always has one -- case-insensitive wikilink resolution over the
|
|
34
|
+
vault folder directly, no external dependency. If `SYNAPSE_VAULT_INTEGRATIONS` ever resolves to a
|
|
35
|
+
backend with no `LinkGraph` at all, these commands exit 1 saying so; stop and report that rather
|
|
36
|
+
than falling back to anything else.
|
|
38
37
|
|
|
39
38
|
This command reaches the vault store only through the `synapse` CLI's `vault-*` subcommands, the
|
|
40
|
-
same door every other skill uses — no MCP tool, no direct
|
|
39
|
+
same door every other skill uses — no MCP tool, no direct store call. `vault-links`/
|
|
41
40
|
`vault-backlinks` each answer for one note at a time, so Step 1's inventory sweep runs one pair per
|
|
42
41
|
note in scope: `2N` process spawns for an `N`-note vault. Acceptable for an on-demand, rare command.
|
|
43
42
|
Step 3's broken-link history check is a plain `git log` call (via Bash, not a compiled tool)
|
|
@@ -87,10 +86,9 @@ guessing:
|
|
|
87
86
|
- Missing `created` → `stat.ctime`, formatted `YYYY-MM-DD HH:MM` to match every other note's
|
|
88
87
|
convention.
|
|
89
88
|
|
|
90
|
-
Apply
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
the same hazard `synapse-vault`/`synapse-task` already document.
|
|
89
|
+
Apply with `synapse frontmatter set <path> <key> <value>` (or `vault-patch --frontmatter`, which
|
|
90
|
+
delegates to the same byte-preserving mechanism) — either writes exactly this one field and leaves
|
|
91
|
+
every other line untouched, the way `synapse-vault`/`synapse-task` already document.
|
|
94
92
|
|
|
95
93
|
## Step 3: Note-health findings (reported, not fixed)
|
|
96
94
|
|
|
@@ -200,4 +198,4 @@ Print a short summary directly in the response, not left only in tool-call outpu
|
|
|
200
198
|
under a `/loop` the user sets up themselves.
|
|
201
199
|
- Every step above goes through the `synapse` CLI's `vault-*` subcommands, or (Step 3's broken-link
|
|
202
200
|
history check only) a plain `git log` via Bash against the vault's own local repo; this command
|
|
203
|
-
never calls
|
|
201
|
+
never calls a store implementation directly.
|
|
@@ -38,10 +38,10 @@ There is no flag syntax here — read intent from how the user asks:
|
|
|
38
38
|
|
|
39
39
|
## Determining the project
|
|
40
40
|
|
|
41
|
-
Every design note
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
Every design note records the project it belongs to as `project: {prefix}` in frontmatter (the
|
|
42
|
+
same short prefix the synapse-note skill's task mode uses for task IDs) — that field also decides
|
|
43
|
+
the note's `designs/{project}/` subfolder, so design notes and task notes can be filtered together
|
|
44
|
+
via `synapse vault-search`. The title itself is plain `{Topic}` — no project prefix, no id.
|
|
45
45
|
|
|
46
46
|
Same resolution the synapse-note skill uses for a missing task ID (its "Resolving a missing task
|
|
47
47
|
ID"), reading the same file:
|
|
@@ -58,6 +58,12 @@ ID"), reading the same file:
|
|
|
58
58
|
4. If nothing confidently matches, ask the user for a short project tag — plain free-text, not a
|
|
59
59
|
multiple-choice list, never hinting at any other project's tag as an example — then append the
|
|
60
60
|
resolved pair to the conf file.
|
|
61
|
+
5. Once the prefix is known, mint the note's `note_id` the same shared-counter way the synapse-note
|
|
62
|
+
skill's "Resolving a missing task ID" step 6 does: `task_id` and `note_id` share one counter per
|
|
63
|
+
prefix, so check both fields (`synapse vault-search --fields frontmatter.task_id,frontmatter.note_id`,
|
|
64
|
+
filter both for `{prefix}-\d+`, take the highest number found across both, add 1; start at 1 if none
|
|
65
|
+
exist yet). This is frontmatter only — unlike a task note, a design note's title and filename stay
|
|
66
|
+
exactly `{Topic}`, with no id and no project prefix prepended.
|
|
61
67
|
|
|
62
68
|
Never hardcode a specific project/prefix pair in this skill's own instructions — the conf file is
|
|
63
69
|
machine-local and deliberately outside the portable Synapse package, so projects from
|
|
@@ -157,11 +163,11 @@ judgment call, not the automatic result of an `## Approach` section existing. Be
|
|
|
157
163
|
blocking question is fine to carry forward), but a note with a *blocking* open question is not
|
|
158
164
|
`Ready`, no matter how developed the rest of it is.
|
|
159
165
|
|
|
160
|
-
- **Both hold** → `Status: Ready`. Confirm: "Design note ready: `designs/{title}.md`.
|
|
166
|
+
- **Both hold** → `Status: Ready`. Confirm: "Design note ready: `designs/{project}/{title}.md`.
|
|
161
167
|
Whenever you're ready to implement, ask me to compile it into a task note — no rush, nothing
|
|
162
168
|
here expires."
|
|
163
169
|
- **Genuinely nothing to build** → `Status: Reference`. Confirm: "Design note concluded as
|
|
164
|
-
Reference: `designs/{title}.md`. No task note needed."
|
|
170
|
+
Reference: `designs/{project}/{title}.md`. No task note needed."
|
|
165
171
|
- **Anything else** (the approach is still hedged, or an open question blocks it) → stays
|
|
166
172
|
`Status: Discussing`. This is the default outcome, not a fallback to apologize for — most
|
|
167
173
|
conversations end here, and that's fine; nothing here expires either.
|
|
@@ -179,7 +185,7 @@ so the `## Status` line is the only lifecycle marker that matters. It simply sta
|
|
|
179
185
|
```
|
|
180
186
|
---
|
|
181
187
|
schema: vault-design-note/v1
|
|
182
|
-
title: "{
|
|
188
|
+
title: "{Topic}"
|
|
183
189
|
project: {prefix}
|
|
184
190
|
note_id: {id}
|
|
185
191
|
created: "{now}"
|
|
@@ -187,7 +193,7 @@ updated: "{now}"
|
|
|
187
193
|
tags: [{comma-separated configured tags, or empty}]
|
|
188
194
|
---
|
|
189
195
|
|
|
190
|
-
# {
|
|
196
|
+
# {Topic}
|
|
191
197
|
|
|
192
198
|
## Status
|
|
193
199
|
Discussing | Ready | Reference
|
|
@@ -198,16 +204,21 @@ Discussing | Ready | Reference
|
|
|
198
204
|
## Approach
|
|
199
205
|
{Chosen approach}
|
|
200
206
|
|
|
201
|
-
### Alternatives considered
|
|
207
|
+
### Alternatives considered
|
|
202
208
|
- {Option}: why not
|
|
203
209
|
|
|
204
210
|
## Constraints
|
|
205
211
|
{Hard constraints, non-negotiables}
|
|
206
212
|
|
|
207
|
-
## Open Questions
|
|
213
|
+
## Open Questions
|
|
208
214
|
- {Anything deferred or unresolved}
|
|
209
215
|
```
|
|
210
216
|
|
|
217
|
+
`### Alternatives considered` and `## Open Questions` are both optional per the schema — omit
|
|
218
|
+
either section entirely rather than leaving it as an empty heading, and never write it as `##
|
|
219
|
+
Open Questions (optional)`: the schema and `/synapse-status`'s own query both match this exact
|
|
220
|
+
heading text, and a suffixed one is invisible to both.
|
|
221
|
+
|
|
211
222
|
Resolve tags through the `synapse-vault` skill's configured vocabulary procedure. Fetch machine
|
|
212
223
|
local time once (`date '+%Y-%m-%d %H:%M:%S %Z'`) — never infer it — and use the exact same value
|
|
213
224
|
for `created` and `updated`.
|
|
@@ -217,8 +228,10 @@ edit history here worth tracking separately.
|
|
|
217
228
|
|
|
218
229
|
## Filename
|
|
219
230
|
|
|
220
|
-
`designs/{
|
|
221
|
-
|
|
231
|
+
`designs/{project}/{Topic}.md` — grouped one level deeper into a per-project
|
|
232
|
+
subfolder named by the note's own `project:` frontmatter value (e.g. `designs/eon/`,
|
|
233
|
+
`designs/synapse/`), the same mapping tasks use. Sanitize filesystem-illegal
|
|
234
|
+
characters (`/ : * ? " < > |`). No slug, no numbering — vault filenames are the title itself.
|
|
222
235
|
|
|
223
236
|
---
|
|
224
237
|
|
|
@@ -239,12 +252,12 @@ Codex: [searches designs/ for existing matches — none found]
|
|
|
239
252
|
|
|
240
253
|
User: Replacing the AggregatingMergeTree rollup resolution with direct-value storage.
|
|
241
254
|
|
|
242
|
-
Codex: [creates designs/{
|
|
255
|
+
Codex: [creates designs/{project}/Rollup direct storage.md, Status: Discussing]
|
|
243
256
|
|
|
244
257
|
What's driving this over just tuning the current argMaxMerge query?
|
|
245
258
|
...
|
|
246
259
|
User: The resolution cost alone dominates the query, tuning won't fix that. Mark it ready.
|
|
247
260
|
|
|
248
|
-
Codex: Design note ready: designs/{
|
|
261
|
+
Codex: Design note ready: designs/{project}/Rollup direct storage.md.
|
|
249
262
|
Ask me to compile the task note whenever you're ready to implement.
|
|
250
263
|
```
|
|
@@ -100,7 +100,7 @@ yours and cannot be scripted because what counts as signal differs per codebase.
|
|
|
100
100
|
**The work directory** defaults to `~/.cache/synapse/work/{repo}@{branch}/`, created on demand, and
|
|
101
101
|
holds `manifest.tsv`, `all.txt`, `lists/`, the authored `b-NN.md` bodies and the coverage files. Override with `$SYNAPSE_WORK_DIR` if you need to. Two things never to do: point it
|
|
102
102
|
at the repo (`synapse` runs from inside the repo, so its working files would land in the user's
|
|
103
|
-
checkout) or at the vault (
|
|
103
|
+
checkout) or at the vault (a file list that runs to six figures of lines has no business inside it).
|
|
104
104
|
It is deliberately persistent rather than a temp dir, so a later run finds the previous manifest
|
|
105
105
|
instead of re-deriving the clustering.
|
|
106
106
|
- **Interpretation (only you can do this):** deciding what the nodes *are*, and writing their prose.
|
|
@@ -289,8 +289,8 @@ emit into tool calls than read into a window. Never hand-author those.
|
|
|
289
289
|
**Then verify, before reporting success.** Three checks, all cheap:
|
|
290
290
|
- `synapse query stale` must print nothing. (40s for a 125k-file namespace.)
|
|
291
291
|
- Every `[[wikilink]]` in the namespace must resolve to a file that exists — extract them all and
|
|
292
|
-
test `-f "$link.md"`. Nothing else catches a broken link
|
|
293
|
-
|
|
292
|
+
test `-f "$link.md"`. Nothing else catches a broken link -- a wikilink to a note that does not
|
|
293
|
+
exist yet just fails silently.
|
|
294
294
|
- Every node file must appear in `Index.md`. An unlisted node exists but is invisible to a reader.
|
|
295
295
|
|
|
296
296
|
```yaml
|
|
@@ -27,7 +27,8 @@ below:
|
|
|
27
27
|
- **Asking to create any other note** ("make a note about X", "save this as a note") → **bare
|
|
28
28
|
mode**: create an empty node (title + frontmatter only). Which category folder it lands in is
|
|
29
29
|
resolved from the vault's index note, per "Choosing a category (bare mode only)" below — not a
|
|
30
|
-
fixed set.
|
|
30
|
+
fixed set. The typical categories are `research/`, `scratchpad/`, or `inbox/` — any plain note
|
|
31
|
+
that isn't a task or design note.
|
|
31
32
|
|
|
32
33
|
The title is whatever the user is naming or describing, minus any mode-signaling phrasing. Example:
|
|
33
34
|
|
|
@@ -138,7 +139,7 @@ offered.
|
|
|
138
139
|
|
|
139
140
|
Resolve this to a `category` matching the folder name exactly as
|
|
140
141
|
the index note currently spells it, before moving on to the creation steps
|
|
141
|
-
below. No project-slug question is needed here —
|
|
142
|
+
below. No project-slug question is needed here — vault filenames are
|
|
142
143
|
the title itself, not a slug-prefixed timestamp, so there's no separate
|
|
143
144
|
namespacing concern to resolve. The note always lands flat at
|
|
144
145
|
`{category}/{filename}.md` — never inferred into a subfolder such as a
|
|
@@ -97,8 +97,8 @@ this skill when it does. What no longer happens is arriving here merely because
|
|
|
97
97
|
### 1. Size the job before doing any of it
|
|
98
98
|
|
|
99
99
|
```sh
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
synapse query drift
|
|
101
|
+
synapse query grounding
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
Report what it says, in the human's terms, **before** touching anything: how far the baseline is from
|
|
@@ -118,7 +118,7 @@ Two answers change the plan:
|
|
|
118
118
|
### 2. Mechanical phase — always, and cheap
|
|
119
119
|
|
|
120
120
|
```sh
|
|
121
|
-
|
|
121
|
+
synapse build-lists --reenumerate
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
`--reenumerate` matters here: without it an existing `all.txt` is reused, so a branch switch would be
|
|
@@ -136,7 +136,7 @@ move a lot and some may reach zero.
|
|
|
136
136
|
Then rebuild the reverse index so the hook and the read path agree with the new enumeration:
|
|
137
137
|
|
|
138
138
|
```sh
|
|
139
|
-
|
|
139
|
+
synapse build-index
|
|
140
140
|
```
|
|
141
141
|
|
|
142
142
|
### 3. Triage each flagged node — reseat, patch, or re-orient
|
|
@@ -193,8 +193,8 @@ straight back stores a quote of a file as it looked at the old baseline, present
|
|
|
193
193
|
current. So rebuild the directive from the pointer the writer recorded:
|
|
194
194
|
|
|
195
195
|
```sh
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
synapse query field "{Node}" crux_path
|
|
197
|
+
synapse query field "{Node}" crux_lines
|
|
198
198
|
```
|
|
199
199
|
|
|
200
200
|
and replace the fenced block with `<!-- crux: <crux_path> <crux_lines> -->` so it is cut from the
|
|
@@ -208,7 +208,7 @@ its directives are stripped from the body, so a recovered body contains none —
|
|
|
208
208
|
the node's provenance is gone with no error. Recover the pointers per node:
|
|
209
209
|
|
|
210
210
|
```sh
|
|
211
|
-
|
|
211
|
+
synapse query grounding "{Node}" --list # path<TAB>lines
|
|
212
212
|
```
|
|
213
213
|
|
|
214
214
|
and re-emit a `<!-- grounded_in: <path> <lines> -->` for each. Run `synapse query grounding` before
|
|
@@ -257,7 +257,7 @@ selection. Never pipe an unbounded `git diff <commit>..HEAD` into a context wind
|
|
|
257
257
|
### 4. Write each rebuilt node
|
|
258
258
|
|
|
259
259
|
```sh
|
|
260
|
-
|
|
260
|
+
synapse write-node --title "{Node}" --summary "{one line}" \
|
|
261
261
|
--paths "$W/lists/NN.txt" --body "$W/body.md"
|
|
262
262
|
```
|
|
263
263
|
|
|
@@ -268,16 +268,16 @@ not merely stale, if the subsystem's shape differs on this line.
|
|
|
268
268
|
### 5. Rebuild the projections and verify
|
|
269
269
|
|
|
270
270
|
```sh
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
271
|
+
synapse build-index
|
|
272
|
+
synapse build-project-index
|
|
273
|
+
synapse query drift # expect silence
|
|
274
|
+
synapse query stale # expect silence
|
|
275
|
+
synapse query grounding # expect silence: re-pointed, not dropped
|
|
276
|
+
synapse query links --check # expect silence: no dangling targets
|
|
277
277
|
```
|
|
278
278
|
|
|
279
279
|
`links --check` covers what used to be a manual instruction here: a broken `[[wikilink]]` is a valid
|
|
280
|
-
link to a not-yet-existing note,
|
|
280
|
+
link to a not-yet-existing note, silently, and nothing else in the
|
|
281
281
|
system notices. It now reports `Node<TAB>relation -> Target (no such node)` per dangling edge.
|
|
282
282
|
|
|
283
283
|
One check is still yours, because no command performs it: **every node file appears in `Index.md`**. An
|
|
@@ -51,7 +51,7 @@ Check whether `synapse/{repo}@{branch}/Index.md` exists.
|
|
|
51
51
|
### 2. Preview the wipe and get explicit confirmation
|
|
52
52
|
|
|
53
53
|
```sh
|
|
54
|
-
|
|
54
|
+
synapse graph-wipe --dry-run
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
Report its output plainly: node count, and — the one thing this step exists to surface — how many
|
|
@@ -72,7 +72,7 @@ attached, which the human hasn't seen a number for yet.
|
|
|
72
72
|
Once confirmed:
|
|
73
73
|
|
|
74
74
|
```sh
|
|
75
|
-
|
|
75
|
+
synapse graph-wipe
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
This deletes `synapse/{repo}@{branch}/` and, if any node had non-empty `## Notes`, first dumps that
|
|
@@ -27,7 +27,7 @@ reinventing a parallel view — this skill has no separate list/continue mode of
|
|
|
27
27
|
|
|
28
28
|
## Prerequisites
|
|
29
29
|
|
|
30
|
-
- Requires a matching
|
|
30
|
+
- Requires a matching design note (`designs/`) with `Status: Ready`.
|
|
31
31
|
- No matching note → "No Ready design note found for '{topic}'. Start or continue that design note
|
|
32
32
|
first." Never generate a checklist from scratch.
|
|
33
33
|
- Matching note but `Status: Discussing` → "Design note for '{topic}' is still in Discussing. Finish
|
|
@@ -123,7 +123,7 @@ skill doesn't set or watch that field itself.
|
|
|
123
123
|
```
|
|
124
124
|
User: let's compile a task note for "rollup direct storage"
|
|
125
125
|
|
|
126
|
-
Codex: [reads designs/{
|
|
126
|
+
Codex: [reads designs/{project}/Rollup direct storage.md, Status: Ready]
|
|
127
127
|
[no existing linked task note]
|
|
128
128
|
|
|
129
129
|
Compiled checklist:
|
|
@@ -134,8 +134,8 @@ Codex: [reads designs/{PROJECT} — Rollup direct storage.md, Status: Ready]
|
|
|
134
134
|
|
|
135
135
|
Project already known: {PROJECT} → {prefix}-005.
|
|
136
136
|
|
|
137
|
-
Created: tasks/{
|
|
138
|
-
Linked back from designs/{
|
|
137
|
+
Created: tasks/{project}/Rollup direct storage implementation.md (task_id: {prefix}-005)
|
|
138
|
+
Linked back from designs/{project}/Rollup direct storage.md.
|
|
139
139
|
|
|
140
140
|
Status transitions happen automatically via the synapse-task skill once you start work.
|
|
141
141
|
```
|
|
@@ -30,14 +30,14 @@ there is no argument to parse, every run produces the same one-pass sweep.
|
|
|
30
30
|
## Prerequisites
|
|
31
31
|
|
|
32
32
|
Requires the `synapse` CLI on `PATH`, resolving a vault with a working link graph
|
|
33
|
-
(`synapse vault-backlinks`/`vault-links`/`vault-unresolved`/`vault-orphans`/`vault-deadends`).
|
|
34
|
-
real
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
(`synapse vault-backlinks`/`vault-links`/`vault-unresolved`/`vault-orphans`/`vault-deadends`).
|
|
34
|
+
`disk`, the one real backend, always has one -- case-insensitive wikilink resolution over the vault
|
|
35
|
+
folder directly, no external dependency. If `SYNAPSE_VAULT_INTEGRATIONS` ever resolves to a backend
|
|
36
|
+
with no link graph at all, these commands exit 1 saying so; stop and report that rather than
|
|
37
|
+
falling back to anything else.
|
|
38
38
|
|
|
39
39
|
This skill reaches the vault store only through the `synapse` CLI's `vault-*` subcommands, the same
|
|
40
|
-
door every other skill uses — no MCP tool, no direct
|
|
40
|
+
door every other skill uses — no MCP tool, no direct store call. `vault-links`/
|
|
41
41
|
`vault-backlinks` each answer for one note at a time, so Step 1's inventory sweep runs one pair per
|
|
42
42
|
note in scope: `2N` process spawns for an `N`-note vault. Acceptable for an on-demand, rare command.
|
|
43
43
|
Step 3's broken-link history check is a plain `git log` call (via the shell, not a compiled tool)
|
|
@@ -87,10 +87,9 @@ derivable without guessing:
|
|
|
87
87
|
- Missing `created` → `stat.ctime`, formatted `YYYY-MM-DD HH:MM` to match every other note's
|
|
88
88
|
convention.
|
|
89
89
|
|
|
90
|
-
Apply
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
the same hazard the vault and task-status skills already document.
|
|
90
|
+
Apply with `synapse frontmatter set <path> <key> <value>` (or `vault-patch --frontmatter`, which
|
|
91
|
+
delegates to the same byte-preserving mechanism) — either writes exactly this one field and leaves
|
|
92
|
+
every other line untouched, the way the vault and task-status skills already document.
|
|
94
93
|
|
|
95
94
|
## Step 3: Note-health findings (reported, not fixed)
|
|
96
95
|
|
|
@@ -199,4 +198,4 @@ Print a short summary directly in the response, not left only in tool-call outpu
|
|
|
199
198
|
asked, or on a recurring cadence the user sets up themselves.
|
|
200
199
|
- Every step above goes through the `synapse` CLI's `vault-*` subcommands, or (Step 3's broken-link
|
|
201
200
|
history check only) a plain `git log` via the shell against the vault's own local repo; this skill
|
|
202
|
-
never calls
|
|
201
|
+
never calls a store implementation directly.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imunitic/synapse",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "Memory for Claude Code, Codex CLI, and OpenCode: a durable
|
|
3
|
+
"version": "0.4.3",
|
|
4
|
+
"description": "Memory for Claude Code, Codex CLI, and OpenCode: a durable markdown vault plus a per-repo code graph.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/imunitic/synapse"
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"*.conf.template"
|
|
24
24
|
],
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"@imunitic/synapse-darwin-arm64": "0.4.
|
|
27
|
-
"@imunitic/synapse-linux-x64": "0.4.
|
|
28
|
-
"@imunitic/synapse-linux-arm64": "0.4.
|
|
26
|
+
"@imunitic/synapse-darwin-arm64": "0.4.3",
|
|
27
|
+
"@imunitic/synapse-linux-x64": "0.4.3",
|
|
28
|
+
"@imunitic/synapse-linux-arm64": "0.4.3"
|
|
29
29
|
},
|
|
30
30
|
"license": "SEE LICENSE IN LICENSE"
|
|
31
31
|
}
|
|
@@ -21,7 +21,7 @@ needs one.
|
|
|
21
21
|
|
|
22
22
|
## Procedure
|
|
23
23
|
|
|
24
|
-
1. **Verify the whole project once, with the script.** Run
|
|
24
|
+
1. **Verify the whole project once, with the script.** Run `synapse query stale` from
|
|
25
25
|
inside the repo. It prints one `{node title}\t{reason}` line per stale node and nothing at all
|
|
26
26
|
when everything is current, so its output is the complete stale set for the project.
|
|
27
27
|
|
|
@@ -50,7 +50,7 @@ needs one.
|
|
|
50
50
|
So skip the frontmatter entirely:
|
|
51
51
|
|
|
52
52
|
```sh
|
|
53
|
-
|
|
53
|
+
synapse query body "{Node title}"
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
That prints only what is between the generated fences — so it excludes `## Notes` as well as the
|
|
@@ -81,11 +81,11 @@ needs one.
|
|
|
81
81
|
- **Get the node's path list into a file, never into context:**
|
|
82
82
|
|
|
83
83
|
```sh
|
|
84
|
-
|
|
84
|
+
synapse query sources "{Node title}" > "$W/paths.txt"
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
If `$W/manifest.tsv` exists (or the namespace has `_manifest.tsv`), prefer re-running
|
|
88
|
-
|
|
88
|
+
`synapse build-lists` instead and use the regenerated `lists/NN.txt`: it
|
|
89
89
|
re-derives every list from the clustering patterns, so files *added* since the last build are
|
|
90
90
|
picked up automatically rather than sitting in `_unassigned`. `synapse query sources` can only
|
|
91
91
|
return what the node already claims.
|
|
@@ -101,7 +101,7 @@ needs one.
|
|
|
101
101
|
and discards findings the diff has nothing to say about. Project the diff as carefully as
|
|
102
102
|
`sources`: names first, `--stat` to size it, hunks only for the selection.
|
|
103
103
|
- Fall back to reading the files when patching cannot be justified — a large fraction changed, the
|
|
104
|
-
`crux` file is gone, or the baseline is unusable. Then try
|
|
104
|
+
`crux` file is gone, or the baseline is unusable. Then try `synapse tags {path}`
|
|
105
105
|
first (exit 0 use the tags, exit 1 fall back to reading the file, exit 2 run the discovery
|
|
106
106
|
procedure `/synapse-init` documents, then retry), and read the load-bearing files in full — the
|
|
107
107
|
tags signal informs regrouping, it never substitutes for reading a file before rewriting its prose.
|
|
@@ -127,22 +127,22 @@ needs one.
|
|
|
127
127
|
- **Write it back with the script:**
|
|
128
128
|
|
|
129
129
|
```sh
|
|
130
|
-
|
|
130
|
+
synapse write-node --title "{Node title}" --summary "{one line}" \
|
|
131
131
|
--paths "$W/paths.txt" --body "$W/body.md"
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
It replaces only the generated region and re-emits everything after the closing fence verbatim,
|
|
135
135
|
which is what makes the `## Notes` guarantee enforceable rather than a promise.
|
|
136
136
|
- **Never hand-write the frontmatter**, with `vault_patch` at `targetType: frontmatter` or
|
|
137
|
-
otherwise.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
otherwise. `--frontmatter` only ever writes a single scalar value, so it can't represent
|
|
138
|
+
`sources:`/`grounded_in:` at all, and enumerating the rest of a node's fields by hand one call
|
|
139
|
+
at a time is how `summary` and `commit` get silently dropped — which then breaks the next
|
|
140
|
+
`synapse build-project-index` run, far from the cause.
|
|
141
141
|
- **`## Notes` is human-authored only.** Never write into it — not at regeneration, not to record
|
|
142
142
|
what you just did. (Task notes in `tasks/` are a different artifact: the `synapse-task` skill *does*
|
|
143
143
|
append there. Do not carry that habit into a Synapse node.)
|
|
144
144
|
- If the node's `summary` or title changed, rebuild the index so the map matches:
|
|
145
|
-
|
|
145
|
+
`synapse build-project-index`.
|
|
146
146
|
- **Say out loud that a regeneration happened** — e.g. "Node '{title}' was stale, regenerated
|
|
147
147
|
before use." This has real latency and token cost, unlike Tier 1/2's detection; it must never
|
|
148
148
|
be absorbed silently into the read.
|
|
@@ -150,13 +150,13 @@ needs one.
|
|
|
150
150
|
- Read the bucket with a shell command, not into context — the index runs to tens of megabytes:
|
|
151
151
|
|
|
152
152
|
```sh
|
|
153
|
-
|
|
153
|
+
synapse index unassigned
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
Empty → nothing to do, skip silently (an empty sweep isn't worth announcing).
|
|
157
157
|
- Otherwise read `synapse/{project}/Index.md` for the current node list (titles + summaries).
|
|
158
158
|
- Tag the whole bucket in **one** call — write the paths to a list and run
|
|
159
|
-
|
|
159
|
+
`synapse tags --paths {list}`, whose output is attributable (an unindented
|
|
160
160
|
line is a path, the tab-indented lines under it are its tags). A per-file loop costs ~33× more
|
|
161
161
|
for the same answer. Fall back to a full read for ambiguous cases, then classify against that
|
|
162
162
|
node list. **The judgment is which cluster a path belongs to; the bookkeeping is not yours to
|
|
@@ -167,7 +167,7 @@ needs one.
|
|
|
167
167
|
immediately. If there is no manifest, add the path to that node's list file instead.
|
|
168
168
|
- **Fits nothing** → leave it unassigned. A genuinely new subsystem wants its own manifest line
|
|
169
169
|
and its own node, which is `/synapse-init` work, not a sweep.
|
|
170
|
-
- Then rebuild the projection with
|
|
170
|
+
- Then rebuild the projection with `synapse build-index`. **Never hand-edit
|
|
171
171
|
`_index.bin`** — it is derived, binary, and tens of megabytes; there is nothing to
|
|
172
172
|
hand-edit.
|
|
173
173
|
- **Announce every outcome**, same transparency rule as regeneration: which file, and which
|
|
@@ -126,8 +126,8 @@ candidate list, not something to copy verbatim.
|
|
|
126
126
|
Never hard-wrap. Write each paragraph as one single unbroken line and let the editor soft-wrap
|
|
127
127
|
it — a newline exists only where a real break is intended (between paragraphs, list items,
|
|
128
128
|
headings). This is a vault-wide rule, not specific to this node, and it is not optional: a
|
|
129
|
-
hard-wrapped paragraph renders as a ragged stack of short lines in
|
|
130
|
-
text.
|
|
129
|
+
hard-wrapped paragraph renders as a ragged stack of short lines in a soft-wrapping viewer instead of
|
|
130
|
+
flowing text.
|
|
131
131
|
```
|
|
132
132
|
|
|
133
133
|
Same model as the orchestrating session, no override — matches the constraint that "a
|
|
@@ -42,15 +42,15 @@ to orient someone already inside. A node without one is an error, not a default.
|
|
|
42
42
|
|
|
43
43
|
- **Filename/title:** short, senior-engineer-style description of the concept (e.g. "World —
|
|
44
44
|
entity/component/resource core"). Filesystem-illegal characters (`/ : * ? " < > |`) are
|
|
45
|
-
sanitized — but **reword the title instead of relying on that**, because
|
|
46
|
-
|
|
45
|
+
sanitized — but **reword the title instead of relying on that**, because a wikilink resolves
|
|
46
|
+
by *filename*, so `[[World — entity/component/resource core]]` silently resolves to
|
|
47
47
|
nothing once the file becomes `...entity_component_resource core.md`. A broken wikilink is a
|
|
48
48
|
valid link to a not-yet-existing note, so it fails quietly. The writer warns when a title needs
|
|
49
49
|
sanitizing; treat that warning as "rename this node". Same trap when you *retitle* a node
|
|
50
50
|
mid-build: inbound links already written keep pointing at the old name.
|
|
51
51
|
- **`sources`:** **every** file the node covers — repo-relative path plus that file's
|
|
52
52
|
`git hash-object <path>` output, run from the repo root at the moment of writing. Exhaustive,
|
|
53
|
-
not a sample: this is a **machine** field, and it is what makes
|
|
53
|
+
not a sample: this is a **machine** field, and it is what makes a path-based lookup able to reach
|
|
54
54
|
a node from any file it covers (searching a class name that appears in no node's prose still
|
|
55
55
|
finds its node via this list). Do **not** trim it to a handful of "representative" files —
|
|
56
56
|
doing so silently destroys that lookup, leaves the node unable to answer "which files am I
|
|
@@ -65,17 +65,15 @@ to orient someone already inside. A node without one is an error, not a default.
|
|
|
65
65
|
someone through this subsystem), `crux` (the few lines that carry the actual logic — **authored
|
|
66
66
|
as line numbers, stored as text**: you point, the writer slices, so composing is impossible at
|
|
67
67
|
authoring time and nothing decays afterwards the way a stored line number would), `links` (typed
|
|
68
|
-
|
|
68
|
+
wikilinks to other nodes in this same namespace: `depends_on`, `part_of`, `uses`, or
|
|
69
69
|
another type that fits better if one doesn't — for `depends_on`/`uses` specifically, `/synapse-init`
|
|
70
70
|
computes candidates before any node exists via `synapse link-graph`; read that node's rows from
|
|
71
71
|
`links.tsv` rather than guessing which siblings it relates to, `part_of` stays a judgement call
|
|
72
72
|
with nothing mechanical behind it), a `## Sources` section, and an empty `## Notes` section.
|
|
73
73
|
- **Break a "does N things" enumeration into real bullets, not inline `(1)/(2)/(3)`.** A sentence
|
|
74
74
|
enumerating three or more parallel sub-points reads as a wall of text once each item carries its
|
|
75
|
-
own clause or parenthetical -- the node is read by a human skimming it
|
|
76
|
-
|
|
77
|
-
was chosen specifically so it stays "just as readable by a human directly in Obsidian as it is by
|
|
78
|
-
Claude"), and a dense inline run-on defeats that. Use a markdown bullet list under the sentence
|
|
75
|
+
own clause or parenthetical -- the node is read by a human skimming it as much as by an agent,
|
|
76
|
+
and a dense inline run-on defeats that. Use a markdown bullet list under the sentence
|
|
79
77
|
introducing them instead. This is narrow, not a general "prefer bullets" rule: an aside of one or
|
|
80
78
|
two items, or connected causal narrative ("X, because Y, which is why Z"), stays flowing prose --
|
|
81
79
|
over-bulleting ordinary narrative just trades one readability problem for another.
|
|
@@ -138,10 +136,10 @@ to orient someone already inside. A node without one is an error, not a default.
|
|
|
138
136
|
per owning directory or module with a file count, `LC_ALL=C` sorted. A node covering 941 files
|
|
139
137
|
would otherwise put 75 KB of paths in front of a reader who wants to know which modules are
|
|
140
138
|
involved — and the frontmatter already carries every path for search, so the mirror doesn't
|
|
141
|
-
need to repeat them. Rewritten from `sources` on every write, never hand-edited. (
|
|
142
|
-
|
|
143
|
-
why a mirror exists at all — but that is an argument for aggregating *the mirror*,
|
|
144
|
-
trimming the field.)
|
|
139
|
+
need to repeat them. Rewritten from `sources` on every write, never hand-edited. (A raw YAML
|
|
140
|
+
list in frontmatter renders as a flattened, truncated one-line string in typical note-viewer
|
|
141
|
+
UI, which is why a mirror exists at all — but that is an argument for aggregating *the mirror*,
|
|
142
|
+
not for trimming the field.)
|
|
145
143
|
- **`## Notes` is human-authored only.** Claude never writes into it — not at build time, not at
|
|
146
144
|
regeneration. It is created empty and preserved verbatim forever after.
|
|
147
145
|
- **Fence the generated region.** Everything the generator owns sits between
|
|
@@ -116,8 +116,8 @@ script fetched from a notes vault. Begin any re-run by reading it, and improve i
|
|
|
116
116
|
re-deriving from scratch. Nothing like it ships, because which aggregations carry signal depends
|
|
117
117
|
on the codebase — a distributed one would encode the wrong ecosystem's conventions.
|
|
118
118
|
|
|
119
|
-
`.txt`, with markdown formatting inside, for a measured reason:
|
|
120
|
-
notes, so a `_profile.md`
|
|
119
|
+
`.txt`, with markdown formatting inside, for a measured reason: a vault viewer indexes `.md` files
|
|
120
|
+
as notes, so a `_profile.md` would turn up in search and note-browsing UI, where it is pure noise
|
|
121
121
|
to a human reading notes. A non-`.md` extension is invisible to all of those and still perfectly
|
|
122
122
|
readable. Note the `_` prefix does *nothing* mechanically — it is only a hint to a human who sees
|
|
123
123
|
the file, matching `_manifest.tsv`. Record **negative results** here too ("this abbreviation has no
|
|
@@ -32,10 +32,10 @@ already named, to locate a specific detail inside it — never as an unscoped re
|
|
|
32
32
|
instead of asking Synapse first. If you catch yourself about to grep the whole repo before checking
|
|
33
33
|
`synapse/{project}/Index.md`, stop and check the index instead.
|
|
34
34
|
|
|
35
|
-
**Why the cost difference is real, not just tidiness.** `synapse query body <node>`
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
**Why the cost difference is real, not just tidiness.** `synapse query body <node>` is a direct disk
|
|
36
|
+
read that extracts only the prose between the generated fences, skipping the node's `sources` list
|
|
37
|
+
entirely. Reading the whole note instead would move that node's entire frontmatter — megabytes — to
|
|
38
|
+
print a few hundred words. On a large
|
|
39
39
|
repo (dozens to hundreds of thousands of tracked files), that difference is the entire reason a
|
|
40
40
|
query stays cheap instead of dominating the turn.
|
|
41
41
|
|
|
@@ -73,9 +73,9 @@ into `status:` either — always go through this skill, which caps at
|
|
|
73
73
|
back what you read.
|
|
74
74
|
|
|
75
75
|
`synapse vault-patch <path> --frontmatter <key> --replace` is also byte-preserving now (it
|
|
76
|
-
delegates to the same field-local mechanism `frontmatter set` uses internally)
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
delegates to the same field-local mechanism `frontmatter set` uses internally) — but it only ever
|
|
77
|
+
writes a plain scalar, and it's a full read-apply-write round trip through the patch layer for
|
|
78
|
+
one field. `frontmatter set` stays the
|
|
79
79
|
right tool for this step: narrower, and the one call that exists specifically for it.
|
|
80
80
|
6. **For completion only:** append implementation bullets to the existing
|
|
81
81
|
`## Notes` section with `synapse vault-patch`:
|
|
@@ -95,6 +95,29 @@ On a `SYNAPSE_VAULT_INTEGRATIONS=git` vault, every edit commits automatically, s
|
|
|
95
95
|
calls, not merely a record of intentional edits. The default `disk` backend keeps no history at all,
|
|
96
96
|
so this safety net only exists once that backend is chosen.
|
|
97
97
|
|
|
98
|
+
## Creating notes: authoring commands, not freeform writes
|
|
99
|
+
|
|
100
|
+
Every new note is created through an authoring command, never by freeforming a file at
|
|
101
|
+
`vault-write`:
|
|
102
|
+
|
|
103
|
+
- `/synapse-note` (bare mode) creates plain notes in any category -- `research/`,
|
|
104
|
+
`scratchpad/`, `inbox/`, anything that is not a tracked task or a design note. It mints the
|
|
105
|
+
frontmatter (`schema`, `title`, `note_id`, `created`, `updated`, `tags`) to the note schema's
|
|
106
|
+
contract, including full-timestamp format.
|
|
107
|
+
- `/synapse-note --task` creates tracked task notes under `tasks/{project}/`.
|
|
108
|
+
- `/synapse-design-note` and `/synapse-task-note` handle design discussions and compiled tasks --
|
|
109
|
+
both delegate the file-minting mechanics to `/synapse-note` internally.
|
|
110
|
+
|
|
111
|
+
`vault-write` is for *editing existing notes*, or the rare read-modify-write round trip. If a
|
|
112
|
+
direct creation is ever genuinely unavoidable, follow bare mode's frontmatter contract exactly
|
|
113
|
+
(`schema`/`title`/`note_id`/`created`/`updated`/`tags`, full `%Y-%m-%d %H:%M:%S %Z` timestamps)
|
|
114
|
+
rather than improvising a shape.
|
|
115
|
+
|
|
116
|
+
Schemas are opt-in by declaration: a note whose frontmatter declares `schema:` is held to that
|
|
117
|
+
schema's contract on every `vault-write`/`vault-patch`; a note without the field is never
|
|
118
|
+
validated or failed. Legacy notes predate the feature and stay valid as they are -- no backfill
|
|
119
|
+
is wanted, and "helpfully" adding `schema:` to old notes is not a service to anyone.
|
|
120
|
+
|
|
98
121
|
## Tagging is part of writing a note, not a separate pass
|
|
99
122
|
|
|
100
123
|
Every note-authoring command (`synapse-note`, `synapse-design-note`, `synapse-task-note`) applies tags as one of the steps in creating or substantially updating a note. There is no separate tagging pass or command — `/synapse-vault-tidy`'s recategorization signal reads tag data, it never writes it.
|
package/synapse-claude.md
CHANGED
|
@@ -100,27 +100,20 @@ a real yes/no answer, not a formality to wave past.
|
|
|
100
100
|
The vault is reached through the `synapse` CLI — `synapse vault-read`/`vault-write`/`vault-list`/
|
|
101
101
|
`vault-search`/`vault-search-text`/`vault-doc-map`/`vault-patch`/`vault-backlinks`/`vault-links`/
|
|
102
102
|
`vault-unresolved`/`vault-orphans`/`vault-deadends`/`vault-ambiguous`/`vault-rename` — for reads
|
|
103
|
-
*and* for writes, never by resolving a vault path or
|
|
104
|
-
Which concrete store the CLI talks to (`SYNAPSE_VAULT_INTEGRATIONS unset`, the default; `
|
|
105
|
-
into for
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
whatsoever: `read`/`write`/`list`/`search`/the link graph/rename are all plain disk I/O and direct
|
|
111
|
-
computation against the vault folder. Under the opted-in `obsidian` backend, `search`/the link
|
|
112
|
-
graph/rename go through Obsidian's own CLI over its local socket instead when Obsidian is running,
|
|
113
|
-
falling back to the same disk-backed behavior automatically and silently (a one-line stderr note,
|
|
114
|
-
nothing an agent turn needs to react to) whenever it isn't — no precondition to check or fail on
|
|
115
|
-
either way.
|
|
103
|
+
*and* for writes, never by resolving a vault path and reading or writing the note file directly.
|
|
104
|
+
Which concrete store the CLI talks to (`SYNAPSE_VAULT_INTEGRATIONS unset`, the default; or `git`,
|
|
105
|
+
opted into for the vault to own its own version control -- commit on every write, push/pull in the
|
|
106
|
+
background) is resolved once, inside the compiled binary, from `SYNAPSE_VAULT_INTEGRATIONS`/
|
|
107
|
+
`SYNAPSE_VAULT_DIR` — never something a skill or an agent turn needs to know or branch on. `read`/
|
|
108
|
+
`write`/`list`/`search`/the link graph/rename are all plain disk I/O and direct computation against
|
|
109
|
+
the vault folder, in every configuration.
|
|
116
110
|
|
|
117
111
|
**Every write to a note goes through `synapse vault-write` or `vault-patch`. Never the `Write`/`Edit`
|
|
118
|
-
tools on the on-disk path
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
which is why the habit never self-corrects on its own. The reason is not a
|
|
112
|
+
tools on the on-disk path** — not for a one-line change, and least of all when `Write`/`Edit` are
|
|
113
|
+
already in hand from editing code earlier in the same turn, because that proximity is precisely
|
|
114
|
+
what causes this to be violated. The vault being an ordinary directory means the wrong path
|
|
115
|
+
*works*: the auto-commit hook matches `Write|Edit`/`Bash` running `vault-write`/`vault-patch`, and
|
|
116
|
+
nothing visibly breaks — which is why the habit never self-corrects on its own. The reason is not a
|
|
124
117
|
failure mode to dodge; it is that an invariant upheld only when convenient is worth nothing. Nothing
|
|
125
118
|
else in the system can rely on it, and every note then has to be re-checked by hand instead of
|
|
126
119
|
trusted. Synapse's own tooling holds this line — `synapse write-node` goes through the same `Store`
|
|
@@ -129,19 +122,18 @@ differ. If the CLI itself ever fails (not installed, no vault configured), that'
|
|
|
129
122
|
failure to report and stop on, never a reason to fall back to a raw file edit.
|
|
130
123
|
|
|
131
124
|
Every shipped command and skill, `/synapse-vault-tidy` included, reaches the vault only through
|
|
132
|
-
the `synapse` CLI's `vault-*` subcommands — none of them
|
|
125
|
+
the `synapse` CLI's `vault-*` subcommands — none of them writes to the vault folder directly.
|
|
133
126
|
|
|
134
127
|
- You may create and edit notes in this vault **without asking for
|
|
135
128
|
permission first**, as long as each note is placed in the folder
|
|
136
129
|
matching its category per `Index.md`.
|
|
137
|
-
- Filenames are human-readable titles (not timestamp-prefixed —
|
|
138
|
-
|
|
139
|
-
poorly there). Sanitize filesystem-illegal characters (`/ : * ? " < > |`)
|
|
130
|
+
- Filenames are human-readable titles (not timestamp-prefixed — the filename is the display title,
|
|
131
|
+
so a timestamp prefix reads poorly). Sanitize filesystem-illegal characters (`/ : * ? " < > |`)
|
|
140
132
|
but otherwise keep the title as-is.
|
|
141
133
|
- Frontmatter carries what the filename no longer does: `title`, `created`
|
|
142
134
|
(real timestamp at creation time), and for task notes `task_id` /
|
|
143
135
|
`status` (`TODO`/`IN-PROGRESS`/`REVIEW`/`DONE`/`CANCELED`).
|
|
144
|
-
- Link with
|
|
136
|
+
- Link with wikilinks: `[[filename]]` or `[[filename|display
|
|
145
137
|
text]]` (no extension, exact filename minus `.md`).
|
|
146
138
|
- **Never hard-wrap note bodies. A newline exists if and only if a break is
|
|
147
139
|
intended in the output** — source line structure mirrors the output's block
|
|
@@ -156,16 +148,16 @@ the `synapse` CLI's `vault-*` subcommands — none of them calls an `mcp__obsidi
|
|
|
156
148
|
makes the text **renderer-independent**: if a newline never appears where
|
|
157
149
|
no break is wanted, then "does a single newline render as `<br>` or as a
|
|
158
150
|
space?" never arises, and strict CommonMark, non-strict CommonMark,
|
|
159
|
-
|
|
151
|
+
pandoc and GitHub all produce the same result — the ambiguous
|
|
160
152
|
input case is simply gone. This is HTML's content model applied to plain
|
|
161
153
|
text: a newline is markup meaning "break here", not cosmetic formatting of
|
|
162
154
|
the source file.
|
|
163
155
|
|
|
164
156
|
It also keeps **line length a view decision rather than a content one**.
|
|
165
157
|
Hard-wrapping is the author asserting a measure, baking one viewport into
|
|
166
|
-
the text; unwrapped, the same bytes are correct at every width —
|
|
167
|
-
|
|
168
|
-
mobile, print. Hard-wrapped prose fails both ways and is unfixable at read
|
|
158
|
+
the text; unwrapped, the same bytes are correct at every width — any
|
|
159
|
+
reader's readable-line-length setting on or off, a narrow split pane, a
|
|
160
|
+
wide monitor, mobile, print. Hard-wrapped prose fails both ways and is unfixable at read
|
|
169
161
|
time: at 80 columns it double-wraps raggedly in a narrow pane, and sits as a
|
|
170
162
|
fixed narrow ribbon in a wide one. Wanting a ~66-character measure is right
|
|
171
163
|
(it's a real typographic optimum, which is why that setting exists) — put it
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
1
|
+
# Read live from the Synapse package as a fallback (tier 3) -- never copied or
|
|
2
|
+
# seeded anywhere, and this template file is never written to. To customize,
|
|
3
|
+
# create your own synapse-ignore-files.conf at $XDG_CONFIG_HOME/synapse/, else
|
|
4
|
+
# ~/.config/synapse/ (the legacy ~/.claude/ also works); your own copy always
|
|
5
|
+
# wins and is never touched by Synapse.
|
|
6
|
+
# Edit or extend your own copy any time.
|
|
3
7
|
#
|
|
4
8
|
# Extra path patterns dropped at enumeration by synapse build-lists, on top
|
|
5
9
|
# of the built-in exclusions (compiled objects, archives, media, model weights,
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
#
|
|
1
|
+
# Read live from the Synapse package as a fallback (tier 3) -- never copied or
|
|
2
|
+
# seeded anywhere, and this template file is never written to. To customize,
|
|
3
|
+
# create your own synapse-module-boilerplate.conf at $XDG_CONFIG_HOME/synapse/, else
|
|
4
|
+
# ~/.config/synapse/ (the legacy ~/.claude/ also works); your own copy always
|
|
5
|
+
# wins and is never touched by Synapse.
|
|
6
|
+
# Add your own ecosystem's conventions any time.
|
|
4
7
|
#
|
|
5
8
|
# Boilerplate path-segment chains that module_of() (synapse query,
|
|
6
9
|
# synapse write-node's ## Sources mirror) strips through wholesale when
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Read live from the Synapse package as a fallback (tier 3) -- never copied or
|
|
2
|
+
# seeded anywhere, and this template file is never written to. To customize,
|
|
3
|
+
# create your own synapse-projects.conf at $XDG_CONFIG_HOME/synapse/, else
|
|
4
|
+
# ~/.config/synapse/ (the legacy ~/.claude/ also works); your own copy always
|
|
5
|
+
# wins and is never touched by Synapse.
|
|
2
6
|
#
|
|
3
7
|
# Known project -> task-prefix mappings for THIS machine only. Deliberately
|
|
4
8
|
# separate from the portable Synapse package (never committed
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
1
|
+
# Read live from the Synapse package as a fallback (tier 3) -- never copied or
|
|
2
|
+
# seeded anywhere, and this template file is never written to. To customize,
|
|
3
|
+
# create your own synapse-prompt-stopwords.conf at $XDG_CONFIG_HOME/synapse/, else
|
|
4
|
+
# ~/.config/synapse/ (the legacy ~/.claude/ also works); your own copy always
|
|
5
|
+
# wins and is never touched by Synapse.
|
|
6
|
+
# Edit or extend your own copy any time.
|
|
3
7
|
#
|
|
4
8
|
# Common English function words, filtered out by `synapse vocab` before
|
|
5
9
|
# building a search pattern from a raw prompt -- without this, an ordinary
|
package/synapse.conf.template
CHANGED
|
@@ -5,15 +5,12 @@ SYNAPSE_VAULT_DIR="$HOME/Vault/YourVault"
|
|
|
5
5
|
# Unset by default: reads/writes the vault folder directly, no external
|
|
6
6
|
# dependency at all -- search and the link graph
|
|
7
7
|
# (backlinks/links/unresolved/orphans/deadends/ambiguous) are computed by
|
|
8
|
-
# DiskStore's own scan.
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# "git,obsidian" combines both. The disk store itself is never named -- it's
|
|
15
|
-
# always the implicit innermost element.
|
|
16
|
-
#SYNAPSE_VAULT_INTEGRATIONS="obsidian"
|
|
8
|
+
# DiskStore's own scan. The one optional integration, "git", layers extra
|
|
9
|
+
# behavior on top instead: it owns the vault's own git lifecycle (commit on
|
|
10
|
+
# write, push once enough pile up) -- see
|
|
11
|
+
# docs/synapse/synapse-extended-store.md. The disk store itself is never
|
|
12
|
+
# named -- it's always the implicit innermost element.
|
|
13
|
+
#SYNAPSE_VAULT_INTEGRATIONS="git"
|
|
17
14
|
|
|
18
15
|
# Where Synapse clones/builds tree-sitter grammars (shared across every
|
|
19
16
|
# project -- not per-repo). Safe to leave at the default.
|