memgineering 0.4.2 → 0.6.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,673 @@ language the reader wants. The bilingual rule the monorepo applies to
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.6.0] — 2026-08-16
15
+
16
+ ### Added
17
+
18
+ - **A memory can say it binds.** `memgineering remember "<the decision>" --rule`
19
+ marks something as a decision rather than a fact — a colour you will not use, a
20
+ step never to skip. `memgineering rules` lists what is marked. Ordinary
21
+ observations are untouched, and a note that never mentions this is stored
22
+ exactly as before.
23
+
24
+ - **Your rules turn up before an edit, not after somebody asks.** With the hooks
25
+ installed (`memgineering setup`, Claude Code and Codex), whichever agent is
26
+ working in a folder is handed your marked decisions the first time it goes near
27
+ a file in that session — once, capped at eight lines, silent for the rest of the
28
+ session. It never blocks an edit and never answers whether one is allowed; the
29
+ worst it can do is stay quiet.
30
+
31
+ This exists because the session-start summary alone was measured not to work.
32
+ Twice, a session was given a recorded decision — "this site uses no blue", hex
33
+ codes included — at session start, and shipped a blue page; adding a stronger
34
+ instruction to that opening made the next run worse. A decision has to arrive
35
+ when it is about to be broken.
36
+
37
+ - **`memgineering undo` works on a hosted brain for more than `remember`.** A
38
+ `revise`, `retire` or `unretire` made against a hosted brain could not be taken
39
+ back — the refusal said the reverse patch was "not written yet", which was true
40
+ of nothing: it had been recorded all along and nothing read it. A change to a
41
+ memory that cannot be reversed is the one thing this tool promises never to
42
+ make, and it was making it. The reversal is byte for byte, refuses if the note
43
+ has been written since, and will not run twice.
44
+
45
+ - **Rules work on a hosted brain.** `memgineering rules` lists them and
46
+ `remember --rule` creates them there; both used to answer "a hosted brain does
47
+ not store the marking yet", which was true of the schema and false of the note —
48
+ a hosted brain keeps the whole text, so the marking arrived with every push and
49
+ nothing read it. Pushing a brain holding five standing decisions produced a
50
+ rules list of zero. Rules already pushed are backfilled, so they appear without
51
+ anyone re-writing them.
52
+
53
+ The before-edit hook still reads a brain on this machine: a network call on the
54
+ path of every file write is not a trade worth making. On a machine pointed at a
55
+ hosted brain, `memgineering rules --local` is what the hook will actually
56
+ deliver.
57
+
58
+ - **A memory can become a rule after it was written**, on a brain in a folder or
59
+ a hosted one. `memgineering revise <ref> --rule` marks an existing memory as a
60
+ decision that binds, and `--no-rule` stops it being one; leaving both off
61
+ changes nothing, as before. Until now the marking was fixed at the moment a note
62
+ was created, which is the wrong moment — a conclusion usually becomes a rule
63
+ later, when it changes.
64
+
65
+ The hosted half briefly shipped as the worst version of this: the command took
66
+ the flag, sent nothing, and reported success, so a rule somebody had just turned
67
+ off was still a rule and nothing said so. It carries now.
68
+
69
+ - **`memgineering use --json` says where the next write goes.** `destination` is
70
+ `"hosted"`, `"local"`, or `"pending"` — the third meaning a sign-in is waiting
71
+ to be approved, so writes land in `brain` until then and in `hosted` after
72
+ (`destination_until_approved` names the first half). `hosted.sign_in_pending`
73
+ carries the same distinction as a boolean. `hosted.signed_in` alone cannot
74
+ answer the question: it is false for both the logged-out and the waiting
75
+ state, and those land in different places.
76
+
77
+ - **`memgineering log --json` carries `superseded` on every operation**, on a
78
+ brain in a folder and a hosted one alike. It is what the printed line uses to
79
+ decide whether to offer `undo`, and a caller reading the structured output had
80
+ no way to reach the same conclusion.
81
+
82
+ ### Changed
83
+
84
+ - **A large push is no longer stopped by the server's rate limit.** The server
85
+ allows 300 requests a minute and `push` sends one per note, in order, so a brain
86
+ past that size climbed to the ceiling and stopped part-way — some notes across,
87
+ some not. A refusal is now waited out and the note re-sent, up to a bounded
88
+ number of times, and the pause says why once rather than going quiet. Only
89
+ `429` is retried: it means the request was refused, so nothing was written and
90
+ repeating it cannot double anything.
91
+
92
+ - **A hook can no longer hold your session open.** Both callbacks now give up
93
+ after five seconds and print nothing, and the hook `setup` installs carries a
94
+ timeout for the host to enforce as well. Neither existed before, and the gap was
95
+ not theoretical: a brain kept in a folder the OS syncs to the cloud, whose notes
96
+ had been evicted and would not come back, blocked `resurface` for over two
97
+ minutes — at the start of every session, because that is when it runs. Run by
98
+ hand, `resurface` still waits as long as your brain takes; you asked for it and
99
+ you are watching.
100
+
101
+ - **`memgineering setup --agent --hook off` now removes the callbacks.** It used
102
+ to skip installing them, which is right on a machine that never had them and
103
+ wrong on every machine that did — so the hooks stayed armed under a report that
104
+ had just printed "Turn it back off with `--hook off`". Only the groups
105
+ memgineering wrote are taken out; every other hook and setting in that file is
106
+ left exactly as it was, and a settings file that cannot be parsed is reported
107
+ rather than passed over in silence.
108
+
109
+ - **A guide whose markers were deleted no longer duplicates in silence.** Without
110
+ `<!-- memgineering-start -->` and `<!-- memgineering-end -->` the file read as
111
+ "never installed", so a second copy of the whole guide was appended — into every
112
+ session, permanently, with nothing to detect it.
113
+
114
+ Where setup can prove it wrote that file, it now skips it, names it, finishes
115
+ the rest of the run, and exits non-zero. Where it cannot — an install from a
116
+ release before this one, or a machine whose config is gone — it installs anyway,
117
+ because refusing there would make a first install impossible for anyone whose
118
+ own notes happen to use the same two verbs, and says so: "Appended below an
119
+ unmarked guide", with what to check. Losing only the end marker still repairs
120
+ itself.
121
+
122
+ - **Replacing something you edited is said out loud.** setup owns the guide block
123
+ and the skill files, so an upgrade overwrites them; it now records what it wrote
124
+ and tells you when what it replaced was not that. Ordinary upgrades stay quiet.
125
+
126
+ - **A flag that does not exist now says what does.** An unknown option used to
127
+ answer with one line and nothing to act on, and the recovery — opening the help
128
+ page — costs ten times what the answer does. The error now lists the command's
129
+ flags inline, and near-misses get a "did you mean" as well.
130
+
131
+ - **Codex gets both callbacks too.** `memgineering setup --hook on` now writes
132
+ them to `~/.codex/hooks.json` as well as Claude Code's settings, with a matcher
133
+ naming the tools Codex actually reports (`apply_patch` and `Bash` — it has no
134
+ Read or Grep tool, so its reading is a shell call). Codex was previously listed
135
+ as unable to run either one; a live session showed otherwise, including that
136
+ the before-edit hook's context reaches the model. One difference worth knowing:
137
+ Codex asks you to review new hooks once, at the start of the next session, and
138
+ runs nothing until you answer — the setup report now says so.
139
+
140
+ - **Grok is a supported tool.** `memgineering setup` installs the guide into
141
+ `~/.grok/rules/memgineering.md` and the skills into `~/.grok/skills/`, and Grok
142
+ loads both on its own.
143
+
144
+ Your rules reach it at the end of a turn rather than before an edit, and that
145
+ is the most the host allows. Three of Grok's hook events were each tried with a
146
+ value the session could not otherwise know — `PreToolUse` with
147
+ `additionalContext`, `SessionStart` stdout, `UserPromptSubmit` with
148
+ `additionalContext` — and all three hooks ran while none of the three arrived.
149
+ `Stop` does arrive. So the rules land as the turn finishes: too late for what
150
+ that turn already wrote, in time for everything after it. It costs one extra
151
+ round, once a session, because speaking there keeps the agent working.
152
+ `resurface` gets no hook on Grok at all; the guide asks for it instead.
153
+
154
+ - **The third tool is called Antigravity now.** Gemini CLI is discontinued and
155
+ Antigravity CLI took its place, keeping the same home — a line planted in
156
+ `~/.gemini/GEMINI.md` came back out of an `agy` session word for word, and one
157
+ planted in `~/.antigravity/` did not. So nothing moves: the guide and the
158
+ skills install exactly where they did, `--tools gemini` still selects it, and
159
+ only the name shown to you changes. It still has no hooks, so its skills tell
160
+ its agent to run `resurface` and `rules` itself.
161
+
162
+ - `memgineering setup --hook on` now arms two callbacks instead of one, and the
163
+ report names both. `--hook off` still installs neither.
164
+
165
+ - `sync-rules` is described as copying the brain's **read/index exclusions**,
166
+ which is what it has always copied. "Rules" alone now has another owner.
167
+
168
+ - **The bundled skills are English throughout, including their trigger
169
+ phrases.** 0.5.0 shipped a handful of Korean phrases in those triggers, so a
170
+ Korean speaker's agent could match a skill from the words they actually used;
171
+ everyone else got a package with one arbitrary second language in it. Picking
172
+ the trigger language at `setup` time is the right answer and is not built yet,
173
+ so until it is, the phrases are English.
174
+
175
+ Measured before saying so: the same Korean request that used to open a skill
176
+ still opens it with only English phrases installed, and six Korean requests
177
+ across two shapes were all handled correctly. A description is read by a model
178
+ that knows the language either way — the phrases name the situation, not the
179
+ wording. Asking for your memory in Korean still works.
180
+
181
+ - **The guidance now says a fact has to be checked, not worked out.** A session
182
+ that reads an address, an identifier or a version and then reasons its way to a
183
+ different one can write that reasoning into the brain as fact, where every later
184
+ session recalls it as one. A guess in a file turns up in a diff; a guess in a
185
+ memory does not. Two sentences, in the hub and in `memgineering-writing`: a
186
+ decision is whatever the user says it is, and anything a command or a file could
187
+ confirm goes in verified or not at all.
188
+
189
+ - **Tools that nothing calls for them now get told so.** On Antigravity — which
190
+ loads no skills of its own, measured — the installed guide was a router
191
+ pointing at five skills that were never opened, so a brain full of answers went
192
+ unread across a whole session. `setup` now appends two lines to the guide it
193
+ writes for any tool with no session hook: run `memgineering resurface` when you
194
+ start work in a folder, and `memgineering rules` before changing a file. Tools
195
+ that do get called back are unchanged, and see nothing extra.
196
+
197
+ Measured on the same task before and after: no memory calls and a generic
198
+ answer, then `resurface` + `rules`, the right answer, and the decision recorded
199
+ as a rule without being asked.
200
+
201
+ ### Fixed
202
+
203
+ - **Everything on the install screen is drawn by the same hand.** The
204
+ comparison's row rules were 1px hairlines running directly underneath
205
+ hand-drawn frames — the only straight edges on the page, and the first thing
206
+ the eye found. Rules, the recommended badge and the checkboxes are drawn now,
207
+ and hovering a drawn control makes its outline quiver in place the way the
208
+ site's do, instead of repainting a background the way nothing else in the
209
+ product does. Reduced-motion settings hold it to a single frame.
210
+
211
+ - **The first install screen stops asking you to match a table to a pair of
212
+ cards.** It compared "this machine only" against "in an account" in a table,
213
+ and then offered the choice underneath as two cards — in the opposite order to
214
+ the columns, worded differently from the column headers. Someone seeing it for
215
+ the first time could not tell which card the left column was about, which is
216
+ the one thing that screen exists to make obvious. The two answers are now the
217
+ table's own column headers: picking one paints its whole column, so every row
218
+ is read against the answer it belongs to. The recommended one is first in both
219
+ senses, because there is only one order left to be first in.
220
+
221
+ - **The Korean install screen is written the way the rest of it should have
222
+ been.** Every sentence moved to 해요체 and lost the clauses it did not need —
223
+ the register a person deciding something is spoken to, rather than one being
224
+ informed of a decision. The draft terms moved with it; a policy nobody can read
225
+ is not a stricter policy.
226
+
227
+ - **A rule about a command now actually arrives.** The before-edit hook is
228
+ installed with a tool matcher, and `Bash` was not in it — so a decision about
229
+ committing, deleting or deploying could never be shown, because those are shell
230
+ calls. A fresh agent asked to make "never put emoji in commit messages" stick
231
+ ran its whole task through `Bash` and was handed that rule zero times. The
232
+ matcher already carried `Read`, `Glob` and `Grep`, none of which writes
233
+ anything, so waiting for a "file tool" was never waiting for a write.
234
+ **Re-run `memgineering setup` to pick this up** — the matcher lives in your
235
+ tool's settings and an upgrade alone does not rewrite it.
236
+
237
+ - **Renaming your notes folder no longer makes your rules disappear.** When the
238
+ brain you set as default is not on disk, everything falls through to the one
239
+ that is — deliberate, so an unmounted drive does not stop you working. Nothing
240
+ said it had happened, so `rules` answered from the other brain with "no
241
+ standing decisions recorded", which reads as "I never wrote any down" and gets
242
+ acted on by writing them again, into a brain that is not the one you lost.
243
+ `use` said "because it is the only brain linked" while two were linked.
244
+ `rules`, `use` and `resurface` now name the folder they could not reach, say
245
+ the answer came from somewhere else, say nothing is lost, and give the one
246
+ command that fixes it. Silent when your default is fine.
247
+
248
+ - **The sign-in screens are on memgineering.com.** Approving a sign-in used to
249
+ happen on `api.memgineering.com`, an API subdomain, on a page built from
250
+ colours that matched nothing else in the product. Approval, the refusals and
251
+ the "you're done" screen are now all at `memgineering.com/auth/device`, drawn
252
+ from the same stylesheet as the rest of the site. Nothing changes in the CLI —
253
+ `login` opens whichever address the server hands it.
254
+
255
+ - **The install screen draws itself again.** `memgineering setup --web` serves one
256
+ self-contained page under `default-src 'none'`, and that policy named no
257
+ `img-src` and no `font-src` — so the browser silently dropped every asset the
258
+ page was carrying inside itself. The hand-drawn borders around the cards, the
259
+ inputs and the buttons never painted, and neither did the typeface. On the
260
+ account step this cost the reader the way forward: the `Next` button is drawn
261
+ rather than filled with a colour, so it rendered as an invisible rectangle with
262
+ a label the same shade as the page. The policy now permits `data:` for images
263
+ and fonts, and nothing else — no host, no scheme, no wildcard — so the screen
264
+ still opens with the machine offline. A test now reads the page for the
265
+ schemes it actually uses and asks the policy about each one, which is the
266
+ comparison nobody was making: both files were correct about themselves.
267
+
268
+ - **A hosted brain shows why a memory changed, in the output you get without
269
+ asking.** Every write is told to carry a `--reason`, on the argument that it is
270
+ the only part of the record still worth anything six months later — and then
271
+ neither read command printed one. On a hosted brain, `memgineering evidence`
272
+ answered with `surfaced 8 · opened 4` and stopped, and `memgineering log` gave a
273
+ timestamp and a path. The reasons had been in the response all along, and in
274
+ `--json`, so nothing was lost; it was simply never shown, which for a default
275
+ output is the same thing.
276
+
277
+ Both commands now print the same report from a hosted brain that they print
278
+ from one on your disk: the title, the standing and what it means, the ledger,
279
+ and the reason quoted. `log` additionally shows who made each change, whether
280
+ it was already undone, and whether the note has moved on since — all of which
281
+ the server was sending and the client was discarding.
282
+
283
+ - **`memgineering use` named the wrong brain.** Signed in and pointed at a
284
+ hosted brain, it reported the folder on this disk — a real folder, that
285
+ nothing had written to in weeks — while every `recall` and `remember` went to
286
+ the server. Naming the wrong destination is the one thing this tool cannot do:
287
+ nothing about the answer looks wrong until somebody goes looking for a note
288
+ that was never written there.
289
+
290
+ It now answers with whichever brain the next command will actually use, in all
291
+ three states: the hosted one when signed in; the folder when the pointer is
292
+ there but the sign-in is not, because that is where writes land; and, when a
293
+ sign-in is merely waiting to be approved, both — the folder until somebody
294
+ approves it, the hosted brain after. It reads state off the disk, so it
295
+ answers with the server down and it never completes a sign-in as a side
296
+ effect of being asked a question. See the `--json` fields under Added.
297
+
298
+ - **`memgineering pull` uses the brain this machine is pointed at.** It was the
299
+ only hosted verb that could not answer "which brain" from state every other
300
+ verb reads, so on an account with two, the command somebody runs to back up
301
+ the brain they had been using all session answered "more than one hosted brain
302
+ — say which". `--brain` still wins, an unpointed machine with two brains still
303
+ gets the refusal, and the success line now names the brain it downloaded.
304
+
305
+ - **`memgineering pull` says which of your brains the folder does not contain.**
306
+ A tester pulled, was told 21 notes had arrived, and had no reason to doubt it —
307
+ the other 45 of their 66 were in a second hosted brain on the same account, and
308
+ a successful run never mentioned that it existed. A backup nobody knows is
309
+ partial is worse than one that failed. Both the real run and `--dry-run` now
310
+ name the other brains and give a command that fetches one; `--json` carries
311
+ `other_brains` and a hint saying not to call this a backup until each has been
312
+ pulled.
313
+
314
+ - **Asking where an install stands no longer means running the command that
315
+ installs.** There is no `status` verb, and the answer lives behind
316
+ `memgineering setup --agent --dry-run`, which writes nothing. A tester looking
317
+ for it either avoided `setup` — whose name says it installs — and got no
318
+ answer, or ran it and changed something to find out. `--help` now names the
319
+ dry run on the `setup` line, and the setup skill collects the three read-only
320
+ questions (`setup --dry-run`, `whoami`, `use`) in one place. It also names
321
+ `memgineering guard` as the hook's entry point, which stays out of `--help` on
322
+ purpose: it reads a hook payload on stdin and does nothing without one.
323
+
324
+ - **A question asked as a sentence is told what `recall` actually matched.**
325
+ "Only titles, aliases and summaries are searched" printed on zero results only
326
+ — the one case where there is nothing to misread. Asked as a whole sentence,
327
+ recall can return notes that share a single ordinary word with the question,
328
+ and every card reads `stated` with nothing to say the match was on "not"
329
+ rather than on the subject. That sentence now also appears under the results
330
+ when the query is a question or four words or more. It is not a warning: this
331
+ cannot know whether the results are any good, and a ⚠ over a right answer is
332
+ how a reader learns to skip the line.
333
+
334
+ - **A hosted card with no age no longer reads `NaN years ago`.** The guard
335
+ tested for `null` and a server that omits the field sends `undefined`, so a
336
+ real answer arrived wearing a number that was not one.
337
+
338
+ - **`memgineering recall` says which results are decisions you already made.**
339
+ `resurface` has labelled them "a standing decision" since rules existed, and
340
+ `recall` — the verb an agent reaches for far more often — returned a decision
341
+ and an ordinary observation looking identical. A brain with five standing
342
+ decisions in it could answer a question without saying which of the answers
343
+ the user had already committed to. The card now says so, and `--json` carries
344
+ a `binding` field on every card: present and `false` on an ordinary memory, so
345
+ a caller can tell "not a rule" from "this version does not say".
346
+
347
+ A hosted brain shows this once its server is updated; nothing breaks in the
348
+ meantime, the label is simply absent.
349
+
350
+ - **An id from `memgineering log` no longer looks like one from `recall`.** They
351
+ are the same length in the same alphabet, arrive in the same backticks, and
352
+ nothing said which was which — so an agent read an operation id off `log`, ran
353
+ `open` on it, and was told "nothing here matches — try searching". No search
354
+ can return an operation id. `log` now labels each one `undo:`, and `op:`
355
+ wherever `undo` would refuse it: an operation already undone, one that is
356
+ itself an undo, one whose note has been written since, or a verb that brain
357
+ cannot reverse — a hosted brain cannot reverse an `exclude`, and neither side
358
+ reverses an `import`. Fed one anyway, `open` says what the id is, which change
359
+ it names, the note it touched, and how to read that note; a truncated id works
360
+ there too, since `undo` accepts one.
361
+
362
+ - **`memgineering log` no longer warns that notes changed when they did not.**
363
+ It checked each operation's file through the note reader, which refuses
364
+ excluded and deny-listed paths — and read that refusal as "the file is gone".
365
+ So every `exclude` anybody ran was reported as changed (its target is
366
+ `.memgignore`, which is deny-listed), and so was the entire history of any
367
+ note that had been excluded. Separately, the divergence check was handed the
368
+ rows newest-first while it keeps the last one it sees per note, so it compared
369
+ against the OLDEST operation — an ordinary remember-then-revise reported the
370
+ note as edited outside the tool, about the tool's own write. Measured in each
371
+ case: the warning appeared and `undo` reversed the operation happily.
372
+
373
+ - **A crafted name from a hosted brain can no longer rewrite your terminal.**
374
+ Titles, paths, handles, brain names, account names, ranking reasons and server
375
+ hints were printed as they arrived, so a string containing terminal escape
376
+ sequences could erase the lines above it, move the cursor, or plant a
377
+ clickable link that goes somewhere else. `pull` was worse than a rendering
378
+ bug: with no destination given it names the folder after the brain, so a
379
+ crafted name created a directory on your disk carrying those bytes.
380
+
381
+ Every command that renders one of these strings now strips it — `recall`
382
+ (cards and the contradictions block), `open`, `evidence`, `log`, `resurface`,
383
+ `rules`, `remember`, `revise`, `undo`, `retire`, `unretire`, `exclude`,
384
+ `unexclude`, `use`, `whoami`, `push`, `pull`, `login`, `setup`'s sign-in step,
385
+ `update`, `link`'s previews, and the error output. Handles are stripped where
386
+ they are built rather than where they are printed, because a handle this tool
387
+ did not mint is the note's own `id:` field and there are a dozen places that
388
+ print one.
389
+
390
+ A brain in a folder gets the same treatment, and it took three passes to mean
391
+ it. The first sweep drove only each verb's hosted half, so a local note's
392
+ title, path, claim, scope, headings and ledger target still reached the
393
+ terminal. Patching those by hand missed five more, and the round after that
394
+ missed six — which is what finally replaced "check each one" with mutation
395
+ testing: break one strip, and a suite has to go red. `stripControl` says why
396
+ this is in scope at all — a folder brain can have synced from another machine
397
+ or be written by a team — and a note that arrived over Dropbox is as much
398
+ somebody else's writing as one that arrived over HTTPS.
399
+
400
+ Two suites drive it, one per brain, against notes and responses poisoned at
401
+ both ends of every string: eighteen local surfaces and eighteen hosted ones,
402
+ plus three server replies the fixture previously could not produce — a
403
+ reversal the server cannot describe, a curation that changed nothing, and a
404
+ recall carrying a contradiction.
405
+
406
+ Coverage is stated as measured rather than asserted. Breaking each of the 120
407
+ strips one at a time and re-running the suite, 92 are caught by a test. Of the
408
+ 28 that are not, most cannot be: `revise`'s diff renders YAML source, and the
409
+ serializer has already turned any control character into the four letters
410
+ `\x1b` before it reaches a screen; `open`'s claim line prints two enums;
411
+ `.memgignore` refuses a path with control characters before the branch that
412
+ would echo one; ids and error codes are excluded from the poisoned fixture on
413
+ purpose, since a caller passes an id back as a selector and branches on a code.
414
+ What is left genuinely untested is small and named: the browser consent screen,
415
+ which needs a terminal; the two `login` lines that need a browser to open and a
416
+ device flow to be approved; and a handful of second arms only a particular
417
+ server reply produces. Saying "every command is covered" was wrong four
418
+ releases running, so this says the number instead.
419
+
420
+ ### Agent guidance
421
+
422
+ - **Re-run `memgineering setup` after upgrading, then restart the
423
+ conversation.** Two things this release changes live outside the package: the
424
+ guidance block in your tool's instructions file, and the before-edit hook's
425
+ tool matcher — which gains `Bash`, without which a rule about a command is
426
+ never shown. Upgrading the CLI rewrites neither; `setup` does. The restart is
427
+ because the guidance is read once, when a conversation starts.
428
+
429
+ - **The block memgineering writes into your `CLAUDE.md` is now a third of the
430
+ size** — 178 lines to 52, and no command syntax at all. That block is in your
431
+ agent's context for every session forever, and it had grown into a second copy
432
+ of a manual that already existed as an on-demand skill. What it keeps is what
433
+ has to be true before any skill loads: what a brain is, which tools this
434
+ actually reaches, when to reach for it, and where the detail is.
435
+
436
+ - **Five skills instead of two.** `memgineering-memory` is now the map — which
437
+ verb answers which question — and points at `memgineering-recall` (recall,
438
+ open, evidence, resurface), `memgineering-writing` (remember, revise, undo,
439
+ retire, exclude, filling in `01_BASE/`), `memgineering-rules` (`--rule`, the
440
+ eight-slot budget, what the before-edit hook shows) and `memgineering-setup`,
441
+ which gains `push`/`pull`. Nothing was dropped; `resurface` had been explained
442
+ twice and now is explained once.
443
+
444
+ - `MEMGINEERING.md` 0.2.0 → 0.4.0, covering `--rule`: what counts as a decision,
445
+ and that a user saying "from now on" or "never" is making one without using
446
+ the word. **Restart your agent session after upgrading** so the new guidance
447
+ is read.
448
+
449
+ ## [0.5.0] — 2026-08-12
450
+
451
+ ### Added
452
+
453
+ - **Every command works on a hosted brain.** `revise`, `resurface`, `retire`,
454
+ `unretire`, `exclude` and `unexclude` used to refuse when this machine was
455
+ pointed at a hosted brain and tell you to add `--local`. They go to the server
456
+ now. Nothing memgineering offers says no because your brain is not on this
457
+ disk.
458
+
459
+ - **The setup screen starts with where your memory goes.**
460
+ `memgineering setup --web` used to open a Google sign-in before it showed you
461
+ anything, so the first thing you saw was a consent page for a product that
462
+ had not told you what it was. It now opens on the choice — what memgineering is in one
463
+ sentence, then a plain comparison of keeping the memory on this machine
464
+ against keeping it in an account, and what each costs. One brain is free, and
465
+ stays free. The sign-in only starts once you have picked it, and the code to
466
+ approve is shown on the last screen. Draft terms and a privacy draft are
467
+ reachable from the same screen; they are marked as drafts because they have
468
+ not been through legal review.
469
+
470
+ - **`memgineering pull [folder]`** — download your hosted brain back to this
471
+ machine, as the markdown it is. Until now notes went up and nothing came back,
472
+ so "your memory is yours" stopped being demonstrable the moment you used the
473
+ hosted side. It **never overwrites**: a file already at that path is left
474
+ exactly as it is and reported as skipped, which is what makes it safe to point
475
+ at the wrong folder and what makes an interrupted download finishable by
476
+ running the command again. Notes your rules exclude come down too — excluded
477
+ means "stop reading this", not "this is no longer yours" — and `.memgignore`
478
+ travels with them, so the folder does not silently un-exclude anything. The
479
+ result is plain markdown; `memgineering link <folder>` is what turns it into a
480
+ brain on this machine, and it is not done for you. `--dry-run` lists what would
481
+ be written without writing it.
482
+
483
+ - **`memgineering push`** — upload the brain on this machine to your hosted one,
484
+ keeping every note at the path it already had. Nothing is deleted locally, a
485
+ note already up there is counted as already up there rather than as a failure
486
+ (so an interrupted upload is finished by running the command again), and any
487
+ note the server refuses is listed in the summary instead of quietly dropped
488
+ from the count. `--dry-run` lists what would go without sending anything.
489
+
490
+ ### Changed
491
+
492
+ - **Setup no longer decides about accounts behind your back.** Run by an agent,
493
+ it skipped sign-in and said nothing — so you got a folder on one machine and
494
+ found out later that your memory does not follow you. It now says plainly that
495
+ no account was used and how to connect one, and the install tells your agent to
496
+ ask you first: memory on this machine, or synced across your devices and tools.
497
+
498
+ - **After install, your agent finishes the job.** Installing used to print
499
+ `Next: memgineering setup` — which agents dutifully relayed to their user as a
500
+ command to type, in a product whose whole premise is that the agent does this
501
+ for you. The install now tells the agent to ask you one question — should it
502
+ set things up, or would you rather choose on a screen — and then run setup
503
+ itself. The message is also no longer suppressed when output is piped, which
504
+ is exactly the case where an agent is the one reading it.
505
+
506
+ - **`--local` still does exactly what it did.** The product works with no
507
+ server: pass `--local` to any command and it reads and writes the folder on
508
+ this machine, whether or not you are signed in.
509
+
510
+ - **A hosted `resurface` says what it ranked by.** It has three signals where a
511
+ local brain has four — it cannot know which folder you asked from, because the
512
+ server records what was recalled and never where you were standing. The output
513
+ names the signals it used rather than leaving you to notice that "recalled 14×
514
+ in this folder" stopped appearing.
515
+
516
+ - **`revise --input` is refused against a hosted brain**, rather than partly
517
+ honoured. The JSON can name a different memory and set fields the flags do not
518
+ expose, so sending only the understood parts would report a success for a
519
+ change you did not ask for. Pass the change as flags, or use `--local`.
520
+
521
+ - **What you exclude travels with your brain.** The rules live in a
522
+ `.memgignore` file inside the brain rather than in a setting beside it, so a
523
+ hosted brain pulled back down to a folder is still scoped the way you scoped
524
+ it. `undo` for an exclusion is `unexclude`, not `undo <op_id>`.
525
+
526
+ - **`memgineering login`, `logout` and `whoami`** — sign in to a hosted brain.
527
+ Optional, and nothing that already worked needs it: a brain is still a folder
528
+ of markdown files on your machine, and every other command works on it with no
529
+ account and no network.
530
+
531
+ `login` pairs this machine with an account without a token ever appearing in a
532
+ browser. It prints a code, opens an approval page, and collects the token
533
+ itself once you approve — so the credential never lands on a screen, in a
534
+ scrollback, or in a chat window.
535
+
536
+ **Agents should use `login --emit-only`.** It starts the sign-in, opens the
537
+ browser and returns immediately rather than waiting for a human to click,
538
+ which no agent's command timeout survives. The next `memgineering` command
539
+ claims the token automatically. Show the printed code in your reply: the
540
+ approval page asks the user to check it against what they were shown, and on
541
+ surfaces where you are the only thing that saw it, they cannot.
542
+
543
+ `logout` revokes on the server before forgetting anything locally — a token
544
+ deleted only here still works for whoever has a copy. `--all` ends every
545
+ session on the account, `--local` forgets it here when the server is
546
+ unreachable and says plainly what that does not do.
547
+
548
+ - **`setup` offers an account as its first step, and lets you walk past it.**
549
+ Skipping installs byte-for-byte the same files; there is a test that compares
550
+ the two trees. With no terminal it does nothing unless you pass `--login`, so
551
+ an agent running `setup --agent` never opens a browser you did not ask for.
552
+
553
+ - **`MEMGINEERING_API_URL`** points the account commands at a different brain
554
+ server. The token is stored with the server that minted it and is never sent
555
+ anywhere else.
556
+
557
+ - **The `--human` prompt no longer hangs where there is no terminal.** Asking for
558
+ `--human` says which mode you want; it does not conjure a screen to draw a
559
+ prompt on.
560
+
561
+ - **The setup screen no longer promises a sync it does not perform.** Its first
562
+ screen ticks "the same memory on another machine" for keeping the memory in an
563
+ account — and choosing that only signed you in. No hosted brain was created and
564
+ no note was uploaded, so you would have found out on the second machine. The
565
+ last screen now says the notes are still only on this machine and what changes
566
+ that; the machine-readable half tells your agent the same thing, and to ask you
567
+ before sending anything to a server.
568
+
569
+ - **Two screens no longer ask near-identical questions.** "기억을 어디에
570
+ 둘까요?" (this machine or an account) was followed two screens later by "기억을
571
+ 어디에 담을까요?" (which folder to read). The second is now "어느 폴더를
572
+ 쓸까요?".
573
+
574
+ - **The screen separates what is kept here from what an upload sends.** It said
575
+ only a note's title and first paragraph get stored — true of the index on this
576
+ machine, and read as the whole of what reaches the server by anyone who had
577
+ just chosen an account. Uploading sends the entire file, and the screen now
578
+ says so where the claim is made.
579
+
580
+ - **The privacy draft says notes are stored in plain text.** No end-to-end
581
+ encryption; whoever runs the server can technically read them, and not doing so
582
+ is a promise rather than an impossibility. It was the one fact a person
583
+ weighing whether to put a diary in an account most needs, and the easiest to
584
+ leave out.
585
+
586
+ - **The setup screen stopped handing out commands.** It answered three of a
587
+ non-developer's questions with one — how to stop a note being surfaced, how to
588
+ update, how to connect a folder — and each answer was a command to type, on the
589
+ one screen built for somebody who has never opened a terminal. Each is now
590
+ phrased as something to ask their agent for. A test fails if any
591
+ `memgineering <verb>` reappears on that page.
592
+
593
+ - **Folder suggestions say how many notes each one holds.** The list offered
594
+ every folder containing at least one markdown file, so a photo archive with a
595
+ stray README sat beside somebody's actual notes with nothing to tell them
596
+ apart. The count is the reason each row is there, so it is now on the row.
597
+ Filtering harder was the wrong fix: a folder with one note is still notes.
598
+
599
+ - **The terms draft lists what it has not decided.** Legal entity and
600
+ jurisdiction, where the servers are, how long a deletion takes to reach
601
+ backups, how a breach would be announced, and where to delete an account —
602
+ absent from the draft, and now absent in writing rather than by omission.
603
+
604
+ - **`recall` stopped telling Korean users their own Korean notes were
605
+ unreachable.** When a query found nothing, the footer could claim "this
606
+ brain's notes are mostly written in English … no rewording in another
607
+ language will reach them" — in a brain holding Korean notes. Two scaffolding
608
+ files were voting: `01_BASE/` was already excluded, `00_HUB/` was not, and on
609
+ a small brain one English note `init` wrote decides the count. A note like
610
+ `글꼴은 Pretendard 하나로` then votes English on the strength of the product
611
+ name, and the majority flips. The hub no longer votes, and the warning is
612
+ suppressed outright when any note somebody wrote is in the asker's script —
613
+ the claim is about reachability, and one such note makes it false.
614
+
615
+ Caught by a fresh-context agent, which read the footer, believed it, and told
616
+ its user that Korean titles are not searchable. A hint that is wrong does not
617
+ merely mislead — it stops the tool being used.
618
+
619
+ - **`resurface` shows what a brain holds before anything has been recalled from
620
+ it.** It ranked purely on evidence of use — recalled here, recalled anywhere,
621
+ read lately — and dropped everything that scored zero. A note that had only
622
+ ever been written scored zero, so a brain nobody had searched yet returned its
623
+ five untouched `01_BASE/` templates and none of its actual notes, even at
624
+ `--limit 8`. That is a loop with no way in: a note is not surfaced until it has
625
+ been recalled, and surfacing is how you find out it exists.
626
+
627
+ It runs at session start, so that was an agent's entire first impression of the
628
+ brain. Measured: one saw five "not filled in yet" placeholders, concluded there
629
+ was nothing there, and did not call memgineering again for the rest of the
630
+ session.
631
+
632
+ Never-reached notes now rank, below anything with evidence behind them, and
633
+ untouched templates take at most two of the slots instead of all five. When
634
+ nothing has been recalled yet the page says so in a line — the order means
635
+ "what this holds", not "what matters here". Refusing to guess was right;
636
+ refusing to speak was not.
637
+
638
+ - **Checking whether you are signed in no longer opens a Google consent page.**
639
+ The `not_signed_in` hint read "YOU run `memgineering login --emit-only`" with
640
+ no precondition attached, and agents follow instructions — so an agent that
641
+ ran `whoami` to orient itself started a sign-in. Measured during testing:
642
+ three consent windows appeared in a user's browser in a session where nobody
643
+ had mentioned accounts. `setup` already refused to do this on the grounds that
644
+ nobody should be sent to a consent screen they did not ask for; the tool held
645
+ both positions and this one ran more often. The hint now leads with the fact
646
+ that an account is optional and `--local` is right there, and gates the
647
+ sign-in on the user having asked for one.
648
+
649
+ - **`resurface` says what to do with what it just showed.** It printed five
650
+ cards and stopped, at session start, to a reader that is always an agent. One
651
+ was handed a note saying this site does not use blue, with the hex codes in
652
+ the summary, and shipped a page with a blue accent: the memory reached its
653
+ context and never reached its output. It now closes with three lines — these
654
+ are the user's own decisions, follow them unasked, recall before answering
655
+ something already settled, remember what this session decides. Untouched
656
+ templates also stop explaining themselves at length when real notes share the
657
+ page; six lines about unfilled files were burying the two that mattered.
658
+
659
+ - **A hosted brain answers the same way as a local one when nothing has been
660
+ recalled from it yet** — the notes, plus a line saying the order is what the
661
+ brain holds rather than what matters here. It used to return an empty list,
662
+ which reads as an empty brain.
663
+
664
+ ### Agent guidance
665
+
666
+ - **The hub now says which tools this actually reaches.** A fresh-context test
667
+ asked an agent to make ChatGPT, Claude and Codex share one memory; it set up
668
+ the two it could and then had to read the product's source code to find out
669
+ whether ChatGPT was possible at all. On a machine without that source it
670
+ would have had to guess. The guidance now states plainly that `setup` covers
671
+ Claude Code, Codex and Gemini CLI, that anything with a shell works, and that
672
+ web and phone surfaces have no connector yet — including the specific wrong
673
+ answer to avoid ("you are signed in, so it works everywhere").
674
+
675
+ - The bundled guidance changed: the hub now tells your agent to fetch your
676
+ notes back with `pull` whenever you ask for them, and the setup skill says
677
+ the account question on the first screen is yours to answer rather than
678
+ something it should decide or pre-empt. **Restart your agent session after
679
+ upgrading** — the guidance is read once, when the session starts.
680
+
14
681
  ## [0.4.2] — 2026-08-10
15
682
 
16
683
  ### Fixed