@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.
- package/ARCHITECTURE.md +173 -0
- package/CHANGELOG.md +18 -0
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/README.tr.md +240 -0
- package/dist/admin.js +1494 -0
- package/dist/core.js +2434 -0
- package/dist/server.js +1790 -0
- package/dist/types/admin/doctor.d.ts +10 -0
- package/dist/types/admin/index.d.ts +2 -0
- package/dist/types/capture/contract.d.ts +102 -0
- package/dist/types/capture/identity.d.ts +25 -0
- package/dist/types/capture/policy.d.ts +9 -0
- package/dist/types/capture/projection.d.ts +17 -0
- package/dist/types/capture/redact.d.ts +12 -0
- package/dist/types/config.d.ts +4 -0
- package/dist/types/context.d.ts +1 -0
- package/dist/types/core.d.ts +30 -0
- package/dist/types/db/backup.d.ts +25 -0
- package/dist/types/db/health.d.ts +11 -0
- package/dist/types/db/migration-lock.d.ts +17 -0
- package/dist/types/db/migrations/v009.d.ts +3 -0
- package/dist/types/db/schema.d.ts +5 -0
- package/dist/types/db.d.ts +6 -0
- package/dist/types/identity.d.ts +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/project.d.ts +4 -0
- package/dist/types/retrieval/backends/none.d.ts +9 -0
- package/dist/types/retrieval/contract.d.ts +42 -0
- package/dist/types/retrieval/derived.d.ts +11 -0
- package/dist/types/retrieval/formatter.d.ts +5 -0
- package/dist/types/retrieval/fusion.d.ts +8 -0
- package/dist/types/server.d.ts +5 -0
- package/dist/types/store/capture.d.ts +46 -0
- package/dist/types/store/outbox.d.ts +14 -0
- package/dist/types/store/retrieval.d.ts +18 -0
- package/dist/types/store.d.ts +95 -0
- package/dist/types/tools.d.ts +3 -0
- package/dist/types/types.d.ts +54 -0
- package/docs/backup-restore-runbook.md +73 -0
- package/package.json +63 -0
package/ARCHITECTURE.md
ADDED
|
@@ -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.
|