sealkeep 0.11.2 → 0.11.4

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,152 @@
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.4 — 2026-09-23 — history stays findable
7
+
8
+ - **An archive can no longer be dropped from search because one sidecar could
9
+ not be read.** The build treats an id missing from the archive ledger as
10
+ deleted and retires it, which in segments mode is permanent: the id vanishes
11
+ from every later lookup and no build indexes it again. But the ledger scan
12
+ skips any sidecar it cannot parse — a partial write being replaced, one
13
+ transient read error — and that scan is cached per directory, so the damage
14
+ only surfaces when something else changes the directory: a seal arriving
15
+ while a build runs, which is what a busy machine does all day. On one real
16
+ vault ten archives had been retired with nothing superseding them, and two
17
+ sessions were genuinely unfindable — words in one returned no hits from it
18
+ while matching hundreds of other sessions. Absence now counts as deletion
19
+ only when the scan read every sidecar.
20
+
21
+ A vault that already lost archives this way recovers with `sealkeep index
22
+ drop` followed by `sealkeep index build`, which clears every retirement and
23
+ indexes the archives again. Repairing it automatically was tried and dropped:
24
+ a retirement also travels between your machines, so a build that lifted one
25
+ could undo a removal another machine meant, and the suite caught that.
26
+
27
+ - **The team check no longer runs on every seal.** 0.11.3 gave the lane its own
28
+ backing-off cadence, but a tick still asked it for a pass, and a tick is
29
+ scheduled whenever the queue has work — so cloud traffic still followed local
30
+ sealing. Measured on a busy machine: passes 4-6 seconds apart while a backlog
31
+ drained, against the 6-to-120-second schedule the lane had chosen. Nothing is
32
+ lost by waiting for that schedule; a pass this machine's own sealing triggers
33
+ cannot learn anything sooner than one the clock triggers.
34
+
35
+ ## 0.11.3 — 2026-09-23 — the context tax, and a vault that catches up
36
+
37
+ - **The team check stops asking the cloud every three seconds.** The daemon
38
+ asked the same four questions twenty times a minute whether or not anything
39
+ had happened, and fetched the team space list three times per pass. Measured
40
+ against a stub plane, an idle daemon made 56 requests in 30 seconds, 55 of
41
+ them from this one loop: about 4.8 million a month per always-on machine,
42
+ with every machine drawing on one shared Cloud allowance. The list is now
43
+ fetched once, and a pass that finds nothing doubles the wait up to two
44
+ minutes; a pass that changes something brings the next one straight back.
45
+ Idle, that is 4 requests every 2 minutes, around 86,000 a month. Pushing
46
+ changes over realtime instead is the next step.
47
+
48
+ - **Automatic uploads finish on a large vault.** Choosing where an archive
49
+ belongs walks every link of its chain and may ask the account whether a copy
50
+ already matches. That is real work that moves no bytes, and the upload
51
+ pass's two-minute idle deadline only counted bytes, so on a vault of 5,062
52
+ archives the first byte came at 168 seconds and every pass was stopped
53
+ before it began: no automatic upload ran for days while every surface
54
+ reported the service healthy. Preparation now counts as progress; a stalled
55
+ transfer still trips the deadline, because it reports no bytes either.
56
+
57
+ - **The start of a long session becomes searchable.** The index build skipped
58
+ every earlier snapshot of a growing session, assuming the newest one would be
59
+ walked and cover them. A snapshot indexed as it was sealed is never walked,
60
+ and covers only the bytes it added, so everything sealed before it was never
61
+ indexed at all. On one real vault that was 400 snapshots across 76 sessions:
62
+ words found only in their early part came back in 0 of 20 searches, words
63
+ from the covered tail in 10. The build now schedules the newest snapshot that
64
+ still needs indexing, and walking its chain covers the rest.
65
+
66
+ - **`sealkeep index build` says what it did.** It printed the index's running
67
+ total as if it were the result — "Indexed 4509 archives" after a run that
68
+ indexed one, while the 410 that doctor had sent the user to fix stayed as
69
+ they were. It now reports what this run covered, says "Already up to date"
70
+ when there was nothing, and names what is still missing. It no longer claims
71
+ the index is never uploaded: it is synced to your account, as ciphertext.
72
+
73
+ - **The daemon's "is the index finished" check can pass.** It counted
74
+ superseded snapshots, which are never indexed on their own by design, so on
75
+ any vault that had ever superseded one it retried `index_incomplete` forever,
76
+ and disk reclaim waits for that check. It now uses the same definition as
77
+ `sealkeep index status` and doctor.
78
+
79
+ - **Settings for what reaches your agent, and what this machine will spend.**
80
+ The local Settings page gains four controls, all with the numbers behind
81
+ them stated plainly rather than hidden: hand preserved history to an agent
82
+ when a session starts (on, with what it costs spelled out), let agents search
83
+ this vault themselves (on, the local MCP server), a background CPU ceiling,
84
+ and a background memory ceiling. Both ceilings only ever make Sealkeep
85
+ gentler than the automatic value, never greedier, and each has a floor below
86
+ which work would stall rather than pace. Turning recall off still leaves
87
+ preserved history written as notes the agent reads for itself.
88
+
89
+ - **The agent-facing hook gets four seconds instead of two.** It unlocks the
90
+ keystore and decrypts a prepared file, measured at about 1.25 s on a modest
91
+ server; a live run went over two seconds and the agent discarded the output
92
+ with "hook timed out after 2s", so recall silently did nothing and nobody was
93
+ told. Four still fails open long before a person notices.
94
+
95
+ - **`sealkeep doctor` reports whether preserved history can reach the agent.**
96
+ A new `agent-memory-notes` check says whether Claude keeps a memory directory
97
+ for this project and how many preserved sessions have been written there.
98
+
99
+ - **Recall is written where the agent believes it.** Tested end to end on a
100
+ server, on two models: history pushed into the prompt by a hook was delivered
101
+ perfectly and then refused, in the agent's own words as "unverified/possibly
102
+ injected". Wording was not the cause — the same text pasted into a plain
103
+ session was believed. What an agent trusts is its own memory directory. So a
104
+ session start now writes preserved sessions there as ordinary notes, with
105
+ plain provenance (when the work happened, in this project) and no language
106
+ that reads as an injection; a note signed "recalled by Sealkeep" was read and
107
+ then discounted for exactly that reason. Notes are namespaced, additive, and
108
+ never touch a person's own notes or index lines. After the change the same
109
+ agent answered from memory, called Sealkeep itself for the detail, and got it
110
+ right.
111
+
112
+ - **Recall never quotes a conversation back to itself.** A long session is
113
+ sealed while it is still running, so the newest preserved session was the one
114
+ you were in: an agent was shown its own earlier "I don't know" above a genuine
115
+ finding, judged the evidence contradictory, and used neither. Automatic recall
116
+ now excludes the current transcript and anything sealed since this
117
+ conversation began. `SEALKEEP_RECALL_DAYS` bounds how far back it looks, off
118
+ by default because a decision from a month ago is worth being reminded of.
119
+
120
+ - **`sealkeep fork`** is the way out of an expensive session. Resuming a long
121
+ conversation sends its whole transcript with every request; one real evening,
122
+ two questions on a resumed session cost 41 million tokens, of which about
123
+ 220,000 were the work. `fork` prices carrying on against starting fresh,
124
+ distils the session into a small pack — where the work got to, what was being
125
+ asked for, which files were open — and prints the command to start a new
126
+ session with it. Crucially it verifies first that the session is sealed and
127
+ indexed, and refuses to suggest walking away when it is not: the promise that
128
+ the history is one search away only holds if the history can actually be
129
+ searched.
130
+
131
+ - **Recall never tells a session the same thing twice.** Preserved context was
132
+ re-sent after every prompt and every Bash, Edit and Write, and 80% of it had
133
+ already been given to that same conversation: the identical preamble 140
134
+ times, the same list of preserved sessions over and over. Because everything
135
+ already in a conversation is re-read on every later request, that repetition
136
+ cost 81.6 million tokens on one measured session. Recall still runs at every
137
+ boundary and still searches against the current prompt; it now remembers what
138
+ this conversation has been told and sends only what is new, says the framing
139
+ once, and treats a passage as already-seen whichever section it arrives in.
140
+ The record is per conversation, so a new session is still told where the work
141
+ is up to. `SEALKEEP_RECALL_PUSH=0` restricts recall to session start only.
142
+
143
+ - **`sealkeep meter`** reports what your live agent sessions cost per step, how
144
+ much of that is re-read history, and what the same work would cost from a
145
+ fresh session carrying a small context pack. It reads local session files
146
+ only: no recovery phrase, no key, no network, nothing uploaded to produce a
147
+ number. Three signals, each of which was true of a session that ended a
148
+ weekly allowance: BLOATED when history is over 90% of input and over 50k a
149
+ step, STALE past seven days or 200 MB, and POLLING when an agent sleeps and
150
+ re-checks five or more times inside one turn.
151
+
6
152
  ## 0.11.2 — 2026-09-18 — a release tells you when a newer one exists
7
153
 
8
154
  - 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