sealkeep 0.11.2 → 0.11.3

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/ARCHITECTURE.md CHANGED
@@ -88,6 +88,26 @@ Automatic context has a deliberately split latency contract:
88
88
  later safe boundary. Provider latency therefore changes freshness, never the
89
89
  latency of the current prompt or tool result.
90
90
 
91
+ What that prepared context is then *used* for changed deliberately. Anything a
92
+ hook adds to a conversation is re-read by the model on every later step of the
93
+ session, so an unrequested block is not paid for once — it is rent for the rest
94
+ of the session. Measured on one real session: 129 automatic injections, about
95
+ 465 tokens each, roughly 60,000 tokens of permanent weight nobody asked for.
96
+
97
+ So recall is pull, not push. `formatNotice` emits one line at the start of a
98
+ session saying preserved history exists and how to search it, and nothing
99
+ afterwards; the agent reaches for the index over MCP when a question actually
100
+ needs it. Teammate events still pass through, because a teammate line is a
101
+ person addressing the session rather than recall addressing itself. The old
102
+ behaviour remains available behind `recallPushEnabled` — `SEALKEEP_RECALL_PUSH=1`
103
+ or a `runtime/recall-push` marker in the data directory — which is also what the
104
+ tests that assert recall *content* switch on.
105
+
106
+ `sealkeep meter` is the other half of the same idea. It reads local session
107
+ files only, with no key and no network, and reports what each live session costs
108
+ per step, what share of that is re-read history, and what the same work would
109
+ cost from a fresh session carrying a small context pack.
110
+
91
111
  Autopilot has a similarly explicit deletion boundary. A fresh installation
92
112
  preserves, indexes, and uploads, while `local-settings.json` records
93
113
  `reclaimEnabled: false`; neither the generated service unit nor the running
package/CHANGELOG.md CHANGED
@@ -3,6 +3,123 @@
3
3
  Notable changes, by published version. Sealkeep is pre-1.0: minor versions
4
4
  may change behavior, and say so here when they do.
5
5
 
6
+ ## 0.11.3 — 2026-09-23 — the context tax, and a vault that catches up
7
+
8
+ - **The team check stops asking the cloud every three seconds.** The daemon
9
+ asked the same four questions twenty times a minute whether or not anything
10
+ had happened, and fetched the team space list three times per pass. Measured
11
+ against a stub plane, an idle daemon made 56 requests in 30 seconds, 55 of
12
+ them from this one loop: about 4.8 million a month per always-on machine,
13
+ with every machine drawing on one shared Cloud allowance. The list is now
14
+ fetched once, and a pass that finds nothing doubles the wait up to two
15
+ minutes; a pass that changes something brings the next one straight back.
16
+ Idle, that is 4 requests every 2 minutes, around 86,000 a month. Pushing
17
+ changes over realtime instead is the next step.
18
+
19
+ - **Automatic uploads finish on a large vault.** Choosing where an archive
20
+ belongs walks every link of its chain and may ask the account whether a copy
21
+ already matches. That is real work that moves no bytes, and the upload
22
+ pass's two-minute idle deadline only counted bytes, so on a vault of 5,062
23
+ archives the first byte came at 168 seconds and every pass was stopped
24
+ before it began: no automatic upload ran for days while every surface
25
+ reported the service healthy. Preparation now counts as progress; a stalled
26
+ transfer still trips the deadline, because it reports no bytes either.
27
+
28
+ - **The start of a long session becomes searchable.** The index build skipped
29
+ every earlier snapshot of a growing session, assuming the newest one would be
30
+ walked and cover them. A snapshot indexed as it was sealed is never walked,
31
+ and covers only the bytes it added, so everything sealed before it was never
32
+ indexed at all. On one real vault that was 400 snapshots across 76 sessions:
33
+ words found only in their early part came back in 0 of 20 searches, words
34
+ from the covered tail in 10. The build now schedules the newest snapshot that
35
+ still needs indexing, and walking its chain covers the rest.
36
+
37
+ - **`sealkeep index build` says what it did.** It printed the index's running
38
+ total as if it were the result — "Indexed 4509 archives" after a run that
39
+ indexed one, while the 410 that doctor had sent the user to fix stayed as
40
+ they were. It now reports what this run covered, says "Already up to date"
41
+ when there was nothing, and names what is still missing. It no longer claims
42
+ the index is never uploaded: it is synced to your account, as ciphertext.
43
+
44
+ - **The daemon's "is the index finished" check can pass.** It counted
45
+ superseded snapshots, which are never indexed on their own by design, so on
46
+ any vault that had ever superseded one it retried `index_incomplete` forever,
47
+ and disk reclaim waits for that check. It now uses the same definition as
48
+ `sealkeep index status` and doctor.
49
+
50
+ - **Settings for what reaches your agent, and what this machine will spend.**
51
+ The local Settings page gains four controls, all with the numbers behind
52
+ them stated plainly rather than hidden: hand preserved history to an agent
53
+ when a session starts (on, with what it costs spelled out), let agents search
54
+ this vault themselves (on, the local MCP server), a background CPU ceiling,
55
+ and a background memory ceiling. Both ceilings only ever make Sealkeep
56
+ gentler than the automatic value, never greedier, and each has a floor below
57
+ which work would stall rather than pace. Turning recall off still leaves
58
+ preserved history written as notes the agent reads for itself.
59
+
60
+ - **The agent-facing hook gets four seconds instead of two.** It unlocks the
61
+ keystore and decrypts a prepared file, measured at about 1.25 s on a modest
62
+ server; a live run went over two seconds and the agent discarded the output
63
+ with "hook timed out after 2s", so recall silently did nothing and nobody was
64
+ told. Four still fails open long before a person notices.
65
+
66
+ - **`sealkeep doctor` reports whether preserved history can reach the agent.**
67
+ A new `agent-memory-notes` check says whether Claude keeps a memory directory
68
+ for this project and how many preserved sessions have been written there.
69
+
70
+ - **Recall is written where the agent believes it.** Tested end to end on a
71
+ server, on two models: history pushed into the prompt by a hook was delivered
72
+ perfectly and then refused, in the agent's own words as "unverified/possibly
73
+ injected". Wording was not the cause — the same text pasted into a plain
74
+ session was believed. What an agent trusts is its own memory directory. So a
75
+ session start now writes preserved sessions there as ordinary notes, with
76
+ plain provenance (when the work happened, in this project) and no language
77
+ that reads as an injection; a note signed "recalled by Sealkeep" was read and
78
+ then discounted for exactly that reason. Notes are namespaced, additive, and
79
+ never touch a person's own notes or index lines. After the change the same
80
+ agent answered from memory, called Sealkeep itself for the detail, and got it
81
+ right.
82
+
83
+ - **Recall never quotes a conversation back to itself.** A long session is
84
+ sealed while it is still running, so the newest preserved session was the one
85
+ you were in: an agent was shown its own earlier "I don't know" above a genuine
86
+ finding, judged the evidence contradictory, and used neither. Automatic recall
87
+ now excludes the current transcript and anything sealed since this
88
+ conversation began. `SEALKEEP_RECALL_DAYS` bounds how far back it looks, off
89
+ by default because a decision from a month ago is worth being reminded of.
90
+
91
+ - **`sealkeep fork`** is the way out of an expensive session. Resuming a long
92
+ conversation sends its whole transcript with every request; one real evening,
93
+ two questions on a resumed session cost 41 million tokens, of which about
94
+ 220,000 were the work. `fork` prices carrying on against starting fresh,
95
+ distils the session into a small pack — where the work got to, what was being
96
+ asked for, which files were open — and prints the command to start a new
97
+ session with it. Crucially it verifies first that the session is sealed and
98
+ indexed, and refuses to suggest walking away when it is not: the promise that
99
+ the history is one search away only holds if the history can actually be
100
+ searched.
101
+
102
+ - **Recall never tells a session the same thing twice.** Preserved context was
103
+ re-sent after every prompt and every Bash, Edit and Write, and 80% of it had
104
+ already been given to that same conversation: the identical preamble 140
105
+ times, the same list of preserved sessions over and over. Because everything
106
+ already in a conversation is re-read on every later request, that repetition
107
+ cost 81.6 million tokens on one measured session. Recall still runs at every
108
+ boundary and still searches against the current prompt; it now remembers what
109
+ this conversation has been told and sends only what is new, says the framing
110
+ once, and treats a passage as already-seen whichever section it arrives in.
111
+ The record is per conversation, so a new session is still told where the work
112
+ is up to. `SEALKEEP_RECALL_PUSH=0` restricts recall to session start only.
113
+
114
+ - **`sealkeep meter`** reports what your live agent sessions cost per step, how
115
+ much of that is re-read history, and what the same work would cost from a
116
+ fresh session carrying a small context pack. It reads local session files
117
+ only: no recovery phrase, no key, no network, nothing uploaded to produce a
118
+ number. Three signals, each of which was true of a session that ended a
119
+ weekly allowance: BLOATED when history is over 90% of input and over 50k a
120
+ step, STALE past seven days or 200 MB, and POLLING when an agent sleeps and
121
+ re-checks five or more times inside one turn.
122
+
6
123
  ## 0.11.2 — 2026-09-18 — a release tells you when a newer one exists
7
124
 
8
125
  - Sealkeep says, once a day at most, when a newer release is on npm and what
package/README.md CHANGED
@@ -50,6 +50,115 @@ source, your prompts, and whatever you pasted at 2am.
50
50
  So the two obvious options are both bad: let them fill the disk, or `rm -rf` the reasoning
51
51
  behind six months of work. Sealkeep is the third option.
52
52
 
53
+ ## What it saves you
54
+
55
+ An AI coding session charges you for its own history on every single step, and nothing
56
+ tells you until the limit is gone. A session that has been alive for three months carries
57
+ roughly 185,000 tokens of accumulated conversation, and every request re-sends all of it.
58
+ Ask a one-line question and you pay 185,000 tokens to ask it. Let an agent run a loop of
59
+ shell commands and you pay it once per command, whatever the command does.
60
+
61
+ The worst version of this is resuming an old session. Pick up a months-old conversation to
62
+ ask two questions and the whole transcript goes with every request: one real evening, two
63
+ questions on a resumed session cost 41 million tokens, of which about 220,000 were the work.
64
+ The weekly allowance was gone by 2am, and nothing had warned anybody.
65
+
66
+ **Leave the session instead of resuming it.** `sealkeep fork` prices the choice, checks the
67
+ history really is recoverable, and writes a small pack — where the work got to, what was
68
+ being asked for, which files were open — to start fresh with. Everything else stays in the
69
+ vault, and the pack tells your agent how to ask for it.
70
+
71
+ ```sh
72
+ sealkeep fork # the most expensive session you have open
73
+ sealkeep fork --write # write the pack and print the command to start fresh
74
+ ```
75
+
76
+ ```
77
+ The most expensive session you have open is the claude one in bot.
78
+
79
+ carrying on there 615k tokens per step, 97% of it re-read history
80
+ starting fresh 22k tokens per step, carrying a 392-token pack instead
81
+ you would save 593k tokens on every step from here on
82
+
83
+ The full session is sealed (afaa0cb4…) and searchable, so nothing is lost by leaving it.
84
+ ```
85
+
86
+ That last line is the part that matters. If the session is not sealed and indexed yet,
87
+ Sealkeep says so and refuses to pretend walking away is safe, because the promise only
88
+ holds if your agent can genuinely get the detail back when it needs one.
89
+
90
+ **It can also just tell you the number.** `sealkeep meter` answers the question nothing else
91
+ can: what is each live session costing per step, how much of that is re-read history, and
92
+ what the same work would cost starting fresh.
93
+
94
+ ```sh
95
+ sealkeep meter # the last 24 hours
96
+ sealkeep meter --hours 6 --json
97
+ ```
98
+
99
+ It reads local session files only. No recovery phrase, no key, no network, nothing uploaded
100
+ to produce a number. One real morning on one machine:
101
+
102
+ ```
103
+ tool where steps per step history total in signals
104
+ claude bot 457 597k 97% 272.8M BLOATED
105
+ claude sometest 368 474k 96% 174.3M BLOATED STALE
106
+ codex spala 581 162k 99% 94.2M BLOATED STALE POLLING
107
+
108
+ Total sent: 807.8M. The same work from fresh sessions carrying a 3k-token pack: about 36.5M.
109
+ That is roughly 771.4M spent re-reading, 95% of everything you sent.
110
+ ```
111
+
112
+ Three signals, each of which was true of a session that ended a weekly allowance:
113
+ **BLOATED** when history is over 90% of input and over 50k a step, **STALE** past seven days
114
+ or 200 MB, and **POLLING** when an agent sleeps and re-checks five or more times inside one
115
+ turn, paying the whole context on every tick.
116
+
117
+ **Recall never tells your session the same thing twice.** It used to re-send the same
118
+ preamble and the same list of preserved sessions after every prompt and every Bash, Edit
119
+ and Write. Measured on one real session:
120
+
121
+ | Injections over one session | 140 |
122
+ | :-- | --: |
123
+ | Payload they carried | ~65,000 tokens |
124
+ | Of that, lines the session had already been given | **80%** |
125
+ | What the repetition cost to re-send | **81.6 million tokens** |
126
+
127
+ A block added early is re-sent on every one of the thousands of requests after it, so
128
+ repeating yourself is the most expensive thing a memory tool can do.
129
+
130
+ So recall still runs at every boundary, exactly as before, and still searches against what
131
+ you just typed. It simply keeps track of what this conversation has already been told and
132
+ sends only the part that is new. The framing is said once. A passage that arrived as a
133
+ preserved session is not sent again as a search excerpt, because it is the same sentence
134
+ wearing a different prefix. Nothing is lost: a genuinely new excerpt, or a teammate's new
135
+ line, still arrives the moment it exists.
136
+
137
+ The book-keeping is per conversation, not permanent. A new session is a new reader and is
138
+ told where the work is up to, even though an earlier session on the same machine was told
139
+ the same thing.
140
+
141
+ Set `SEALKEEP_RECALL_PUSH=0` if you want memories only at session start and silence after.
142
+
143
+ **Your history stays searchable without living in the prompt.** The whole archive is one
144
+ `sealkeep search` or one MCP call away, so nothing has to be carried forward just in case.
145
+
146
+ **Your disk comes back.** Verified, searchable, idle sessions are reclaimed, and the
147
+ reasoning behind them survives in a form you can still read years later.
148
+
149
+ ## What you can turn off
150
+
151
+ Everything automatic has a switch, on the local Settings page, with its cost stated rather
152
+ than hidden.
153
+
154
+ | Setting | Default | What it means |
155
+ | --- | --- | --- |
156
+ | Hand preserved history to an agent at session start | on | Your agent opens a project and knows where you left off. Each thing is sent once and never repeated; on a measured session that was under one percent of what the session sent. Off still writes the notes. |
157
+ | Let agents search this vault themselves | on | The local tool server, so an agent can look things up on demand. Nothing is exposed to the network. |
158
+ | Background CPU ceiling | automatic | Targets 30% of one core. A number here only ever makes Sealkeep gentler. |
159
+ | Background memory ceiling | automatic | The ceiling a worker may reach before it stops and retries smaller. |
160
+ | Background network limit | automatic | One 8 Mbps ceiling shared across Sealkeep's jobs. |
161
+
53
162
  ## How it works
54
163
 
55
164
  The order is the safety property. Nothing is reclaimed before it is verified, and nothing is
@@ -160,6 +269,8 @@ it stores archives as single objects, and says so.
160
269
  | `sealkeep autopilot status` · `off` | Check on it, or stop it |
161
270
  | `sealkeep quickstart` | Same setup, no background service |
162
271
  | `sealkeep status` · `doctor` | What is archived; whether this machine is healthy |
272
+ | `sealkeep meter` | What your live sessions cost per step, and how much of it is re-read history |
273
+ | `sealkeep fork` | Leave an expensive session without losing what it knows |
163
274
  | `sealkeep queue run` | Encrypt everything waiting |
164
275
  | `sealkeep daemon` | Watch, seal, index, and upload continuously; reclaim only when enabled |
165
276
  | `sealkeep search <query>` | Metadata search; `--content` searches inside sessions |
@@ -181,9 +292,12 @@ Codex, so the agent itself can search your sealed history, check vault
181
292
  status, and restore a session it needs — six tools, all local, nothing new
182
293
  exposed to the network.
183
294
 
184
- Ordinary work does not depend on the agent remembering to call that tool.
185
- The installed lifecycle hooks identify the current Git project and inject a
186
- small, labelled context automatically:
295
+ The installed lifecycle hooks identify the current Git project and prepare that
296
+ history locally, so the search is instant when the agent asks for it. What they
297
+ no longer do is push it into the conversation: at the start of a session you get
298
+ one line saying preserved history exists, and after that, silence until something
299
+ is actually requested. Two things still arrive on their own, because both are a
300
+ person talking rather than recall talking to itself:
187
301
 
188
302
  - **One developer, several machines.** A finished Mac session is sealed and
189
303
  its encrypted index syncs in the background. When the same developer opens