@unblocklabs/unblock-memory 0.3.21 → 0.3.23
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/README.md +86 -990
- package/dist/src/config.d.ts +0 -5
- package/dist/src/config.js +2 -21
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/manager.d.ts +0 -1
- package/dist/src/manager.js +2 -22
- package/dist/src/people-store.d.ts +37 -3
- package/dist/src/people-store.js +23 -9
- package/dist/src/people-tools.js +5 -5
- package/dist/src/plugin.js +13 -63
- package/dist/src/slack-directory.js +3 -2
- package/docs/configuration.md +380 -0
- package/docs/peoplesql.md +223 -0
- package/docs/response-audit.md +217 -0
- package/docs/retrieval.md +576 -0
- package/openclaw.plugin.json +7 -23
- package/package.json +6 -2
- package/skills/memory-curator/SKILL.md +5 -0
- package/skills/people-whisperer/SKILL.md +10 -0
- package/dist/src/xsearch-bm25.d.ts +0 -4
- package/dist/src/xsearch-bm25.js +0 -56
- package/dist/src/xsearch.d.ts +0 -62
- package/dist/src/xsearch.js +0 -124
package/README.md
CHANGED
|
@@ -1,1006 +1,102 @@
|
|
|
1
1
|
# Unblock Memory
|
|
2
2
|
|
|
3
|
-
## Hybrid search (`memory_xsearch`, opt-in)
|
|
4
|
-
|
|
5
|
-
`memory_search` remains vector-only. Enable `memory_xsearch` to combine vector
|
|
6
|
-
and BM25 retrieval, then independently score complete source excerpts with
|
|
7
|
-
TypeSafe. It is disabled by default and requires shared TypeSafe credentials
|
|
8
|
-
plus an explicit approved corpus list:
|
|
9
|
-
|
|
10
|
-
```json
|
|
11
|
-
{
|
|
12
|
-
"xsearch": {
|
|
13
|
-
"enabled": true,
|
|
14
|
-
"corpora": ["memory"],
|
|
15
|
-
"timeoutMs": 10000
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Place this under `plugins.entries.unblock-memory.config`. Enabling it approves
|
|
21
|
-
sending the query and selected excerpts from those corpora to TypeSafe. Skills
|
|
22
|
-
are excluded. Unapproved corpora are rejected; session filters apply to both
|
|
23
|
-
retrieval methods. `minScore` is final usefulness (0–1), not vector similarity.
|
|
24
|
-
The tool returns existing source spans with normal `memory_get` citations.
|
|
25
|
-
|
|
26
|
-
## Response quality tracking (opt-in)
|
|
27
|
-
|
|
28
|
-
`responseAudit` evaluates bounded human-agent exchanges in the background. It is
|
|
29
|
-
separate from chunk-quality auditing and never changes memories or prompts. It
|
|
30
|
-
creates private response-review tasks, not memory-curation tasks.
|
|
31
|
-
Its primary purpose is tracking delivery quality over time: visible fulfillment,
|
|
32
|
-
deliverable fit, clear underdelivery and its observable reason. Memory gaps are only
|
|
33
|
-
an optional diagnostic lead, not a proxy for performance.
|
|
34
|
-
Only approved Slack sender IDs with trusted `senderKind: human` or owner metadata
|
|
35
|
-
qualify (older Slack records use unknown senderKind even for known owners).
|
|
36
|
-
Explicit bots, unverified identities, internal messages, other senders and thread changes form
|
|
37
|
-
hard boundaries. Synthetic delivery mirrors and gateway-injected answers are excluded.
|
|
38
|
-
Assistant progress messages are grouped with the terminal answer.
|
|
39
|
-
Recognized Slack envelopes are stripped even inside `upstreamUserText`; embedded
|
|
40
|
-
history is not treated as current human text. Ambiguous envelopes are excluded.
|
|
41
|
-
Removed history marks the context as limited; ordinary Markdown/JSON is preserved.
|
|
42
|
-
Human feedback closes when the next assistant turn starts. Still-open feedback,
|
|
43
|
-
no-response exchanges, incomplete/failed turns and oversized inputs are not graded.
|
|
44
|
-
|
|
45
|
-
```json
|
|
46
|
-
{
|
|
47
|
-
"responseAudit": {
|
|
48
|
-
"enabled": true,
|
|
49
|
-
"sentimentEnabled": true,
|
|
50
|
-
"senderIds": ["YOUR_SLACK_USER_ID"],
|
|
51
|
-
"chatTypes": ["direct"],
|
|
52
|
-
"historyMessages": 6,
|
|
53
|
-
"lookbackDays": 30,
|
|
54
|
-
"maxEpisodes": 20,
|
|
55
|
-
"intervalMinutes": 60,
|
|
56
|
-
"memoryCorpora": ["memory", "knowledge"]
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
This is explicit approval to send those exchanges to TypeSafe. Sender IDs apply
|
|
62
|
-
across the agent's Slack accounts; use only identities approved in all such accounts.
|
|
63
|
-
`memoryCorpora` is optional and separately approves configured **file** corpora for
|
|
64
|
-
memory-gap investigation. Leave it empty to send no indexed memory evidence.
|
|
65
|
-
`typesafe.enabled: false` or missing credentials prevents evaluation. An interval
|
|
66
|
-
of zero means manual-only. Defaults are disabled, no approved senders, direct chats,
|
|
67
|
-
6 preceding visible messages, 30 days, 20 episodes per run and a 60-minute interval.
|
|
68
|
-
`sentimentEnabled` defaults to **true within that opt-in audit**; it does not bypass
|
|
69
|
-
approved senders or TypeSafe credentials. Set it false to omit polarity, annoyance,
|
|
70
|
-
frustration and intensity questions while retaining quality/repair judgments.
|
|
71
|
-
`intervalMinutes` controls their shared cadence; no second sentiment timer is needed.
|
|
72
|
-
The Gateway checks a durable per-agent due time on startup and every minute (no
|
|
73
|
-
agent-turn cron or separate launchd job). First enablement waits one interval;
|
|
74
|
-
restarts preserve the due time and an overdue schedule gets one bounded catch-up,
|
|
75
|
-
not one run per missed interval. Each attempt advances the due time before work,
|
|
76
|
-
including missing-key skips, failures or interrupted runs, to prevent retry storms.
|
|
77
|
-
Changing the interval recalculates the due time from the last scheduled attempt
|
|
78
|
-
(or initial enablement). The Gateway must be running; manual audits do not change
|
|
79
|
-
the automatic schedule. Missing/unreadable credentials skip all quality and sentiment
|
|
80
|
-
inference without failing Gateway startup or normal memory functionality.
|
|
81
|
-
Changing the interval does not invalidate cached results. Changing the sentiment
|
|
82
|
-
toggle selects a separate reporting cohort, so older missing sentiment is not
|
|
83
|
-
treated as neutral; unchanged quality/feedback stages are reused across the toggle.
|
|
84
|
-
|
|
85
|
-
Operator commands (not agent tools):
|
|
86
|
-
|
|
87
|
-
```sh
|
|
88
|
-
openclaw memory-responses audit --agent main --dry-run
|
|
89
|
-
openclaw memory-responses audit --agent main
|
|
90
|
-
openclaw memory-responses report --agent main
|
|
91
|
-
openclaw memory-responses report --agent main --episode EPISODE_ID
|
|
92
|
-
openclaw memory-responses report --agent main --sender SLACK_USER_ID --account ACCOUNT_SCOPE --bucket day --since 2026-09-01 --until 2026-10-01
|
|
93
|
-
openclaw memory-responses report --agent main --person PERSON_ID
|
|
94
|
-
openclaw memory-responses tasks --agent main
|
|
95
|
-
openclaw memory-responses review --agent main --id TASK_ID --status deferred --reviewer human --note "Review the linked exchanges before changing preferences"
|
|
96
|
-
openclaw memory-responses annotate --agent main --date 2026-09-18 --kind prompt --note "Known prompt revision deployed"
|
|
97
|
-
openclaw memory-responses retry-failed --agent main
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Reports group by scoped human identity as well as task/model/time. Names are not
|
|
101
|
-
identity keys. Existing active people-store links are resolved read-only at assessment
|
|
102
|
-
time; missing links do not prevent analysis. Unknown account scopes stay isolated
|
|
103
|
-
per session. No new identity fields are sent to TypeSafe. Date ranges are UTC with
|
|
104
|
-
an inclusive start and exclusive end. `periodStart` identifies a day/week bucket;
|
|
105
|
-
legacy `week`/`fromWeek`/`toWeek` fields remain aliases. `--task-type` and `--model`
|
|
106
|
-
further narrow comparisons. Human-specific scores are not rankings of the humans:
|
|
107
|
-
task difficulty, feedback habits and selection bias remain important.
|
|
108
|
-
|
|
109
|
-
Session checkpoints hash bounded active source bytes; unchanged sessions skip
|
|
110
|
-
extraction and all inference. Changed sessions are re-extracted within the existing
|
|
111
|
-
budget, then stage hashes reuse unchanged quality, feedback, sentiment and later
|
|
112
|
-
evidence judgments. Only hashes/counts are checkpointed, never a transcript copy.
|
|
113
|
-
A persisted cursor rotates through discovery and tracked-session reconciliation;
|
|
114
|
-
`deferredByLimit` includes known backlog and a lower-bound marker for unvisited
|
|
115
|
-
sessions. `stages` exposes pending/failed/succeeded counts and exhausted retries
|
|
116
|
-
for the cohort/date range, before person filters. `retry-failed` only resets failed
|
|
117
|
-
work; successful stages remain cached. Source freshness is checked before activation.
|
|
118
|
-
|
|
119
|
-
Review tasks distinguish concrete delivery shortfalls from high-intensity human
|
|
120
|
-
experience complaints. Stable task keys include exchange, scoped human and issue
|
|
121
|
-
family. Decisions survive rescoring; stale source evidence and superseded findings
|
|
122
|
-
are labeled separately. Review status/provenance never changes the raw judgments.
|
|
123
|
-
Tasks and change annotations are operator-only and stay out of memory/whisperer
|
|
124
|
-
prompts. `--reviewer` records human/agent provenance, not authentication or a new
|
|
125
|
-
permission grant. Task lists disclose their 1,000-item cap. There are no automatic
|
|
126
|
-
dossier updates: review the evidence and approve any concrete preference separately.
|
|
127
|
-
Old cohorts remain stored; the first staged-cohort run does not silently import
|
|
128
|
-
unverified older rubric judgments. Audit-history retention is not automatic.
|
|
129
|
-
|
|
130
|
-
Two separate TypeSafe requests prevent human feedback from influencing the original
|
|
131
|
-
fulfillment/deliverable-fit grade. The feedback pass distinguishes acceptance,
|
|
132
|
-
correction, continuation, unrelated replies, expressed sentiment, repeated constraints
|
|
133
|
-
and avoidable rework. Current-index memory investigation runs only for a strong
|
|
134
|
-
memory-gap signal: lexical retrieval selects up to three whole short documents from
|
|
135
|
-
approved collections. This is an investigation lead, **not proof of historical
|
|
136
|
-
availability, factual truth, or agent fault**. Tool-call counts do not establish what
|
|
137
|
-
the model saw or whether it should have searched. Unseen artifacts are unassessable.
|
|
138
|
-
|
|
139
|
-
Deliverable kind/format/scope has its own assessability gate, independent of whether
|
|
140
|
-
execution or external facts can be verified. Feedback attribution distinguishes the
|
|
141
|
-
current answer, earlier behavior, delivery, missing proactive action, external events,
|
|
142
|
-
new work and mixed/unclear targets. A reported forgotten instruction does not prove
|
|
143
|
-
searchable memory existed. A third, separate request examines the original exchange,
|
|
144
|
-
human feedback and available next assistant block for specific reported shortfalls,
|
|
145
|
-
acknowledgment, explicit factual corrections, delivery failures and regressions. These are
|
|
146
|
-
retrospective signals, not independently verified facts and never inputs to the
|
|
147
|
-
original grade. Clean text preceding a synthetic error/delivery notice can be assessed
|
|
148
|
-
as **partial** evidence; the notice itself is excluded and no successful completion
|
|
149
|
-
is inferred. Later evidence is capped at six messages/12K characters; incomplete,
|
|
150
|
-
unsafe or oversized blocks stay explicitly pending/unavailable/oversized. New later
|
|
151
|
-
evidence changes the input hash; only changed assessment stages are re-evaluated,
|
|
152
|
-
within normal audit budgets. Successful stages survive failures in later stages.
|
|
153
|
-
When the next block is unavailable, the third pass uses only the original exchange
|
|
154
|
-
and feedback; it cannot infer a missing delivery from missing later evidence.
|
|
155
|
-
|
|
156
|
-
Code combines narrow, confident evidence into an **observed outcome**, preserving
|
|
157
|
-
its basis and reason. A concrete original-answer shortfall or later admission takes
|
|
158
|
-
precedence over praise. Broad reported failures are used only when they do not
|
|
159
|
-
depend on a newly introduced requirement. Accurate explanations of earlier mistakes,
|
|
160
|
-
ordinary follow-ups, necessary clarification and unseen work are not automatically
|
|
161
|
-
failures. Sentiment and earlier-workflow complaints remain separate review signals.
|
|
162
|
-
Sentiment includes independent annoyance and frustration yes-probabilities (both
|
|
163
|
-
can apply), plus an expressed-dissatisfaction intensity score from 0 to 3. Intensity
|
|
164
|
-
means no expressed displeasure / restrained displeasure / pointed complaint /
|
|
165
|
-
explicit rejection or loss of trust. It is **not confidence or failure severity**.
|
|
166
|
-
External frustration, brevity and factual corrections alone do not establish
|
|
167
|
-
annoyance or frustration; mixed praise and complaints can still carry both signals.
|
|
168
|
-
Weekly reports show dissatisfaction, annoyance and frustration rates, intensity
|
|
169
|
-
means, unknown counts and their own assessment denominators. Unassessed results
|
|
170
|
-
are never counted as neutral. Sentiment deltas require 20 samples in both periods
|
|
171
|
-
and matching assessment coverage; they remain descriptive, not causal evidence.
|
|
172
|
-
Outcome, evidence basis and failure reasons remain distinct: a correction does not
|
|
173
|
-
automatically mean `incorrect_claim`. Confident reason judgments and direct
|
|
174
|
-
delivery/regression admissions supply reasons; otherwise `reasonStatus` is
|
|
175
|
-
`uncertain`. `reasonDetails` retain each label's source and strength, distinguishing
|
|
176
|
-
Choice confidence from Noul yes-probability. Multiple supported reasons can coexist.
|
|
177
|
-
`reportVersion` identifies composition/reporting semantics independently of the
|
|
178
|
-
judge rubric, allowing cached judgments to be re-reported without re-inference.
|
|
179
|
-
|
|
180
|
-
Results live in operator-only tables in the agent's private
|
|
181
|
-
`unblock-memory/unblock-memory.sqlite`, outside the memory index. These tables
|
|
182
|
-
are not searched or injected into agent prompts. They store judgments and source event references/hashes, not copies
|
|
183
|
-
of conversations. Identical successful inputs are cached; source rewrites invalidate
|
|
184
|
-
in-scope results on the next scan. Reports partition by fixed judge/rubric/context
|
|
185
|
-
configuration, UTC week, task type and agent model. They expose eligible/assessed
|
|
186
|
-
counts, excluded cases, confidence-qualified score means with per-dimension denominators, rework rates with Wilson
|
|
187
|
-
intervals, and evidence IDs. Small groups (<20) are marked explicitly. Confidence
|
|
188
|
-
thresholds are provisional, not calibrated guarantees. Human-reviewed evaluation
|
|
189
|
-
data is still needed before drawing performance conclusions.
|
|
190
|
-
Reports include dated clear-underdelivery examples and reason counts. Descriptive
|
|
191
|
-
score deltas compare successive available UTC weeks within the same task type,
|
|
192
|
-
agent model and rubric/configuration, with at least 20 confident scores per dimension
|
|
193
|
-
in each period and unchanged scored coverage; changed coverage withholds the score
|
|
194
|
-
delta. Outcome trends show acknowledgment, reported-shortfall and unknown rates
|
|
195
|
-
against **all evaluated exchanges**, with at least 20 evaluated exchanges per period.
|
|
196
|
-
Read the three rates together: fewer acknowledgments can mean more unknowns, not
|
|
197
|
-
more failures. Every delta includes before/after values, sample counts, denominator
|
|
198
|
-
and coverage-change flags. Unknown task types/models cannot produce deltas. These
|
|
199
|
-
are not statistical change-point detections or proof of causality; model/version
|
|
200
|
-
changes remain visible as separate groups rather than silently mixing cohorts.
|
|
201
|
-
The legacy `observedSuccessRate` group field remains acknowledgment / known outcomes
|
|
202
|
-
for compatibility, but is not used for trends. Unknowns are never successes.
|
|
203
|
-
Coverage changes and threshold variability can move rates; acknowledgment is not
|
|
204
|
-
factual verification. Week buckets
|
|
205
|
-
may be partial, and several exchanges in one session are not independent. Wilson
|
|
206
|
-
intervals are descriptive, not calibrated confidence about overall agent ability.
|
|
207
|
-
|
|
208
|
-
Each run selects at most 100 recent sessions for inference, each at most 2,000 active events/2M
|
|
209
|
-
characters; episodes must fit 24K characters and six feedback messages without
|
|
210
|
-
truncating the answer. Coverage counts describe the scanned sessions; only episodes
|
|
211
|
-
within `lookbackDays` are judged. Caps, failures and no-feedback cases remain visible.
|
|
212
|
-
Saved sessions in the report window are also reconciled independently of that
|
|
213
|
-
selection, so removing an entire active branch retires its scores. Oversized saved
|
|
214
|
-
sessions defer reconciliation rather than being treated as deleted; the report
|
|
215
|
-
exposes `reconciledSessions` and `reconciliationDeferred`. All reconciliation shares
|
|
216
|
-
the run deadline. Freshness checks compare the assessed episode, not unrelated
|
|
217
|
-
later session activity. Actual snapshot races do not exhaust provider retries.
|
|
218
|
-
The whole run has a two-minute deadline, at most three provider attempts per input (ten-minute
|
|
219
|
-
backoff), and a cross-process lease. Scheduling never starts inference on the agent
|
|
220
|
-
turn path or boots a QMD manager. No model downloads or source re-indexing occur.
|
|
221
|
-
The report is observational: different task mixes, selective human replies and judge
|
|
222
|
-
changes can produce apparent trends. It does not automatically declare regressions,
|
|
223
|
-
rewrite prompts, or treat silence as success.
|
|
224
|
-
|
|
225
|
-
## Review and diagnostics
|
|
226
|
-
|
|
227
|
-
- `memory_diagnostics` reports credential **availability only**, per-agent process-local
|
|
228
|
-
whisperer counters, projection version, old indexed-session projection count, and
|
|
229
|
-
embedding readiness. Counters are bounded to 100 agents and reset on restart.
|
|
230
|
-
No prompts, excerpts, paths, keys, or provider error bodies enter these counters.
|
|
231
|
-
Parser cleanup/budget-skip counts are persisted with the latest completed
|
|
232
|
-
`memory_sync_status`; unchanged sessions are not counted again. QMD structural
|
|
233
|
-
omission counts cover this manager's embedding passes, not the whole corpus.
|
|
234
|
-
- Quality-audit groups distinguish `preserve_evidence_repair`, `inspect_scaffolding`,
|
|
235
|
-
and `context_review`, reusing cached noise/evidence judgments without another call.
|
|
236
|
-
Evidence-preserving repair tasks sort first. Maintenance tasks expose indexed
|
|
237
|
-
fingerprint presence; `not_present_in_index` is **not** a verified repair and
|
|
238
|
-
never resolves or deletes the task. Chunk boundaries may simply have changed.
|
|
239
|
-
- `memory_review_cluster` uses the existing `qualityAudit` opt-in/corpus allowlist.
|
|
240
|
-
It judges up to three representative and three low-membership members, deduplicates
|
|
241
|
-
the sample, and skips unapproved or >2,000-character chunks whole. Repeated defect
|
|
242
|
-
labels are investigation leads only. Stale/changed samples are rejected; useful
|
|
243
|
-
or uncertain members are retained. No tasks or sources are modified.
|
|
244
|
-
- `memory_review_claim` accepts one atomic claim (up to 2,000 characters) and 1–3
|
|
245
|
-
citations `{path, from, lines}`. It reads approved indexed evidence itself (at
|
|
246
|
-
most 6,000 characters), returns supports/contradicts/insufficient_evidence with
|
|
247
|
-
confidence and source hashes, and never writes or authorizes a write. Support
|
|
248
|
-
below 0.9 confidence is marked for review. This threshold is provisional, not a
|
|
249
|
-
guarantee of truth; read original evidence and verify current-state claims.
|
|
250
|
-
|
|
251
|
-
New optional configuration (corpora must already be configured):
|
|
252
|
-
|
|
253
|
-
```json
|
|
254
|
-
{
|
|
255
|
-
"evidenceReview": { "enabled": true, "corpora": ["memory", "knowledge", "sessions"] },
|
|
256
|
-
"memoryWhisperer": {
|
|
257
|
-
"enabled": true, "corpora": ["memory", "knowledge"], "complementaryHints": true
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
Both additions default off. Claim review sends the proposed claim and approved
|
|
263
|
-
source excerpts to TypeSafe; cluster review sends approved sampled excerpts.
|
|
264
|
-
Complementary hints use one extra bounded call over at most four already-useful
|
|
265
|
-
candidates (six directional comparisons). Only redundancy probability >=0.9
|
|
266
|
-
removes a hint; distinct evidence and contradictions should remain. Provider errors
|
|
267
|
-
retain baseline hints, while the existing total turn deadline/cancellation still
|
|
268
|
-
suppresses late results. Missing keys or disabled TypeSafe never enable these calls.
|
|
269
|
-
The retrieval corpus/session boundaries are unchanged.
|
|
270
|
-
|
|
271
3
|
Workspace-native memory for OpenClaw, powered internally by `@unblocklabs/qmd`.
|
|
272
|
-
It keeps one warm QMD store per agent and exposes
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
Optional memory analysis uses those same stored vectors in the same SQLite
|
|
277
|
-
index. It does not re-embed memory, copy vectors, or create another database.
|
|
4
|
+
It keeps one warm QMD store per agent and exposes `memory_search` and `memory_get`.
|
|
5
|
+
Ordinary recall is local vector search over semantic chunks: no query expansion,
|
|
6
|
+
reranker or TypeSafe key is required.
|
|
278
7
|
|
|
279
|
-
|
|
8
|
+
## Start here
|
|
280
9
|
|
|
281
|
-
|
|
282
|
-
from its workflow prompt. Session projection recognizes that format and also
|
|
283
|
-
normalizes complete legacy Loggie JSON envelopes. Unrecognized, malformed or
|
|
284
|
-
truncated legacy payloads keep their original text; source sessions are never
|
|
285
|
-
rewritten. Summaries remain labeled as generated material, distinct from speech.
|
|
10
|
+
Install once per OpenClaw host, not once per agent:
|
|
286
11
|
|
|
287
|
-
|
|
288
|
-
Search expands around the matching exchange within its existing budget. Long
|
|
289
|
-
monologue excerpts regain the source speaker label while citations still point
|
|
290
|
-
to the exact original source lines. No identity or timestamp is invented.
|
|
291
|
-
|
|
292
|
-
Within a session, identical replayed transcripts are suppressed; distinct
|
|
293
|
-
complete revisions with ordered source sequence numbers retain their history
|
|
294
|
-
and assistant follow-ups, with older versions marked superseded. Account,
|
|
295
|
-
workspace, meeting and external transcript identifiers scope the comparison.
|
|
296
|
-
Ambiguous/partial revisions are preserved. Separate session windows are not
|
|
297
|
-
globally deduplicated.
|
|
298
|
-
|
|
299
|
-
Use the session projection as the searchable meeting copy. Loggie raw archives
|
|
300
|
-
remain opt-in and should stay outside file-corpus globs (new default:
|
|
301
|
-
`transcripts/loggie-archive`). Memory never follows archive paths embedded in
|
|
302
|
-
messages. Truncated sessions stay explicitly incomplete; enabling archive
|
|
303
|
-
enrichment is not part of this version.
|
|
304
|
-
|
|
305
|
-
### Conservative ingestion cleanup
|
|
306
|
-
|
|
307
|
-
Session projections unwrap complete, recognized task/attachment envelopes while
|
|
308
|
-
keeping the actual result, task/status, filename, MIME type, and untrusted-content
|
|
309
|
-
label. Internal task cleanup requires structured inter-session provenance, not
|
|
310
|
-
just matching text. Unknown formats, malformed envelopes, and code examples stay
|
|
311
|
-
intact. Assistant messages and Loggie's separate projection path are unaffected.
|
|
312
|
-
Raw session events and workspace memory files are never rewritten.
|
|
313
|
-
Attachment matching has a fixed work budget; oversized or repeatedly nested/
|
|
314
|
-
incomplete envelopes leave the entire message unchanged rather than blocking sync.
|
|
315
|
-
|
|
316
|
-
The companion QMD semantic-chunking update skips only source-confirmed standalone
|
|
317
|
-
REM heading/marker spans and orphan closing fences. Reflections and useful text
|
|
318
|
-
remain searchable, with original source offsets. These are deterministic rules,
|
|
319
|
-
not TypeSafe judgments; audit flags never authorize automatic memory deletion.
|
|
320
|
-
|
|
321
|
-
This release pins QMD 2.9.6. Projector/chunker version changes refresh derived
|
|
322
|
-
projections and embeddings on their next normal sync; the first sync may take
|
|
323
|
-
longer while re-embedding. No manual deletion of source memories or review tasks
|
|
324
|
-
is needed.
|
|
325
|
-
|
|
326
|
-
## Installation
|
|
327
|
-
|
|
328
|
-
From npm:
|
|
329
|
-
|
|
330
|
-
```bash
|
|
12
|
+
```sh
|
|
331
13
|
openclaw plugins install npm:@unblocklabs/unblock-memory
|
|
332
14
|
```
|
|
333
15
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
```bash
|
|
337
|
-
openclaw plugins install git:github.com/unblocklabs-ai/unblock-memory
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
Install the plugin once on each OpenClaw host, not once per agent. It installs
|
|
341
|
-
its pinned `@unblocklabs/qmd` runtime dependency automatically, so QMD does not
|
|
342
|
-
need to be installed separately. Each agent gets its own QMD index when it first
|
|
343
|
-
uses memory.
|
|
344
|
-
|
|
345
|
-
## Configuration
|
|
346
|
-
|
|
347
|
-
Select the plugin as the memory provider and group exact Markdown files,
|
|
348
|
-
directories, or globs into named corpora:
|
|
349
|
-
|
|
350
|
-
```json5
|
|
351
|
-
{
|
|
352
|
-
plugins: {
|
|
353
|
-
slots: { memory: "unblock-memory" },
|
|
354
|
-
entries: {
|
|
355
|
-
"unblock-memory": {
|
|
356
|
-
hooks: {
|
|
357
|
-
// Required when either whisperer is enabled.
|
|
358
|
-
allowConversationAccess: true,
|
|
359
|
-
},
|
|
360
|
-
config: {
|
|
361
|
-
// Default: avoid repeated model cold starts after idle periods.
|
|
362
|
-
keepEmbeddingModelWarm: true,
|
|
363
|
-
corpora: [
|
|
364
|
-
{
|
|
365
|
-
name: "memory",
|
|
366
|
-
kind: "files",
|
|
367
|
-
paths: ["MEMORY.md", "USER.md", "memory/**/*.md"],
|
|
368
|
-
},
|
|
369
|
-
{
|
|
370
|
-
name: "sessions",
|
|
371
|
-
kind: "sessions",
|
|
372
|
-
chatTypes: ["channel", "group"],
|
|
373
|
-
maxExpandedTokens: 500,
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
name: "knowledge",
|
|
377
|
-
kind: "files",
|
|
378
|
-
paths: ["knowledge/**/*.md"],
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
name: "skills",
|
|
382
|
-
kind: "skills",
|
|
383
|
-
paths: [
|
|
384
|
-
"skills/**/SKILL.md",
|
|
385
|
-
".agents/skills/**/SKILL.md",
|
|
386
|
-
"~/.agents/skills/**/SKILL.md",
|
|
387
|
-
"~/.openclaw/skills/**/SKILL.md",
|
|
388
|
-
"~/.openclaw/plugin-skills/**/SKILL.md",
|
|
389
|
-
],
|
|
390
|
-
},
|
|
391
|
-
],
|
|
392
|
-
skillWhisperer: {
|
|
393
|
-
enabled: false,
|
|
394
|
-
historyMessages: 5,
|
|
395
|
-
minScore: 0.5,
|
|
396
|
-
cooldownTurns: 10,
|
|
397
|
-
},
|
|
398
|
-
typesafe: {
|
|
399
|
-
enabled: true, // Default; shared by enabled Skill and Memory Whisperers.
|
|
400
|
-
// Alternatively set TYPESAFE_API_KEY in the Gateway environment.
|
|
401
|
-
apiKeyFile: "/absolute/path/to/.env",
|
|
402
|
-
timeoutMs: 1500,
|
|
403
|
-
},
|
|
404
|
-
people: {
|
|
405
|
-
enabled: false,
|
|
406
|
-
whisperer: { enabled: false, maxChars: 1200 },
|
|
407
|
-
},
|
|
408
|
-
// Optional: omit unless the local analysis worker is installed.
|
|
409
|
-
analysis: {
|
|
410
|
-
executable: "/absolute/path/to/unblock-cluster/bin/unblock-memory-analysis",
|
|
411
|
-
},
|
|
412
|
-
},
|
|
413
|
-
},
|
|
414
|
-
},
|
|
415
|
-
},
|
|
416
|
-
}
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
Relative entries resolve from each agent workspace. Absolute paths and `~/`
|
|
420
|
-
paths are supported. A directory means recursive Markdown. When `corpora` is
|
|
421
|
-
omitted, the plugin creates a `memory` corpus containing `MEMORY.md`, `USER.md`,
|
|
422
|
-
and `memory/**/*.md`. Explicit configuration must include exactly one `memory`
|
|
423
|
-
corpus; other unique names may be added for custom material.
|
|
424
|
-
|
|
425
|
-
`keepEmbeddingModelWarm` defaults to `true`, keeping the embedding model and
|
|
426
|
-
context resident after first use. Set it to `false` to restore QMD's five-minute
|
|
427
|
-
idle unload behavior.
|
|
428
|
-
|
|
429
|
-
`memory_search` searches every configured non-skill corpus by default. Pass
|
|
430
|
-
`corpora: ["knowledge"]` to search selected corpora or `corpora: ["all"]` to
|
|
431
|
-
request all of them explicitly. Search results include their corpus name and
|
|
432
|
-
remain readable by passing the returned `qmd://` path to `memory_get`.
|
|
433
|
-
|
|
434
|
-
### Memory Whisperer
|
|
435
|
-
|
|
436
|
-
Memory Whisperer is optional and **off by default**. It proactively retrieves
|
|
437
|
-
historical context before user-triggered turns, without changing `memory_search`
|
|
438
|
-
or `memory_get`. Enable it in the plugin config with an explicit corpus allowlist:
|
|
439
|
-
|
|
440
|
-
```json5
|
|
441
|
-
memoryWhisperer: {
|
|
442
|
-
enabled: true,
|
|
443
|
-
corpora: ["knowledge"], // Must exist in corpora; approve its contents for all agent audiences.
|
|
444
|
-
historyMessages: 5,
|
|
445
|
-
minUsefulness: 0.9,
|
|
446
|
-
maxHints: 2,
|
|
447
|
-
cooldownTurns: 10,
|
|
448
|
-
timeoutMs: 3000,
|
|
449
|
-
},
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
Requires `hooks.allowConversationAccess: true` on the plugin entry, prompt
|
|
453
|
-
injection permission, and the shared TypeSafe credentials described below.
|
|
454
|
-
An empty allowlist is invalid when enabled; `all`, unknown names, and `skills`
|
|
455
|
-
are not accepted. File corpora are approved for **every audience using the agent**:
|
|
456
|
-
do not allowlist private dossiers for an agent that also serves shared channels.
|
|
457
|
-
If `sessions` is allowlisted, only the exact current session is searched, including
|
|
458
|
-
its older indexed messages. Missing session identity excludes that corpus. Other
|
|
459
|
-
sessions, even in the same channel, are excluded before sending excerpts to TypeSafe.
|
|
460
|
-
Session availability still depends on the normal indexing/sync schedule.
|
|
461
|
-
|
|
462
|
-
QMD searches the current request plus the last N user/assistant messages (at most
|
|
463
|
-
12,000 characters), retrieving up to eight vector candidates without query expansion,
|
|
464
|
-
the local reranker, or a similarity-score cutoff. TypeSafe evaluates one independent
|
|
465
|
-
Noul question per candidate in a single request: does the excerpt add material value
|
|
466
|
-
beyond what the conversation already contains? Merely related, redundant,
|
|
467
|
-
wrong-person/project, and clearly superseded information should be rejected;
|
|
468
|
-
useful contradictory evidence can qualify. `minUsefulness` thresholds the probability
|
|
469
|
-
of yes, not a calibrated guarantee of accuracy. Evaluate it on your own conversations.
|
|
470
|
-
|
|
471
|
-
**Privacy and budgets:** this feature sends up to 16,000 characters of the available
|
|
472
|
-
user/assistant conversation, prioritizing the current request and recent messages,
|
|
473
|
-
plus up to eight 1,200-character excerpts, corpus names, and session dates to
|
|
474
|
-
`api.typesafe.ai`. Session excerpts retain a complete turn or message when it fits,
|
|
475
|
-
otherwise the complete matched chunk. Chunks exceeding the excerpt budget are
|
|
476
|
-
skipped, never sliced; ordinary `memory_search` is unchanged.
|
|
477
|
-
It does not fetch a complete historical transcript; the host may
|
|
478
|
-
already have compacted the available context. Truncation is marked in the judge's
|
|
479
|
-
input. System messages, thinking blocks, images, and tool-result messages are omitted;
|
|
480
|
-
anything quoted in ordinary user/assistant text can still be transmitted.
|
|
481
|
-
|
|
482
|
-
At most two qualifying excerpts are injected verbatim with source references and
|
|
483
|
-
historical/untrusted-data framing. Excerpts are deduplicated by normalized content
|
|
484
|
-
and overlapping source lines; recently injected content has a ten-user-turn cooldown
|
|
485
|
-
by default. Cooldown state is in memory and resets on session end or Gateway restart.
|
|
486
|
-
The complete hint payload is capped at 5,000 characters plus a short framing paragraph.
|
|
487
|
-
|
|
488
|
-
Unlike Skill Whisperer, **disabled TypeSafe, a missing key, no qualifying hits, or any
|
|
489
|
-
failure means no memory hint**—there is no vector-only fallback. The overall process
|
|
490
|
-
has a 3-second deadline, with the shared 1.5-second TypeSafe request deadline inside it;
|
|
491
|
-
neither performs retries. Timed-out or superseded runs cannot inject late hints.
|
|
492
|
-
Already-running local QMD work may finish in the background, but does not keep the
|
|
493
|
-
agent waiting beyond the deadline. No new indexing, clustering, or summarization runs
|
|
494
|
-
are triggered by this feature beyond the memory manager's normal initialization.
|
|
495
|
-
|
|
496
|
-
### Skill Whisperer
|
|
497
|
-
|
|
498
|
-
Skill Whisperer is an optional semantic reminder for user turns. Configure one
|
|
499
|
-
isolated `skills` corpus, set `skillWhisperer.enabled` to `true`, and authorize
|
|
500
|
-
`plugins.entries.unblock-memory.hooks.allowConversationAccess`. The feature
|
|
501
|
-
embeds the current prompt plus the configured number of prior user/assistant
|
|
502
|
-
messages, compares it with each configured skill's frontmatter `name` and
|
|
503
|
-
`description`. With TypeSafe enabled and a key available, the top three valid
|
|
504
|
-
candidates are sent to TypeSafe, without a vector-score cutoff. TypeSafe chooses
|
|
505
|
-
one skill or none. A "none" decision never falls back to a vector hint. Full skill
|
|
506
|
-
procedures do not influence routing; no skill is invoked automatically.
|
|
507
|
-
|
|
508
|
-
The shared `typesafe` configuration defaults to `enabled: true` and
|
|
509
|
-
`timeoutMs: 1500`. Skill and Memory Whisperers share it. Credentials come from
|
|
510
|
-
`typesafe.apiKey`, an absolute `typesafe.apiKeyFile`, or (when neither is set)
|
|
511
|
-
the Gateway's `TYPESAFE_API_KEY` environment variable. Configure at most one of
|
|
512
|
-
`apiKey` and `apiKeyFile`. A key file may contain just the key or dotenv entries
|
|
513
|
-
including `TYPESAFE_API_KEY`; it is reread each turn to support rotation. A dotenv
|
|
514
|
-
file is not sourced as shell code and does not change the process environment.
|
|
515
|
-
Missing/empty files or dotenv files without that variable count as no key;
|
|
516
|
-
an explicit file never falls back to an unrelated environment key. Protect key
|
|
517
|
-
files with owner-only permissions. Workspace `.env` files are not auto-discovered:
|
|
518
|
-
point `apiKeyFile` at the intended file or load the variable into the Gateway.
|
|
519
|
-
|
|
520
|
-
If TypeSafe is disabled or no key is found, selection uses the original local
|
|
521
|
-
vector process and `skillWhisperer.minScore`. With a key present, an API error,
|
|
522
|
-
invalid response, or timeout emits no hint and logs a sanitized warning; it does
|
|
523
|
-
not switch to vector-only selection. There are no automatic HTTP retries. Other
|
|
524
|
-
credential-file read errors likewise produce a warning and no hint.
|
|
525
|
-
|
|
526
|
-
**Privacy:** enabled TypeSafe selection sends up to 12,000 characters of current
|
|
527
|
-
prompt/recent user-assistant text, plus the shortlisted names/descriptions, to
|
|
528
|
-
`api.typesafe.ai`. Source-path fields, full skill procedures, tool-result messages,
|
|
529
|
-
and system messages are excluded; dossiers and ordinary memory files are not read
|
|
530
|
-
for this call. Material already quoted in user/assistant text can still be included.
|
|
531
|
-
Disable `typesafe.enabled` to keep Skill Whisperer entirely local. The pinned model
|
|
532
|
-
is `jev-1.13.0`.
|
|
533
|
-
|
|
534
|
-
The defaults use five prior messages, a vector-only score threshold of `0.5`,
|
|
535
|
-
and a ten-turn cooldown. A skill is cooling down after either a suggestion or a
|
|
536
|
-
successful direct `read` of its indexed `SKILL.md`. When the selected
|
|
537
|
-
skill is cooling down, no hint is emitted; Skill Whisperer does not fall through
|
|
538
|
-
to a weaker match. Cooldown state is per session and intentionally resets with
|
|
539
|
-
the Gateway. Shell-command reads are not tracked.
|
|
540
|
-
|
|
541
|
-
The `skills` corpus shares the existing QMD store and warm embedding model but
|
|
542
|
-
is private to Skill Whisperer: it is excluded from ordinary `memory_search`
|
|
543
|
-
(including `corpora: ["all"]`), `memory_get`, clustering, and memory-maintenance
|
|
544
|
-
tasks. Paths are explicit by design; the plugin does not reconstruct
|
|
545
|
-
OpenClaw's effective skill inventory from `openclaw.json`. Configured skill
|
|
546
|
-
globs follow symlinked directories, including OpenClaw's `plugin-skills`
|
|
547
|
-
directory.
|
|
548
|
-
|
|
549
|
-
### People Whisperer
|
|
550
|
-
|
|
551
|
-
#### Optional People Dossier Primer
|
|
552
|
-
|
|
553
|
-
`memory_people_prime({ personId, agentName? })` prepares evidence for an existing person;
|
|
554
|
-
it does **not** generate claims, update dossiers, or inject context. With
|
|
555
|
-
`people.enabled: true`, opt in separately:
|
|
556
|
-
|
|
557
|
-
```json
|
|
558
|
-
{
|
|
559
|
-
"peoplePrimer": {
|
|
560
|
-
"enabled": true,
|
|
561
|
-
"corpora": ["memory", "knowledge", "sessions"],
|
|
562
|
-
"hitsPerQuestion": 30,
|
|
563
|
-
"minScore": 0.35,
|
|
564
|
-
"minUsefulness": 0.8,
|
|
565
|
-
"maxEvidencePerQuestion": 3,
|
|
566
|
-
"timeoutMs": 30000
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
List only configured, approved non-skill corpora. The feature is **off by
|
|
572
|
-
default** and requires shared TypeSafe credentials. Disabled TypeSafe or missing/
|
|
573
|
-
unreadable credentials safely skip the primer; agents can still research normally.
|
|
574
|
-
Enabling it approves sending the person's identity, retrieved excerpts and optional
|
|
575
|
-
draft snippet to TypeSafe. Existing dossiers are not sent as grading evidence.
|
|
576
|
-
Sessions includes all indexed conversations;
|
|
577
|
-
results are available to the agent's tool callers, so scope approval accordingly.
|
|
578
|
-
|
|
579
|
-
Three default questions cover explicit role/organization, enduring organizational
|
|
580
|
-
background, and the person's relationship to the agent (not its business mission).
|
|
581
|
-
Preferences, working styles, priorities, feedback and task history are excluded.
|
|
582
|
-
Each uses QMD vector search (no query expansion) for up to 30 hits, configurable
|
|
583
|
-
up to 40. All unique eligible hits above the vector threshold are graded, not just
|
|
584
|
-
the final top three. Complete excerpts over 6,000 characters are counted and skipped,
|
|
585
|
-
not silently truncated. Duplicate source spans across questions share a request;
|
|
586
|
-
Independent attribution, explicit-background, durability, recognition-value and
|
|
587
|
-
question-usefulness judgments run together; every dimension must pass the threshold.
|
|
588
|
-
Every candidate is graded against all three questions, regardless of which search
|
|
589
|
-
found it. Mixed excerpts may supply a useful background fact without making their
|
|
590
|
-
surrounding behavioral content eligible for the snippet.
|
|
591
|
-
Provider concurrency is four, with a two-minute overall tool deadline.
|
|
592
|
-
|
|
593
|
-
Supply the agent's human-facing name when no identity name is configured; otherwise
|
|
594
|
-
questions use "the assistant", never an internal routing ID such as `main`.
|
|
595
|
-
The output includes a deduplicated source-linked excerpt list referenced by each
|
|
596
|
-
question's evidence IDs, a bounded uncertain-review shortlist,
|
|
597
|
-
and retrieval/cache/failure counts. Coverage is `evidence_found`, `uncertain` or
|
|
598
|
-
`unknown`, not a claim that a question has been definitively answered. Partial
|
|
599
|
-
provider failures are explicit; absence of selected hits does not prove absence of
|
|
600
|
-
evidence. The agent must verify dates, speakers and contradictions before writing.
|
|
601
|
-
Memory evidence never grants permissions or establishes that an old request is
|
|
602
|
-
still open.
|
|
603
|
-
|
|
604
|
-
`memory_people_update({ action: "replace_dossier", personId, dossier, reason,
|
|
605
|
-
agentName? })` automatically checks the proposed blurb before saving. Exact
|
|
606
|
-
`qmd://path#Lstart-Lend` claim evidence locators supply up to three indexed ranges
|
|
607
|
-
from the primer's approved corpora (120 lines each, 6,000 characters total).
|
|
608
|
-
Support confidence and background-only/explicit-support probabilities must all
|
|
609
|
-
be >=0.9. `needs_review` or `review_unavailable` leaves the dossier and history
|
|
610
|
-
unchanged; missing keys and failures never count as approval. A concurrent dossier
|
|
611
|
-
edit/deletion returns `conflict` instead of overwriting the newer change.
|
|
612
|
-
|
|
613
|
-
After independently verifying every assertion and background eligibility, an agent
|
|
614
|
-
can supply a source-specific `manualVerification` explanation (up to 400 characters)
|
|
615
|
-
for direct human corrections, non-indexed evidence or disabled/unavailable/incorrect
|
|
616
|
-
reviews. This explicit path skips TypeSafe, records manual provenance in change
|
|
617
|
-
history and keeps all structural limits. It is not a provider pass. Normal success
|
|
618
|
-
returns `status: "ok"`, `saved: true` and `verification: "typesafe" | "manual"`.
|
|
619
|
-
The skill documents when to use each path. Sources outside approved corpora are
|
|
620
|
-
rejected before egress; no separate `evidenceReview` toggle is needed.
|
|
621
|
-
|
|
622
|
-
For optional read-only diagnostics, `memory_people_prime({ personId, agentName?,
|
|
623
|
-
draft: { blurb, citations: [{ path, from, lines }] } })` still reviews a snippet
|
|
624
|
-
without writing. Agents do not need this extra call in the normal update workflow.
|
|
625
|
-
|
|
626
|
-
Judgments are cached privately in `unblock-memory.sqlite` (maximum 2,000 entries), keyed
|
|
627
|
-
by person, agent, exact evidence/context, questions,
|
|
628
|
-
and judge version. No source text or credentials are stored in the cache.
|
|
629
|
-
Retrieval reruns against the current index; unchanged judgments are reused.
|
|
630
|
-
This is on-demand preparation, not a new scheduler or incremental session scanner.
|
|
631
|
-
Use it from an existing People Whisperer maintenance cron. Refresh stale session
|
|
632
|
-
indexes with `memory_sync_sessions` before priming when needed.
|
|
633
|
-
|
|
634
|
-
#### People store and maintenance
|
|
635
|
-
|
|
636
|
-
PeopleSQL is an optional agent-local people store. When `people.enabled` is
|
|
637
|
-
true, incoming Slack messages with a canonical agent session key and exact
|
|
638
|
-
account and sender IDs create or refresh an injection-enabled person record.
|
|
639
|
-
Incomplete Slack identities create a bounded, deduplicated todo without storing
|
|
640
|
-
message content. Other channels are ignored.
|
|
641
|
-
|
|
642
|
-
PeopleSQL registers these tools when enabled:
|
|
643
|
-
|
|
644
|
-
- `memory_people_inspect` lists active people, reads one exact person, reads one
|
|
645
|
-
person's dossier change history, or lists bounded actionable todos;
|
|
646
|
-
- `memory_people_update` replaces or deletes dossiers, toggles one person's
|
|
647
|
-
injection, and manages company, todo, deletion, or restoration state;
|
|
648
|
-
- `memory_people_prime` prepares evidence when the separately opted-in primer is
|
|
649
|
-
enabled, otherwise returns disabled; and
|
|
650
|
-
- the optional `memory_people_sync` enriches one active OpenClaw Slack account;
|
|
651
|
-
its tool input accepts an account ID, not a token.
|
|
652
|
-
|
|
653
|
-
The inspect and update tools are part of the normal agent tool surface; they do
|
|
654
|
-
not depend on sender-owner authorization. Directory sync remains optional and
|
|
655
|
-
may need to be allowed explicitly. The sync is bounded to
|
|
656
|
-
200 normalized directory entries per call and is safe to rerun. Unblock Memory
|
|
657
|
-
keeps only normalized ID, name, handle, and avatar fields. Slack requires the
|
|
658
|
-
`users:read` scope.
|
|
659
|
-
|
|
660
|
-
The agent owns dossier generation and refresh. It can list people, inspect one
|
|
661
|
-
person's current dossier, search ordinary memory and sessions with
|
|
662
|
-
`memory_search`/`memory_get`, and replace the dossier when that would improve a
|
|
663
|
-
future conversation. The plugin owns no dossier-maintenance workflow or refresh
|
|
664
|
-
schedule. A dossier's `reviewedAt` value records its last successful write; it
|
|
665
|
-
is not scheduling state. Dossier generation belongs to the agent; prompt injection
|
|
666
|
-
performs no model call. The optional primer grades evidence and reviews draft snippets.
|
|
667
|
-
The goal is recognition, not a behavioral profile: one short paragraph of at most
|
|
668
|
-
70 words identifying the person and their enduring organization/agent relationship.
|
|
669
|
-
New writes allow only `role`/`relationship` sections and explicit `observed`/`reported`
|
|
670
|
-
claims; priorities, preferences and inferred profiles belong outside dossiers.
|
|
671
|
-
Legacy dossiers remain readable, but must be deliberately rewritten by the agent
|
|
672
|
-
before replacement. No automatic destructive migration or blanket deletion occurs.
|
|
673
|
-
|
|
674
|
-
Every `replace_dossier` and `delete_dossier` action requires a concise `reason`
|
|
675
|
-
(up to 500 characters for replacements, 1,000 for deletions). Replacement history
|
|
676
|
-
also records whether TypeSafe checks passed or a manual attestation was used.
|
|
677
|
-
The plugin transactionally records that reason with its authoritative before and
|
|
678
|
-
after dossier snapshots. List small newest-first summaries with
|
|
679
|
-
`memory_people_inspect({ view: "dossier_changes", personId, limit?, offset? })`,
|
|
680
|
-
then fetch one exact diff with
|
|
681
|
-
`memory_people_inspect({ view: "dossier_change", personId, changeId })`. List
|
|
682
|
-
responses include `nextOffset`, so all history remains reachable without loading
|
|
683
|
-
many dossiers into one tool result. Because the injected snippet is the dossier's
|
|
684
|
-
`blurb`, its changes are included in the same history. A complete new serialized
|
|
685
|
-
dossier is capped at 64 KiB; larger legacy dossiers remain readable and repairable.
|
|
686
|
-
|
|
687
|
-
Set `people.whisperer.enabled` to inject context. For each exact Slack sender,
|
|
688
|
-
the plugin prepends that person's stored dossier blurb, bounded by `maxChars`,
|
|
689
|
-
once per `(Slack thread, person)`. Receipts are durable across retries and
|
|
690
|
-
Gateway restarts, while different people in one thread are handled independently.
|
|
691
|
-
Unthreaded DMs use their OpenClaw session as the conversational scope. Unknown,
|
|
692
|
-
unavailable, disabled, or dossierless people produce no context. Injection
|
|
693
|
-
remains subject to OpenClaw's `allowPromptInjection` policy.
|
|
694
|
-
|
|
695
|
-
The package includes a `$people-whisperer` skill with the canonical agent
|
|
696
|
-
procedure and dossier shape. For a manual refresh, ask:
|
|
697
|
-
|
|
698
|
-
```text
|
|
699
|
-
Use $people-whisperer to maintain this person's brief background snippet.
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
For an optional cron or isolated agent session, use this goal:
|
|
703
|
-
|
|
704
|
-
```text
|
|
705
|
-
Use $people-whisperer to maintain brief background snippets for people you interact
|
|
706
|
-
with. Follow the packaged skill, including source verification and write results.
|
|
707
|
-
Update only when useful; several people or nobody is fine. Report changes and gaps.
|
|
708
|
-
```
|
|
709
|
-
|
|
710
|
-
Choose any cadence appropriate for the agent; the plugin does not require or
|
|
711
|
-
track one. If session transcripts are a source, configure a `sessions` corpus
|
|
712
|
-
(including `direct` when DMs matter) and refresh it with
|
|
713
|
-
`memory_sync_sessions`. Ordinary `memory_search` calls accept targeted queries,
|
|
714
|
-
corpora, session metadata filters, score thresholds, and up to 20 results per
|
|
715
|
-
call; People Whisperer itself imposes no evidence-window limit.
|
|
716
|
-
|
|
717
|
-
Use `sessionFilter` to restrict session results by metadata while leaving file
|
|
718
|
-
corpora searchable. Supported fields are `startedFrom` and `startedTo`
|
|
719
|
-
(inclusive ISO 8601 timestamps), `provider`, `chatType`, `accountId`, and
|
|
720
|
-
`conversationId`:
|
|
16
|
+
Merge this into your OpenClaw configuration, preserving other plugins/settings:
|
|
721
17
|
|
|
722
18
|
```json
|
|
723
19
|
{
|
|
724
|
-
"
|
|
725
|
-
|
|
726
|
-
"
|
|
727
|
-
|
|
728
|
-
|
|
20
|
+
"plugins": {
|
|
21
|
+
"slots": { "memory": "unblock-memory" },
|
|
22
|
+
"entries": {
|
|
23
|
+
"unblock-memory": { "enabled": true, "config": {} }
|
|
24
|
+
}
|
|
729
25
|
}
|
|
730
26
|
}
|
|
731
27
|
```
|
|
732
28
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
plugin versions together: old writers can keep changing their separate files.
|
|
808
|
-
Back up the new database with SQLite's online backup API, or stop all writers
|
|
809
|
-
and safely checkpoint WAL first. Copying only a live `.sqlite` file is unsafe.
|
|
810
|
-
|
|
811
|
-
To roll back before any new writes, stop all writers, preserve the new database
|
|
812
|
-
and its WAL/SHM sidecars, and restore the old plugin against the retained files.
|
|
813
|
-
**After new writes, the legacy files are stale:** rollback requires an explicit
|
|
814
|
-
reverse data migration or accepting the loss of post-upgrade changes.
|
|
815
|
-
Retain recovery files until the upgrade is verified; cleanup is a separate step.
|
|
816
|
-
|
|
817
|
-
## Memory quality audit
|
|
818
|
-
|
|
819
|
-
`memory_audit_quality` is an on-demand, source-read-only audit. TypeSafe flags likely
|
|
820
|
-
ingestion noise for agent investigation; it never deletes, rewrites, or suppresses
|
|
821
|
-
memory. Enable it with explicit approval for the corpora sent to TypeSafe:
|
|
822
|
-
|
|
823
|
-
```json5
|
|
824
|
-
qualityAudit: {
|
|
825
|
-
enabled: true,
|
|
826
|
-
corpora: ["memory", "knowledge"], // Must be configured non-skill corpora.
|
|
827
|
-
minNoise: 0.8,
|
|
828
|
-
},
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
Off by default. Uses the shared TypeSafe credentials and request timeout. Missing
|
|
832
|
-
credentials or disabled TypeSafe produces no audit. Approval includes transmission
|
|
833
|
-
of full eligible chunks and visibility of findings to all audiences using the agent.
|
|
834
|
-
Unlike Memory Whisperer, approving `sessions` includes **all indexed sessions** in
|
|
835
|
-
that corpus, including configured direct conversations. Only approve that when intended.
|
|
836
|
-
|
|
837
|
-
Call with `{ "limit": 10 }` (maximum 20 indexed chunk occurrences per page), then
|
|
838
|
-
pass the returned `next` as `after` until `done` is true. A `partial` result preserves
|
|
839
|
-
the completed cursor; retry there, or from the beginning if no cursor exists. This
|
|
840
|
-
is not a full-document audit: unindexed content is not scanned. Chunks over 6,000
|
|
841
|
-
characters are counted as skipped, not silently truncated. No clustering is required.
|
|
842
|
-
|
|
843
|
-
Two independent Noul questions distinguish ingestion noise from identifiable useful
|
|
844
|
-
evidence. High values for both can indicate valuable content trapped in a wrapper.
|
|
845
|
-
Low evidence alone does not create a junk finding. JSON, logs, code, terse facts,
|
|
846
|
-
historical records, and missing context are not automatically defects. Empty chunks
|
|
847
|
-
are detected locally. A JSON string that decodes to a message envelope is also
|
|
848
|
-
flagged as a possible double-encoding defect, even when its content is useful.
|
|
849
|
-
An ordinary JSON message object is not flagged from its shape alone. These are
|
|
850
|
-
review clues, never verdicts about whether the information should be kept.
|
|
851
|
-
|
|
852
|
-
At most four unique chunks (24,000 characters) and their source kinds are sent in
|
|
853
|
-
one request, without conversation context or source paths. Requests do not retry
|
|
854
|
-
automatically and stop starting new work after a 30-second audit deadline; existing
|
|
855
|
-
manager initialization/indexing may finish later. Judgments are cached in the
|
|
856
|
-
curation database by content, source kind, model and question version. A rescan from
|
|
857
|
-
the beginning reuses cached results, including after corpus/index changes. Changes
|
|
858
|
-
behind a page cursor are picked up on the next rescan.
|
|
859
|
-
|
|
860
|
-
Suspect chunks become `quality_review` tasks in `memory_list_maintenance_tasks`.
|
|
861
|
-
The audit returns page-local groups by configured source and suspected issue,
|
|
862
|
-
with up to three examples each, not a claim that a whole cluster is defective.
|
|
863
|
-
Findings include source references, bounded previews, probabilities and content
|
|
864
|
-
fingerprints. Reviewed tasks are not reopened for unchanged content. The curator
|
|
865
|
-
inspects the original source and ingestion path, proposes or performs authorized
|
|
866
|
-
repairs, and verifies the resulting source/index before resolving with a required
|
|
867
|
-
note. Prefer repairing a common extractor or inclusion rule over many symptoms;
|
|
868
|
-
never manually edit generated session projections. Thresholds need evaluation on
|
|
869
|
-
your data; model probability is not proof of a defect.
|
|
870
|
-
|
|
871
|
-
## Memory analysis
|
|
872
|
-
|
|
873
|
-
Analysis is opt-in. Core indexing, `memory_search`, and `memory_get` need only
|
|
874
|
-
Unblock Memory and its automatically installed QMD dependency. To enable
|
|
875
|
-
clustering, install the public
|
|
876
|
-
[`unblock-cluster`](https://github.com/unblocklabs-ai/unblock-cluster) worker once
|
|
877
|
-
on the same host:
|
|
878
|
-
|
|
879
|
-
```bash
|
|
880
|
-
git clone https://github.com/unblocklabs-ai/unblock-cluster.git
|
|
881
|
-
cd unblock-cluster
|
|
882
|
-
python3 -m venv .venv
|
|
883
|
-
.venv/bin/python -m pip install -r requirements-analysis.txt
|
|
884
|
-
```
|
|
885
|
-
|
|
886
|
-
Set `analysis.executable` to the absolute path of
|
|
887
|
-
`bin/unblock-memory-analysis` in that checkout. One worker installation can
|
|
888
|
-
serve every agent on the host. The plugin invokes it directly with
|
|
889
|
-
`--db <the agent's known index path>`, the plugin's non-skill collection IDs,
|
|
890
|
-
and, when requested, a validated `--config-json <clustering options>` payload.
|
|
891
|
-
Agents cannot choose a database, executable, collection, shell command, or
|
|
892
|
-
arbitrary arguments.
|
|
893
|
-
|
|
894
|
-
Without the worker, `memory_list_clusters` reports that memory has not been
|
|
895
|
-
analyzed and `memory_recluster` reports that analysis is unavailable. Ordinary
|
|
896
|
-
memory search and reads continue to work.
|
|
897
|
-
|
|
898
|
-
The analysis worker reads QMD's existing semantic vectors and writes only
|
|
899
|
-
derived results into four namespaced tables in that same `index.sqlite`:
|
|
900
|
-
|
|
901
|
-
- `memory_analysis_runs`
|
|
902
|
-
- `memory_analysis_clusters`
|
|
903
|
-
- `memory_analysis_memberships`
|
|
904
|
-
- `memory_analysis_duplicate_occurrences`
|
|
905
|
-
|
|
906
|
-
Unblock Memory exposes:
|
|
907
|
-
|
|
908
|
-
- `memory_list_clusters` to cheaply list current clusters and report whether the
|
|
909
|
-
retained analysis is stale
|
|
910
|
-
- `memory_recluster` to explicitly rebuild clusters when the list is missing or stale
|
|
911
|
-
- `memory_fetch_cluster` to return a sorted, paginated selection of QMD chunks
|
|
912
|
-
for a short `clusterId` returned by `memory_list_clusters`
|
|
913
|
-
|
|
914
|
-
`memory_recluster` optionally accepts UMAP controls (`method`, components,
|
|
915
|
-
neighbors, and minimum distance), HDBSCAN controls (minimum cluster size,
|
|
916
|
-
minimum samples, selection method and epsilon, and single-cluster behavior),
|
|
917
|
-
and a deterministic seed. Omitting them uses the worker's defaults.
|
|
918
|
-
|
|
919
|
-
`memory_fetch_cluster` accepts `topK` (1–50), a zero-based `offset`, and
|
|
920
|
-
`sort`: `representative` (the default), `score_desc`, `score_asc`, `date_desc`,
|
|
921
|
-
or `date_asc`. Score is cluster membership probability for normal clusters and
|
|
922
|
-
outlier score for noise. Each member reports raw `sourceModifiedAt` separately
|
|
923
|
-
from `eventTime` and `eventTimeBasis`. Session start times and dated memory paths
|
|
924
|
-
resolve programmatically; reviewed annotations resolve otherwise ambiguous
|
|
925
|
-
chunks or whole documents. Date sorting uses resolved event time when available
|
|
926
|
-
and the clearly labeled source modification time only as a fallback. Responses
|
|
927
|
-
include page totals and the next offset when more members remain.
|
|
928
|
-
|
|
929
|
-
A chronological cluster read creates a coalesced maintenance proposal only for
|
|
930
|
-
returned documents whose event time remains ambiguous; it does not scan the
|
|
931
|
-
whole corpus for chores. Persisted exact-duplicate analysis can likewise create
|
|
932
|
-
review proposals for non-session Markdown. `memory_list_maintenance_tasks`
|
|
933
|
-
returns at most ten tasks, while `memory_update_maintenance_task` can resolve,
|
|
934
|
-
defer, or mark one irrelevant and optionally attach a supported event date.
|
|
935
|
-
For duplicate proposals, defer confirmed cleanup until the source change is
|
|
936
|
-
complete, mark intentional repetition irrelevant, and resolve only completed
|
|
937
|
-
work. These tools never edit or delete source Markdown. Duplicate cleanup
|
|
938
|
-
remains a reviewed source change outside the maintenance tool, and generated
|
|
939
|
-
session projections must never be edited directly.
|
|
940
|
-
|
|
941
|
-
Member excerpts are capped at 2 KB each and 12 KB across a response; source
|
|
942
|
-
aliases are capped at five per member and 50 across a response. These budgets
|
|
943
|
-
are shared across the page so every returned member receives a useful excerpt
|
|
944
|
-
and at least one source path, including a full 50-member page.
|
|
945
|
-
|
|
946
|
-
If indexing changes content or vectors, the previous derived analysis is kept
|
|
947
|
-
and marked stale. Cluster reads include the analysis timestamp, stale timestamp,
|
|
948
|
-
and a hint to call `memory_recluster`; unavailable chunks reduce `availableSize`
|
|
949
|
-
without copying canonical text into analysis tables. A no-op sync stays fresh.
|
|
950
|
-
A failed rebuild leaves the stale result intact, while a successful rebuild
|
|
951
|
-
atomically replaces it. Analysis is never scheduled automatically. If the worker
|
|
952
|
-
is absent or fails, `memory_search` and `memory_get` continue to work.
|
|
953
|
-
|
|
954
|
-
## Curating knowledge
|
|
955
|
-
|
|
956
|
-
The plugin bundles the `memory-curator` skill for turning useful clusters into
|
|
957
|
-
durable knowledge. It becomes available when the plugin is enabled. If the
|
|
958
|
-
agent has an explicit skill allowlist, include `memory-curator`.
|
|
959
|
-
|
|
960
|
-
Keep maintained knowledge outside `memory/**` so each file belongs to only one
|
|
961
|
-
corpus. Use stable topic files updated in place:
|
|
962
|
-
|
|
963
|
-
```text
|
|
964
|
-
knowledge/
|
|
965
|
-
├── fleet.md
|
|
966
|
-
├── people/
|
|
967
|
-
│ └── rico.md
|
|
968
|
-
└── projects/
|
|
969
|
-
└── unblock-memory.md
|
|
970
|
-
```
|
|
971
|
-
|
|
972
|
-
Knowledge is the agent's maintained, current understanding of its unique world:
|
|
973
|
-
facts such as fleet membership, local decisions and preferences, assessments,
|
|
974
|
-
and explicit uncertainty that would be expensive to reconstruct from scattered
|
|
975
|
-
history. Each claim should carry its own epistemic qualification so it remains
|
|
976
|
-
honest when semantic chunking retrieves it alone. Remove stale conclusions
|
|
977
|
-
instead of preserving history, changelogs, or `Supersedes` passages in the same
|
|
978
|
-
file; raw memory and sessions retain the evidence history.
|
|
979
|
-
|
|
980
|
-
Public or vendor-owned facts, generic command syntax, and behavior likely to
|
|
981
|
-
change with third-party releases should normally be looked up from the current
|
|
982
|
-
authoritative source. A local policy or deliberate divergence may belong in
|
|
983
|
-
knowledge, but the local decision—not copied generic documentation—is the
|
|
984
|
-
durable content.
|
|
985
|
-
|
|
986
|
-
For a manual run, ask the agent:
|
|
987
|
-
|
|
988
|
-
```text
|
|
989
|
-
Use $memory-curator to review my memory clusters and curate any durable updates.
|
|
990
|
-
```
|
|
991
|
-
|
|
992
|
-
For recurring curation, use an OpenClaw automation with the same thin message:
|
|
993
|
-
|
|
994
|
-
```text
|
|
995
|
-
Use $memory-curator to run the scheduled memory curation cycle.
|
|
996
|
-
```
|
|
997
|
-
|
|
998
|
-
The skill treats a cluster as an incomplete attention signal. It frames the
|
|
999
|
-
question raised, uses representative, score, and chronological views as useful,
|
|
1000
|
-
searches existing knowledge and adjacent corpora, and investigates live systems,
|
|
1001
|
-
files, documentation, or the web when those are better evidence. It then updates
|
|
1002
|
-
a stable knowledge topic or correctly writes nothing. Its own writes are indexed
|
|
1003
|
-
for the next cycle; it does not recluster recursively in the same run.
|
|
1004
|
-
|
|
1005
|
-
Existing `unblock-qmd` indexes are derived caches and may be left in place;
|
|
1006
|
-
Unblock Memory rebuilds its own index from configured corpora.
|
|
29
|
+
The default `memory` corpus contains `MEMORY.md`, `USER.md` and
|
|
30
|
+
`memory/**/*.md`, relative to each agent's workspace. The first use builds its
|
|
31
|
+
index; Markdown changes refresh it in the background. QMD is installed as a
|
|
32
|
+
pinned dependency, not a separate service. A global QMD CLI is not required.
|
|
33
|
+
|
|
34
|
+
Optional installation from source:
|
|
35
|
+
`openclaw plugins install git:github.com/unblocklabs-ai/unblock-memory`.
|
|
36
|
+
|
|
37
|
+
## What does what?
|
|
38
|
+
|
|
39
|
+
| Capability | What it does | Default / prerequisite |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| [Search and reads](docs/retrieval.md#search-and-read) | Vector recall, then exact indexed source reads | Available with the memory plugin; files only unless more corpora are configured |
|
|
42
|
+
| [Session indexing](docs/retrieval.md#sessions) | Makes past user/assistant exchanges searchable | Opt-in corpus; channel/group by default, DMs explicitly included |
|
|
43
|
+
| [Skill Whisperer](docs/retrieval.md#skill-whisperer) | Suggests one relevant skill; never invokes it | Off; explicit skills corpus; TypeSafe optional |
|
|
44
|
+
| [Memory Whisperer](docs/retrieval.md#memory-whisperer) | Injects up to two useful historical excerpts | Off; approved corpora + TypeSafe |
|
|
45
|
+
| [People dossiers](docs/peoplesql.md) | Stores agent-authored, evidence-backed recognition snippets | Off; `people.enabled` |
|
|
46
|
+
| [People Primer](docs/peoplesql.md#optional-people-dossier-primer) | Selects evidence and reviews proposed blurbs; never generates/saves dossiers itself | Off; people + approved corpora + TypeSafe |
|
|
47
|
+
| [People Whisperer](docs/peoplesql.md#injection-and-person-state) | Injects a saved blurb for an exact Slack identity | Off; separate global/per-person gates; no model call |
|
|
48
|
+
| [Analysis and curation](docs/retrieval.md#memory-analysis) | Clusters existing vectors; agent maintains useful knowledge | Optional local analysis worker; no plugin-owned curation schedule |
|
|
49
|
+
| [Quality and evidence review](docs/retrieval.md#review-and-diagnostics) | Advisory ingestion/claim checks and maintenance leads | Off; feature-specific corpora + TypeSafe |
|
|
50
|
+
| [Response quality/sentiment](docs/response-audit.md) | Operator-only evaluation of approved Slack exchanges | Off; approved humans + TypeSafe; no memory/dossier updates |
|
|
51
|
+
| [Compaction memory flush](docs/configuration.md#compaction-memory-writes) | Supplies the host an append-only daily-memory write plan | Offered unless the host's memory-flush setting is false; separate from whisperers |
|
|
52
|
+
|
|
53
|
+
**Search is not one interchangeable API:** plugin `memory_search` is vector-only;
|
|
54
|
+
standalone QMD `query` is hybrid vector + BM25 with TypeSafe ranking.
|
|
55
|
+
They have separate configuration/index boundaries. See
|
|
56
|
+
[search modes and the xsearch migration](docs/retrieval.md#qmd-search-modes).
|
|
57
|
+
|
|
58
|
+
## Configuration and operating guides
|
|
59
|
+
|
|
60
|
+
- [Configuration](docs/configuration.md): every setting/default, feature dependencies,
|
|
61
|
+
TypeSafe credentials/data scopes, host permissions and compaction.
|
|
62
|
+
- [Retrieval](docs/retrieval.md): search/read workflow, sessions, whisperers,
|
|
63
|
+
indexing, diagnostics, clustering and curation.
|
|
64
|
+
- [People](docs/peoplesql.md): dossier workflow, primer/save review, injection and
|
|
65
|
+
pause/delete/restore semantics.
|
|
66
|
+
- [Response audit](docs/response-audit.md): operator commands, cadence, sentiment,
|
|
67
|
+
evidence-linked reports and their limits.
|
|
68
|
+
|
|
69
|
+
The shared TypeSafe integration defaults on, but its features are opt-in.
|
|
70
|
+
A key activates only features already enabled. Ordinary search and People
|
|
71
|
+
Whisperer's injection stay local; Skill Whisperer has a local fallback.
|
|
72
|
+
[Provider gates and failure behavior](docs/configuration.md#feature-gates-and-fallbacks)
|
|
73
|
+
differ by feature.
|
|
74
|
+
|
|
75
|
+
## For agents
|
|
76
|
+
|
|
77
|
+
Use `memory_search` to locate evidence, then `memory_get` to inspect context,
|
|
78
|
+
attribution and dates. Follow bounded-read continuation when present. Empty search
|
|
79
|
+
results are not proof of absence; old memory is not current authorization.
|
|
80
|
+
|
|
81
|
+
The package includes two focused procedures:
|
|
82
|
+
[people-whisperer](skills/people-whisperer/SKILL.md) and
|
|
83
|
+
[memory-curator](skills/memory-curator/SKILL.md).
|
|
84
|
+
Include them in any explicit agent skill allowlist. Read their longer references
|
|
85
|
+
only when needed; Skill Whisperer does not install or authorize skills.
|
|
86
|
+
|
|
87
|
+
## Storage and development
|
|
88
|
+
|
|
89
|
+
Each agent has a rebuildable `index.sqlite` and durable `unblock-memory.sqlite`.
|
|
90
|
+
The latter holds people/dossiers/history, curation and private response audits;
|
|
91
|
+
sharing a file does not make audit data searchable or prompt-visible.
|
|
92
|
+
Read [migration, backup and rollback](docs/configuration.md#durable-database-migration)
|
|
93
|
+
before upgrading from the former separate databases.
|
|
94
|
+
|
|
95
|
+
Source-checkout-only fleet key tooling, when present, is documented in
|
|
96
|
+
`scripts/TYPESAFE-FLEET.md` and run through `scripts/typesafe-fleet.mjs`.
|
|
97
|
+
It is not part of the npm package; keep populated key files private.
|
|
98
|
+
|
|
99
|
+
[Release instructions](https://github.com/unblocklabs-ai/unblock-memory/blob/main/docs/RELEASE.md)
|
|
100
|
+
and [product direction](https://github.com/unblocklabs-ai/unblock-memory/blob/main/docs/vision.md)
|
|
101
|
+
are source-repository references. Planning documents describe historical or future
|
|
102
|
+
designs, not the installed runtime contract.
|