@vaur94/agz-memory 0.4.0-beta.1

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.
Files changed (41) hide show
  1. package/ARCHITECTURE.md +173 -0
  2. package/CHANGELOG.md +18 -0
  3. package/LICENSE +21 -0
  4. package/README.md +237 -0
  5. package/README.tr.md +240 -0
  6. package/dist/admin.js +1494 -0
  7. package/dist/core.js +2434 -0
  8. package/dist/server.js +1790 -0
  9. package/dist/types/admin/doctor.d.ts +10 -0
  10. package/dist/types/admin/index.d.ts +2 -0
  11. package/dist/types/capture/contract.d.ts +102 -0
  12. package/dist/types/capture/identity.d.ts +25 -0
  13. package/dist/types/capture/policy.d.ts +9 -0
  14. package/dist/types/capture/projection.d.ts +17 -0
  15. package/dist/types/capture/redact.d.ts +12 -0
  16. package/dist/types/config.d.ts +4 -0
  17. package/dist/types/context.d.ts +1 -0
  18. package/dist/types/core.d.ts +30 -0
  19. package/dist/types/db/backup.d.ts +25 -0
  20. package/dist/types/db/health.d.ts +11 -0
  21. package/dist/types/db/migration-lock.d.ts +17 -0
  22. package/dist/types/db/migrations/v009.d.ts +3 -0
  23. package/dist/types/db/schema.d.ts +5 -0
  24. package/dist/types/db.d.ts +6 -0
  25. package/dist/types/identity.d.ts +1 -0
  26. package/dist/types/index.d.ts +2 -0
  27. package/dist/types/project.d.ts +4 -0
  28. package/dist/types/retrieval/backends/none.d.ts +9 -0
  29. package/dist/types/retrieval/contract.d.ts +42 -0
  30. package/dist/types/retrieval/derived.d.ts +11 -0
  31. package/dist/types/retrieval/formatter.d.ts +5 -0
  32. package/dist/types/retrieval/fusion.d.ts +8 -0
  33. package/dist/types/server.d.ts +5 -0
  34. package/dist/types/store/capture.d.ts +46 -0
  35. package/dist/types/store/outbox.d.ts +14 -0
  36. package/dist/types/store/retrieval.d.ts +18 -0
  37. package/dist/types/store.d.ts +95 -0
  38. package/dist/types/tools.d.ts +3 -0
  39. package/dist/types/types.d.ts +54 -0
  40. package/docs/backup-restore-runbook.md +73 -0
  41. package/package.json +63 -0
@@ -0,0 +1,173 @@
1
+ # AGZ Memory v9 Architecture
2
+
3
+ ## System Boundaries
4
+
5
+ ```text
6
+ OpenCode V2 beta-18743
7
+ -> @vaur94/agz-memory-plugin
8
+ -> projection -> redaction -> policy -> CaptureEventV1
9
+ -> bounded retrieval -> untrusted context
10
+ -> @vaur94/agz-memory/core
11
+ -> SQLite schema v9 (canonical)
12
+ -> FTS5 + graph + revisions + provenance + outbox
13
+ -> optional replaceable derived backend (currently none)
14
+
15
+ OpenCode MCP client
16
+ -> agz-memory stdio server
17
+ -> unchanged nine-tool MCP adapter
18
+ -> same core and canonical SQLite database
19
+ ```
20
+
21
+ The MCP adapter owns tool schemas and text result envelopes. The core owns
22
+ transactions, project isolation, capture, lifecycle, retrieval, and outbox.
23
+ The plugin owns only exact OpenCode V2 hook/event adaptation. It writes no SQL.
24
+
25
+ ## Canonical Storage
26
+
27
+ `projects`, `notes`, and `note_edges` preserve the public v8 identities and
28
+ fields. Schema v9 adds internal note fields:
29
+
30
+ | Field | Invariant |
31
+ |---|---|
32
+ | `current_revision` | Integer `>= 1` |
33
+ | `subject_key` | Optional normalized supersession key |
34
+ | `content_hash` | SHA-256 of canonical kind/title/summary/content |
35
+
36
+ Additional tables:
37
+
38
+ | Table | Purpose |
39
+ |---|---|
40
+ | `project_bindings` | Explicit OpenCode project/workspace to memory project mapping; stores only path hashes |
41
+ | `capture_checkpoints` | Crash-safe session reconciliation progress without transcript text |
42
+ | `capture_events` | Bounded redacted idempotent event audit |
43
+ | `note_provenance` | Source IDs, extractor/redaction versions, and confidence; no prompt/tool payload |
44
+ | `note_revisions` | Full snapshot for every committed note state |
45
+ | `index_outbox` | Payload-free at-least-once derived-index queue |
46
+
47
+ `schema_state` is the only schema version source and contains exactly `9` after
48
+ migration. Foreign keys are enabled during normal operation.
49
+
50
+ ## Transaction Invariants
51
+
52
+ - Create commits note, provenance, revision, FTS trigger, and outbox together.
53
+ - Patch and pin increment revision only when values actually change.
54
+ - Hard note delete cascades revision, provenance, edge, and FTS state.
55
+ - Project delete queues payload-free backend purge operations before project
56
+ cascades, in the same transaction.
57
+ - Supersession marks the old note `superseded`, snapshots it, creates the active
58
+ replacement, adds a `SUPERSEDES` edge, and writes outbox operations atomically.
59
+ - Capture materialization commits the event disposition and note lifecycle in
60
+ one transaction.
61
+
62
+ The partial unique index on `(project_id, kind, subject_key)` applies only to
63
+ active notes with a subject key. Manual MCP notes keep `subject_key = NULL`, so
64
+ the existing free-form contract remains unchanged.
65
+
66
+ ## FTS And Retrieval
67
+
68
+ `notes_fts` is an external-content FTS5 table keyed by `notes.rowid`. Insert,
69
+ update, and delete triggers maintain it inside note transactions. Migration
70
+ uses FTS `rebuild` and compares note/FTS counts.
71
+
72
+ Retrieval channels are bounded:
73
+
74
+ | Channel | Candidate limit |
75
+ |---|---:|
76
+ | Lexical BM25 | 40 |
77
+ | Optional semantic | 40 |
78
+ | One-hop graph | 30 |
79
+
80
+ Weighted reciprocal rank fusion uses `1.00`, `0.80`, and `0.35` channel weights
81
+ with constant `60`. Every semantic hit is re-read by `(project_id, note_id)` and
82
+ rejected when missing, inactive, cross-project, stale-revision, or hash-mismatched.
83
+ Semantic failure falls back to lexical retrieval.
84
+
85
+ The injection formatter emits only kind, opaque ID, title, and summary. It
86
+ escapes delimiter characters, includes a fixed untrusted-data warning, limits
87
+ output to eight cards and 4,800 characters, and never injects full note content.
88
+
89
+ ## Capture Pipeline
90
+
91
+ The plugin uses the exact `@opencode-ai/plugin@0.0.0-beta-18743` Promise API:
92
+
93
+ - `ctx.session.hook("prompt")`
94
+ - `ctx.session.hook("context")`
95
+ - `ctx.tool.hook("execute.after")`
96
+ - `ctx.event.subscribe({ signal })`
97
+ - `ctx.session.get({ sessionID })`
98
+ - `ctx.session.context({ sessionID })`
99
+
100
+ The live event stream is a latency hint, not the canonical ingestion boundary.
101
+ Prompt checkpoints and bounded context reconciliation recover missed terminal
102
+ events. Event reconnect uses bounded backoff. Plugin cleanup aborts the stream,
103
+ disposes hooks, and waits only a bounded period.
104
+
105
+ The projection boundary accepts user prompt text and assistant terminal text.
106
+ It excludes reasoning, tool arguments/results, attachments, files, shell output,
107
+ system/synthetic/skill/compaction parts, paths, diffs, environment values, and
108
+ provider state. Tool capture stores only name, terminal status, opaque native
109
+ IDs, and a normalized error type.
110
+
111
+ Redaction runs before extraction and again inside core. High-risk payloads are
112
+ quarantined with `payload_json = NULL`. Raw secret values and hashes are not
113
+ stored in capture audit tables.
114
+
115
+ ## Binding And Isolation
116
+
117
+ Plugin bindings require memory project UUID, OpenCode project ID, optional
118
+ workspace ID, and a verified canonical directory. Raw paths are not persisted.
119
+ The binding key is:
120
+
121
+ ```text
122
+ sha256("opencode-v2\0" + projectID + "\0" + workspaceID + "\0" + sha256(realpath))
123
+ ```
124
+
125
+ Basenames are never project identities. Event location or session location must
126
+ match the active plugin instance. Missing, conflicting, moved, or cross-project
127
+ bindings disable capture/injection for that callback.
128
+
129
+ ## Backup And Migration
130
+
131
+ Migration uses `<database>.migration.lock/owner.json`, mode `0700/0600`, with
132
+ PID, process-start marker, host, timestamp, target schema, and random owner ID.
133
+ A live owner cannot be broken by runtime or admin.
134
+
135
+ Before v8-to-v9 DDL:
136
+
137
+ 1. Checkpoint WAL and validate source integrity/foreign keys.
138
+ 2. Create a unique `VACUUM INTO` snapshot.
139
+ 3. Validate the snapshot on a separate connection.
140
+ 4. Write SHA-256, byte size, schema, SQLite version, and row counts to a manifest.
141
+ 5. Fsync temporary files and the backup directory, then atomically rename.
142
+ 6. Rebuild notes/edges, create revision/provenance rows, create v9 tables and
143
+ trigger-based FTS, and set schema `9` as the final SQL step.
144
+ 7. Re-enable and verify foreign keys, integrity, counts, revisions, and FTS.
145
+
146
+ Failure closes the candidate DB and restores the verified snapshot. Restore
147
+ never overwrites the previous canonical DB; it preserves the old file and
148
+ quarantines WAL/SHM sidecars.
149
+
150
+ ## Outbox
151
+
152
+ Outbox work is FIFO per `(backend, project_id)`. Atomic claims use random worker
153
+ lease IDs and expiry. Stale revision upserts complete without export. Vendor
154
+ exports apply redaction again and derive a hash from the redacted document.
155
+ High-risk manual notes remain canonical but are not exported.
156
+
157
+ Delivery is at least once and adapters must be idempotent by opaque project/note
158
+ key. Ten failed attempts move work to `dead`; canonical note commits are never
159
+ rolled back by a derived backend outage.
160
+
161
+ ## Fail-Open And Fail-Closed
162
+
163
+ | Operation | Behavior |
164
+ |---|---|
165
+ | Plugin capture/injection | Fail-open; OpenCode request continues |
166
+ | Semantic query | Lexical fallback |
167
+ | Binding conflict | Fail-closed for memory feature |
168
+ | Secret quarantine | Fail-closed for note write |
169
+ | MCP mutation | Transaction rollback and explicit tool error |
170
+ | Migration/restore | Fail-closed; service does not start on partial state |
171
+
172
+ Logs contain allowlisted operation/outcome/error codes only. Prompt, query,
173
+ note text, paths, tool payloads, headers, and credentials are never logged.
package/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## 0.4.0-beta.1 - 2026-08-31
4
+
5
+ - Added verified backup manifests, migration locking, schema v9, restore, and
6
+ the `agz-memory-admin` binary.
7
+ - Added note revisions, provenance, trigger-maintained FTS5, supersession, and
8
+ payload-free derived-index outbox processing.
9
+ - Added strict `CaptureEventV1`, deterministic idempotency, double redaction,
10
+ quarantine, retention, and explicit high-confidence auto-write policy.
11
+ - Added bounded lexical/graph/hybrid retrieval contracts and untrusted context
12
+ formatting.
13
+ - Added the separate exact-beta OpenCode V2 plugin package with safe `off`
14
+ default and staged rollout modes.
15
+ - Preserved all nine MCP tool names, selectors, result envelopes, project
16
+ isolation, and destructive confirmations.
17
+ - Renamed the public repository, packages, binaries, MCP server, and plugin to
18
+ AGZ Memory while retaining legacy persisted contract identifiers.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AGZ Memory contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # AGZ Memory
2
+
3
+ English | [Türkçe](README.tr.md)
4
+
5
+ Project-scoped persistent memory for OpenCode V2. The repository publishes two
6
+ lockstep packages:
7
+
8
+ - `@vaur94/agz-memory`: the nine-tool stdio MCP server, reusable core, and
9
+ recovery-oriented admin CLI.
10
+ - `@vaur94/agz-memory-plugin`: optional safe capture and bounded context
11
+ injection for an exact OpenCode V2 beta.
12
+
13
+ SQLite schema v9 is the canonical source of truth. Optional semantic services
14
+ are disposable derived indexes and are disabled unless their isolation,
15
+ deletion, purge, and quality contracts pass the benchmark gates.
16
+
17
+ ## Compatibility
18
+
19
+ | Component | Version |
20
+ |---|---|
21
+ | Core/MCP | `0.4.0-beta.1` |
22
+ | Plugin | `0.4.0-beta.1` |
23
+ | OpenCode V2 | `0.0.0-beta-18743` |
24
+ | `@opencode-ai/plugin` | `0.0.0-beta-18743` |
25
+ | Bun | `>=1.3.14` |
26
+ | SQLite schema | `9` |
27
+
28
+ The plugin disables itself when the running OpenCode version does not exactly
29
+ match its supported beta. The MCP server remains independently usable.
30
+
31
+ ## MCP Server
32
+
33
+ ```sh
34
+ bunx @vaur94/agz-memory@0.4.0-beta.1
35
+ ```
36
+
37
+ OpenCode V2 configuration uses `mcp.servers`:
38
+
39
+ ```jsonc
40
+ {
41
+ "mcp": {
42
+ "servers": {
43
+ "agz-memory": {
44
+ "type": "local",
45
+ "command": ["bunx", "@vaur94/agz-memory@0.4.0-beta.1"],
46
+ "environment": {
47
+ "OPENCODE_MEMORY_DATABASE_PATH": "{env:OPENCODE_MEMORY_DATABASE_PATH}"
48
+ },
49
+ "codemode": false
50
+ }
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ The default database path is
57
+ `~/.local/share/opencode-memory/memory.sqlite`. Override it with
58
+ `OPENCODE_MEMORY_DATABASE_PATH` before starting OpenCode.
59
+
60
+ ### Tools
61
+
62
+ The external MCP contract remains exactly nine tools:
63
+
64
+ | Tool | Purpose |
65
+ |---|---|
66
+ | `project_list` | List immutable project IDs and current names |
67
+ | `project_create` | Create an empty project |
68
+ | `project_update` | Rename a project without changing its ID |
69
+ | `project_delete` | Permanently delete one confirmed project |
70
+ | `memory_recall` | Project-filtered FTS5 and one-hop graph recall |
71
+ | `memory_update` | Create, patch, or permanently delete notes |
72
+ | `memory_pin` | Set note priority inside one project |
73
+ | `memory_link` | Add same-project graph edges |
74
+ | `memory_read` | Read full note bodies and graph edges |
75
+
76
+ Every `memory_*` request selects exactly one `projectID` or `projectName`.
77
+ Cross-project reads, updates, deletes, links, and recall are rejected. Ordered
78
+ batches are intentionally non-atomic, so inspect every item result.
79
+
80
+ Project deletion requires all three values:
81
+
82
+ ```json
83
+ {
84
+ "projectID": "<immutable UUID>",
85
+ "confirmProjectName": "<exact current case-sensitive name>",
86
+ "confirmation": "DELETE_PROJECT_AND_ALL_MEMORY"
87
+ }
88
+ ```
89
+
90
+ ## Optional OpenCode Plugin
91
+
92
+ The plugin is a separate package so the moving OpenCode beta dependency never
93
+ enters the MCP-only runtime. Its safe default is `off`.
94
+
95
+ ```jsonc
96
+ {
97
+ "plugins": [
98
+ {
99
+ "package": "@vaur94/agz-memory-plugin@0.4.0-beta.1",
100
+ "options": {
101
+ "mode": "off",
102
+ "autoCreateProjects": false,
103
+ "bindings": [],
104
+ "capture": {
105
+ "enabled": false,
106
+ "allowedKinds": ["preference", "decision"],
107
+ "minConfidence": 0.95
108
+ },
109
+ "retrieval": {
110
+ "semanticBackend": "none",
111
+ "timeoutMs": 300,
112
+ "maxCards": 8,
113
+ "maxCharacters": 4800
114
+ }
115
+ }
116
+ }
117
+ ]
118
+ }
119
+ ```
120
+
121
+ Bindings are explicit allowlist entries. The plugin never selects a memory
122
+ project by basename and never auto-creates one:
123
+
124
+ ```jsonc
125
+ {
126
+ "memoryProjectID": "<UUID from project_list>",
127
+ "opencodeProjectID": "<ctx.location.project.id>",
128
+ "canonicalDirectory": "/absolute/canonical/project/path",
129
+ "workspaceID": "<optional workspace ID>"
130
+ }
131
+ ```
132
+
133
+ The rollout modes are cumulative:
134
+
135
+ | Mode | Capture | Retrieval | Injection | Auto-write |
136
+ |---|---:|---:|---:|---:|
137
+ | `off` | No | No | No | No |
138
+ | `shadow-capture` | Redacted audit only | No | No | No |
139
+ | `shadow-retrieval` | Yes | Metrics only | No | No |
140
+ | `inject` | Yes | Yes | Bounded | No |
141
+ | `auto-write` | Yes | Yes | Bounded | Explicit high-confidence decisions/preferences only |
142
+
143
+ Injection is fail-open, summary-only, limited to eight cards and 4,800
144
+ characters, and wrapped as `trust="untrusted"`. A memory timeout or binding
145
+ error does not block the main OpenCode request.
146
+
147
+ ## Capture Safety
148
+
149
+ The canonical event contract remains `opencode2-memory.capture/1` for database
150
+ and event compatibility with earlier releases.
151
+
152
+ - Native session/message/ordinal/tool IDs produce deterministic SHA-256
153
+ idempotency keys. SQLite uniqueness is the final duplicate guard.
154
+ - Projection discards reasoning, tool input/output, attachments, files, system
155
+ parts, diffs, environment data, and provider state.
156
+ - Text is redacted before extraction and again inside the core before any DB
157
+ insert.
158
+ - Private keys, credential URIs, multiple high-risk secrets, and canaries are
159
+ quarantined without a text payload.
160
+ - Event JSON is limited to 16 KiB; automatic content is limited to 4,800
161
+ characters.
162
+ - `[memory:off]` disables capture for that user message.
163
+ - Auto-write initially accepts only explicit `preference` and `decision`
164
+ candidates at confidence `>= 0.95`.
165
+
166
+ ## Schema V9
167
+
168
+ Schema v9 preserves project, note, edge, timestamp, status, and pin identities
169
+ while adding:
170
+
171
+ - `project_bindings`
172
+ - `capture_checkpoints`
173
+ - `capture_events`
174
+ - `note_provenance`
175
+ - `note_revisions`
176
+ - `index_outbox`
177
+
178
+ Every committed note state has provenance and a full revision snapshot. Note
179
+ create, patch, pin, supersession, FTS triggers, and derived-index outbox writes
180
+ share transactions. Normal recall only returns `active` notes.
181
+
182
+ FTS5 now uses external content and insert/update/delete triggers rather than
183
+ manual synchronization.
184
+
185
+ ## Backup, Upgrade, And Restore
186
+
187
+ The admin binary writes JSON to stdout and sanitized errors to stderr:
188
+
189
+ ```sh
190
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin doctor
191
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin backup
192
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin upgrade --to 9
193
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin outbox status
194
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin capture status
195
+ ```
196
+
197
+ Every schema upgrade takes an atomic migration lock and creates a verified
198
+ `VACUUM INTO` snapshot plus a SHA-256 manifest before DDL runs. Integrity,
199
+ foreign keys, table counts, revision invariants, and FTS counts are checked.
200
+
201
+ Restore is dry-run unless the manifest hash and confirmation are supplied:
202
+
203
+ ```sh
204
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin restore \
205
+ /path/to/memory.sqlite.backup/<manifest>.manifest.json
206
+
207
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin restore \
208
+ /path/to/memory.sqlite.backup/<manifest>.manifest.json \
209
+ --sha256 <manifest-database-sha256> \
210
+ --confirm RESTORE_DATABASE_FROM_VERIFIED_BACKUP
211
+ ```
212
+
213
+ Stop every MCP/plugin writer before an upgrade or restore. The current database
214
+ is preserved as `failed-restore-source-*`; WAL/SHM sidecars are quarantined.
215
+ See [`docs/backup-restore-runbook.md`](docs/backup-restore-runbook.md).
216
+
217
+ ## Semantic Backend Decision
218
+
219
+ Production remains `semanticBackend: "none"`. The exact vendor contract review
220
+ did not produce a complete live A/B proof for all required server-side project
221
+ filter, deterministic delete, purge, leakage, and latency gates. SQLite
222
+ lexical+graph retrieval is therefore the production path. See
223
+ [`benchmark/baselines/vendor-decision.json`](benchmark/baselines/vendor-decision.json).
224
+
225
+ ## Development
226
+
227
+ ```sh
228
+ bun install
229
+ bun test
230
+ bun run check
231
+ bun run build
232
+ npm pack --dry-run --json
233
+ ```
234
+
235
+ The test suite includes MCP snapshots, legacy and v8-to-v9 migration fixtures,
236
+ backup/restore, revisions, outbox FIFO, capture idempotency, secret quarantine,
237
+ retrieval isolation, bounded formatter, and exact-beta plugin hook smoke tests.
package/README.tr.md ADDED
@@ -0,0 +1,240 @@
1
+ # AGZ Memory
2
+
3
+ [English](README.md) | Türkçe
4
+
5
+ OpenCode V2 için proje kapsamlı kalıcı hafıza. Depo, sürümleri birlikte ilerleyen
6
+ iki paket yayımlar:
7
+
8
+ - `@vaur94/agz-memory`: dokuz araçlı stdio MCP sunucusu, yeniden kullanılabilir
9
+ çekirdek ve kurtarma odaklı yönetim komut satırı aracı.
10
+ - `@vaur94/agz-memory-plugin`: exact bir OpenCode V2 beta sürümü için isteğe
11
+ bağlı güvenli yakalama ve sınırlı bağlam ekleme eklentisi.
12
+
13
+ SQLite schema v9, tek yetkili veri kaynağıdır. İsteğe bağlı anlamsal servisler
14
+ yeniden üretilebilir türetilmiş indekslerdir; izolasyon, silme, temizleme ve
15
+ kalite sözleşmeleri benchmark kapılarından geçmedikçe kapalı kalır.
16
+
17
+ ## Uyumluluk
18
+
19
+ | Bileşen | Sürüm |
20
+ |---|---|
21
+ | Core/MCP | `0.4.0-beta.1` |
22
+ | Plugin | `0.4.0-beta.1` |
23
+ | OpenCode V2 | `0.0.0-beta-18743` |
24
+ | `@opencode-ai/plugin` | `0.0.0-beta-18743` |
25
+ | Bun | `>=1.3.14` |
26
+ | SQLite schema | `9` |
27
+
28
+ Eklenti, çalışan OpenCode sürümü desteklenen beta ile tam eşleşmediğinde
29
+ kendisini devre dışı bırakır. MCP sunucusu bağımsız olarak kullanılabilir.
30
+
31
+ ## MCP Sunucusu
32
+
33
+ ```sh
34
+ bunx @vaur94/agz-memory@0.4.0-beta.1
35
+ ```
36
+
37
+ OpenCode V2 yapılandırması `mcp.servers` alanını kullanır:
38
+
39
+ ```jsonc
40
+ {
41
+ "mcp": {
42
+ "servers": {
43
+ "agz-memory": {
44
+ "type": "local",
45
+ "command": ["bunx", "@vaur94/agz-memory@0.4.0-beta.1"],
46
+ "environment": {
47
+ "OPENCODE_MEMORY_DATABASE_PATH": "{env:OPENCODE_MEMORY_DATABASE_PATH}"
48
+ },
49
+ "codemode": false
50
+ }
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ Varsayılan veritabanı yolu `~/.local/share/opencode-memory/memory.sqlite` olur.
57
+ OpenCode başlamadan önce `OPENCODE_MEMORY_DATABASE_PATH` ile değiştirilebilir.
58
+
59
+ ### Araçlar
60
+
61
+ Dış MCP sözleşmesi tam olarak dokuz araçtan oluşur:
62
+
63
+ | Araç | Amaç |
64
+ |---|---|
65
+ | `project_list` | Değişmez proje kimliklerini ve güncel adları listeler |
66
+ | `project_create` | Boş bir proje oluşturur |
67
+ | `project_update` | Kimliği değiştirmeden projeyi yeniden adlandırır |
68
+ | `project_delete` | Onaylanmış tek bir projeyi kalıcı olarak siler |
69
+ | `memory_recall` | Proje filtreli FTS5 ve tek adımlı grafik araması yapar |
70
+ | `memory_update` | Not oluşturur, günceller veya kalıcı olarak siler |
71
+ | `memory_pin` | Proje içindeki not önceliğini ayarlar |
72
+ | `memory_link` | Aynı proje içinde grafik bağlantısı ekler |
73
+ | `memory_read` | Tam not içeriklerini ve grafik bağlantılarını okur |
74
+
75
+ Her `memory_*` isteği tam olarak bir `projectID` veya `projectName` seçer.
76
+ Projeler arası okuma, güncelleme, silme, bağlantı ve arama reddedilir. Sıralı
77
+ toplu işlemler kasıtlı olarak atomik değildir; her öğenin sonucu incelenmelidir.
78
+
79
+ Proje silmek için üç değerin de sağlanması gerekir:
80
+
81
+ ```json
82
+ {
83
+ "projectID": "<immutable UUID>",
84
+ "confirmProjectName": "<exact current case-sensitive name>",
85
+ "confirmation": "DELETE_PROJECT_AND_ALL_MEMORY"
86
+ }
87
+ ```
88
+
89
+ ## İsteğe Bağlı OpenCode Eklentisi
90
+
91
+ Hareketli OpenCode beta bağımlılığının yalnız MCP kullanan çalışma ortamına
92
+ girmemesi için eklenti ayrı bir pakettir. Güvenli varsayılanı `off` değeridir.
93
+
94
+ ```jsonc
95
+ {
96
+ "plugins": [
97
+ {
98
+ "package": "@vaur94/agz-memory-plugin@0.4.0-beta.1",
99
+ "options": {
100
+ "mode": "off",
101
+ "autoCreateProjects": false,
102
+ "bindings": [],
103
+ "capture": {
104
+ "enabled": false,
105
+ "allowedKinds": ["preference", "decision"],
106
+ "minConfidence": 0.95
107
+ },
108
+ "retrieval": {
109
+ "semanticBackend": "none",
110
+ "timeoutMs": 300,
111
+ "maxCards": 8,
112
+ "maxCharacters": 4800
113
+ }
114
+ }
115
+ }
116
+ ]
117
+ }
118
+ ```
119
+
120
+ Bağlamalar açık izin listesi girdileridir. Eklenti bir hafıza projesini hiçbir
121
+ zaman klasör adına göre seçmez ve otomatik proje oluşturmaz:
122
+
123
+ ```jsonc
124
+ {
125
+ "memoryProjectID": "<UUID from project_list>",
126
+ "opencodeProjectID": "<ctx.location.project.id>",
127
+ "canonicalDirectory": "/absolute/canonical/project/path",
128
+ "workspaceID": "<optional workspace ID>"
129
+ }
130
+ ```
131
+
132
+ Rollout modları birikimli olarak ilerler:
133
+
134
+ | Mod | Yakalama | Getirme | Ekleme | Otomatik yazma |
135
+ |---|---:|---:|---:|---:|
136
+ | `off` | Hayır | Hayır | Hayır | Hayır |
137
+ | `shadow-capture` | Yalnız maskelenmiş denetim | Hayır | Hayır | Hayır |
138
+ | `shadow-retrieval` | Evet | Yalnız ölçüm | Hayır | Hayır |
139
+ | `inject` | Evet | Evet | Sınırlı | Hayır |
140
+ | `auto-write` | Evet | Evet | Sınırlı | Yalnız açık ve yüksek güvenli karar/tercihler |
141
+
142
+ Bağlam ekleme fail-open çalışır; yani hafıza hatası ana isteği engellemez. Yalnız
143
+ özetleri kullanır, sekiz kart ve 4.800 karakterle sınırlıdır ve
144
+ `trust="untrusted"` olarak sarılır. Hafıza zaman aşımı veya bağlama hatası ana
145
+ OpenCode isteğini durdurmaz.
146
+
147
+ ## Yakalama Güvenliği
148
+
149
+ Veritabanı ve önceki sürümlerin olay uyumluluğu için yetkili olay sözleşmesi
150
+ `opencode2-memory.capture/1` olarak korunur.
151
+
152
+ - Yerel session/message/ordinal/tool kimlikleri belirlenebilir SHA-256 tekilleştirme
153
+ anahtarları üretir. SQLite benzersizliği son tekrar korumasıdır.
154
+ - Projeksiyon; reasoning, araç girdisi/çıktısı, ekler, dosyalar, sistem parçaları,
155
+ diff, ortam verileri ve sağlayıcı durumunu atar.
156
+ - Metin, çıkarımdan önce ve veritabanına yazılmadan önce çekirdek içinde tekrar
157
+ maskelenir.
158
+ - Özel anahtarlar, kimlik bilgisi URI'ları, birden çok yüksek riskli sır ve
159
+ canary değerleri metin yükü olmadan karantinaya alınır.
160
+ - Olay JSON'u 16 KiB, otomatik içerik 4.800 karakter ile sınırlıdır.
161
+ - `[memory:off]`, ilgili kullanıcı mesajı için yakalamayı kapatır.
162
+ - Otomatik yazma başlangıçta yalnız güveni `>= 0.95` olan açık `preference` ve
163
+ `decision` adaylarını kabul eder.
164
+
165
+ ## Schema V9
166
+
167
+ Schema v9; proje, not, bağlantı, zaman damgası, durum ve pin kimliklerini korur.
168
+ Eklenen tablolar:
169
+
170
+ - `project_bindings`
171
+ - `capture_checkpoints`
172
+ - `capture_events`
173
+ - `note_provenance`
174
+ - `note_revisions`
175
+ - `index_outbox`
176
+
177
+ Kaydedilen her not durumunda kaynak bilgisi ve tam revision görüntüsü bulunur.
178
+ Not oluşturma, güncelleme, pin, supersession, FTS trigger ve türetilmiş indeks
179
+ outbox yazımları aynı transaction içinde yapılır. Normal arama yalnız `active`
180
+ notları döndürür.
181
+
182
+ FTS5 artık elle eşitleme yerine dış içerik ile insert/update/delete trigger'larını
183
+ kullanır.
184
+
185
+ ## Yedekleme, Yükseltme Ve Geri Yükleme
186
+
187
+ Yönetim binary'si JSON çıktısını stdout'a, temizlenmiş hataları stderr'e yazar:
188
+
189
+ ```sh
190
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin doctor
191
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin backup
192
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin upgrade --to 9
193
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin outbox status
194
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin capture status
195
+ ```
196
+
197
+ Her schema yükseltmesi atomik bir migration lock alır ve DDL çalışmadan önce
198
+ SHA-256 manifest içeren doğrulanmış bir `VACUUM INTO` snapshot oluşturur.
199
+ Bütünlük, foreign key, tablo sayıları, revision kuralları ve FTS sayıları kontrol
200
+ edilir.
201
+
202
+ Manifest hash'i ve onay sağlanmadıkça geri yükleme yalnız kuru çalışır:
203
+
204
+ ```sh
205
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin restore \
206
+ /path/to/memory.sqlite.backup/<manifest>.manifest.json
207
+
208
+ bunx --package @vaur94/agz-memory@0.4.0-beta.1 agz-memory-admin restore \
209
+ /path/to/memory.sqlite.backup/<manifest>.manifest.json \
210
+ --sha256 <manifest-database-sha256> \
211
+ --confirm RESTORE_DATABASE_FROM_VERIFIED_BACKUP
212
+ ```
213
+
214
+ Yükseltme veya geri yükleme öncesinde tüm MCP/plugin yazıcılarını durdurun. Güncel
215
+ veritabanı `failed-restore-source-*` olarak korunur; WAL/SHM yan dosyaları
216
+ karantinaya alınır. Ayrıntılar için
217
+ [`docs/backup-restore-runbook.md`](docs/backup-restore-runbook.md) belgesine bakın.
218
+
219
+ ## Anlamsal Backend Kararı
220
+
221
+ Üretim `semanticBackend: "none"` olarak kalır. Tam vendor sözleşmesi incelemesi,
222
+ zorunlu sunucu tarafı proje filtresi, belirlenebilir silme, purge, sızıntı ve
223
+ gecikme kapılarının tümü için eksiksiz canlı A/B kanıtı üretmedi. Bu nedenle
224
+ üretim yolu SQLite metin+grafik aramasıdır. Ayrıntılar:
225
+ [`benchmark/baselines/vendor-decision.json`](benchmark/baselines/vendor-decision.json).
226
+
227
+ ## Geliştirme
228
+
229
+ ```sh
230
+ bun install
231
+ bun test
232
+ bun run check
233
+ bun run build
234
+ npm pack --dry-run --json
235
+ ```
236
+
237
+ Test paketi; MCP snapshot'ları, eski sürüm ve v8-to-v9 migration fixture'ları,
238
+ yedekleme/geri yükleme, revision'lar, outbox FIFO, capture tekilleştirme, sır
239
+ karantinası, retrieval izolasyonu, sınırlı formatter ve exact-beta plugin hook
240
+ smoke testlerini içerir.