@imunitic/synapse 0.4.2 → 0.4.4
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 +5 -5
- 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/harness/opencode/plugin/synapse.js +14 -1
- package/package.json +5 -5
- package/skills/synapse-node/SKILL.md +16 -16
- package/skills/synapse-node-authoring/SKILL.md +2 -2
- package/skills/synapse-node-format/SKILL.md +12 -14
- package/skills/synapse-orientation/SKILL.md +4 -4
- 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.
|
|
@@ -153,7 +153,7 @@ emit into tool calls than read into a window. Never hand-author those.
|
|
|
153
153
|
|
|
154
154
|
**Load the `synapse-orientation` skill** for how to read the vocabulary, the four questions that
|
|
155
155
|
cover a tree with no grammar, and the grammar-discovery procedure. It is shared with
|
|
156
|
-
`/synapse-rebuild`'s re-orient class, which needs the same technique.
|
|
156
|
+
`/synapse-rebuild-diff`'s re-orient class, which needs the same technique.
|
|
157
157
|
4. **Cluster into nodes — write `manifest.tsv`, the seam.** Group what you learned into a few dozen
|
|
158
158
|
readable nodes, not one per file — same density Graft aims for. A node is a subsystem or concept,
|
|
159
159
|
not a file; a file may legitimately belong to more than one node's `sources` when it's genuinely
|
|
@@ -249,7 +249,7 @@ emit into tool calls than read into a window. Never hand-author those.
|
|
|
249
249
|
**Load the `synapse-node-format` skill too, before writing the first one** — it is the
|
|
250
250
|
single description of the node contract itself (summary, the crux *pointer*, `## Links`,
|
|
251
251
|
`grounded_in`, what the writer adds and what it refuses), shared with the `synapse-node`
|
|
252
|
-
skill and `/synapse-rebuild`, which write the same artifact. `synapse-node-authoring`
|
|
252
|
+
skill and `/synapse-rebuild-diff`, which write the same artifact. `synapse-node-authoring`
|
|
253
253
|
covers *how* nodes get written; this covers *what* one is. Do not re-derive either from an
|
|
254
254
|
existing node: a node you are reading may predate a change to its format.
|
|
255
255
|
8. **Write `_index.bin`** — mechanics, run `synapse build-index`. It emits
|
|
@@ -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
|