# Matryca Plumber v1.8 — Edge Computing & Performance Update

**Status:** Core edge profile shipped in **1.8.0** (see [`CHANGELOG.md`](../CHANGELOG.md) `[1.8.0]`). **Round 4 audit** hardening is in `[Unreleased]` — same strategic constraint (no new cognitive features).  
**Strategic constraint:** v1.8 adds **zero** new semantic or graph-manipulation features — only performance, memory governance, and host-survival mechanics.

**USP:** Flawless, silent, indefinite operation on a **CPU-only 16 GB laptop**, indexing **≤10,000** Markdown pages without freezing the host OS.

**Engineering spec:** [`openspec/llm-performance.md`](openspec/llm-performance.md)  
**Architecture context:** [`ARCHITECTURE.md`](ARCHITECTURE.md#edge-computing--performance-v18)  
**Maintainer narrative:** [`PROJECT_DIARY.md`](PROJECT_DIARY.md) (2026-05-27 entry)

---

## Why v1.8 exists

Phase 14d shipped the **Context Acceleration Shield** (summaries + content-before-task ordering). Production graphs at thousands of pages exposed three remaining bottlenecks:

1. **KV-cache misses** — Bootstrap harvest still sent `Task` before `Content`; alias maps lived in the **system** prompt; cognitive modules rebuilt unrelated prefixes per page.
2. **RAM growth** — Full BM25 token lists, unbounded semantic cache RAM, and full-graph backlink rescans on every bootstrap.
3. **Host stalls** — Tight synchronous loops over 10k files with no cooperative yield and aggressive daemon checkpoint writes.

v1.8 closes that gap without changing Logseq semantics or adding new lint modules.

---

## What shipped (summary)

### Pillar 1 — Zero-Prefill (KV-cache)

| Deliverable | Module |
|-------------|--------|
| Per-page stable LLM prefix | `src/agent/page_prompt_session.py` |
| Stable system prompt (alias out of system) | `src/agent/semantic_lint_prompts.py` |
| Cache-aligned bootstrap harvest | `InstructorLLMClient.harvest_page_summary` |
| Cache-aligned MapReduce reduce | `src/graph/hierarchical_summarization.py` |
| `stateless=True` on per-page inference | `semantic_index_page`, MARPA, seeds, overlap, properties |
| Minimal cluster history (optional) | `MATRYCA_LLM_CLUSTER_HISTORY` |

### Pillar 2 — Memory (16 GB profile)

| Deliverable | Module |
|-------------|--------|
| RSS telemetry + soft budget | `src/agent/memory_budget.py` |
| BM25 postings-lite + release | `src/graph/generational_cache.py` |
| Semantic cache in-process LRU | `src/agent/plumber_modules/semantic_cache_router.py` |
| Catalog unload after Phase 1 | `unload_master_catalog()` in `master_catalog.py` |
| Post-bootstrap teardown | `release_phase1_memory()` in daemon pipeline |
| Safe semantic cache purge | Reserved JSON files no longer deleted by TTL sweep |

### Pillar 3 — I/O & CPU (host survival)

| Deliverable | Module |
|-------------|--------|
| Cooperative yield in harvest | `src/agent/cooperative_yield.py`, `bootstrap_harvest.py` |
| Persistent backlink counts | `src/graph/backlink_index.py` |
| Process priority | `src/agent/process_priority.py` |
| Configurable bootstrap checkpoints | `MATRYCA_BOOTSTRAP_CHECKPOINT_EVERY` |
| Cluster precompute after Phase 1 | `load_or_compute_semantic_clusters` at bootstrap end |

---

## Environment variables

Full list with **Default (code)** vs **Template** commentary: [`.env.example`](../.env.example). Context compression trigger in code is `100000` tokens (not `70000`).

| Variable | Default | Purpose |
|----------|---------|---------|
| `MATRYCA_RAM_BUDGET_MB` | `4096` | Soft RSS budget; warnings in logs when exceeded |
| `MATRYCA_ALIAS_PROMPT_MAX_CHARS` | `2048` | Cap AliasIndex footer in stable user block |
| `MATRYCA_SEMANTIC_CACHE_MEMORY_ENTRIES` | `512` | In-process semantic inference LRU |
| `MATRYCA_BM25_MODE` | `resident` | `resident` or `ondemand` (rebuild per query) |
| `MATRYCA_BOOTSTRAP_YIELD_EVERY` | `25` | `yield_host()` interval during harvest |
| `MATRYCA_BOOTSTRAP_CHECKPOINT_EVERY` | `50` | Daemon state persist interval during Phase 1 |
| `MATRYCA_BOOTSTRAP_IO_BATCH_PAUSE_MS` | `2` | Micro-pause after non-LLM harvest steps (not thermal — see below) |
| `MATRYCA_YIELD_SLEEP_MS` | `0` | Extra yield sleep on `yield_host()` ticks (use 1–5 on HDD) |
| `MATRYCA_LLM_CLUSTER_HISTORY` | `false` | Full vs minimal cluster ack in Ermes history |
| `MATRYCA_LLM_PROMPT_CACHE_MODE` | *(reserved)* | Documented in `.env.example` only — **not read** by runtime yet |
| `MATRYCA_CPU_SANDBOX` | `true` | CPU affinity + idle I/O class when `psutil` is installed (`[edge]` extra) |
| `MATRYCA_PLUMBER_CPU_AFFINITY` | *(unset)* | Optional comma-separated core list; overrides auto sandbox mask |
| `MATRYCA_GRAPH_READ_MMAP` | `true` | Phase 1 regex catalog path uses `mmap_graph_page()` |
| `MATRYCA_MMAP_MIN_BYTES` | `4096` | Skip mmap for tiny files (read into heap instead) |

Existing thermal and low-priority knobs remain: `MATRYCA_THERMAL_DELAY_*`, `MATRYCA_PLUMBER_LOW_PRIORITY_MODE`.

Install CPU sandbox support: `uv sync --extra edge` or `pip install matryca-plumber[edge]` (`psutil`).

### Thermal pauses vs cooperative micro-yield

| Sleep source | Typical duration | When |
|--------------|------------------|------|
| **Thermal** (`MATRYCA_THERMAL_DELAY_BOOTSTRAP` / `_COGNITIVE`) | ≥ 1 s (operator-tuned) | After each **LLM** turn in bootstrap or cognitive pipeline |
| **Micro-yield** (`MATRYCA_BOOTSTRAP_IO_BATCH_PAUSE_MS`, default 2 ms) | &lt; 1 s | Between non-LLM harvest steps so the host OS stays responsive |
| **`yield_host()`** | `MATRYCA_YIELD_SLEEP_MS` (often 0) | Every `MATRYCA_BOOTSTRAP_YIELD_EVERY` files during harvest |

Tests that assert thermal behavior must filter `time.sleep` calls with `s >= 1.0` so micro-yields are not counted as thermal delays (see `test_bootstrap_harvest_thermal_delay_only_after_llm` in `tests/test_master_catalog.py`).

Software-edge directives (frozen KV prefix, adaptive LLM, mmap): [`v1.8-SOFTWARE-EDGE-PLAN.md`](v1.8-SOFTWARE-EDGE-PLAN.md).

---

## Operator workflows

### Large vault bootstrap

1. Point `LOGSEQ_GRAPH_PATH` at a **clone** of your graph (see README).
2. Enable v1.8 env block from `.env.example`.
3. Start daemon: `matryca plumber start --foreground` — Phase 1 harvest yields periodically; watch Sovereign UI progress.
4. After Phase 1: memory teardown runs automatically; Phase 2 begins with cluster map warm.

### Synthetic load testing

```bash
uv run python scripts/gen_synthetic_graph.py /path/to/test-graph --count 1000
uv run matryca plumber start --foreground
make perf   # slow memory/soak tests (--no-cov; not subject to the 70% suite gate)
```

---

## Round 4 audit — pre-release hardening (2026-05-29)

Read-only review after LLM JSON resilience rounds 1–3. Five **must-fix** items before finalizing the v1.8 line (documented in [`resilience-llm-json-triz.md`](resilience-llm-json-triz.md) §5 and [`PROJECT_DIARY.md`](PROJECT_DIARY.md)):

| Fix | Module | Operator impact |
|-----|--------|-----------------|
| Stateless `generate_graph_insights` | `llm_client.py` | Ontology reports no longer pollute Ermes history |
| Sanitize compression summaries on persist | `context_compressor.py`, `llm_client.py` | Degenerate `\n` walls cannot re-enter history via condensation |
| Block catalog **8k** char cap | `maintenance_daemon._enumerate_blocks_for_prompt` | Block-rich pages stay within local context budget |
| Lock only on write in Phase 2 | `_process_llm_cycle_file` → `apply_semantic_page_result` | Logseq can save during slow local inference |
| Exclude `id::` from property matchers | `mldoc_properties.py` | UUID lines never edited as `key::` hygiene targets |

No new env vars. Verification: `make test` (includes new tests in `test_mldoc_phase7`, `test_maintenance_daemon`, `test_context_compressor`).

---

## Explicit non-goals (v1.8)

- New cognitive modules or graph algorithms.
- Louvain / clustering quality changes.
- Cloud LLM orchestration or multi-GPU scheduling.
- Embedding-based search replacing BM25 (unless internal-only with identical query API).

---

## Verification matrix

| Test | Purpose |
|------|---------|
| `test_harvest_prompt_layout_content_before_task` | Bootstrap prompt order |
| `test_page_prompt_session_stable_prefix` | Shared stable block across tasks |
| `test_semantic_cache_memory_lru_eviction` | Bounded `_memory` |
| `test_release_phase1_memory_clears_bm25_cache` | Teardown |
| `test_backlink_index_*` | Persisted incoming counts |
| `test_bootstrap_harvest_calls_yield_host` | Cooperative scheduling |
| `test_bootstrap_harvest_thermal_delay_only_after_llm` | Thermal sleeps only after LLM (`thermal_sleeps = [s for s in sleeps if s >= 1.0]`) |
| `tests/slow/test_daemon_memory_soak.py` | RSS bound on 200-page harvest |

---

## Related reading

- [`v1.8-SOFTWARE-EDGE-PLAN.md`](v1.8-SOFTWARE-EDGE-PLAN.md) — CPU pinning, frozen KV prefix, adaptive LLM, mmap I/O
- [`openspec/llm-performance.md`](openspec/llm-performance.md) — module-level contract
- [`ARCHITECTURE.md`](ARCHITECTURE.md) — system placement
- [`PROJECT_DIARY.md`](PROJECT_DIARY.md) — decision log
- Phase 14d — original Context Acceleration Shield narrative
