memgineering 0.26.0 → 0.27.0

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/CHANGELOG.md CHANGED
@@ -11,6 +11,144 @@ language the reader wants. The bilingual rule the monorepo applies to
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.27.0] — 2026-10-18
15
+
16
+ ### Added
17
+
18
+ - **`recall --json` says why nothing the user wrote came back.** An answer
19
+ with no card the user wrote — no cards at all, or only cards still exactly
20
+ what `init` wrote (`scaffolding: true`) — had no `hint`: most of the advice
21
+ the terminal footer gives was left out, and so was a hosted brain's own
22
+ `hint`. It now carries `hint`, the single most specific next step, and an
23
+ answer of template cards only keeps its cards; `hint` is absent whenever a
24
+ card the user wrote came back. First, a brain with nothing to search. One
25
+ with no notes yet (for a hosted brain, as its account listing reports) gets
26
+ the `remember` command that writes the first one there — or, after `--brain`
27
+ named a brain this machine does not point at, the `memgineering use --brain`
28
+ that makes it the target, since `remember` has no `--brain`. A folder brain
29
+ that left out everything it had gets "Nothing in this brain could be
30
+ searched: …", described below. After that: notes in a script the question is
31
+ not in, other brains that were not read (a `--brain` or `--vault` command for
32
+ each), meaning that was not searched (with the server's reason), the hosted
33
+ server's own advice, and last, what was searched in this brain and what to
34
+ try there — fewer or broader words, `--depth standard` after
35
+ `--depth exact`, or dropping `--scope`.
36
+ - **`reindex` and `push` name the symlinks they did not follow.** The walk
37
+ never follows a symlink, so notes in a folder behind one were counted
38
+ nowhere and named by nothing. `reindex`, and a `push` that has notes to
39
+ send, now list every symlink that is not itself a note — under `--json` as
40
+ the new `skipped_other_symlinks`, beside `excluded_folders` — and a left-out
41
+ count beside a non-empty one of either is a floor, not the whole answer. A
42
+ `push` with nothing to send still calls such a folder empty and names no
43
+ link.
44
+
45
+ ### Changed
46
+
47
+ - **`recall` says when a brain in a folder left notes out of the search, in
48
+ the terminal as well as in `--json`.** The notes it counts were excluded by
49
+ the user's rules, listed in `.memgdeny`, held back because the name looks
50
+ private, refused because the content looks like a credential, or sit behind
51
+ a symlink. Notes inside a folder the rules exclude are not among them: the
52
+ walk never looks inside such a folder, so they are neither searched nor
53
+ counted. Whenever no card the user wrote came back — no cards at all, or
54
+ only cards still exactly what `init` wrote — and one of those notes was left
55
+ out, the answer says how many and why, lists beside them any excluded
56
+ folders and other symlinks nobody looked inside, and says that
57
+ `memgineering reindex` names each one: in the terminal under
58
+ `_Nothing matched._`, or under the "Nothing you have written matched this."
59
+ header above template cards, and under `--json` at the start of `hint`.
60
+ Excluded folders and other symlinks on their own, beside notes that were
61
+ searched, change nothing. When every note was left out — nothing indexed,
62
+ and the walk left out notes, or only folders and links it never looked
63
+ inside, which are not evidence of a note — the answer says "Nothing in this
64
+ brain could be searched: …" and nothing more about the brain: that sentence
65
+ and the `reindex` command are the whole `hint`, and the terminal no longer
66
+ adds "try fewer or broader words". When other notes were searched and one of
67
+ the counted notes was left out, `hint` starts with "Not every note in this
68
+ brain was searched: …" and goes on with the step it would otherwise give,
69
+ whose last-resort sentence then reads "Within the rest of this brain, …".
70
+ Recall never names a held-back note or shows its content. In the terminal, a
71
+ folder with no notes and nothing left out, answers with at least one card
72
+ the user wrote, and empty answers where notes were searched and none of the
73
+ counted kinds was left out all look as they did.
74
+ - **An answer of template cards only now names the brains the recall did not
75
+ read.** In the terminal it lists them under its header, with the command
76
+ that reads each, as an empty answer always has — except when the notes being
77
+ in another script is the reason: then, as for an empty answer, the script
78
+ notice prints instead of that block, and `hint` carries the script sentence
79
+ rather than the other-brains step, after the left-out count when a note was
80
+ also left out.
81
+
82
+ ### Fixed
83
+
84
+ - **Two memgineering commands refreshing the registry sign-in at once no
85
+ longer cost one of them its link.** On a machine signed in to the registry,
86
+ a `memgineering registry` command refreshes that sign-in as it starts, and
87
+ the registry rotates the token on every refresh, so of two commands that
88
+ refresh together it refuses the second. That one used to report the link as
89
+ gone (`not_linked`, with "`memgineering login` re-links both"), or, for the
90
+ verbs that can read without an account — `registry search`, `read`, `pull`
91
+ and the like — carry on anonymously. It now waits up to about two seconds
92
+ for the token the winning command saved and retries once with it, never
93
+ with its own spent token. If the retry loses too — with three or more
94
+ commands started together, say — or no newer token turns up within those
95
+ two seconds, a command that needs the sign-in reports `not_authenticated`
96
+ with a hint to run it again, and one that can read without it reads
97
+ anonymously, as before. Running it again does not always work: when the
98
+ command that won was a `logout`, or its save never landed, the next run
99
+ finds no newer sign-in and reports `not_linked`.
100
+ - **A busy or unreachable registry no longer reads as an expired link.** A
101
+ command that needs the registry sign-in, such as `registry publish`, turned
102
+ every failed refresh into `not_linked` and pointed at `memgineering login`,
103
+ which fixes neither. A refresh that meets a rate limit, a server error or no
104
+ network now reports that: `rate_limited`, the registry's own code, or
105
+ `server_unreachable`.
106
+ - **The sign-in file is no longer briefly missing while it is written.**
107
+ `credentials.json` used to be deleted and then written again, so a command
108
+ that read it in between took this machine for signed out. Saving it now
109
+ writes a new file and renames it into place (still mode 600), and a stale
110
+ temp file left by a crash is swept by a later save; a sign-out still deletes
111
+ the file. Changes also take a lock, and a rotated registry token is saved
112
+ only while the file still holds the token its refresh spent, so a sign-in or
113
+ sign-out that lands while another command's refresh is out is kept rather
114
+ than overwritten. A change that cannot take the lock within two seconds goes
115
+ ahead without it, and a lock held for more than 30 seconds is taken over as
116
+ dead; in either case the two can still cross.
117
+ - **`logout` revokes the registry session even when a command beside it has
118
+ just refreshed it.** It reads the sign-in file again right before revoking,
119
+ and its refresh retries a lost race the same way, where it used to give up
120
+ and leave the session to expire on its own
121
+ (`"registry": "revoke-failed-expires-on-its-own"` under `--json`).
122
+
123
+ ### Agent guidance
124
+
125
+ - `memgineering-recall`: with `--json`, an answer with nothing the user wrote
126
+ in it — no cards, or only template cards (`scaffolding: true`), which are
127
+ what `init` wrote and not the user's notes — carries `hint`, the one next
128
+ step; read it before concluding anything from `cards: []` or from template
129
+ cards. A `memgineering use --brain` in a hint moves this machine's pointer
130
+ for every later command, so offer it to the user and run it only on their
131
+ yes. Held-back notes are counted in both modes. For a counted note, tell the
132
+ user that such a note exists and why — never that the brain is empty or that
133
+ they never wrote it down — and, to say where, run the printed `reindex` and
134
+ give them the path; do not open, print or read a held-back note unless they
135
+ ask what it says. An excluded folder or another symlink is a place nobody
136
+ looked inside, not evidence of a note: say that recall could not look inside
137
+ it and that `reindex` names it, and do not say a note was held back. An empty
138
+ answer is not proof that the user never wrote something: recall never looks
139
+ inside a folder their own rules exclude, so say what was searched and that
140
+ such folders were not, and do not open one yourself. An answer of template
141
+ cards only also names the brains it did not read; run that command before
142
+ saying the fact was never written down.
143
+ - `memgineering-setup`: `reindex` and `push` list `skipped_other_symlinks`;
144
+ read their left-out count together with it and `excluded_folders`, because
145
+ beside a non-empty one the count is a floor. A `recall` that brings back
146
+ nothing the user wrote counts the same set by reason — beside notes it did
147
+ search, only when a note is among them — and prints the `reindex` command,
148
+ never a path.
149
+
150
+ Restart your agent session after upgrading so it reads the new guidance.
151
+
14
152
  ## [0.26.0] — 2026-10-10
15
153
 
16
154
  ### Changed
@@ -2,7 +2,7 @@
2
2
  name: memgineering
3
3
  description: Use whenever the user refers to something they told you before, asks what was decided, tells you something worth keeping, or settles something that should hold next time. The memory lives in their own folder and outlives this session; check it before answering from guesswork, and write to it when you learn something durable.
4
4
  type: skill
5
- version: 0.26.0
5
+ version: 0.27.0
6
6
  ---
7
7
 
8
8
  # memgineering
@@ -191,18 +191,72 @@ summary before you answer from it — never quote it back on the label alone.
191
191
  ## Two answers that are answers
192
192
 
193
193
  **Nothing matched.** Say so, and do not go read their folder yourself to
194
- compensate. At the default depth this has already searched every note body of
195
- **the brain it searched**, so "nothing" is real information about that brain
196
- rather than a hint to search harder — read `semantic` first, per above. Broader
197
- words are still worth one retry; `--depth exact` is not — it looks at strictly
198
- less.
194
+ compensate. At the default depth this has already searched the body of every
195
+ note recall could read in **the brain it searched**, so "nothing" is real
196
+ information about those notes rather than a hint to search harder — read
197
+ `semantic` first, per above. Broader words are still worth one retry;
198
+ `--depth exact` is not — it looks at strictly less.
199
+
200
+ In a brain in a folder, that is not a promise about every file. Notes it left
201
+ out are counted below, but recall never looks inside a folder the user's own
202
+ rules exclude (`.gitignore`, `.memgignore`, the rules file): notes in one are
203
+ neither searched nor counted, and an answer where other notes were searched does
204
+ not mention them. So an empty answer is not proof that the user never wrote
205
+ something down. Say what was searched, and that folders their rules exclude
206
+ were not, rather than telling them they never wrote it. Do not open such a
207
+ folder yourself.
199
208
 
200
209
  One brain is not the account. On a hosted account with more than one brain, an
201
- empty answer now names the brains that were NOT read and prints a runnable
202
- `--brain` command for each. Run it before you tell them the fact was never
203
- written down — four testers reached that conclusion about a note sitting in the
204
- next brain, and three of them said it out loud. Reading another brain does not
205
- move the machine's pointer.
210
+ empty answer — or one of template cards only — names the brains that were NOT
211
+ read and prints a runnable `--brain` command for each. Run it before you tell
212
+ them the fact was never written down — four testers reached that conclusion
213
+ about a note sitting in the next brain, and three of them said it out loud.
214
+ Reading another brain does not move the machine's pointer.
215
+
216
+ With `--json`, an answer with nothing the user wrote in it carries `hint`: no
217
+ cards, or only template cards (`scaffolding: true`, below) — those are what
218
+ `init` wrote, not the user's notes. `hint` is the one next step, the most
219
+ specific that applies. First, the brain had nothing to search: it has no notes
220
+ yet (the `remember` command that writes the first one into that brain — or,
221
+ after `--brain` named a brain this machine does not point at, the
222
+ `memgineering use --brain "<name>"` that makes it the target, since `remember`
223
+ has no `--brain`), or it is a folder whose every note was left out (how many,
224
+ why, and the `memgineering reindex` command that names each one). Then: its
225
+ notes are in a script the question is not (ask again in that language), another
226
+ brain was not read (the `--brain` or `--vault` command that reads it), meaning
227
+ was not searched (and the server's reason), the hosted server's own advice, or
228
+ fewer and broader words. Read it before you conclude anything from
229
+ `cards: []` or from template cards. A `memgineering use --brain` in a hint
230
+ moves this machine's pointer for every later command, not just the next one:
231
+ offer it to the user and run it only on their yes. `hint` is absent whenever a
232
+ card they wrote came back.
233
+
234
+ **Held-back notes are counted in both modes.** When an answer has nothing the
235
+ user wrote in it, recall counts what a brain in a folder left out, says why,
236
+ and prints the `memgineering reindex` command that names each one: in the
237
+ terminal right under `_Nothing matched._` or under the template cards' header,
238
+ and at the front of `hint`. It opens with "Nothing in this brain could be
239
+ searched: …" when no note could be searched at all, and with "Not every note in
240
+ this brain was searched: …" when other notes were searched and at least one
241
+ note of the first kind below was left out. Recall itself never names or shows a
242
+ left-out note. The counts come in two kinds, and they mean different things:
243
+
244
+ - **Notes**: excluded by the user's rules (`.gitignore`, `.memgignore`, the
245
+ rules file), listed in `.memgdeny`, held back because the name looks private,
246
+ refused because the content looks like a credential, or behind a symlink. A
247
+ note the user wrote exists and was left out on purpose. Do NOT tell them the
248
+ brain is empty or that they never wrote it down: tell them such a note exists,
249
+ and why; to say where it is, run that `reindex` — it lists each path and
250
+ changes no note — and give them the path. Do not open, print or read a
251
+ held-back note into the conversation unless they ask what it says: it was
252
+ held back because it may be private.
253
+ - **Places nobody looked inside**: an excluded folder ("not looked inside"), or
254
+ another symlink, which is never followed. These are not evidence of a note —
255
+ an ignored `images/` or `.venv/` holds none. Say that recall could not look
256
+ inside them and that `reindex` names them; do not say a note was held back.
257
+ When "Nothing in this brain could be searched" lists only these, the brain may
258
+ hold no notes at all. Beside notes that were searched they are not counted at
259
+ all — see **Nothing matched** above.
206
260
 
207
261
  **Cards that are not answers.** A card marked `not filled in yet` is one of the
208
262
  five `01_BASE/` files, still exactly what `init` wrote (line endings aside). Nobody has answered
@@ -506,17 +506,23 @@ by hand in the ordinary case — writes keep the index in step on their own.
506
506
  what is missing and clears stored rows for notes the brain has since been told
507
507
  not to read, reporting both; `--local` forces the folder brain. On a brain in a
508
508
  FOLDER it also names what it left out — notes a deny name, a `.memgignore` rule
509
- or a symlink kept from the index, and any folder a rule excluded whole — so "3
510
- notes rebuilt" is never the whole answer when a fourth was dropped. A hosted
511
- reindex cannot say that: the rules are applied on the machine that pushed, so
512
- the server only ever saw what arrived.
509
+ or a symlink kept from the index, any folder a rule excluded whole, and any other
510
+ symlink, which is never followed — so "3 notes rebuilt" is never the whole
511
+ answer when a fourth was dropped. A hosted reindex cannot say that: the rules are
512
+ applied on the machine that pushed, so the server only ever saw what arrived.
513
513
 
514
514
  Under `--json` that is `not_indexed` with `denied_by_name`, `denied_explicitly`,
515
- `excluded_by_rule`, `skipped_symlinks` and `excluded_folders`. **Read the count
516
- together with `excluded_folders`**: a rule that names a folder stops the walk at
517
- the folder, so nothing inside it is ever counted — `not_indexed: 0` beside a
518
- non-empty `excluded_folders` means the count is a floor, not the answer. `push`
519
- reports the same set with its total under `not_sent`. `--rebuild`
515
+ `excluded_by_rule`, `skipped_symlinks`, `excluded_folders` and
516
+ `skipped_other_symlinks`. **Read the count together with the last two**: a rule
517
+ that names a folder stops the walk at the folder, and a symlink is never
518
+ followed, so the notes in such a folder are never counted — `not_indexed: 0`
519
+ beside a non-empty `excluded_folders` or `skipped_other_symlinks` means the count
520
+ is a floor, not the answer. `push` reports the same set with its total under
521
+ `not_sent`. A `recall` that brings back nothing the user wrote — no cards, or
522
+ only templates — counts the same set by reason in both modes (beside notes it
523
+ did search, only when a note is among them) and prints this command, never a
524
+ path; what to tell the user then is in `memgineering-recall`.
525
+ `--rebuild`
520
526
  exists for one situation only, where an embedding model changed the shape of its
521
527
  answers without changing its name and the index has to be laid down again.
522
528