yaams 0.3.0__tar.gz

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 (121) hide show
  1. yaams-0.3.0/LICENSE +21 -0
  2. yaams-0.3.0/PKG-INFO +308 -0
  3. yaams-0.3.0/README.md +286 -0
  4. yaams-0.3.0/pyproject.toml +76 -0
  5. yaams-0.3.0/setup.cfg +4 -0
  6. yaams-0.3.0/tests/test_associate.py +183 -0
  7. yaams-0.3.0/tests/test_calendar.py +40 -0
  8. yaams-0.3.0/tests/test_cli.py +65 -0
  9. yaams-0.3.0/tests/test_cli_assoc.py +80 -0
  10. yaams-0.3.0/tests/test_cli_doctor.py +120 -0
  11. yaams-0.3.0/tests/test_cli_entity_metadata.py +76 -0
  12. yaams-0.3.0/tests/test_cli_envelopes.py +144 -0
  13. yaams-0.3.0/tests/test_cli_ingest_envelope.py +251 -0
  14. yaams-0.3.0/tests/test_cli_init.py +79 -0
  15. yaams-0.3.0/tests/test_cli_interactive_rejection.py +46 -0
  16. yaams-0.3.0/tests/test_cli_merge.py +167 -0
  17. yaams-0.3.0/tests/test_cli_query_tier.py +168 -0
  18. yaams-0.3.0/tests/test_cli_remaining_envelopes.py +245 -0
  19. yaams-0.3.0/tests/test_cli_sources.py +505 -0
  20. yaams-0.3.0/tests/test_config_aliases.py +71 -0
  21. yaams-0.3.0/tests/test_config_discovery.py +131 -0
  22. yaams-0.3.0/tests/test_config_validation.py +67 -0
  23. yaams-0.3.0/tests/test_consolidate.py +159 -0
  24. yaams-0.3.0/tests/test_conventions.py +202 -0
  25. yaams-0.3.0/tests/test_email_mbox.py +371 -0
  26. yaams-0.3.0/tests/test_embed_prompt.py +50 -0
  27. yaams-0.3.0/tests/test_entities.py +33 -0
  28. yaams-0.3.0/tests/test_github.py +156 -0
  29. yaams-0.3.0/tests/test_imessage.py +244 -0
  30. yaams-0.3.0/tests/test_ingest_folder.py +231 -0
  31. yaams-0.3.0/tests/test_ingest_runs.py +101 -0
  32. yaams-0.3.0/tests/test_junk_detector.py +115 -0
  33. yaams-0.3.0/tests/test_m365_mail.py +137 -0
  34. yaams-0.3.0/tests/test_merge.py +185 -0
  35. yaams-0.3.0/tests/test_metadata.py +89 -0
  36. yaams-0.3.0/tests/test_normalize_entities.py +128 -0
  37. yaams-0.3.0/tests/test_parse.py +301 -0
  38. yaams-0.3.0/tests/test_people_import.py +304 -0
  39. yaams-0.3.0/tests/test_query_json_envelope.py +122 -0
  40. yaams-0.3.0/tests/test_query_prompt.py +196 -0
  41. yaams-0.3.0/tests/test_render.py +99 -0
  42. yaams-0.3.0/tests/test_retrieve.py +536 -0
  43. yaams-0.3.0/tests/test_review.py +457 -0
  44. yaams-0.3.0/tests/test_route.py +192 -0
  45. yaams-0.3.0/tests/test_signal.py +282 -0
  46. yaams-0.3.0/tests/test_signals.py +174 -0
  47. yaams-0.3.0/tests/test_stats_json_envelope.py +85 -0
  48. yaams-0.3.0/tests/test_store.py +188 -0
  49. yaams-0.3.0/tests/test_synonyms.py +85 -0
  50. yaams-0.3.0/tests/test_synthesize.py +253 -0
  51. yaams-0.3.0/tests/test_teams.py +322 -0
  52. yaams-0.3.0/tests/test_version.py +41 -0
  53. yaams-0.3.0/tests/test_watermark.py +21 -0
  54. yaams-0.3.0/yaams/__init__.py +6 -0
  55. yaams-0.3.0/yaams/_default_config.yaml +129 -0
  56. yaams-0.3.0/yaams/cli/__init__.py +22 -0
  57. yaams-0.3.0/yaams/cli/_envelope.py +167 -0
  58. yaams-0.3.0/yaams/cli/_root.py +57 -0
  59. yaams-0.3.0/yaams/cli/_shared.py +107 -0
  60. yaams-0.3.0/yaams/cli/assoc.py +224 -0
  61. yaams-0.3.0/yaams/cli/consolidate.py +190 -0
  62. yaams-0.3.0/yaams/cli/doctor.py +182 -0
  63. yaams-0.3.0/yaams/cli/enrich.py +85 -0
  64. yaams-0.3.0/yaams/cli/entities.py +1402 -0
  65. yaams-0.3.0/yaams/cli/ingest.py +923 -0
  66. yaams-0.3.0/yaams/cli/main.py +354 -0
  67. yaams-0.3.0/yaams/cli/promote.py +232 -0
  68. yaams-0.3.0/yaams/cli/query.py +594 -0
  69. yaams-0.3.0/yaams/cli/review.py +180 -0
  70. yaams-0.3.0/yaams/cli/signals.py +143 -0
  71. yaams-0.3.0/yaams/cli/sources.py +1173 -0
  72. yaams-0.3.0/yaams/config.py +158 -0
  73. yaams-0.3.0/yaams/consolidate/__init__.py +19 -0
  74. yaams-0.3.0/yaams/consolidate/session.py +201 -0
  75. yaams-0.3.0/yaams/conventions.py +241 -0
  76. yaams-0.3.0/yaams/db.py +61 -0
  77. yaams-0.3.0/yaams/enrich/__init__.py +5 -0
  78. yaams-0.3.0/yaams/enrich/embed.py +78 -0
  79. yaams-0.3.0/yaams/enrich/entities.py +156 -0
  80. yaams-0.3.0/yaams/ingest/__init__.py +4 -0
  81. yaams-0.3.0/yaams/ingest/base.py +34 -0
  82. yaams-0.3.0/yaams/ingest/calendar.py +85 -0
  83. yaams-0.3.0/yaams/ingest/email_mbox.py +491 -0
  84. yaams-0.3.0/yaams/ingest/folder.py +300 -0
  85. yaams-0.3.0/yaams/ingest/github.py +360 -0
  86. yaams-0.3.0/yaams/ingest/imessage.py +280 -0
  87. yaams-0.3.0/yaams/ingest/ledger_notes.py +66 -0
  88. yaams-0.3.0/yaams/ingest/m365_mail.py +257 -0
  89. yaams-0.3.0/yaams/ingest/obsidian.py +143 -0
  90. yaams-0.3.0/yaams/ingest/signal.py +552 -0
  91. yaams-0.3.0/yaams/ingest/teams.py +353 -0
  92. yaams-0.3.0/yaams/ingest/teams_chatsvc.py +399 -0
  93. yaams-0.3.0/yaams/logsetup.py +77 -0
  94. yaams-0.3.0/yaams/people_import.py +256 -0
  95. yaams-0.3.0/yaams/promote/__init__.py +4 -0
  96. yaams-0.3.0/yaams/promote/candidates.py +355 -0
  97. yaams-0.3.0/yaams/promote/review.py +98 -0
  98. yaams-0.3.0/yaams/render.py +130 -0
  99. yaams-0.3.0/yaams/retrieve/__init__.py +19 -0
  100. yaams-0.3.0/yaams/retrieve/associate.py +232 -0
  101. yaams-0.3.0/yaams/retrieve/hybrid.py +559 -0
  102. yaams-0.3.0/yaams/retrieve/metadata.py +64 -0
  103. yaams-0.3.0/yaams/retrieve/parse.py +377 -0
  104. yaams-0.3.0/yaams/retrieve/route.py +137 -0
  105. yaams-0.3.0/yaams/retrieve/synonyms.py +93 -0
  106. yaams-0.3.0/yaams/schema.py +377 -0
  107. yaams-0.3.0/yaams/signals/__init__.py +37 -0
  108. yaams-0.3.0/yaams/signals/logger.py +160 -0
  109. yaams-0.3.0/yaams/signals/review.py +749 -0
  110. yaams-0.3.0/yaams/store.py +803 -0
  111. yaams-0.3.0/yaams/synthesize/__init__.py +29 -0
  112. yaams-0.3.0/yaams/synthesize/answer.py +232 -0
  113. yaams-0.3.0/yaams/synthesize/llm.py +266 -0
  114. yaams-0.3.0/yaams/time.py +31 -0
  115. yaams-0.3.0/yaams/watermark.py +36 -0
  116. yaams-0.3.0/yaams.egg-info/PKG-INFO +308 -0
  117. yaams-0.3.0/yaams.egg-info/SOURCES.txt +119 -0
  118. yaams-0.3.0/yaams.egg-info/dependency_links.txt +1 -0
  119. yaams-0.3.0/yaams.egg-info/entry_points.txt +2 -0
  120. yaams-0.3.0/yaams.egg-info/requires.txt +16 -0
  121. yaams-0.3.0/yaams.egg-info/top_level.txt +1 -0
yaams-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Carl Joakim Damsleth
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.
yaams-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,308 @@
1
+ Metadata-Version: 2.4
2
+ Name: yaams
3
+ Version: 0.3.0
4
+ Summary: Yet Another Agent Memory System
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: click>=8.1
9
+ Requires-Dist: cryptography>=42.0
10
+ Requires-Dist: pyyaml>=6.0
11
+ Requires-Dist: numpy<2
12
+ Requires-Dist: pyobjc-framework-Cocoa>=12.1; sys_platform == "darwin"
13
+ Requires-Dist: sentence-transformers>=3.0
14
+ Requires-Dist: spacy>=3.7
15
+ Requires-Dist: sqlite-vec>=0.1.6
16
+ Requires-Dist: tqdm>=4.66
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest>=8.0; extra == "dev"
19
+ Requires-Dist: ruff>=0.6; extra == "dev"
20
+ Requires-Dist: pyright>=1.1.380; extra == "dev"
21
+ Dynamic: license-file
22
+
23
+ # YAAMS
24
+
25
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
26
+ ![python](https://img.shields.io/badge/python-3.11+-blue)
27
+
28
+ **Yet Another Agent Memory System.** A local-first, high-recall memory store
29
+ for your personal digital exhaust - messages, email, calendar, GitHub
30
+ activity, notes - searchable in seconds and synthesizable into grounded,
31
+ cited answers by the LLM of your choice.
32
+
33
+ YAAMS is Tier 1 of a two-tier memory architecture: the firehose. Tier 2 is
34
+ the [cognitive-ledger](https://github.com/damsleth/cognitive-ledger): curated
35
+ atomic notes you keep forever. YAAMS ingests everything, lets you query
36
+ across the lot, and promotes the gems upstream when you're ready.
37
+
38
+ Each tier is split between a public **engine** and a private **store**:
39
+
40
+ | Tier | Engine (public) | Store (private, your data) |
41
+ | --- | --- | --- |
42
+ | Tier 1 | **YAAMS** - this repo | a single SQLite file at `db_path` |
43
+ | Tier 2 | **cognitive-ledger** - sibling repo | a markdown tree of curated atomic notes |
44
+
45
+ Engines ship code, no data. Stores live outside the repo, are gitignored
46
+ by default, and never get pushed.
47
+
48
+ ## Suite
49
+
50
+ YAAMS is one of four tools in the **[hugr](https://github.com/damsleth/hugr)**
51
+ memory suite. The suite gives you one install (`brew install
52
+ damsleth/tap/hugr`), one verb surface (`hugr query`, `hugr ingest`,
53
+ `hugr promote`, ...), and one CLI contract (output classes, exit
54
+ codes, action envelopes - see
55
+ [hugr/CONVENTIONS.md](https://github.com/damsleth/hugr/blob/main/CONVENTIONS.md)).
56
+ Power users can still call `yaams` directly and get byte-identical
57
+ JSON.
58
+
59
+ ## What
60
+
61
+ ```
62
+ query
63
+ |
64
+ v
65
+ ingest -> normalize -> embed -> retrieve -> fuse -> answer (cited)
66
+ | | | |
67
+ iMessage SQLite BGE-M3 Tier 2 boost
68
+ Signal + FTS5 + spaCy (cognitive-ledger)
69
+ Email + vec
70
+ Teams
71
+ Calendar
72
+ GitHub
73
+ Obsidian
74
+ ```
75
+
76
+ - **Local-only by default.** Embeddings, NER, and LLM synthesis run on your
77
+ machine. Nothing leaves the host unless you point an adapter at a hosted
78
+ backend.
79
+ - **Append-only.** Raw items are immutable. Re-ingest is idempotent.
80
+ - **Cited answers.** Every synthesized claim points back to the source items.
81
+ - **Pluggable LLM.** `claude`, `codex`, `ollama`, any subprocess, or `dummy`.
82
+ - **Single SQLite file.** No daemons, no servers, no cloud bill.
83
+
84
+ ## Why
85
+
86
+ Language models forget everything between sessions, and the answer is not
87
+ "shove more raw chat logs into the context window." The answer is a memory
88
+ system you can grep, query, and audit, that lives on your machine and that
89
+ you fully control.
90
+
91
+ YAAMS gives you that for the high-volume side of your life: every iMessage,
92
+ every email, every calendar event, every GitHub issue you have touched. It
93
+ normalizes them into a common schema, embeds them, and lets you ask
94
+ questions like *"what did we decide about the deploy in May?"* and get back
95
+ a grounded answer with citations - in seconds, offline.
96
+
97
+ ## Quickstart
98
+
99
+ Requires Python 3.11+ and macOS (Linux works for everything except the
100
+ iMessage adapter).
101
+
102
+ Homebrew (recommended):
103
+
104
+ ```bash
105
+ brew install damsleth/tap/yaams
106
+ ```
107
+
108
+ PyPI via pipx:
109
+
110
+ ```bash
111
+ pipx install yaams
112
+ ```
113
+
114
+ Bleeding-edge from main:
115
+
116
+ ```bash
117
+ brew install --HEAD damsleth/tap/yaams
118
+ ```
119
+
120
+ Then bootstrap a config and run the dry-run ingest:
121
+
122
+ ```bash
123
+ mkdir -p ~/.config/yaams
124
+ cp "$(brew --prefix)/share/yaams/config.yaml.example" ~/.config/yaams/config.yaml
125
+ $EDITOR ~/.config/yaams/config.yaml
126
+ yaams init-db
127
+ yaams ingest --dry-run
128
+ ```
129
+
130
+ If you cloned the repo instead of installing the package, run the
131
+ all-in-one bootstrap script (`scripts/install_phase_a.sh`) - it creates
132
+ `.venv`, runs the config wizard, downloads the spaCy NER model, and runs
133
+ `init-db` + `ingest --dry-run` in sequence.
134
+
135
+ Verify the setup:
136
+
137
+ ```bash
138
+ yaams --version # 0.1.1
139
+ yaams stats # zero items - that is expected before first ingest
140
+ yaams ingest --dry-run # see what each adapter would pick up
141
+ ```
142
+
143
+ Then do a real ingest:
144
+
145
+ ```bash
146
+ yaams ingest
147
+ ```
148
+
149
+ The first run downloads the embedding model (`BAAI/bge-m3`, ~2GB). YAAMS
150
+ will prompt before downloading; after the cache is populated, subsequent
151
+ runs are fully offline.
152
+
153
+ Ask a question:
154
+
155
+ ```bash
156
+ yaams query "what did we decide about the deploy in May"
157
+ yaams query --answer "open items from the kickoff meeting"
158
+ ```
159
+
160
+ ## CLI
161
+
162
+ ```
163
+ yaams <command> [options]
164
+ ```
165
+
166
+ Bare `yaams` lists commands. Global flags: `--version`, `--help`.
167
+ Per-command help: `yaams <command> --help`.
168
+
169
+ For the full feature walkthrough — every command, the entity-curation
170
+ workflow, query flags, and best practices — see the
171
+ **[User Guide](docs/user-guide.md)**.
172
+
173
+ | command | what it does |
174
+ | --- | --- |
175
+ | `init-db` | create the SQLite schema (idempotent) |
176
+ | `ingest` | run ingest for all enabled sources (or `--source <name>`) |
177
+ | `stats` | print item counts per source, plus last ingest run timing |
178
+ | `query` | full-text + vector search; `--answer` for synthesized response |
179
+ | `feedback` | log relevance signals against a prior query result |
180
+ | `signals` | inspect recent query history |
181
+ | `consolidate` | group conversational items into sessions |
182
+ | `promote` | review and accept atomic-note candidates into the Tier 2 ledger |
183
+ | `reset-db` | drop and recreate the database (asks first) |
184
+ | `version` | print version (`--json` for machine-readable) |
185
+
186
+ ### Ingest sources
187
+
188
+ | source | config key | what it ingests |
189
+ | --- | --- | --- |
190
+ | `imessage` | `ingest.imessage` | iMessage conversations from local `chat.db` |
191
+ | `signal` | `ingest.signal` | Signal Desktop messages (1:1 + groups, attachment metadata) |
192
+ | `email` | `ingest.email` | `.emlx` (Apple Mail) or `.mbox` |
193
+ | `notes` | `ingest.notes` | Obsidian vault markdown |
194
+ | `tier2_ledger` | `ingest.tier2_ledger` | curated atomic notes from cognitive-ledger |
195
+ | `github` | `ingest.github` | GitHub issues and PRs across your repos |
196
+ | `calendar` / `calendar_<profile>` | `ingest.calendar` | Outlook calendar via `owa-cal` |
197
+ | `teams` / `teams_<profile>` | `ingest.teams` | Microsoft Teams via Graph API |
198
+
199
+ Run one source: `yaams ingest --source imessage`.
200
+
201
+ ### Query
202
+
203
+ ```bash
204
+ yaams query "budget discussion"
205
+ yaams query --top-k 20 "deploy"
206
+ yaams query --no-vector "fast FTS-only path" # skips embedder load
207
+ yaams query --source imessage "holiday plans"
208
+ yaams query --since 2025-06-01 --until 2025-09-01 "summer"
209
+ yaams query --no-consolidations "raw items only"
210
+ yaams query --format json "search term"
211
+ yaams query --answer "what are the open items from the kickoff"
212
+ ```
213
+
214
+ ### Promote
215
+
216
+ Surface candidate atomic notes from recent items, review them interactively,
217
+ and write accepted ones into your ledger inbox:
218
+
219
+ ```bash
220
+ yaams promote generate # scan last 30 days
221
+ yaams promote generate --days 60
222
+ yaams promote review # interactive: a/e/r/s/q
223
+ ```
224
+
225
+ Nothing is promoted without your explicit acceptance. Accepted notes land in
226
+ `promote.inbox_path` (default `~/yaams/ledger-inbox/`).
227
+
228
+ ## Configure
229
+
230
+ `config.yaml` lives in the repo root (or `~/.config/yaams/config.yaml`, or
231
+ wherever `$YAAMS_CONFIG` points). It is gitignored: it carries your
232
+ personal entity dictionary, source paths, and addresses. Edit
233
+ `config.yaml.example` instead when contributing structural changes.
234
+
235
+ Rerun the wizard at any time:
236
+
237
+ ```bash
238
+ python scripts/configure_phase_a.py --config config.yaml
239
+ ```
240
+
241
+ Key blocks:
242
+
243
+ ```yaml
244
+ db_path: ~/yaams/data.db
245
+
246
+ ingest:
247
+ since: '2025-01-01T00:00:00Z'
248
+ imessage:
249
+ chat_db_path: ~/Library/Messages/chat.db
250
+ email:
251
+ sources:
252
+ - type: emlx
253
+ path: ~/Library/Mail/V10
254
+
255
+ embed:
256
+ model: BAAI/bge-m3
257
+ device: mps # or cpu
258
+
259
+ synth:
260
+ backend: claude # claude | codex | ollama | subprocess | dummy
261
+ model: claude-sonnet-4-6
262
+ ```
263
+
264
+ On Apple Silicon, use the Homebrew arm64 Python explicitly - PyTorch 2.4+
265
+ has no x86_64 macOS wheels:
266
+
267
+ ```bash
268
+ /opt/homebrew/bin/python3.12 -m venv .venv
269
+ ```
270
+
271
+ ## Scheduling
272
+
273
+ YAAMS is meant to run unattended. See [docs/scheduling.md](docs/scheduling.md)
274
+ for a `launchd` agent that runs a single nightly `yaams ingest` across all
275
+ enabled sources, plus the macOS Full Disk Access setup required for the
276
+ `imessage` adapter to work under `launchd`.
277
+
278
+ ## Privacy and security
279
+
280
+ YAAMS reads and stores sensitive personal data. The defaults keep
281
+ everything local, but **you are responsible for protecting the database
282
+ file at rest** - enable full-disk encryption (FileVault / LUKS / BitLocker)
283
+ on the host machine.
284
+
285
+ See [SECURITY.md](SECURITY.md) for the full threat model, data
286
+ classification, and vulnerability disclosure flow. See
287
+ [docs/privacy-security.md](docs/privacy-security.md) for the operational
288
+ detail on what is written, what is not, and how to scrub.
289
+
290
+ ## Documentation
291
+
292
+ - **[User Guide](docs/user-guide.md)** - the end-to-end manual: every
293
+ feature, the entity-curation workflow, query power-flags, best practices,
294
+ and troubleshooting.
295
+ - [Implementation status](docs/implementation-status.md) - architecture and
296
+ what's shipped.
297
+ - [Scheduling](docs/scheduling.md) - unattended nightly ingest via `launchd`.
298
+ - [Privacy and security](docs/privacy-security.md) - what's written, what
299
+ isn't, and how to scrub.
300
+
301
+ ## Contributing
302
+
303
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, the test
304
+ suite, schema-migration rules, and commit conventions.
305
+
306
+ ## License
307
+
308
+ [MIT](LICENSE). Copyright 2026 Carl Joakim Damsleth.
yaams-0.3.0/README.md ADDED
@@ -0,0 +1,286 @@
1
+ # YAAMS
2
+
3
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+ ![python](https://img.shields.io/badge/python-3.11+-blue)
5
+
6
+ **Yet Another Agent Memory System.** A local-first, high-recall memory store
7
+ for your personal digital exhaust - messages, email, calendar, GitHub
8
+ activity, notes - searchable in seconds and synthesizable into grounded,
9
+ cited answers by the LLM of your choice.
10
+
11
+ YAAMS is Tier 1 of a two-tier memory architecture: the firehose. Tier 2 is
12
+ the [cognitive-ledger](https://github.com/damsleth/cognitive-ledger): curated
13
+ atomic notes you keep forever. YAAMS ingests everything, lets you query
14
+ across the lot, and promotes the gems upstream when you're ready.
15
+
16
+ Each tier is split between a public **engine** and a private **store**:
17
+
18
+ | Tier | Engine (public) | Store (private, your data) |
19
+ | --- | --- | --- |
20
+ | Tier 1 | **YAAMS** - this repo | a single SQLite file at `db_path` |
21
+ | Tier 2 | **cognitive-ledger** - sibling repo | a markdown tree of curated atomic notes |
22
+
23
+ Engines ship code, no data. Stores live outside the repo, are gitignored
24
+ by default, and never get pushed.
25
+
26
+ ## Suite
27
+
28
+ YAAMS is one of four tools in the **[hugr](https://github.com/damsleth/hugr)**
29
+ memory suite. The suite gives you one install (`brew install
30
+ damsleth/tap/hugr`), one verb surface (`hugr query`, `hugr ingest`,
31
+ `hugr promote`, ...), and one CLI contract (output classes, exit
32
+ codes, action envelopes - see
33
+ [hugr/CONVENTIONS.md](https://github.com/damsleth/hugr/blob/main/CONVENTIONS.md)).
34
+ Power users can still call `yaams` directly and get byte-identical
35
+ JSON.
36
+
37
+ ## What
38
+
39
+ ```
40
+ query
41
+ |
42
+ v
43
+ ingest -> normalize -> embed -> retrieve -> fuse -> answer (cited)
44
+ | | | |
45
+ iMessage SQLite BGE-M3 Tier 2 boost
46
+ Signal + FTS5 + spaCy (cognitive-ledger)
47
+ Email + vec
48
+ Teams
49
+ Calendar
50
+ GitHub
51
+ Obsidian
52
+ ```
53
+
54
+ - **Local-only by default.** Embeddings, NER, and LLM synthesis run on your
55
+ machine. Nothing leaves the host unless you point an adapter at a hosted
56
+ backend.
57
+ - **Append-only.** Raw items are immutable. Re-ingest is idempotent.
58
+ - **Cited answers.** Every synthesized claim points back to the source items.
59
+ - **Pluggable LLM.** `claude`, `codex`, `ollama`, any subprocess, or `dummy`.
60
+ - **Single SQLite file.** No daemons, no servers, no cloud bill.
61
+
62
+ ## Why
63
+
64
+ Language models forget everything between sessions, and the answer is not
65
+ "shove more raw chat logs into the context window." The answer is a memory
66
+ system you can grep, query, and audit, that lives on your machine and that
67
+ you fully control.
68
+
69
+ YAAMS gives you that for the high-volume side of your life: every iMessage,
70
+ every email, every calendar event, every GitHub issue you have touched. It
71
+ normalizes them into a common schema, embeds them, and lets you ask
72
+ questions like *"what did we decide about the deploy in May?"* and get back
73
+ a grounded answer with citations - in seconds, offline.
74
+
75
+ ## Quickstart
76
+
77
+ Requires Python 3.11+ and macOS (Linux works for everything except the
78
+ iMessage adapter).
79
+
80
+ Homebrew (recommended):
81
+
82
+ ```bash
83
+ brew install damsleth/tap/yaams
84
+ ```
85
+
86
+ PyPI via pipx:
87
+
88
+ ```bash
89
+ pipx install yaams
90
+ ```
91
+
92
+ Bleeding-edge from main:
93
+
94
+ ```bash
95
+ brew install --HEAD damsleth/tap/yaams
96
+ ```
97
+
98
+ Then bootstrap a config and run the dry-run ingest:
99
+
100
+ ```bash
101
+ mkdir -p ~/.config/yaams
102
+ cp "$(brew --prefix)/share/yaams/config.yaml.example" ~/.config/yaams/config.yaml
103
+ $EDITOR ~/.config/yaams/config.yaml
104
+ yaams init-db
105
+ yaams ingest --dry-run
106
+ ```
107
+
108
+ If you cloned the repo instead of installing the package, run the
109
+ all-in-one bootstrap script (`scripts/install_phase_a.sh`) - it creates
110
+ `.venv`, runs the config wizard, downloads the spaCy NER model, and runs
111
+ `init-db` + `ingest --dry-run` in sequence.
112
+
113
+ Verify the setup:
114
+
115
+ ```bash
116
+ yaams --version # 0.1.1
117
+ yaams stats # zero items - that is expected before first ingest
118
+ yaams ingest --dry-run # see what each adapter would pick up
119
+ ```
120
+
121
+ Then do a real ingest:
122
+
123
+ ```bash
124
+ yaams ingest
125
+ ```
126
+
127
+ The first run downloads the embedding model (`BAAI/bge-m3`, ~2GB). YAAMS
128
+ will prompt before downloading; after the cache is populated, subsequent
129
+ runs are fully offline.
130
+
131
+ Ask a question:
132
+
133
+ ```bash
134
+ yaams query "what did we decide about the deploy in May"
135
+ yaams query --answer "open items from the kickoff meeting"
136
+ ```
137
+
138
+ ## CLI
139
+
140
+ ```
141
+ yaams <command> [options]
142
+ ```
143
+
144
+ Bare `yaams` lists commands. Global flags: `--version`, `--help`.
145
+ Per-command help: `yaams <command> --help`.
146
+
147
+ For the full feature walkthrough — every command, the entity-curation
148
+ workflow, query flags, and best practices — see the
149
+ **[User Guide](docs/user-guide.md)**.
150
+
151
+ | command | what it does |
152
+ | --- | --- |
153
+ | `init-db` | create the SQLite schema (idempotent) |
154
+ | `ingest` | run ingest for all enabled sources (or `--source <name>`) |
155
+ | `stats` | print item counts per source, plus last ingest run timing |
156
+ | `query` | full-text + vector search; `--answer` for synthesized response |
157
+ | `feedback` | log relevance signals against a prior query result |
158
+ | `signals` | inspect recent query history |
159
+ | `consolidate` | group conversational items into sessions |
160
+ | `promote` | review and accept atomic-note candidates into the Tier 2 ledger |
161
+ | `reset-db` | drop and recreate the database (asks first) |
162
+ | `version` | print version (`--json` for machine-readable) |
163
+
164
+ ### Ingest sources
165
+
166
+ | source | config key | what it ingests |
167
+ | --- | --- | --- |
168
+ | `imessage` | `ingest.imessage` | iMessage conversations from local `chat.db` |
169
+ | `signal` | `ingest.signal` | Signal Desktop messages (1:1 + groups, attachment metadata) |
170
+ | `email` | `ingest.email` | `.emlx` (Apple Mail) or `.mbox` |
171
+ | `notes` | `ingest.notes` | Obsidian vault markdown |
172
+ | `tier2_ledger` | `ingest.tier2_ledger` | curated atomic notes from cognitive-ledger |
173
+ | `github` | `ingest.github` | GitHub issues and PRs across your repos |
174
+ | `calendar` / `calendar_<profile>` | `ingest.calendar` | Outlook calendar via `owa-cal` |
175
+ | `teams` / `teams_<profile>` | `ingest.teams` | Microsoft Teams via Graph API |
176
+
177
+ Run one source: `yaams ingest --source imessage`.
178
+
179
+ ### Query
180
+
181
+ ```bash
182
+ yaams query "budget discussion"
183
+ yaams query --top-k 20 "deploy"
184
+ yaams query --no-vector "fast FTS-only path" # skips embedder load
185
+ yaams query --source imessage "holiday plans"
186
+ yaams query --since 2025-06-01 --until 2025-09-01 "summer"
187
+ yaams query --no-consolidations "raw items only"
188
+ yaams query --format json "search term"
189
+ yaams query --answer "what are the open items from the kickoff"
190
+ ```
191
+
192
+ ### Promote
193
+
194
+ Surface candidate atomic notes from recent items, review them interactively,
195
+ and write accepted ones into your ledger inbox:
196
+
197
+ ```bash
198
+ yaams promote generate # scan last 30 days
199
+ yaams promote generate --days 60
200
+ yaams promote review # interactive: a/e/r/s/q
201
+ ```
202
+
203
+ Nothing is promoted without your explicit acceptance. Accepted notes land in
204
+ `promote.inbox_path` (default `~/yaams/ledger-inbox/`).
205
+
206
+ ## Configure
207
+
208
+ `config.yaml` lives in the repo root (or `~/.config/yaams/config.yaml`, or
209
+ wherever `$YAAMS_CONFIG` points). It is gitignored: it carries your
210
+ personal entity dictionary, source paths, and addresses. Edit
211
+ `config.yaml.example` instead when contributing structural changes.
212
+
213
+ Rerun the wizard at any time:
214
+
215
+ ```bash
216
+ python scripts/configure_phase_a.py --config config.yaml
217
+ ```
218
+
219
+ Key blocks:
220
+
221
+ ```yaml
222
+ db_path: ~/yaams/data.db
223
+
224
+ ingest:
225
+ since: '2025-01-01T00:00:00Z'
226
+ imessage:
227
+ chat_db_path: ~/Library/Messages/chat.db
228
+ email:
229
+ sources:
230
+ - type: emlx
231
+ path: ~/Library/Mail/V10
232
+
233
+ embed:
234
+ model: BAAI/bge-m3
235
+ device: mps # or cpu
236
+
237
+ synth:
238
+ backend: claude # claude | codex | ollama | subprocess | dummy
239
+ model: claude-sonnet-4-6
240
+ ```
241
+
242
+ On Apple Silicon, use the Homebrew arm64 Python explicitly - PyTorch 2.4+
243
+ has no x86_64 macOS wheels:
244
+
245
+ ```bash
246
+ /opt/homebrew/bin/python3.12 -m venv .venv
247
+ ```
248
+
249
+ ## Scheduling
250
+
251
+ YAAMS is meant to run unattended. See [docs/scheduling.md](docs/scheduling.md)
252
+ for a `launchd` agent that runs a single nightly `yaams ingest` across all
253
+ enabled sources, plus the macOS Full Disk Access setup required for the
254
+ `imessage` adapter to work under `launchd`.
255
+
256
+ ## Privacy and security
257
+
258
+ YAAMS reads and stores sensitive personal data. The defaults keep
259
+ everything local, but **you are responsible for protecting the database
260
+ file at rest** - enable full-disk encryption (FileVault / LUKS / BitLocker)
261
+ on the host machine.
262
+
263
+ See [SECURITY.md](SECURITY.md) for the full threat model, data
264
+ classification, and vulnerability disclosure flow. See
265
+ [docs/privacy-security.md](docs/privacy-security.md) for the operational
266
+ detail on what is written, what is not, and how to scrub.
267
+
268
+ ## Documentation
269
+
270
+ - **[User Guide](docs/user-guide.md)** - the end-to-end manual: every
271
+ feature, the entity-curation workflow, query power-flags, best practices,
272
+ and troubleshooting.
273
+ - [Implementation status](docs/implementation-status.md) - architecture and
274
+ what's shipped.
275
+ - [Scheduling](docs/scheduling.md) - unattended nightly ingest via `launchd`.
276
+ - [Privacy and security](docs/privacy-security.md) - what's written, what
277
+ isn't, and how to scrub.
278
+
279
+ ## Contributing
280
+
281
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, the test
282
+ suite, schema-migration rules, and commit conventions.
283
+
284
+ ## License
285
+
286
+ [MIT](LICENSE). Copyright 2026 Carl Joakim Damsleth.
@@ -0,0 +1,76 @@
1
+ [project]
2
+ name = "yaams"
3
+ version = "0.3.0"
4
+ description = "Yet Another Agent Memory System"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = [
8
+ "click>=8.1",
9
+ "cryptography>=42.0",
10
+ "pyyaml>=6.0",
11
+ "numpy<2",
12
+ "pyobjc-framework-Cocoa>=12.1; sys_platform == 'darwin'",
13
+ "sentence-transformers>=3.0",
14
+ "spacy>=3.7",
15
+ "sqlite-vec>=0.1.6",
16
+ "tqdm>=4.66",
17
+ ]
18
+
19
+ [project.optional-dependencies]
20
+ dev = [
21
+ "pytest>=8.0",
22
+ "ruff>=0.6",
23
+ "pyright>=1.1.380",
24
+ ]
25
+
26
+ [project.scripts]
27
+ yaams = "yaams.cli:cli"
28
+
29
+ [tool.setuptools.package-data]
30
+ yaams = ["_default_config.yaml"]
31
+
32
+ [tool.pytest.ini_options]
33
+ testpaths = ["tests"]
34
+
35
+ [tool.ruff]
36
+ line-length = 100
37
+ target-version = "py311"
38
+ indent-width = 2
39
+ extend-exclude = [
40
+ ".venv",
41
+ "yaams.egg-info",
42
+ ".plans",
43
+ ".tmp",
44
+ ]
45
+
46
+ [tool.ruff.lint]
47
+ # Initial rule set. Broaden to B/UP/SIM after a one-time auto-fix sweep.
48
+ select = [
49
+ "E", # pycodestyle errors
50
+ "F", # pyflakes (undefined names, unused imports)
51
+ "I", # isort (import ordering)
52
+ "W", # pycodestyle warnings
53
+ ]
54
+ ignore = [
55
+ "E501", # long lines, project uses soft limit
56
+ "E741", # ambiguous variable names (existing usage)
57
+ ]
58
+
59
+ [tool.ruff.format]
60
+ quote-style = "double"
61
+ indent-style = "space"
62
+
63
+ [tool.pyright]
64
+ include = ["yaams", "tests"]
65
+ exclude = [".venv", "yaams.egg-info", ".plans", ".tmp"]
66
+ pythonVersion = "3.11"
67
+ typeCheckingMode = "basic"
68
+ reportMissingImports = "warning"
69
+ reportFunctionMemberAccess = "none"
70
+ reportOperatorIssue = "warning"
71
+ reportArgumentType = "warning"
72
+ reportGeneralTypeIssues = "warning"
73
+
74
+ [build-system]
75
+ requires = ["setuptools>=69", "wheel"]
76
+ build-backend = "setuptools.build_meta"
yaams-0.3.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+