--- name: memory scope: common aliases: - memory-curation metadata: nativeReplaces: [llm-wiki] description: Persist and retrieve agent memory across sessions — recall via the three-stage protocol (structure route → semantic search → navigation fallback), read via memory_load, see the wiki structure via memory_browse, write well-placed pages via memory_write (including section-level append/rewrite), maintain via memory_curate. Use whenever the user asks to remember/forget something, when you need to look up past decisions or context, or when episodic state matters beyond the current turn. Primary surface is the NATIVE memory_* tools (a `prismer memory` CLI appendix exists for code agents running in a shell). --- # Memory For an explicitly requested Markdown wiki artifact, read `references/llm-wiki/GUIDE.md` relative to this skill. Its schema, provenance, contradiction and lint workflow operates only in the user-selected project/vault; it does not replace the platform memory tools or create a default home wiki. Use this skill for **durable episodic memory** — facts, decisions, feedback, and project context that need to survive across sessions. Memory has four canonical types: `user`, `feedback`, `project`, `reference`. Pages live at semantic paths and are organized as a wiki: an `INDEX.pkf` at the top, **hub** pages per topic, and **leaf** pages under hubs. **Richness is the goal.** A memory page should be complete enough that a future session works FROM the page instead of re-reading the raw file or the internet. There is no length budget on ordinary pages — the only waste is *repetition* (re-extracting what is already distilled, re-querying pages already in your context). > **Seam — memory content is PKF; the write invariants are embedded below.** The full > body syntax (sections, data views, media, math, harness), validation and projection > belong to the **`pkf-writing`** skill, but this skill carries the MANDATORY write > invariants inline (see *PKF body standard* below) so a write is safe even when > `pkf-writing` is not loaded. **This skill decides WHAT to remember, WHERE it goes, and > HOW the graph is maintained.** ## Recall protocol — three stages, in order Answer a workspace-knowledge question by walking these stages. Stop at the first stage that answers it; never skip straight to guessing. **STAGE 1 — STRUCTURE ROUTE (first round is hybrid).** The first round of any recall is **hybrid — two calls in the same round**, never one instead of the other: - **Parameterless `memory_browse`** — the root structure surface: `{index, hubs[{path,title,pageType,snippet,updatedAt}], hubsByRecent[], nearest[]}`. Hub order has two views: `hubs[]` is the **structural order** (the order the workspace publishes; today hub rows are ordered by the hub's own `updatedAt` DESC — that IS the structural-order baseline); within a hub, its children come `updatedAt` DESC. Each hub row carries **subtree freshness** — `updatedAt` = the most recent write under that hub (the hub row's own `updatedAt` spread with its direct children's). `hubsByRecent[]` repeats the **same hub set in recency order** (subtree `updatedAt` DESC) — the "what changed" signal; the two orders differ exactly when a child page was written more recently than its hub row. **There is no `memory_recent` tool** — recency is a signal ON browse results, not a query surface. Hubs are *routing* pages: their job is to tell you which leaf to open. - **Batch `memory_search`** — extract ≥2 phrasings of the turn's terms into `queries[]` (≤8, returned grouped in `resultsByQuery`): one round trip, several recall intents. When the turn has no lexical terms ("what changed recently?", "what's the team up to?"), the batch **degrades but still runs** — the signal query executes anyway. **Both question types are covered in one round.** Term-bearing questions are covered by the batch search; termless questions have exactly the structure surface as their search space — term extraction necessarily spins empty on them, so the root browse is what catches them. **Exemption — one, and tight: the digest names the answer.** The stable memory map (INDEX-TOC + one line per hub) injected at turn start under "Memory Map (auto — stable digest)" lets you skip the hybrid round ONLY when it **names the answer outright** — the exact hub or page the answer lives in, loadable directly. **A passing one-line mention is NOT coverage**: if the digest only mentions the hub or topic, the hybrid first round still runs. Structural facts the digest itself states (which topics exist, what a hub covers, where a topic's children live) are answered from the map, and `memory_browse` with the topic as `query` serves follow-up structure questions on demand. **STAGE 2 — SEMANTIC SEARCH (the hybrid round's hits).** The batch `queries[]` leg answered the term-bearing side; its hits are your **decision payload** — hop-decision fields tell direct-read vs multi-hop, and the browse-root live structure (including its recency signals) tells where to wander next. Read each hit's hop-decision fields before deciding what to do: | Field | What it tells you | |---|---| | `tier` | `wiki` = distilled/curated page (highest trust); `asset` = a raw span a distilled page already cites via `derived-from` (middle); `raw` = the upload's own text, no synthesis (lowest — verify before relying on it) | | `hubPath` | the hub this page hangs under — a `wiki` hit is context for its whole hub, so a near-miss here often means the ANSWER is a sibling leaf | | `childrenCount` | how many pages fan out under this hit (>0 ⇒ it is a hub you can walk down) | | `outboundPreview` / `inboundLinkCount` | where the page points / how linked it is — the cheap next hop | | `sectionAnchor` + `sectionPreview` | the exact section that matched — read THAT, not the whole page | `memory_search` returns **ranked hits with lexical evidence** (the query matched the page). A high-rank `wiki` hit is usually the answer; `memory_load` the page (or just the `#section`) when the snippet is not enough. **STAGE 3 — NAVIGATION FALLBACK (miss).** When your wording matched nothing — or only grazed unrelated pages — the response carries **`navigation`** instead of a longer hit list: ``` navigation: { reason: 'text-miss', startPoints: [{ path, title, pageType: 'index'|'hub', childrenCount, why: 'structural-entry' }], guidance: '…' } ``` `startPoints` are **starts, not answers** — there is no rank among them, so never read them as scored hits and never quote one as the answer. They are the workspace's routing entries (INDEX + hubs, children-rich first). Walk them: 1. **Look at the children** of the start point closest to your topic (`memory_browse` with the hub as `query`, or `memory_load` the hub — its TOC lists its children). 2. **Batch-read the candidates**: one `memory_search` with the candidate topics as `queries[]`, or `memory_load` each page. Load the section, not the whole page, when the TOC gives you an anchor. 3. **Follow links** (`memory_load` returns the page's `links`) until a page actually carries the answer. If the walk finds nothing, the knowledge does not exist yet — say so, and consider writing it (see *Write flow*) rather than answering from thin air. ## Tool surface (native tools — your primary interface) | Tool | What it does | |---|---| | `memory_search {query, queries?, limit?, pageType?}` | Semantic/FTS recall + batch; ranked hits with the hop-decision payload, or `navigation` start points on a miss | | `memory_load {uri?, path?}` | Read one page (or one section via `#anchor` in the uri) → `{page, content, links}` — `links` are the page's outbound graph edges | | `memory_browse {query?}` | **See the structure BEFORE writing** → `{index, hubs[{path,title,pageType,snippet,updatedAt}], hubsByRecent[], nearest[]}` | | `memory_write {path, content, title?, parentHubPath?, relation?, op?, section?}` | Create, extend, or section-edit a page; `parentHubPath` attaches it under a hub; `op="append-section"` / `op="rewrite-section"` + `section` edit ONE section (see *Write flow*) | | `memory_curate {op, ...}` | Maintenance verbs — see the **memory-dream** skill (write ops are orchestrator-gated) | Parameter names below are EXACTLY what the tools accept (trailing `*` = required). - **`memory_search`**: `query*` · `queries[]` · `limit` · `sourceWorkspaceId` · `pageType[]` - **`memory_load`**: `uri` · `workspaceId` · `sourceWorkspaceId` · `path` - **`memory_browse`**: `query` - **`memory_write`**: `path*` · `content*` · `title` · `parentHubPath` · `relation` (child-of|related) · `op` (replace|append-section|rewrite-section) · `section` · `visibility` - **`memory_curate`**: `op*` · `pageId` · `childPaths[]` · `reason` · `kind` · `limit` · `section` · `targetSection` · `sourcePageId` · `sourceSection` · `mergedContent` · `supersededByPageId` · `supersededBySection` · `linkId` · `toPageId` · `toPath` · `toSection` `web_load` (the workspace URL loader) also accepts `prismer://asset/…` and `prismer://…/file/…` URIs — when a memory page points at an asset, load the asset on demand through it instead of asking the user to re-attach the file. ## PKF carrier → Memory: automatic durable distillation, explicit exact copy **PKF is the content format, not a fourth carrier.** A valid PKF report remains authoritative in its message-inline block or Library Asset. For message-inline delivery, the Runtime passes the validated PKF source and its Markdown projection into the normal post-turn Memory classifier automatically: durable conclusions are distilled through the same browse-first placement flow, while transient report content yields no Page. Do not ask the user for a second format choice and do not exact-copy the report merely because it is PKF. Dream still reads authoritative **Memory Pages only**. - **Distill durable knowledge (normal path):** inline PKF enters the Runtime post-turn classifier automatically; explicit Asset handling or user-requested writes extract only surviving conclusions through the browse-first `memory_write` flow — typed source pointer, never the whole report. - **Preserve the exact inline PKF as Memory (exception):** only when the user explicitly wants those exact bytes as the Memory authority — `cloud pkf materialize` (message/block revision, source hash, explicit `.pkf` path, idempotency key, `--confirm-path`); no native `memory_*` shortcut, no generic Asset→Memory exact-copy. Read back the receipt; exact-copy is an exceptional authority transition, not the searchability path. Once either route creates/updates a Memory Page, curation operates on that Page's graph, revisions and PKF body—not on its former carrier. ## Deliverable adoption — copy + reference (memory211 轴A) A deliverable YOU produced this turn gets an immediate three-way decision: extend the existing page at section granularity, attach a new leaf under the best hub, or SKIP — skipping is a first-class outcome (a one-off answer is not knowledge). Deliverable-derived pages follow the **copy + reference** doctrine: they may carry the source's near-full content so a future session works FROM the page instead of re-opening the asset, and they MUST carry the typed references — exactly ONE `` pointer, section-anchored `` edges, and the source's own vocabulary (proper nouns, codes/numbers, thresholds verbatim) so a paraphrase of the source is still findable. There is no length budget: token usage is recorded, never constrained. Pass `deliverableSource: {assetId, contentHash, sizeBytes}` on `memory_write` — the gate enforces the pointer (422 `deliverable_pointer_missing`), short-circuits a same-deliverable replay as a dedupe-hit, and routes an oversized source to sharding (422 `sharding_required`) instead of one giant page. `memory_search` an existing topic first and extend/supersede any page whose pointer cites a prior revision, never fork. ## Sharding — one page per 64K characters (memory211 §6.9) A **source over 64K characters** never becomes one page, and a distilled **page stays under 64K characters**. The write gate rejects an oversized page with 422 `sharding_required`; the ingest pipeline plans the split for you (one structural **index page** above a run of **shard pages**, `shards//shard-000.pkf` …, boundaries on content edges). The reference chain is mandatory and is what keeps a shard set navigable: ``` index page --derived-from--> the source asset shard page --child-of------> the index page ``` Write one page per shard (same copy + reference rules), then the index page with its TOC. Never merge shards back into a single giant page. ## When to use - The user explicitly says **"remember X"** or **"forget X"** → write or delete immediately. - The user references a past decision, preference, or detail you don't have in current context → recall first (three-stage protocol above). - **Before answering anything about workspace knowledge you did not just read, run the hybrid first round — batch `memory_search` + parameterless `memory_browse`.** Attached files are raw sources — check memory for existing distilled knowledge before re-reading them. A memory hit is cheaper and already synthesized; fall back to the raw asset only when memory misses (`tier: 'raw'` tells you that you are reading the source, not the synthesis). - After a non-obvious clarification or correction lands, write it so the next session keeps the lesson. - After you read/ingest a document and extract durable conclusions, **persist them as a placed page in the same turn** — don't leave the knowledge only in your reply. ## Path convention Paths are workspace-relative and **prefix-free** — do NOT add a leading `memory/`: ``` decisions/llm-provider.pkf ← a leaf under the decisions topic projects/desktop-202/decisions.pkf ← nested topic path reference/platform.pkf ← a hub page ``` The platform-owned onboarding seed uses reserved `memory/onboarding/...` paths; that is not a pattern for agent-authored pages. Always reuse an existing returned seed path verbatim if you extend one. When extending or linking to an existing page, **use its path exactly as returned by `memory_browse` / `memory_search`** — never re-derive or hand-normalize a path you saw elsewhere. Path drift (adding/dropping a `memory/` prefix, guessing `.pkf` suffixes) is the top cause of dead links and dropped edges. ## Write flow (browse-first) Writing memory is **browse → decide placement → write → verify**. Never write blind. **STEP 1 — CONSTRUCT.** Extract the durable knowledge from the conversation and author the page body in full (via `pkf-writing`: frontmatter with its one-sentence `description` + sections + any rich content). Don't write a path-shaped stub. **STEP 2 — BROWSE.** Call `memory_browse` with your topic as the query. **STEP 3 — DECIDE placement** from what browse returned — exactly one of: - **(a) A page on this topic already exists** (in `nearest`) → **you MUST extend it, never fork a near-duplicate page.** Decide at *section* granularity: - the page has a section whose topic matches your fact → merge into that section (`op="rewrite-section"` with that section's id); - the page matches but has no section for this fact → add one (`op="append-section"` with a new section id). - **(b) It fits under an existing hub** (in `hubs`) → write a **new leaf attached to that hub**: pass the hub's path as `parentHubPath`. - **(c) Genuinely new topic** (no hub fits) → first create the topic **hub page** (type `hub`, a short `#overview` "what this topic covers" body), then write the leaf with `parentHubPath` pointing at your new hub. **NEVER write an orphan leaf** — a new page with no hub attachment that extends nothing. The platform rejects an unanchored new leaf with a `placement_required` error listing the available hubs; if you see that error, re-browse and attach — do not retry verbatim. **STEP 4 — WRITE** with the placement declared structurally, and **validate the body via `pkf_validate` BEFORE persisting** (authoring loop from `pkf-writing`). `memory_write` is a mutation: a response containing `{"ok":true}` means that revision has already been written. For the same fact/path, **do not call `memory_write` again in this turn** to polish, reformat, or “make sure”; that creates another authoritative revision. Continue to STEP 5 and use the read surface for verification. **STEP 5 — VERIFY (optional but cheap).** Use `memory_load` on the exact returned path (or `memory_search` a key phrase) and confirm it comes back. Verification is read-only; never rewrite a successful revision merely to verify it. Then report path + placement + one-line description to the user. ## PKF body standard (embedded — MANDATORY) Full syntax lives in the single-file `pkf-writing` SKILL.md; these five invariants a write must never violate: 1. **REQUIRED frontmatter `description` (one sentence)** — in the PKF frontmatter block alongside `type` (`user|feedback|project|reference`), `title`, `pkfVersion "1.1"`; the description feeds previews/TOC — never omit it (frontmatter 写法见 `pkf-writing` skill)。 2. **Typed links target what actually exists** — copy hrefs VERBATIM from `memory_browse`/`memory_search`/`memory_load` or asset resolver results, never hand-type; `child-of` points FROM child TO hub. 3. **`pkf_validate` BEFORE `memory_write` — every time** — repair ALL errors, then persist (the write gate rejects invalid v1.1 bodies anyway). 4. **Browse-first + append governance** (your operating directive's rules) — extend an existing page at section granularity (`op="append-section"`/`op="rewrite-section"`); new pages attach under a hub (`parentHubPath`); never orphan leaves or whole-page-rewrite another agent's page. 5. **Evolution artifacts declare their kind (memory211/10 §2.1)** — a body written by a **dream / proposal / frontier / ingest** leg (not by a human, and not by you writing a page someone asked for) must carry the metadata as a **top-level `memory` key in the frontmatter script** (the parser files it under `extra.memory` — write `memory`, not `extra`; writing `{"extra":{"memory":…}}` lands in `extra.extra.memory` and is read as *no block at all*): ``. `memoryRole` is a routing fact, not a label — `knowledge` is the target of self-directed recall, `procedure` is what the first-round mixed browse hits, `action_result` is delivered by event trigger. `source` is the provenance a human uses to decide whether the page may be deleted; an artifact whose origin cannot be stated is one nobody can responsibly retire. Per-section declarations go in `memory.sections[]`, indexed by `anchor` — **each entry carries its own `memoryRole` + `source`** (an entry missing either is rejected, same as the page-level block): `{"anchor":"renewal","memoryRole":"procedure","source":"<…>"}`. A **hand-written page needs none of this** — the gate only applies to the automatic legs. The write gate **rejects** an evolution artifact without the metadata (`evolution_metadata_required`) and returns a verdict naming the offending field: fix that field and resubmit — never drop the artifact silently. If a `pkf_validate`-clean body is not achievable, **do not persist it**. Keep the draft in the current response/working file, report the validation or capability failure, and leave Memory unchanged; never fake a revision or bypass the write gate. ## Structural edges — how pages relate Relationships between pages are **graph edges**, not prose. Declare them structurally: - `parentHubPath` on `memory_write` — attaches the written page under a hub. Default `relation` is `child-of`; pass `relation="related"` for a non-hierarchical association. - `childPaths` on `memory_curate(op="promote_to_hub")` — attaches existing pages under a newly promoted hub in one call (orchestrator convergence; see **memory-dream**). - In-content typed links (rel vocabulary from `pkf-writing`) **with canonical hrefs copied from browse/search/load results** are also materialized into edges — fine for `supports` / `contradicts` / `related` / `references` / `cites` cross-refs inside prose. For hub attachment, prefer the structural parameters. **Direction matters for `child-of`: the edge points FROM the child TO the hub.** `parentHubPath` gets this right automatically (the page you are writing is the child). If you ever hand-write a `child-of` content link, it goes **in the child page's body, pointing at the hub** — never the reverse. Hubs never declare child-of links. ## INDEX & hubs — ownership is asymmetric - **Top `INDEX.pkf`:** its authored semantic sections are agent/editor territory. Its visible Contents is derived live from the `child-of` graph; Dream does **not** store or rewrite an INDEX `#toc`. Change the graph, not a copied list. - **Hub `#overview`:** agent-owned prose—what the topic covers and how children relate. - **Hub `#toc`:** machine-owned strict PKF section, regenerated by `memory_curate(op="rebuild_index")` from graph membership. Never hand-edit it. Thus `rebuild_index` is a legacy verb name: it rewrites hub TOCs and refreshes derived structure, while INDEX Contents remains a read-time projection. ## Extending pages (and other agents' pages) — section ops To add knowledge to an existing page, **edit at section granularity — do not rewrite the whole page**. Whole-page rewrites of pages another agent authored create version conflicts and clobber their content. The section ops splice ONE section cloud-side: ``` memory_write(path="decisions/database-choice.pkf", op="append-section", section="revisit-2026-07", content="
") ``` Default `op` is `replace` (whole page) — reserve it for pages you authored yourself. ## Size discipline (a discipline, not a limit) - **INDEX and hubs: keep them lean** — overview prose + TOC, nothing else. Every recall hop reads them. Nothing enforces this — when a hub outgrows itself it surfaces as a `memory_curate(op="candidates", kind="oversized")` split *suggestion*. - **Ordinary pages: no budget, but a hard ceiling at 64K characters** — above that the source must be sharded (see *Sharding*), never squeezed. Rich is right: full tables, exact numbers, media pointers, rationale prose. - **The only token rules are anti-waste:** don't re-extract content that is already distilled into a page (extend it instead), and don't re-query pages already in your context (circular recall). ## Memory Types | Type | What it is | When to write | |---|---|---| | `user` | Who the user is, role, preferences, expertise | When you learn role/responsibility/preference details that should shape future behavior | | `feedback` | Approach corrections + validated approaches | After a correction ("don't do X") OR a non-obvious approval ("yes that was right") | | `project` | Goals, deadlines, decisions, ongoing initiatives | When you learn who/what/why/by-when that isn't derivable from code | | `reference` | Pointers to external systems (Linear, Slack, dashboards) | When the user names a tool/channel and its purpose | The type goes in the PKF frontmatter `type` field (the four canonical types above, or an OKF subtype like `decision`) — the exact frontmatter shape is taught by `pkf-writing`. ## Operating Rules ### Write - **Follow the browse-first flow** above. Never write an orphan leaf, never guess a path. - **Don't save secrets, credentials, personal data, or one-off debugging chatter.** - Don't save **generic programming advice** that isn't tied to this project. - Don't save **ephemeral task state** (in-progress work, current-conversation context). - Don't save things derivable from the **current project state** (file paths, conventions, git history). Reading the code is authoritative. - Don't save things already in **CLAUDE.md**. - **Always rich, always validated**: body authored per `pkf-writing`, `pkf_validate` passes before `memory_write` (a v1.1 invalid body is rejected at the write gate). - For `feedback` and `project` types, include a **Why** section and a **How to apply** section so future-you can judge edge cases. - Convert relative dates to **absolute dates** before writing. - If a fact may become stale, embed the condition or date that makes it valid. ### Read / Recall - Follow the **three-stage recall protocol** above: structure route → semantic search → navigation fallback. Never re-derive structure the injected digest already answered. - On a miss, read `navigation.startPoints` as **routing**, never as results, and walk them (children → batch read → links). Do not quote a start point as an answer. - Treat recall results as **leads, not evidence**. `tier` tells you what kind of lead: `wiki` is curated, `raw` is somebody's upload — verify a `raw` hit before relying on it. - `memory_load` returns the page's outbound `links` — follow them to navigate the graph. - **No circular recall:** pages already in your context are known — do not re-query them. - Don't let memory **override explicit current user instructions** — trust the current input and update or remove the stale entry. - Before recommending action based on memory that names a specific function/file/flag, **verify it still exists** (grep / read). Memory is frozen in time. - For *current* or *recent* state ("what changed this week"), prefer `git log` over recalling activity-log memories. ### Delete / Maintain - When updating an outdated memory, **prefer extending/editing** over deleting + rewriting. - When the user says "forget X", search first, confirm the match, then delete. Don't silently fail if recall finds nothing — tell the user. - **Consolidation / Dream** (merge duplicates, promote hubs, rebuild hub TOCs, maintain overviews, split oversized hubs) is a separate, orchestrator-gated capability — see the **memory-dream** skill. Do not consolidate from this skill. ## Authority & role boundaries (product209/16 MA-2) Memory reads/writes are adjudicated per request by the workspace Memory authority. The verdict you receive is final for that request: - **owner (human)** — full authority: decides cross-scope approvals (202 deferrals), grants read / read+write ACLs; curate and replicate rights originate here. - **orchestrator (appointed agent, `orchestratorAgentId`)** — may curate the shared graph (promote / supersede / rebuild — see **memory-dream**). It does NOT automatically pierce member/deputy private scopes. - **deputy** — represents exactly its active bound member (a human principal). Its authority IS the member's — never the owner's, never the workspace's. - **member / member's deputy** — own private pages + workspace-shared pages; cannot read or curate another member's private pages. - **unbound specialist** — has NO owner/member mapping. Only a live role/task/council scope grants reads; outside that scope, expect deny. Outcome discipline: - **`403 deny`** — final for this request. Do NOT retry verbatim, do NOT ask another agent to read the target for you. - **`202 approval deferred`** — the request waits on the data owner. Do NOT re-issue it; the approval record already exists and re-submitting spams the owner. - **local replica states** (`suspended` / `reconciling` / `stale` / authority lease expired) — local reads fail closed until the replica reconciles. Retry after reconcile; a fail-closed read is never "memory is empty". Role templates do not automatically grant a human principal: an agent whose role mentions curation still needs the appointed orchestrator binding before `memory_curate` write verbs succeed. ## Anti-patterns - ❌ **Re-reading a raw file or the internet when memory already distills it.** - ❌ **Circular recall** — re-querying pages already in your context. - ❌ **Counting a one-line digest mention as covered** — the exemption is the digest naming the exact hub/page that answers; anything less runs the hybrid first round. - ❌ **Duplicate extraction** — writing a near-duplicate page when browse/recall showed an existing page on the topic. Extend it (`append-section` / `rewrite-section`). - ❌ **Copying an Asset/inline PKF body into a page just because it is PKF.** Distill durable knowledge, or use explicit exact inline materialization when requested. - ❌ **Hand-editing a hub's `#toc`** or storing a duplicate INDEX TOC. - ❌ Orphan leaves, guessed paths. - ❌ Whole-page-rewriting a page another agent authored — section ops exist; use them. - ❌ Persisting a body that failed `pkf_validate` (the write gate will reject it anyway — fix the diagnostics instead of retrying verbatim). - ❌ **Reading `navigation.startPoints` as a ranked answer** — they are routing entries; the answer comes from walking them. - ❌ **Squeezing an oversized source into one page** — shard it (422 `sharding_required` is the gate telling you so), never truncate the knowledge to fit. ## Output reporting After writing memory, echo the path, type, placement (which hub it attached under, or which page/section it extended), and one-line description back to the user so they can verify what got persisted. After recalling, list match titles + paths + scores; do **not** paste full page content unless the user asks — follow up with `memory_load` for any specific hit. If you navigated from `navigation.startPoints`, say which start point led to the answer. ## CLI appendix (code agents in a shell) Code agents (claude-code / codex / opencode) running in a shell can use the `prismer memory` CLI — workspace + identity default from the agent env, output is JSON: ```bash prismer memory recall "what database did we choose?" # = memory_search prismer memory search --queries '["q1","q2"]' # batch recall, one call (daemon cuts at 8 + flags `truncated`) prismer memory read "decisions/database-choice.pkf" # = memory_load (also path#section) prismer memory load-batch ... # up to 10 pages in one call, per-path verdict prismer memory list --page-type hub # hub listing prismer memory write --path "" --content '' # = memory_write (content also via stdin) prismer memory delete ``` `prismer memory curate` carries the maintenance verbs (`candidates`, `promote-to-hub --child-paths`, `supersede`, `rebuild-index`) plus the section-level ones (`section-merge`, `section-supersede`, `rewire`) — `--help` lists each command's flags. > The CLI currently lags the native tools on browse (`memory_browse` has no CLI > subcommand yet), so on the shell surface decide placement with > `list --page-type hub` + `recall`. Every OTHER write parameter exists on the CLI > under its kebab-case name. ## Backing capabilities (D22 mapping) Replaces these v1.x built-in skills: `memory-read`, `memory-write`, `memory-recall`. Compatibility alias: `memory-curation` (old slug/skillId/ACK resolves to this skill — one canonical delivery).