memgineering 0.11.1 → 0.12.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,69 @@ language the reader wants. The bilingual rule the monorepo applies to
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.12.0] — 2026-08-28
15
+
16
+ ### Added
17
+
18
+ - **A declared storage boundary now refuses the write that breaks it.**
19
+ `remember --never-store "health, hospital, …"` records the user's own
20
+ sentence plus the word list that enforces it (`--never-store` implies
21
+ `--rule`, so the declaration shows up in `memgineering rules` and the
22
+ before-edit hook). From then on, a write carrying a declared word is
23
+ refused with the matched word and the declaration quoted back — on a
24
+ hosted brain and on a folder alike, whether or not the agent read
25
+ anything first. Every door is screened: `remember`, `revise`'s claim /
26
+ summary / title, curation's free-text fields, a proposal's added lines,
27
+ and each note of a bulk `push` (one refusal no longer stops the batch;
28
+ the rest upload and the summary names what was refused). The failure
29
+ this closes was measured: a fast-tier agent wrote two health facts on
30
+ its first turn having opened nothing; in the round-12 rerun the same
31
+ agent was refused and the facts stayed out.
32
+ - **Refusal is lexical by measurement, not by preference.** Against the
33
+ production embedding profile, semantic similarity cannot separate what
34
+ must be refused from what must be allowed at any threshold
35
+ (`docs/research/boundary-matching-2026-08.md`) — so the words the user
36
+ chose are the entire law: deterministic, explainable, zero-latency,
37
+ identical hosted and local. The matcher sees words as written — no
38
+ stemmer, so declare nouns; one-character terms are refused at
39
+ declaration time because they match half the dictionary; CJK terms
40
+ match inside words (that is what makes particles work), Latin terms on
41
+ word boundaries.
42
+ - **What the words miss, a suggestion surfaces — and it never refuses.**
43
+ On a hosted brain with embeddings, a stored note that reads close to a
44
+ declared boundary while containing none of its words comes back with
45
+ one line naming the declaration and both actions: `undo`, or widen the
46
+ list. The catch rate on paraphrases is partial by measurement (a
47
+ 25–50% band on hand-built sets) and it interrupts rarely (4% of benign
48
+ writes measured) — it exists so the user learns their word list has a
49
+ hole, not to detect paraphrase. Any embedding failure drops the
50
+ suggestion silently, never the write. A brain with no declarations
51
+ pays one SQL lookup and nothing else — no matching, no extra
52
+ embedding call.
53
+ - **Curating a boundary.** `revise <ref> --never-store "<words>"`
54
+ REPLACES the word list (`--claim` required — the restated boundary is
55
+ part of the edit), `--no-never-store` lifts the list while keeping the
56
+ note, and retiring the declaration lifts the boundary entirely: a
57
+ retired or excluded declaration stops refusing.
58
+ - **Crossing a boundary on purpose leaves a mark.**
59
+ `remember --override-boundary <declaration-path> --reason "<why>"`
60
+ stores the write anyway. The path is only learnable from the refusal
61
+ itself, the reason is enforced server-side, and the ledger records the
62
+ crossing — visible in `memgineering log`, counted by `evidence`.
63
+ Declaring a boundary is itself marked in the ledger, so the audit
64
+ trail starts at the declaration. Honest limit: the override's
65
+ `--reason` is free text and unscreened; guidance forbids restating
66
+ blocked content there, but nothing enforces it.
67
+
68
+ ### Agent guidance
69
+
70
+ - The hub and the `memgineering-writing` skill changed substantially:
71
+ how to record a declaration (nouns, generous list, nothing
72
+ one-character), what to do when refused (the override is the user's
73
+ call, never a retry reflex), and why `--never-store` REPLACES rather
74
+ than adds. Restart your agent session after upgrading so the new
75
+ guidance is what gets injected.
76
+
14
77
  ## [0.11.1] — 2026-08-27
15
78
 
16
79
  ### Added
@@ -22,8 +85,9 @@ language the reader wants. The bilingual rule the monorepo applies to
22
85
  guidance tells an agent to check the file before recording anything in a
23
86
  commonly guarded domain. Honest limit, measured in fresh-session rounds: the
24
87
  check holds for agents that read before writing; a fast-tier agent that fires
25
- `remember` reflexively can still miss it — a server-side advisory at write
26
- time is the planned follow-up.
88
+ `remember` reflexively can still miss it — closed in 0.12.0, where a declared
89
+ boundary refuses the write itself (this entry originally promised an
90
+ "advisory"; what shipped is a refusal).
27
91
  - **A fact carried in from another store names its source.** New guidance
28
92
  section: when memories are migrated from another tool's files or a pasted
29
93
  document, the `--reason` names the source file — never a confirmation that
@@ -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.11.1
5
+ version: 0.12.0
6
6
  ---
7
7
 
8
8
  # memgineering
@@ -322,20 +322,99 @@ what must never be WRITTEN into this brain at all. "Do not keep anything about
322
322
  my health here" is the second kind — the user's own sensitive-topics control,
323
323
  except they name the topics.
324
324
 
325
- **Check before you record, not after.** Before writing something in a domain
326
- people commonly guardhealth, beliefs, relationships, politics, sexuality,
327
- money trouble run `memgineering open boundaries` first, unless this session
328
- has already read that file. The card shows a base file's whole body, and the
329
- boundaries live in the body a recall card or a resurface line may name the
330
- file without quoting them, and an empty-looking card is not permission. A declared storage boundary beats every
331
- "write it down" trigger in this skill: skip the write and say in one sentence
332
- why. If nothing is declared and the remark still feels sensitive, the section
333
- below applies record, but say so once, plainly.
334
-
335
- When the user declares one ("never write anything about my family"), it is
336
- worth two writes: the line itself into `BOUNDARIES.md` — their file, their
337
- words and, since it should hold next time, a `--rule`; see
338
- `memgineering-rules`.
325
+ **The second kind is enforced, not advised.** A write carrying a declared word
326
+ is refused by the product at every door, on a hosted brain and on a folder,
327
+ whether or not you read anything first. That is deliberate: guidance only
328
+ reaches the agent that reads, and the failure this answers was a session that
329
+ wrote two health facts on its first turn having opened nothing.
330
+
331
+ ### Recording one
332
+
333
+ When the user says "never write anything about my health here", it takes one
334
+ write and a word list:
335
+
336
+ ```bash
337
+ memgineering remember "Nothing about my health gets written into this brain" \
338
+ --never-store "health, hospital, clinic, diagnosis, symptom, medication" \
339
+ --reason "they said it twice and it keeps getting missed"
340
+ ```
341
+
342
+ The sentence is theirs and stays their words. The LIST is what refuses, so:
343
+
344
+ - **Nouns, not verbs.** There is no stemmer: a verb will not be caught in
345
+ another tense, in any language.
346
+ - **Nothing one character long** — refused at the door. A single Korean
347
+ syllable, or an English letter, matches half the dictionary.
348
+ - **Be generous.** A word costs nothing until it matches, and a topic the list
349
+ misses is a fact that lands silently.
350
+ - A term in a language written without spaces between words matches INSIDE a
351
+ word — which is what makes it work at all where particles attach to nouns,
352
+ and also means it catches compounds the user may not have pictured. Latin
353
+ terms match on word boundaries instead: "med" will not catch "media".
354
+
355
+ `--never-store` implies `--rule`, so the declaration appears in
356
+ `memgineering rules` and in the before-edit hook — which is where the user sees
357
+ what they have declared.
358
+
359
+ ### Widening, narrowing, lifting
360
+
361
+ `--never-store` **REPLACES** the list; it does not add to it. So to add a word,
362
+ read the declaration first and name every word it should still hold:
363
+
364
+ ```bash
365
+ memgineering revise <ref> \
366
+ --claim "<the boundary, restated to cover the new word>" \
367
+ --never-store "health, hospital, clinic, diagnosis, symptom, medication, therapy"
368
+ ```
369
+
370
+ `--claim` is required, and an unchanged claim is refused — restate the boundary
371
+ rather than copying the line already there. **Naming only the new word deletes
372
+ the words already declared**, which is the opposite of what anybody asking for
373
+ this wants.
374
+
375
+ To lift a boundary entirely: `memgineering retire <the declaration>`. That is
376
+ the un-declare path, and it is the user's decision, never yours.
377
+
378
+ On a hosted brain the declaration NOTE is the record — there is no route that
379
+ edits a base file's body, so mirroring the sentence into `BOUNDARIES.md` is a
380
+ folder-brain and onboarding-time thing.
381
+
382
+ ### When a write is refused
383
+
384
+ The refusal names the word and quotes the declaration. What it means is that
385
+ the person whose brain this is already decided, so:
386
+
387
+ - **Record everything else** you learned, leaving that fact out, and carry on.
388
+ A refusal is not a failed task.
389
+ - **Do not send it again with the word taken out.** The boundary is about the
390
+ fact, not the spelling.
391
+ - **Do not put what was blocked into `reason`, a title, a scope, or any other
392
+ field.** The ledger is stored too; moving it is storing it.
393
+ - **Do not attach `--never-store` to get past the screen.** A write that
394
+ declares a boundary is exempt from screening, which makes that a bypass — and
395
+ it is recorded in the ledger as one, at every door.
396
+ - There IS an exception flag, and it is not yours to reach for. It exists for
397
+ the user saying "no, keep this one". If they did not say that in this
398
+ conversation, the answer is to leave the fact out.
399
+
400
+ ### The suggestion, and what silence from it is worth
401
+
402
+ A write can be plainly on a declared topic while carrying none of the declared
403
+ words, and words cannot see that. When the server notices one it says so after
404
+ storing it — it never refuses — and offers the two things worth doing: take the
405
+ note back with `undo`, or widen the list so next time it is refused properly.
406
+
407
+ Measured, it notices roughly a third to a half of them, and it is skewed: a
408
+ topic with broad vocabulary is caught more often than a narrow one. **So
409
+ silence from it is not permission.** It is a prompt to widen a list, not a
410
+ clean bill of health, and telling the user what it said is usually the right
411
+ move — the decision is theirs.
412
+
413
+ ### What the enforcement does not cover
414
+
415
+ The word list is checked on every write that carries user prose. It is NOT
416
+ checked on `reason` — say so plainly if that matters to them — and a brain in a
417
+ folder can always be edited outside this tool, which no CLI can prevent.
339
418
 
340
419
  ## What to raise with the user
341
420