# GitHub Release — v1.9.7 (copy-paste)

**Title:** v1.9.7 - Agent Experience (AX) Robustness & Lenient Resolution

**Tag:** `v1.9.7`

**Codename:** AX Robustness & Lenient Resolution

---

## Summary

This release hardens the MCP server for **local LLM agents** (Qwen, Hermes, and similar) that often hallucinate page names, namespace separators, or block targets. Matryca Plumber now **normalizes page input defensively** and **recovers gracefully** from invalid write targets — without modifying the upstream `logseq-matryca-parser` package.

## Lenient Page Resolution

New module: `src/agent/page_input_normalizer.py`

| Agent mistake | Plumber behavior |
|---------------|------------------|
| `progetti___Lancio` vs `progetti/Lancio` | Bidirectional `/` ↔ `___` normalization |
| `pages/Foo.md` or trailing `.md` | Stripped before lookup |
| `PROGETTI/foo` casing drift | Case-insensitive match to on-disk title |
| `progetti///Lancio` | Collapsed to canonical namespace |
| `../../etc/passwd` | Rejected with a clear MCP message (no crash) |

Wired into `read_graph_data`, `mutate_graph` (`edit_property`), `refactor_blocks`, and block read helpers. Resolution notes are returned to the agent in the response body or `warnings` field.

## Safe Fallback Append

When `mutate_graph` / `write_outline` receives `Page Title|block` and the block UUID or `[n]` alias is invalid **but the page exists**:

1. Plumber logs a stderr warning.
2. Appends the outline under the last top-level block, **or** at EOF when the page is empty/blockless.
3. Returns `warnings` in the JSON payload so the agent can self-correct.

`inject_query` still requires a real parent block; empty pages return an actionable error instead of crashing.

## heading_level (preserved)

Outline `heading_level` coercion and disk strip from v1.9.6 remain intact — parser metadata never lands as `heading_level::` in `.md` files.

## Verification

- `tests/test_agent_experience_robustness.py` — 29 chaos/regression tests
- Full suite: **672 passed** at release cut

---

**Technical changelog (canonical):** see [`CHANGELOG.md`](../../CHANGELOG.md) section `[1.9.7]`.

**Agent onboarding:** [`llms.txt`](../../llms.txt) · [`docs/openspec/agent-onboarding.md`](../openspec/agent-onboarding.md).
