@rayul/kordis 0.15.1 → 0.15.2

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/NOTICE CHANGED
@@ -31,4 +31,4 @@ package and is not licensed with it.
31
31
  where no keychain is available.
32
32
  * `KORDIS_API_URL` points the CLI at a different host.
33
33
  * Error telemetry is off unless turned on, carries no identity, and is
34
- described in the repository's CLAUDE.md.
34
+ described in the repository's `docs/security.md`, under "Error telemetry".
@@ -0,0 +1,108 @@
1
+ # packages/skills — the agent guidance both CLIs ship
2
+
3
+ Markdown that an agent on a user's machine reads and acts on. It is not a pnpm
4
+ package (no `package.json`, no scripts): the two CLIs copy it into their npm tarballs
5
+ at build time, and their `setup` commands install it into the user's agent tools.
6
+ These files are the product's user documentation; a reader who gets a wrong command
7
+ from them runs it in front of a user.
8
+
9
+ ## Scope
10
+
11
+ - `MEMGINEERING.md` — the memgineering hub. `memgineering setup` strips its
12
+ frontmatter and injects the body between `<!-- memgineering-start -->` and
13
+ `<!-- memgineering-end -->` into `~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md` and
14
+ `~/.gemini/GEMINI.md` (and writes it as its own file under `~/.grok/rules/`). It is
15
+ in context for every session of every one of those tools.
16
+ - `memgineering-*` — seven sub-skills (`memory` is the map from question to verb;
17
+ `recall`, `writing`, `rules`, `setup`, `registry`, `installing` carry the detail),
18
+ installed into each tool's `skills/` directory and loaded by description match.
19
+ - `KORDIS.md` — the hub of the older `kordis` CLI, injected between
20
+ `<!-- kordis-start -->` and `<!-- kordis-end -->` by `kordis setup`.
21
+ - `kordis-*` — six sub-skills. `kordis setup` installs five; `kordis-memory` stays
22
+ in the repo and is drift-checked but is not installed, because its commands are
23
+ registered only under `KORDIS_EXPERIMENTAL_MEMORY=1`.
24
+
25
+ ## Not in scope
26
+
27
+ - The behaviour these files describe and the code that installs them:
28
+ `apps/memgineering` (`src/brand.ts`, `src/commands/setup.ts`) and `apps/cli`
29
+ (`src/brand.ts`, `src/commands/setup.ts`). Change the code there, the words here,
30
+ in the same change.
31
+ - `apps/memgineering/assets/` and `apps/cli/assets/`: gitignored build output that
32
+ every build deletes and recopies. Never edit them.
33
+ - Contributor documentation; these files are written for users' agents.
34
+
35
+ ## How the files ship
36
+
37
+ - `pnpm -F memgineering build` copies `MEMGINEERING.md` and every `memgineering-*`
38
+ directory into `apps/memgineering/assets/` (`apps/memgineering/scripts/copy-skills.mjs`).
39
+ `pnpm -F @rayul/kordis build` copies this whole directory into `apps/cli/assets/`.
40
+ - In both CLIs the hub file's presence in `assets/` is how the program tells a
41
+ published install from a source checkout; without it, `setup` reads this
42
+ directory directly.
43
+ - A user's installed copy changes only when they upgrade the CLI and `setup` runs
44
+ again. A fix here does not reach anyone until a release.
45
+
46
+ ## Invariants
47
+
48
+ - Every command, subcommand and flag a file names exists in the CLI that ships it.
49
+ `memgineering <verb> [<subcommand>] --flag` is checked against the program
50
+ `apps/memgineering` builds; `kordis <verb> --flag` against `kordis <verb> --help`.
51
+ Every backticked `snake_case` identifier in a kordis file must exist as a key or
52
+ string literal in the source of `packages/contracts`, `packages/harness-schema`,
53
+ `packages/memory-engine`, `apps/mcp` or `apps/cli`.
54
+ - memgineering files spell the registry as `memgineering registry <verb>`. The flat
55
+ top-level aliases still work and are never taught.
56
+ - The set of `memgineering-*` directories equals `BRAND.subSkills` in
57
+ `apps/memgineering/src/brand.ts`, in both directions, and the hub names every one.
58
+ A new sub-skill is a directory, a `BRAND.subSkills` entry and a hub mention.
59
+ - Directory names are permanent. `setup` has no delete path, so a renamed sub-skill
60
+ leaves the old one on users' machines teaching the old surface.
61
+ - The `MEMGINEERING.md` body (after frontmatter) stays under 5,000 characters with no
62
+ fenced code blocks. It sits two characters under the cap, so any addition moves
63
+ text into a sub-skill; phrases already moved into `memgineering-writing` are pinned
64
+ by the drift test and may not disappear.
65
+ - `MEMGINEERING.md`'s `version:` frontmatter equals `apps/memgineering/package.json`
66
+ `version`; bumping the CLI means bumping this line. `KORDIS.md` carries its own
67
+ `version:` (0.2.0) that nothing ties to a package.
68
+ - memgineering files are English only (no Hangul anywhere, triggers included), and
69
+ no shipped file contains an absolute home path (`/Users/...`, `/home/...`) or a
70
+ real person's name or conversation. The kordis files' descriptions carry Korean
71
+ trigger phrases on purpose.
72
+ - The hosted connector URL in `memgineering-setup/SKILL.md` and in the hub equals the
73
+ one documented in `apps/mcp/README.md` and `HOSTED_CONNECTOR_URL` in the setup
74
+ command.
75
+ - The hub and `memgineering-writing` both keep the rule that a stored fact is one
76
+ that was checked, not worked out.
77
+ - A behaviour change in either CLI updates the matching file here in the same
78
+ change, and that release's changelog gets an `### Agent guidance` subsection: root
79
+ `CHANGELOG.md` (both language halves) for `KORDIS.md` and `kordis-*`,
80
+ `apps/memgineering/CHANGELOG.md` for the memgineering files.
81
+
82
+ ## Writing patterns
83
+
84
+ - The hub routes; sub-skills explain. The hub holds only what must be true before
85
+ any skill loads, because it is paid for in every session.
86
+ - A sub-skill keeps its frontmatter (`name`, `description`, `type`,
87
+ `allowed-tools`). The description says when to load it, lists trigger phrases and
88
+ says what it is not for — tools pick skills by that text alone.
89
+ - When guidance has to override what a model assumes by default, state the negation
90
+ outright ("It does NOT wait for them") rather than only the fact.
91
+ - Commands are written for the agent to run on the user's behalf, not as
92
+ instructions for the user to type; the reader may be someone who has never opened
93
+ a terminal.
94
+
95
+ ## Tests
96
+
97
+ There is no test runner here; the suites that check these files live in the CLIs.
98
+
99
+ - `pnpm -F memgineering test`, or `test:unit` (what CI's unit job runs) — both build
100
+ first, which recopies these files into `assets/`; `src/skill-drift.test.ts` covers
101
+ the memgineering files. Vitest run without that build checks whatever `assets/` an
102
+ earlier build left, not these files.
103
+ - `pnpm -F @rayul/kordis test` — `src/__tests__/skill-doc-drift.test.ts` spawns
104
+ `kordis <verb> --help` through tsx for every verb the kordis files mention; it is
105
+ slow by design and has a two-minute per-test ceiling.
106
+ - Read `Test Files N passed` for each package. A drift failure names the file and
107
+ the command or flag that does not exist; fix the guidance or the CLI, never the
108
+ test's verb list alone.
@@ -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.21.0
5
+ version: 0.26.0
6
6
  ---
7
7
 
8
8
  # memgineering
@@ -83,6 +83,8 @@ at six skills, each of which loads on its own when its topic comes up:
83
83
  - `memgineering-registry` — the public layer
84
84
  - `memgineering-installing` — putting a package in their project, and updating it
85
85
 
86
+ Not shell-only: ChatGPT and Claude.ai reach a hosted brain via connector `https://mcp.memgineering.com/mcp`.
87
+
86
88
  A host short on room lists a skill by NAME ONLY, no description — measured on
87
89
  Claude Code. When you cannot see what it covers, READ
88
90
  `<tool-home>/skills/memgineering-<name>/SKILL.md` before deciding it is empty.
@@ -80,10 +80,13 @@ feeds the `community-adapted` trust tier, and gives a small trending boost:
80
80
  | `--absorbs <slug>` | `absorption` | folds the source in as one part |
81
81
  | `--remixes <slug>` | `remix` | recombines multiple sources |
82
82
 
83
- Unresolved sources (typo'd / unpublished slug) are **skipped fail-open** — the
84
- publish still succeeds and the response's `lineage.skipped` lists them so you
85
- can fix the slug or publish the source first. Declare lineage honestly; it is
86
- the registry's trust signal, not decoration.
83
+ A source that does not resolve — a typo'd slug, or a package that is
84
+ unpublished, deleted or private — **refuses the whole publish** with
85
+ `usage_error` (exit 2), and `--dry-run` refuses it the same way, so a dry run
86
+ catches a typo before anything is written. Fix the slug, or publish the source
87
+ first, then push again. (Naming your own package as its source is skipped
88
+ instead, and listed in the response's `lineage.skipped`.) Declare
89
+ lineage honestly; it is the registry's trust signal, not decoration.
87
90
 
88
91
  ## Yanking a bad version (0.10.0+)
89
92
 
@@ -191,9 +194,13 @@ Possible verdicts:
191
194
  - `validation_failed` (exit 30) — fix every listed flag, re-dry-run.
192
195
  - `conflict` (exit 40) — slug taken; suggest a different slug (or pass
193
196
  `--slug` if first publish).
194
- - `ai_review_rejected` (exit 32) — EXPLAIN the rejection to the user. Do NOT
195
- silently retry. Includes deterministic Stage-1 hits like
196
- `curl_pipe_shell`, `aws_access_key`, `private_key_block`, etc.
197
+ - Review rejection — never from a dry-run, which does not run the reviewer.
198
+ On the real push (step 3) a rejection is not an error: the push exits 0
199
+ and returns `status: "rejected"` with the reasons in `review.flags`
200
+ (`ai_review_rejected`, exit 32, is defined but never sent). EXPLAIN the
201
+ rejection to the user. Do NOT silently retry. Includes deterministic
202
+ Stage-1 hits like `curl_pipe_shell`, `aws_access_key`,
203
+ `private_key_block`, etc.
197
204
  - `rate_limited` (exit 31) — wait `retry_after_seconds`.
198
205
  - `not_authenticated` (exit 10) — `kordis login`, then retry.
199
206
 
@@ -245,10 +252,10 @@ User (push-back after adapting a judgment): "that decision rule we adapted from
245
252
  frontmatter; see "Publishing a judgment-pattern")
246
253
  2. kordis push ./judgment.md --type judgment-pattern --adapted-from <upstream/slug> --dry-run --json
247
254
  3. clean → drop --dry-run for the real push
248
- 4. the response's `lineage.recorded` confirms the edge; if `lineage.skipped`
249
- lists the source, the upstream slug was wrong or unpublished — fix it, or
250
- publish the source first, then re-push. The edge gives the upstream
251
- `community-adapted` credit and shows in its "Adapted by" graph.
255
+ 4. the response's `lineage.recorded` confirms the edge. A wrong or unpublished
256
+ upstream slug never gets this far: step 2's dry run already refuses it with
257
+ `usage_error` — fix the slug, or publish the source first. The edge gives the
258
+ upstream `community-adapted` credit and shows in its "Adapted by" graph.
252
259
  </example>
253
260
 
254
261
  <example>
@@ -46,7 +46,8 @@ Anonymous: works without login. Personalized signal rides on an opt-in
46
46
  `X-Kordis-Context` HTTP header (installed agent tools, top 3 CWD file
47
47
  extensions, framework hints from package.json/pyproject.toml/Cargo.toml,
48
48
  SHA-256-truncated hashes of installed slugs). Server uses it for in-flight
49
- re-ranking ONLY — never persisted (see CLAUDE.md "Telemetry / privacy").
49
+ re-ranking ONLY — never persisted (see `docs/security.md` in the Kordis
50
+ repository, "Search, context and addresses").
50
51
 
51
52
  ## Personalization opt-in
52
53
 
@@ -153,6 +153,11 @@ What you must not do is report what came back as everything the brain holds,
153
153
  which is exactly what a short answer looks like to anyone who does not read the
154
154
  line under it.
155
155
 
156
+ When every card with a project came from ONE project and the brain holds
157
+ others, recall says so (`scope_spread`: the project, and up to five others). If
158
+ the user meant one of those, ask again with `--scope <that project>` — the note
159
+ they want may be ranked just below a page full of the one the question named.
160
+
156
161
  ## Whether meaning was searched
157
162
 
158
163
  A hosted brain can match on meaning as well as words — the same idea in other
@@ -177,6 +182,12 @@ anything about what the user knows.
177
182
  If coverage says notes are missing entries, meaning was searched over part of
178
183
  the brain. Do not report that as a complete search.
179
184
 
185
+ When meaning was used, each card also says what reached it — `matched`:
186
+ `"words"`, `"meaning"`, or `"both"`. A `"meaning"` card (printed as _matched by
187
+ meaning only_) shares no word with the question. That is right for a note in
188
+ another language and wrong for one the model merely found nearby, so read its
189
+ summary before you answer from it — never quote it back on the label alone.
190
+
180
191
  ## Two answers that are answers
181
192
 
182
193
  **Nothing matched.** Say so, and do not go read their folder yourself to
@@ -194,11 +205,14 @@ next brain, and three of them said it out loud. Reading another brain does not
194
205
  move the machine's pointer.
195
206
 
196
207
  **Cards that are not answers.** A card marked `not filled in yet` is one of the
197
- five `01_BASE/` files, still byte-for-byte what `init` wrote. Nobody has answered
208
+ five `01_BASE/` files, still exactly what `init` wrote (line endings aside). Nobody has answered
198
209
  it, so it is evidence of nothing — do not quote it back as what they think. When
199
210
  every card carries that mark, recall says so above them (`--json`:
200
211
  `scaffolding: true`), and that is the moment to offer to fill them in rather
201
- than answer from them — see `memgineering-writing`.
212
+ than answer from them — see `memgineering-writing`. At most two such cards come
213
+ back per answer, plus any that is one side of a conflict, so both sides of a
214
+ conflict always show; the rest are counted (`templates_withheld`), never
215
+ silently dropped, and nothing anyone wrote is ever held back.
202
216
 
203
217
  The mark disappears once the user writes in the file. A filled-in base note is
204
218
  often the best answer in the brain: _who am I_, _what am I not allowed to do_,
@@ -219,8 +233,11 @@ On a hosted brain the folder counts too, as a name rather than a path: the CLI
219
233
  sends the folder's project — `owner/repo` from the git remote, or whatever
220
234
  `memgineering project` shows — and the server ranks what was asked about in
221
235
  that project first. The response says so itself: `ranked_by` gains `asked about
222
- in this project`, a card's reason reads `recalled 2× in this project`, and the
223
- footer names which project those words mean. Trust the footer over your
236
+ in this project`, a card's reason reads `opened 1× · surfaced 2× in this project`
237
+ (or `surfaced 2× …, never opened`), and the footer names which project those
238
+ words mean. Only an open, or being the FIRST card of a recall, counts toward
239
+ the order; a card merely listed further down is counted in words but earns
240
+ nothing. Trust the footer over your
224
241
  assumption in the other cases as well — it says when this folder names no
225
242
  project (nothing was sent), and when the server does not rank by project yet
226
243
  (it was sent and ignored). A path never leaves the machine either way.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: memgineering-rules
3
- description: Use when the user settles something they expect to hold next time — a colour they will not use, a step never to skip, a way things get named here — or when you want to see what already binds you in this folder. A decision does not have to be announced as a rule to be one. Triggers include "from now on", "always", "never", "don't do that again", "let's go with X from here", "we always do it this way", "what rules do I have". Covers remember --rule, rules, and what the before-edit hook shows.
3
+ description: Use when the user settles something they expect to hold next time — a colour they will not use, a step never to skip, a way things get named here — or when you want to see what already binds you in this folder. A decision does not have to be announced as a rule to be one. Triggers include "from now on", "always", "never", "don't do that again", "let's go with X from here", "we always do it this way", "what rules do I have" — and, for moving one, "that should apply everywhere", "not just this project", "all my projects", "only in this repo from now on". Covers remember --rule, rules, rescope, and what the before-edit hook shows.
4
4
  type: skill
5
5
  allowed-tools: Bash(memgineering:*)
6
6
  ---
@@ -69,6 +69,20 @@ A hosted brain answers this too, and `--rule` writes to one land marked. The
69
69
  marking lives in the note's own frontmatter either way, so a brain that was
70
70
  pushed from a folder keeps every rule it had.
71
71
 
72
+ **A rule saved from a chat app waits for the user.** ChatGPT, Claude.ai and
73
+ other connectors can write notes, but not rules: a rule asked for there is
74
+ kept as an ordinary note, and binds only once the user promotes it at a
75
+ terminal. Promoting binds the note's own text as the chat wrote it — `--claim`
76
+ changes the summary, not the words that bind — so they read it first with
77
+ `memgineering open <id> --detail full` (the card alone shows only the title and
78
+ summary, which a chat app may have rewritten), then `memgineering revise <id> --rule --claim "<what
79
+ the note says>"`. Worded differently, it is a new rule: `memgineering remember
80
+ "<the rule>" --rule`. A connector also cannot change or unmark an existing rule. Once
81
+ promoted, the rule says where its words came from — `(written by the ChatGPT
82
+ connector)` beside it in `memgineering rules` and in the before-edit hook, and
83
+ `written_by` in `--json`. Treat it as their rule; the label says which surface
84
+ it was first said on.
85
+
72
86
  **A rule also wins a tie in `recall` now.** Where an ordinary memory and a
73
87
  standing decision matched a query equally well, the decision is ranked first —
74
88
  the asymmetry being that a missed fact costs the reader some context, while a
@@ -85,12 +99,23 @@ alone earned — not that the top card is a rule, and not that it never could be
85
99
  since the engine noticing a note is decision-shaped is weaker evidence than its
86
100
  author saying it binds.
87
101
 
88
- One difference is worth knowing rather than discovering. The before-edit hook
89
- reads a brain **on this machine**, so on a machine pointed at a hosted brain it
90
- shows the local folder's rules, not the hosted brain's — a network call on the
91
- path of every file write is not a trade this makes. `memgineering rules` shows
92
- whichever brain the machine is pointed at; add `--local` to see what the hook
93
- will actually deliver.
102
+ **Rules arrive in two budgets, not one list.** What a session is shown is the
103
+ strongest few that hold everywhere, plus the strongest few scoped to the project
104
+ it is standing in — ten in total, and each half gives its unused room to the
105
+ other, so a brain with nothing scoped still fills the list. Rules scoped to a
106
+ DIFFERENT project are not shown to an agent working here at all; they bind
107
+ there. `memgineering rules` lists them separately under "scoped to other
108
+ projects", which is the one place to notice a scope with a typo in it — such a
109
+ rule binds nowhere and would otherwise appear nowhere.
110
+
111
+ Before the split there was one list ranked by use, and it did not work: measured
112
+ in a real repository, every slot went to rules about other things and a rule
113
+ written that morning about that project's own layout ranked 49th of 54.
114
+
115
+ The before-edit hook and `memgineering rules` read the same brain — the hosted
116
+ one when this machine is pointed at it, the folder on disk otherwise — so what
117
+ the hook will deliver is what the command shows. Add `--local` to read the
118
+ folder on this disk specifically.
94
119
 
95
120
  ## What the user's agent actually sees
96
121
 
@@ -135,11 +160,30 @@ a long list is fewer rules, not a longer one.
135
160
 
136
161
  Two consequences worth knowing before you mark things:
137
162
 
138
- - **Global habits crowd out project decisions.** A rule that has been recalled
139
- in other folders outranks a project rule written yesterday that nobody has
140
- reached for. If a user's own working preferences fill all eight slots, a new
141
- a rule written for the folder they are in may never be shown. Keep the
142
- standing set small.
143
- - **A retired rule stops being shown.** `memgineering retire <ref>` is the way
144
- out when a decision no longer holds — it stays visible in recall, ranked last
145
- and labelled, but it stops binding.
163
+ - **Global habits used to crowd out project decisions**, and the two budgets
164
+ are why they no longer can: a rule scoped to the project has its own room and
165
+ cannot lose every slot to whatever the user has been reaching for lately. It
166
+ still pays to keep the standing set small — ten is what a session reads.
167
+ - **Three ways out, and they are not the same.** `memgineering revise <ref>
168
+ --no-rule --reason "…"` says it was never a rule: it stops being shown before
169
+ an edit, and stays a perfectly ordinary current memory that recall returns.
170
+ `memgineering retire <ref>` says it no longer holds: it stops binding AND
171
+ drops to the bottom of recall, labelled. `memgineering expire <ref> --until
172
+ <date>` says it held until then: it KEEPS binding and recall keeps returning
173
+ it, ranked below what is current and labelled from that date. Reach for the
174
+ first when the marking was the mistake, the second when the decision has been
175
+ overtaken, and the third when it was always going to run out.
176
+ - **`memgineering rescope <ref>` changes WHERE a rule binds, not whether it
177
+ does.** `--scope <project>` binds it in that project alone — agents working
178
+ anywhere else stop being shown it. `--global` binds it everywhere, which is
179
+ the change hardest to notice afterwards, so it has a flag of its own rather
180
+ than being what happens when you leave the scope off. Nothing the note says
181
+ changes either way, and `memgineering undo` reverses it.
182
+ Ask before widening: a rule the user wrote about one repository, made global,
183
+ arrives in every session they open.
184
+ - **`--no-rule` on its own asks for nothing else.** No claim, no summary — the
185
+ conclusion, the summary and the title come back byte for byte, which is the
186
+ whole reason it exists. It used to go through `revise`, which requires a
187
+ claim, so taking a marking back meant restating a conclusion nobody had
188
+ changed, from text this CLI hands back truncated. Do not restate anything;
189
+ `memgineering undo` reverses it.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: memgineering-setup
3
- description: Use when installing or configuring memgineering, when moving a brain between a machine and an account, when renaming or deleting a hosted brain, or whenever the user asks WHICH of their AI tools can see this memory. Triggers include "set up memgineering", "connect my notes", "rename my brain", "delete that brain", "does my other AI see this too", "which of my tools can read this", "will it work in the app on my phone", "no brain is linked".
3
+ description: Use when installing or configuring memgineering, when moving a brain between a machine and an account, when renaming or deleting a hosted brain, or whenever the user asks WHICH of their AI tools can see this memory. Triggers include "set up memgineering", "connect my notes", "rename my brain", "delete that brain", "does my other AI see this too", "which of my tools can read this", "will it work in the app on my phone", "can I use this in ChatGPT", "does it work in Claude.ai", "no brain is linked".
4
4
  type: skill
5
5
  allowed-tools: Bash(memgineering:*)
6
6
  ---
@@ -12,20 +12,37 @@ allowed-tools: Bash(memgineering:*)
12
12
  Answer this from here, not from a guess. The line is capability, not brand, so
13
13
  it does not move as products come and go:
14
14
 
15
- | | |
16
- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
17
- | **Any tool that can run a shell command** | Reads and writes the same brain. Nothing has to be built for a tool that does not exist yet. |
18
- | **Any tool that cannot** | **Not yet.** There is no connector. A hosted brain is reachable in principle and is not wired up in practice. |
15
+ | | |
16
+ | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
17
+ | **Any tool that can run a shell command** | Reads and writes the same brain. Nothing has to be built for a tool that does not exist yet. |
18
+ | **A chat app that takes a custom MCP connector, no shell** | Reads and writes the **hosted** brain on their account through `https://mcp.memgineering.com/mcp`, once they add that connector in the app and sign in with Google. Not a folder brain. |
19
+ | **Neither** | **Not yet.** |
19
20
 
20
21
  `memgineering setup` writes its guidance into the agent tools it finds on the
21
22
  machine, and `setup --dry-run` names the ones it actually found rather than
22
23
  guessing from a list.
23
24
 
24
25
  So when someone names a tool and asks whether it remembers too, work it out from
25
- that line and answer **not yet, and here is what does** — not a hedge, not a
26
- promise. "You are signed in, so it works everywhere" is the specific wrong
27
- answer: the account syncs the brain between machines, it does not add a surface
28
- that can read it.
26
+ those rows and answer plainly — not a hedge, not a promise:
27
+
28
+ - **ChatGPT** — Settings → **Developer mode** → add an MCP server with
29
+ `https://mcp.memgineering.com/mcp`, then sign in with Google when it asks.
30
+ - **Claude.ai, Claude Desktop, Cowork** — **Customize** → **Connectors** →
31
+ **Add custom connector** → the same URL. One connector covers all three, and
32
+ custom connectors are on every plan, the free one included.
33
+ - It reaches the brain **on their account**. A brain that lives only as a folder
34
+ on this machine is out of its reach until it is moved up (see "Moving a brain
35
+ between this machine and their account").
36
+ - Moving it up does NOT make it appear in the chat app by itself. When their
37
+ brain is still a folder, the answer is both steps, in order: move it up, then
38
+ add the connector above in their app. An answer that stops at the first step
39
+ leaves them with an account brain and no way in.
40
+ - `npx memgineering-mcp` — the local, stdio server — is **registry-only**. It has
41
+ no memory tools; for memory from a chat app, the URL above is the way.
42
+
43
+ "You are signed in here, so it works everywhere" is still the wrong answer: the
44
+ account syncs the brain between machines, and each chat app needs the connector
45
+ added in that app, once.
29
46
 
30
47
  ## 1. Register with the agents
31
48
 
@@ -49,6 +66,17 @@ Three things to do after running it:
49
66
  picks it up on its own when they do. There is nothing to poll and nothing
50
67
  to wait for.
51
68
 
69
+ The link is the key to that screen, not the code: whoever holds the whole link
70
+ can drive it. Give it only to them, never paste it anywhere else — with
71
+ `--json`, `setup_url` is printed only when no browser opened.
72
+
73
+ If they chose to upload existing notes on the screen, this machine does NOT
74
+ upload them on its own: the next `memgineering` command shows which folder and
75
+ which account would receive them, with the `push` that sends them. Check with
76
+ them that the account is theirs before running it. And a machine already
77
+ signed in to a different account is never switched by `setup --web` — the
78
+ terminal says so; `logout` first if they really mean to switch.
79
+
52
80
  The screen asks everything `--agent` takes from flags — sign in, where the
53
81
  memory lives, which brain, which tools, auto-update, the session hook — with
54
82
  the recommended answer pre-selected. A person who is already signed in to
@@ -93,8 +121,16 @@ restart. (Measured: a fresh agent relayed "restart required" as fact, the user
93
121
  checked, and it was not one.)
94
122
 
95
123
  **Ask before setting policy for them.** Auto-update means the tool updates
96
- itself; `--hook on` means note summaries and their standing rules reach an agent
97
- unasked. Recommend both, but they are theirs to decide.
124
+ itself: once a day, when a newer version exists, a global install starts
125
+ `memgineering update` in the background and the next run uses it (a project-local
126
+ or npx copy is never touched — it only gets the notice; nor is anything installed
127
+ from a session hook or under CI). One install runs at a time: `memgineering
128
+ update` run while a background install is going answers `update_in_progress`
129
+ and installs nothing — wait a few minutes and run it again; it reports whether
130
+ that install worked. `update_claim_stuck` means a crashed install's leftover
131
+ could not be cleared; its hint names the folder to delete. `--hook on` means note
132
+ summaries and their standing rules reach an agent unasked. Recommend both, but
133
+ they are theirs to decide.
98
134
 
99
135
  **Error telemetry is theirs to decide too, and defaults to off.** With
100
136
  `--error-telemetry on`, the CLI sends an anonymous report when it ITSELF
@@ -146,6 +182,15 @@ answered, and the trust is recorded per hook CONTENT
146
182
  so an upgrade that changes a hook asks again. Somebody who is not told this
147
183
  reads the silence as an install that did not take.
148
184
 
185
+ **An update brings the hooks along.** The first `resurface` (session start)
186
+ after an update — or the next command anybody types — replaces memgineering's
187
+ own hook commands with the new version's, in both Claude Code and Codex, and
188
+ says so once. It replaces only a command memgineering itself shipped: a hook
189
+ someone edited (an absolute path, say), a removed hook, a symlinked or
190
+ unreadable settings file are left exactly as they are, and the last two are
191
+ named once. When a Codex hook changed this way, Codex asks for the review
192
+ above again at its next start — relay that, with the key.
193
+
149
194
  Grok is the case worth knowing, because the obvious guess is wrong: it has
150
195
  hooks, more events than either of those two, and `~/.grok/hooks/` needs no
151
196
  trust prompt — but a hook there cannot say anything to the model. Measured
@@ -441,9 +486,12 @@ as a next step rather than running it.
441
486
 
442
487
  ### What a hosted brain does that a folder does not
443
488
 
444
- Every verb works on either kind now, consolidation included. Two things are
489
+ Every verb works on either kind now, consolidation included. Three things are
445
490
  only true of a hosted brain.
446
491
 
492
+ **A chat app with no shell can reach it** — through the connector at the top of
493
+ this file. A folder brain is reached only by tools that can run `memgineering`.
494
+
447
495
  **Meaning is searched, if a model is configured for it.** That is what lets an
448
496
  English question reach a Korean note. It needs `BRAIN_EMBEDDING_URL` and
449
497
  `BRAIN_EMBEDDING_MODEL` set on the server; with neither, the brain searches text
@@ -475,7 +523,7 @@ answers without changing its name and the index has to be laid down again.
475
523
  ## Turning things off
476
524
 
477
525
  ```
478
- memgineering setup --agent --auto-update off
526
+ memgineering setup --agent --auto-update off # the hook stays as this machine recorded it
479
527
  memgineering unlink # stop reading a brain; notes untouched
480
528
  memgineering unlink --purge # also delete the local index and undo snapshots
481
529
  ```