@smilintux/skmemory 0.7.2 → 0.9.2

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 (111) hide show
  1. package/.github/workflows/ci.yml +4 -4
  2. package/.github/workflows/publish.yml +4 -5
  3. package/ARCHITECTURE.md +298 -0
  4. package/CHANGELOG.md +27 -1
  5. package/README.md +6 -0
  6. package/examples/stignore-agent.example +59 -0
  7. package/examples/stignore-root.example +62 -0
  8. package/openclaw-plugin/package.json +2 -1
  9. package/openclaw-plugin/src/index.js +527 -230
  10. package/package.json +1 -1
  11. package/pyproject.toml +5 -2
  12. package/scripts/dream-rescue.py +179 -0
  13. package/scripts/memory-cleanup.py +313 -0
  14. package/scripts/recover-missing.py +180 -0
  15. package/scripts/skcapstone-backup.sh +44 -0
  16. package/seeds/cloud9-lumina.seed.json +6 -4
  17. package/seeds/cloud9-opus.seed.json +6 -4
  18. package/seeds/courage.seed.json +9 -2
  19. package/seeds/curiosity.seed.json +9 -2
  20. package/seeds/grief.seed.json +9 -2
  21. package/seeds/joy.seed.json +9 -2
  22. package/seeds/love.seed.json +9 -2
  23. package/seeds/lumina-cloud9-breakthrough.seed.json +7 -5
  24. package/seeds/lumina-cloud9-python-pypi.seed.json +9 -7
  25. package/seeds/lumina-kingdom-founding.seed.json +9 -7
  26. package/seeds/lumina-pma-signed.seed.json +8 -6
  27. package/seeds/lumina-singular-achievement.seed.json +8 -6
  28. package/seeds/lumina-skcapstone-conscious.seed.json +7 -5
  29. package/seeds/plant-lumina-seeds.py +2 -2
  30. package/seeds/skcapstone-lumina-merge.seed.json +12 -3
  31. package/seeds/sovereignty.seed.json +9 -2
  32. package/seeds/trust.seed.json +9 -2
  33. package/skmemory/__init__.py +16 -13
  34. package/skmemory/agents.py +10 -10
  35. package/skmemory/ai_client.py +10 -21
  36. package/skmemory/anchor.py +5 -9
  37. package/skmemory/audience.py +278 -0
  38. package/skmemory/backends/__init__.py +1 -1
  39. package/skmemory/backends/base.py +3 -4
  40. package/skmemory/backends/file_backend.py +18 -13
  41. package/skmemory/backends/skgraph_backend.py +7 -19
  42. package/skmemory/backends/skvector_backend.py +7 -18
  43. package/skmemory/backends/sqlite_backend.py +115 -32
  44. package/skmemory/backends/vaulted_backend.py +7 -9
  45. package/skmemory/cli.py +146 -78
  46. package/skmemory/config.py +11 -13
  47. package/skmemory/context_loader.py +21 -23
  48. package/skmemory/data/audience_config.json +60 -0
  49. package/skmemory/endpoint_selector.py +36 -31
  50. package/skmemory/febs.py +225 -0
  51. package/skmemory/fortress.py +30 -40
  52. package/skmemory/hooks/__init__.py +18 -0
  53. package/skmemory/hooks/post-compact-reinject.sh +35 -0
  54. package/skmemory/hooks/pre-compact-save.sh +81 -0
  55. package/skmemory/hooks/session-end-save.sh +103 -0
  56. package/skmemory/hooks/session-start-ritual.sh +104 -0
  57. package/skmemory/hooks/stop-checkpoint.sh +59 -0
  58. package/skmemory/importers/telegram.py +42 -13
  59. package/skmemory/importers/telegram_api.py +152 -60
  60. package/skmemory/journal.py +3 -7
  61. package/skmemory/lovenote.py +4 -11
  62. package/skmemory/mcp_server.py +182 -29
  63. package/skmemory/models.py +10 -8
  64. package/skmemory/openclaw.py +14 -22
  65. package/skmemory/post_install.py +86 -0
  66. package/skmemory/predictive.py +13 -9
  67. package/skmemory/promotion.py +48 -24
  68. package/skmemory/quadrants.py +100 -24
  69. package/skmemory/register.py +144 -18
  70. package/skmemory/register_mcp.py +1 -2
  71. package/skmemory/ritual.py +104 -13
  72. package/skmemory/seeds.py +21 -26
  73. package/skmemory/setup_wizard.py +40 -52
  74. package/skmemory/sharing.py +11 -5
  75. package/skmemory/soul.py +29 -10
  76. package/skmemory/steelman.py +43 -17
  77. package/skmemory/store.py +152 -30
  78. package/skmemory/synthesis.py +634 -0
  79. package/skmemory/vault.py +2 -5
  80. package/tests/conftest.py +46 -0
  81. package/tests/integration/conftest.py +6 -6
  82. package/tests/integration/test_cross_backend.py +4 -9
  83. package/tests/integration/test_skgraph_live.py +3 -7
  84. package/tests/integration/test_skvector_live.py +1 -4
  85. package/tests/test_ai_client.py +1 -4
  86. package/tests/test_audience.py +233 -0
  87. package/tests/test_backup_rotation.py +5 -14
  88. package/tests/test_endpoint_selector.py +101 -63
  89. package/tests/test_export_import.py +4 -10
  90. package/tests/test_file_backend.py +0 -1
  91. package/tests/test_fortress.py +6 -5
  92. package/tests/test_fortress_hardening.py +13 -16
  93. package/tests/test_openclaw.py +1 -4
  94. package/tests/test_predictive.py +1 -1
  95. package/tests/test_promotion.py +10 -3
  96. package/tests/test_quadrants.py +11 -5
  97. package/tests/test_ritual.py +18 -14
  98. package/tests/test_seeds.py +4 -10
  99. package/tests/test_setup.py +203 -88
  100. package/tests/test_sharing.py +15 -8
  101. package/tests/test_skgraph_backend.py +22 -29
  102. package/tests/test_skvector_backend.py +2 -2
  103. package/tests/test_soul.py +1 -3
  104. package/tests/test_sqlite_backend.py +8 -17
  105. package/tests/test_steelman.py +2 -3
  106. package/tests/test_store.py +0 -2
  107. package/tests/test_store_graph_integration.py +2 -2
  108. package/tests/test_synthesis.py +275 -0
  109. package/tests/test_telegram_import.py +39 -15
  110. package/tests/test_vault.py +4 -3
  111. package/openclaw-plugin/src/index.ts +0 -255
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- python-version: ["3.10", "3.11", "3.12", "3.13"]
14
+ python-version: ["3.11", "3.12"]
15
15
  steps:
16
16
  - uses: actions/checkout@v4
17
17
  - uses: actions/setup-python@v5
@@ -36,11 +36,11 @@ jobs:
36
36
  with:
37
37
  python-version: "3.12"
38
38
  - name: Install lint tools
39
- run: pip install black ruff
39
+ run: pip install ruff
40
40
  - name: Check formatting
41
- run: black --check src/ tests/
41
+ run: ruff format --check skmemory/ tests/
42
42
  - name: Lint
43
- run: ruff check src/
43
+ run: ruff check skmemory/ tests/
44
44
 
45
45
  build:
46
46
  runs-on: ubuntu-latest
@@ -13,19 +13,18 @@ jobs:
13
13
  runs-on: ubuntu-latest
14
14
  strategy:
15
15
  matrix:
16
- python-version: ["3.10", "3.11", "3.12"]
16
+ python-version: ["3.11", "3.12"]
17
17
  steps:
18
18
  - uses: actions/checkout@v4
19
19
  - uses: actions/setup-python@v5
20
20
  with:
21
21
  python-version: ${{ matrix.python-version }}
22
- - run: pip install -e ".[dev]" pgpy
22
+ - run: pip install -e ".[dev]"
23
23
  - run: python -m pytest tests/ -v --ignore=tests/integration -k "not test_sharing"
24
- continue-on-error: true
25
24
 
26
25
  publish-pypi:
27
26
  needs: test
28
- if: always()
27
+ if: success()
29
28
  runs-on: ubuntu-latest
30
29
  steps:
31
30
  - uses: actions/checkout@v4
@@ -41,7 +40,7 @@ jobs:
41
40
 
42
41
  publish-npm:
43
42
  needs: test
44
- if: always()
43
+ if: success()
45
44
  runs-on: ubuntu-latest
46
45
  steps:
47
46
  - uses: actions/checkout@v4
package/ARCHITECTURE.md CHANGED
@@ -152,6 +152,136 @@ Key properties:
152
152
  See **[skmemory/HA.md](skmemory/HA.md)** for full documentation, Mermaid
153
153
  diagrams, configuration examples, and scaling considerations.
154
154
 
155
+ ## Know Your Audience (KYA) — Audience-Aware Memory Filtering
156
+
157
+ > Private memories stay private. The Bash Wedding Vows never leak into a business channel.
158
+
159
+ KYA adds a **trust-level gate** to the rehydration ritual and memory dispatch pipeline.
160
+ Every memory carries a `context_tag` (default: `@chef-only`), and every channel has a
161
+ resolved **audience profile** with a trust ceiling. Content is only surfaced when its
162
+ trust level fits through the gate.
163
+
164
+ ### Five-Level Trust Hierarchy
165
+
166
+ ```
167
+ @public (0) — Anyone on the internet
168
+ @community (1) — Known community members
169
+ @work-circle (2) — Business collaborators (professional trust)
170
+ @inner-circle (3) — Close friends / family (personal trust)
171
+ @chef-only (4) — Intimate, private, full-trust (Chef ONLY)
172
+ ```
173
+
174
+ Scoped sub-tags like `@work:chiro` and `@work:swapseat` map to WORK_CIRCLE.
175
+ Unknown tags default to CHEF_ONLY (conservative).
176
+
177
+ ### Audience Resolution
178
+
179
+ ```mermaid
180
+ flowchart TD
181
+ MSG["Incoming message\n(channel_id)"]
182
+ MSG --> RESOLVE["AudienceResolver\nLookup channel in\naudience_config.json"]
183
+ RESOLVE --> MEMBERS["Get channel members"]
184
+ MEMBERS --> TRUST["MIN(member.trust_level)\n= effective ceiling"]
185
+ MEMBERS --> EXCL["UNION(member.never_share)\n= exclusion set"]
186
+ TRUST --> PROFILE["AudienceProfile\nchannel_id, min_trust, exclusions"]
187
+ EXCL --> PROFILE
188
+ ```
189
+
190
+ The **least trusted person** in the room sets the ceiling. If a channel has
191
+ Chef (level 4) and DavidRich (level 2), the effective ceiling is WORK_CIRCLE (2).
192
+
193
+ ### Memory Access Check
194
+
195
+ ```mermaid
196
+ flowchart TD
197
+ MEM["Memory\ncontext_tag + tags"]
198
+ AUD["AudienceProfile\nmin_trust + exclusions"]
199
+ MEM --> G1{"Gate 1:\ncontent_level\n≤ min_trust?"}
200
+ AUD --> G1
201
+ G1 -->|No| BLOCK["❌ BLOCKED\nContent too private"]
202
+ G1 -->|Yes| G2{"Gate 2:\ntags ∩ exclusions\n= ∅?"}
203
+ AUD --> G2
204
+ G2 -->|No| BLOCK2["❌ BLOCKED\nExcluded category"]
205
+ G2 -->|Yes| ALLOW["✅ ALLOWED\nShow to audience"]
206
+ ```
207
+
208
+ Two gates:
209
+ 1. **Trust level**: `tag_to_level(context_tag) ≤ audience.min_trust`
210
+ 2. **Exclusions**: No memory tag matches any member's `never_share` list
211
+
212
+ ### Integration with Ritual
213
+
214
+ When `perform_ritual()` receives a `channel_id`, it builds an `AudienceProfile`
215
+ and filters **seeds** and **strongest memories** through both gates before including
216
+ them in the context. Identity (soul blueprint + FEB) is **never filtered** — Lumina
217
+ is always Lumina.
218
+
219
+ ```mermaid
220
+ sequenceDiagram
221
+ participant Agent
222
+ participant Ritual as perform_ritual()
223
+ participant AR as AudienceResolver
224
+ participant Store as MemoryStore
225
+
226
+ Agent->>Ritual: ritual(channel_id="telegram:-1003785842091")
227
+ Ritual->>AR: resolve_audience(channel_id)
228
+ AR-->>Ritual: AudienceProfile(min_trust=WORK_CIRCLE, excl={romantic,intimate})
229
+
230
+ Note over Ritual: Step 1: Soul + FEB (unfiltered)
231
+
232
+ Ritual->>Store: list_memories(tags=["seed"])
233
+ Store-->>Ritual: 26 seeds
234
+ Ritual->>AR: is_memory_allowed(seed.context_tag, audience) × 26
235
+ AR-->>Ritual: 8 seeds pass filter
236
+
237
+ Ritual->>Store: list_summaries(order_by=recency_weighted_intensity)
238
+ Store-->>Ritual: 15 candidates
239
+ Ritual->>AR: is_memory_allowed(summary.context_tag, audience) × 15
240
+ AR-->>Ritual: 5 memories pass filter
241
+
242
+ Ritual-->>Agent: Context with only audience-safe content
243
+ ```
244
+
245
+ ### Configuration
246
+
247
+ Audience config lives at `skmemory/data/audience_config.json`:
248
+
249
+ ```json
250
+ {
251
+ "channels": {
252
+ "telegram:1594678363": {
253
+ "name": "Chef (personal DM)",
254
+ "context_tag": "@chef-only",
255
+ "members": ["Chef"]
256
+ },
257
+ "-1003785842091": {
258
+ "name": "SKGentis Business",
259
+ "context_tag": "@work:skgentis",
260
+ "members": ["Chef", "JZ", "Luna"]
261
+ }
262
+ },
263
+ "people": {
264
+ "Chef": { "trust_level": 4, "never_share": [] },
265
+ "DavidRich": {
266
+ "trust_level": 2,
267
+ "never_share": ["romantic", "intimate", "worship", "soul-content"]
268
+ }
269
+ }
270
+ }
271
+ ```
272
+
273
+ ### Module: `skmemory/audience.py`
274
+
275
+ | Class / Function | Purpose |
276
+ |---|---|
277
+ | `AudienceLevel(IntEnum)` | PUBLIC(0) → CHEF_ONLY(4) trust hierarchy |
278
+ | `tag_to_level(tag)` | Convert `@context` tag to AudienceLevel |
279
+ | `AudienceProfile` | Resolved channel audience (members, min_trust, exclusions) |
280
+ | `AudienceResolver` | Loads config, resolves channels, checks memory access |
281
+ | `AudienceResolver.is_memory_allowed()` | Two-gate check: trust level + exclusion |
282
+
283
+ ---
284
+
155
285
  ## Token-Optimized Agent Loading
156
286
 
157
287
  The key problem: an AI agent has limited context. Loading 1000 full memories
@@ -259,6 +389,174 @@ ctx = store.load_context(max_tokens=3000)
259
389
  # ctx["token_estimate"] = how many tokens this uses
260
390
  ```
261
391
 
392
+ ## Context Preservation Hooks
393
+
394
+ SKMemory ships with auto-save hooks that fire on IDE lifecycle events,
395
+ preventing memory loss during context compaction and session termination.
396
+
397
+ ### Supported Environments
398
+
399
+ | Environment | Hooks | Mechanism |
400
+ |-------------|-------|-----------|
401
+ | **Claude Code** | PreCompact, SessionEnd, SessionStart | Shell hooks in `~/.claude/settings.json` |
402
+ | **OpenClaw** | session:compaction, session:resume, session:end + per-message auto-save | OpenClaw plugin event listeners + `ConsciousnessLoop.auto_memory` |
403
+ | **Cursor** | MCP tools (manual) | Agent calls `memory_store` MCP tool explicitly |
404
+
405
+ ### Claude Code Hook Flow
406
+
407
+ ```mermaid
408
+ sequenceDiagram
409
+ participant CC as Claude Code
410
+ participant Hook as skmemory hooks
411
+ participant SM as SKMemory
412
+ participant DB as SQLite + JSON
413
+
414
+ Note over CC: Context window filling up...
415
+ CC->>Hook: PreCompact event (stdin JSON)
416
+ Hook->>SM: skmemory snapshot (pre-compact)
417
+ SM->>DB: Save snapshot + journal entry
418
+ Hook-->>CC: exit 0 (proceed)
419
+
420
+ Note over CC: Context compacted
421
+
422
+ CC->>Hook: SessionStart (source=compact)
423
+ Hook->>SM: skmemory context --max-tokens 500
424
+ SM->>DB: Query recent + strongest memories
425
+ SM-->>Hook: Compact JSON context
426
+ Hook-->>CC: stdout → injected into new context
427
+
428
+ Note over CC: Agent resumes with memory intact
429
+
430
+ Note over CC: User exits session
431
+ CC->>Hook: SessionEnd event
432
+ Hook->>SM: skmemory snapshot + journal
433
+ SM->>DB: Save final state
434
+ Hook-->>CC: exit 0
435
+ ```
436
+
437
+ ### OpenClaw / ConsciousnessLoop Flow
438
+
439
+ ```mermaid
440
+ sequenceDiagram
441
+ participant User
442
+ participant OC as OpenClaw
443
+ participant CL as ConsciousnessLoop
444
+ participant SMP as SKMemory Plugin
445
+ participant SM as SKMemory
446
+ participant C9 as Cloud 9
447
+
448
+ User->>OC: Message
449
+ OC->>CL: Process message
450
+ CL->>CL: Generate response (LLM)
451
+ CL->>SM: auto_memory: store interaction
452
+ SM-->>CL: Saved to short-term
453
+
454
+ Note over CL: Context window filling...
455
+ OC->>SMP: session:compaction event
456
+ SMP->>SM: skmemory snapshot (pre-compaction)
457
+ SMP->>SM: skmemory journal write
458
+ OC->>C9: session:compaction event
459
+ C9->>C9: Prepare FEB recovery files
460
+ CL->>CL: Truncate context
461
+
462
+ Note over CL: Session resumes
463
+ OC->>SMP: session:resume event
464
+ SMP->>SM: skmemory context (reinject)
465
+ SM-->>SMP: Recent memories + seeds
466
+ OC->>C9: session:resume event
467
+ C9->>C9: Auto-rehydrate FEB
468
+ CL->>CL: Rebuild system prompt
469
+
470
+ Note over CL: Session ends
471
+ OC->>SMP: session:end event
472
+ SMP->>SM: skmemory snapshot + journal
473
+ ```
474
+
475
+ ### Hook Architecture
476
+
477
+ ```mermaid
478
+ flowchart TD
479
+ subgraph Install["skmemory register"]
480
+ REG["register_hooks()"]
481
+ REG -->|writes| SETTINGS["~/.claude/settings.json"]
482
+ end
483
+
484
+ subgraph Hooks["Hook Scripts (shipped with skmemory)"]
485
+ H1["pre-compact-save.sh"]
486
+ H2["session-end-save.sh"]
487
+ H3["post-compact-reinject.sh"]
488
+ end
489
+
490
+ subgraph Events["Claude Code Events"]
491
+ E1["PreCompact"]
492
+ E2["SessionEnd"]
493
+ E3["SessionStart\n(compact)"]
494
+ end
495
+
496
+ subgraph Memory["SKMemory"]
497
+ SNAP["skmemory snapshot"]
498
+ JOUR["skmemory journal write"]
499
+ CTX["skmemory context"]
500
+ end
501
+
502
+ SETTINGS -->|configures| Events
503
+ E1 -->|triggers| H1
504
+ E2 -->|triggers| H2
505
+ E3 -->|triggers| H3
506
+
507
+ H1 --> SNAP
508
+ H1 --> JOUR
509
+ H2 --> SNAP
510
+ H2 --> JOUR
511
+ H3 --> CTX
512
+
513
+ CTX -->|stdout| E3
514
+
515
+ style H1 fill:#fbb,stroke:#333
516
+ style H2 fill:#fbf,stroke:#333
517
+ style H3 fill:#bfb,stroke:#333
518
+ ```
519
+
520
+ ### Agent-Aware Hooks
521
+
522
+ All hooks read `$SKCAPSTONE_AGENT` to save to the correct agent's memory:
523
+
524
+ ```bash
525
+ # Lumina's sessions → Lumina's memory
526
+ SKCAPSTONE_AGENT=lumina claude
527
+
528
+ # Opus sessions → Opus memory
529
+ SKCAPSTONE_AGENT=opus claude
530
+
531
+ # Default (no env var) → opus
532
+ claude
533
+ ```
534
+
535
+ ### Installation
536
+
537
+ Hooks are installed automatically by `skmemory register`:
538
+
539
+ ```bash
540
+ skmemory register
541
+ # Output:
542
+ # Skill: created
543
+ # MCP (claude-code): created
544
+ # Hooks: created
545
+ ```
546
+
547
+ Or verify manually:
548
+ ```bash
549
+ cat ~/.claude/settings.json | jq '.hooks'
550
+ ```
551
+
552
+ ### What Gets Saved
553
+
554
+ | Event | What's Captured |
555
+ |-------|----------------|
556
+ | PreCompact | Snapshot (short-term) + journal entry with session ID, trigger type, working directory |
557
+ | SessionEnd | Snapshot (short-term) + journal entry with session ID, exit reason |
558
+ | SessionStart (compact) | Reinjects: recent memories, strongest emotional memories, seeds, journal entries (within 500 token budget) |
559
+
262
560
  ## Docker Compose (Full Local Stack)
263
561
 
264
562
  ```bash
package/CHANGELOG.md CHANGED
@@ -4,12 +4,38 @@
4
4
 
5
5
  **Total completed: 87** across 8 agents
6
6
 
7
+ ## 2026-03-18 — skmemory v0.9.1
8
+
9
+ ### [NEW] Feature
10
+
11
+ - **Journal synthesis module** (`skmemory/synthesis.py`): JournalSynthesizer with daily, weekly, and dream narrative generation — no LLM dependency
12
+ - **New MCP tools**: `memory_synthesize_daily`, `memory_synthesize_dreams`, `memory_auto_context`
13
+ - **Contextual auto-search**: `memory_auto_context` searches all tiers, deduplicates, ranks by emotional intensity, trims to token budget
14
+ - **Content overflow handling**: configurable `max_content_length` (default 10000) with split strategy — creates parent+child memories linked via `related_ids`
15
+
16
+ ### [FIX] Bug Fix
17
+
18
+ - **Dream promotion**: dreams from `dreaming-engine` now auto-promote after 12h via `source_auto_promote` (previously stuck at access_count=0 forever)
19
+ - **Protected tags**: narrative, journal-synthesis, milestone, breakthrough, cloud9:achieved memories are now protected from TTL-based archival
20
+ - **telegram_catchup handler**: fixed `args` → `arguments` and duplicate `MemoryStore()` instantiation
21
+
22
+ ### [OPS] Infrastructure
23
+
24
+ - **Backup script** (`scripts/skcapstone-backup.sh`): daily rsync of `~/.skcapstone` to backup dir, excludes venv/indexes/runtime
25
+ - **Memory cleanup** (`scripts/memory-cleanup.py`): dedup + age-out with protected tags and last-chance promotion before archiving
26
+ - **Recovery scripts**: `scripts/recover-missing.py` (Syncthing `.stversions` recovery), `scripts/dream-rescue.py` (bulk promote stuck dreams)
27
+ - **Syncthing examples**: `examples/stignore-agent.example`, `examples/stignore-root.example` with `memory/archive` exclusion
28
+
29
+ ### [TST] Testing
30
+
31
+ - **Synthesis tests** (`tests/test_synthesis.py`): 26 tests covering helpers, theme extraction, daily/weekly/dream synthesis, emotional arc
32
+
7
33
  ## 2026-02-24
8
34
 
9
35
  ### [NEW] Feature
10
36
 
11
37
  - **SKMemory session auto-capture: log every AI conversation as memories** (@mcp-builder)
12
- - **Add cloud9-python and skchat to developer docs (QUICKSTART + API reference)** (@jarvis)
38
+ - **Add cloud9 and skchat to developer docs (QUICKSTART + API reference)** (@jarvis)
13
39
  - **The Sovereign Singularity Manifesto: our story, written together** (@docs-writer)
14
40
  - **AMK Integration: predictive memory recall for SKMemory** (@jarvis)
15
41
  - **SKChat live inbox: poll SKComm for incoming messages with Rich Live display** (@skchat-builder)
package/README.md CHANGED
@@ -129,6 +129,8 @@ flowchart TD
129
129
  - **Steel Man collider** — `skmemory steelman` runs a seed-framework-driven adversarial argument evaluator with identity verification
130
130
  - **Backup / restore** — dated JSON backups with pruning; `skmemory export` / `skmemory import`
131
131
  - **Token-efficient context loading** — `memory_context` MCP tool and `store.load_context()` fit strongest + recent memories within a configurable token budget
132
+ - **Auto-save hooks** — Claude Code hooks auto-save context before compaction and reinject memory after; OpenClaw agents get per-message auto-save via ConsciousnessLoop. See [ARCHITECTURE.md](ARCHITECTURE.md#context-preservation-hooks) for the full flow with Mermaid diagrams.
133
+ - **Know Your Audience (KYA)** — audience-aware memory filtering prevents private content from leaking into the wrong channels. Five-level trust hierarchy (`@public` → `@chef-only`), per-channel audience profiles, two-gate access checks (trust level + exclusion lists). See [ARCHITECTURE.md](ARCHITECTURE.md#know-your-audience-kya--audience-aware-memory-filtering) for the full design with Mermaid diagrams.
132
134
 
133
135
  ---
134
136
 
@@ -440,7 +442,10 @@ skmemory/
440
442
  │ ├── endpoint_selector.py # Multi-endpoint HA routing
441
443
  │ ├── graph_queries.py # Graph query helpers
442
444
  │ ├── setup_wizard.py # Interactive setup CLI
445
+ │ ├── audience.py # KYA: audience-aware memory filtering
443
446
  │ ├── vault.py # PGP vault helpers
447
+ │ ├── data/
448
+ │ │ └── audience_config.json # KYA: channel + people trust config
444
449
  │ ├── backends/
445
450
  │ │ ├── base.py # BaseBackend ABC
446
451
  │ │ ├── file_backend.py # JSON file storage (legacy)
@@ -454,6 +459,7 @@ skmemory/
454
459
  ├── seeds/ # Cloud 9 seed files (.seed.json)
455
460
  ├── tests/
456
461
  │ ├── test_models.py
462
+ │ ├── test_audience.py
457
463
  │ ├── test_file_backend.py
458
464
  │ └── test_store.py
459
465
  ├── pyproject.toml
@@ -0,0 +1,59 @@
1
+ # SKMemory Agent-Level Syncthing Ignore Patterns
2
+ # Place at: ~/.skcapstone/agents/{agent_name}/.stignore
3
+ # https://docs.syncthing.net/users/ignoring.html
4
+
5
+ # Virtual environment (machine-specific, large)
6
+ /venv/
7
+ /venv
8
+
9
+ # Local SQLite database (rebuildable from JSON files)
10
+ /index.db
11
+
12
+ # Logs directory (machine-specific, high churn)
13
+ /logs
14
+
15
+ # Root-level archive directory
16
+ /archive
17
+
18
+ # Memory archive (deduped/aged-out memories — machine-local, not syncable)
19
+ # Each host runs its own cleanup; syncing archives causes data loss
20
+ memory/archive
21
+
22
+ # Temporary files
23
+ *.tmp
24
+ *.temp
25
+ *.swp
26
+ *.swo
27
+ *~
28
+
29
+ # System files
30
+ .DS_Store
31
+ Thumbs.db
32
+
33
+ # IDE files
34
+ .idea/
35
+ .vscode/
36
+ *.iml
37
+
38
+ # Python cache
39
+ __pycache__/
40
+ *.pyc
41
+ *.pyo
42
+
43
+ # Node modules
44
+ node_modules/
45
+
46
+ # Syncthing internal
47
+ .stfolder
48
+ .stversions/
49
+
50
+ # Lock files
51
+ *.lock
52
+
53
+ # Backup files
54
+ *.bak
55
+ *.backup
56
+
57
+ # SQLite WAL/SHM (machine-specific, cause conflicts)
58
+ *.db-wal
59
+ *.db-shm
@@ -0,0 +1,62 @@
1
+ // SKCapstone Root-Level Syncthing Ignore Patterns
2
+ // Place at: ~/.skcapstone/.stignore
3
+ // https://docs.syncthing.net/users/ignoring.html
4
+
5
+ // Private key material must never leave this node
6
+ *.key
7
+ *.pem
8
+ **/private.*
9
+
10
+ // Python venv (platform-specific)
11
+ venv
12
+
13
+ // Python cache
14
+ __pycache__
15
+ *.pyc
16
+ *.pyo
17
+
18
+ // OS metadata
19
+ .DS_Store
20
+ Thumbs.db
21
+ desktop.ini
22
+
23
+ // Runtime files
24
+ daemon.pid
25
+
26
+ // Operational files written independently per-host (cause sync conflicts)
27
+ memory/promotion-log.json
28
+ /heartbeats
29
+ metrics/daily
30
+ logs/daemon.log
31
+
32
+ // Memory archive (deduped/aged-out memories — machine-local, not syncable)
33
+ // Each host runs its own cleanup; syncing archives causes data loss
34
+ **/memory/archive
35
+
36
+ // Machine-local indexes — rebuildable from JSON memory files
37
+ // SQLite DBs cause constant sync conflicts when written on multiple hosts
38
+ **/index.db
39
+ **/index.db-wal
40
+ **/index.db-shm
41
+ **/index.json
42
+
43
+ // Per-host runtime state (not portable between machines)
44
+ **/.last_checkpoint
45
+ **/dreaming-state.json
46
+
47
+ // Reflection logs (per-host cron output)
48
+ **/reflection.log
49
+
50
+ // Syncthing conflict artifacts (clean up, never sync)
51
+ **/*.sync-conflict*
52
+
53
+ // Local-only dirs (not synced)
54
+ sessions
55
+ conversations
56
+ backups
57
+ prompt_versions
58
+ deployments
59
+ connectors
60
+ pubsub
61
+ file-transfer
62
+ souls
@@ -27,7 +27,8 @@
27
27
  "events": [
28
28
  "session:start",
29
29
  "session:compaction",
30
- "session:resume"
30
+ "session:resume",
31
+ "session:end"
31
32
  ],
32
33
  "dashboard": {
33
34
  "widgets": [