docs(#956): MemPalace capability pre-proposal (PRD/ADR draft) (#957)

Combined PRD + ADR for wiring MemPalace (local-first AI memory) into the
GSD loop as an ADR-857 feature capability. Bidirectional sync, three
selectable memory-relationship modes (augment/kg_backend/replace),
loop-point recall+capture map, opt-in tier:full, MCP-primary/CLI-fallback.

Marked Pre-Proposal: the first-party-plugin proposal standard is not yet
established and ADR-857 phase-6 loop wiring is pending. First of a planned
series; PRD/ADR format is provisional pending PM-method evaluation.

Refs #956

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-06-09 22:30:48 -04:00
committed by GitHub
parent 85cfa5dc13
commit e006ff74fd

View File

@@ -0,0 +1,288 @@
# PRD + ADR — MemPalace Capability
> **Status:** **Pre-Proposal** (the stage *before* `Proposed`). The first-party-plugin proposal **standard is not yet established**; this is exploratory and intentionally not a formal ADR yet. Advancement Pre-Proposal → Proposed → Accepted happens once that standard exists.
> **Tracking issue:** [#956](https://github.com/open-gsd/gsd-core/issues/956)
> **Type:** Feature Capability (ADR-857 plug-in)
> **ADR number:** TBD — assign when advanced to `Proposed`, then promote to `docs/adr/<issue>-mempalace-capability.md`
> **Format caveat:** This is the **first of a planned series** of first-party-plugin proposals. The PRD/ADR-combined instrument used here is **provisional** — a better PM format (RFC, PR-FAQ, one-pager + spike, opportunity/solution tree, problem-framing doc) may be adopted as the standard and this doc retro-fitted to it.
> **Depends on:** ADR-857 (Capability System), capability-registry generation, federated config, loop-resolver (`loop render-hooks`)
> **External dependency:** [MemPalace](https://github.com/MemPalace/mempalace) — local-first AI memory (ChromaDB + SQLite), MCP server + CLI + Claude Code hooks
> **Format:** Part I = PRD (problem, users, requirements, metrics). Part II = ADR (forks, decisions, manifest, rollout).
---
# Part I — PRD
## 1. Problem
GSD's memory today is **per-project and per-artifact**: `STATE.md`, `.planning/graphs/` (the gsd-graphify knowledge graph), phase `CONTEXT.md`/`PLAN.md`/`SUMMARY.md`, and `gsd-extract-learnings` output. These are excellent *within* a milestone but have three gaps:
1. **No durable cross-session recall.** A decision made in phase 3 is re-derived in phase 9 because nothing surfaces it at the right moment. The learnings exist on disk but are not *retrieved* at discuss/plan time.
2. **No cross-project memory.** A pattern learned in `gsd-core` is invisible when working in `gsd-pi`. There is no semantic search across the developer's whole body of work.
3. **No verbatim, time-aware decision graph.** `.planning/graphs/` is project-scoped and lacks temporal validity (when did a decision become true; when was it superseded?).
MemPalace solves exactly these: local-first verbatim storage (wings/rooms/drawers), semantic search, a temporal knowledge graph (subject→predicate→object with `valid_from`/`valid_to`), cross-project tunnels, and a ~600–900-token `wake-up` recall layer that "leaves 95%+ of context free."
The opportunity: **wire MemPalace into the GSD loop's natural memory moments** — recall before you think, capture after you decide — via the ADR-857 capability mechanism, so it is opt-in, declarative, and default-resilient (no behavior change when MemPalace is absent).
## 2. Users & personas
| Persona | Need | What the capability gives them |
|---|---|---|
| **Solo maintainer across many repos** (the gsd-core author) | "Why did I decide X three milestones ago?" answered without grep archaeology | Cross-project recall at discuss/plan; temporal KG of decisions |
| **Long-running autonomous runs** (`/gsd-autonomous`, cron) | Memory that survives context compaction and session boundaries | precompact capture; diary journaling; CLI-path capture that works headless |
| **Team onboarding** (`/gsd-milestone-summary` consumer) | A queryable narrative of how the project got here | Verbatim drawers + KG timeline per wing |
| **Privacy-sensitive users** | Memory that never leaves the machine | MemPalace is local-first by construction; capability adds nothing cloud-bound |
## 3. Goals
- **G1 — Deliberate recall.** Surface relevant prior decisions, patterns, and surprises at `discuss:pre` and `plan:pre`, cheaply (wake-up + targeted search), so planning starts informed.
- **G2 — Deliberate capture.** Persist phase artifacts and extracted learnings into the palace at `discuss:post`, `plan:post`, `verify:post`, and `ship:post`, mapped to a stable wing/room taxonomy.
- **G3 — Bidirectional KG sync.** Mirror GSD's decisions/learnings into MemPalace's temporal KG, and (in the stronger modes) read them back.
- **G4 — Cross-project knowledge.** Build tunnels between related wings so a pattern in one repo is reachable from another.
- **G5 — Session journaling.** Write a per-agent diary entry at `ship:post` and on long-run boundaries.
- **G6 — Default-resilient & opt-in.** `tier: full`, master toggle `mempalace.enabled` defaults **off**. Every hook is `onError: skip`. Absent MCP/CLI ⇒ loop proceeds unchanged.
## 4. Non-goals
- **N1** — Not replacing `gsd-extract-learnings` analysis; we *feed* it into the palace, not supersede it.
- **N2** — No third-party-code loading into gsd-core (ADR-857 §7 keeps that out of scope). Integration is via MemPalace's MCP tools + CLI only.
- **N3** — Not authoring a new MemPalace source-adapter (RFC-002); GSD ships text artifacts MemPalace already mines.
- **N4** — Not a blocking gate. Memory never halts the loop. (No `blocking: true` hooks.)
- **N5** — Not shipping MemPalace itself; the capability declares the dependency and wires it, but install/`pip install mempalace` is the user's action.
## 5. Functional requirements
### 5.1 Memory-relationship modes (selectable)
The capability exposes **three modes** via `mempalace.memory_mode`, so the user chooses how tightly MemPalace couples to GSD's native memory. **All three are first-class and selectable** (not a one-time design pick):
| Mode | `.planning/graphs` KG | Learnings / STATE | Recall source of truth | Coupling |
|---|---|---|---|---|
| **`augment`** (default) | stays native | stays native | GSD native; palace is an *additional* recall layer fed from artifacts | lowest — palace is write-mostly, read-optional |
| **`kg_backend`** | routed to `mempalace_kg_*` | stays native | KG queries hit MemPalace's temporal graph | medium — graphify reads/writes the palace KG |
| **`replace`** | backed by palace | backed by palace | palace is the durable store; GSD reads memory through it | highest — MemPalace is a hard dependency |
Mode is read at hook-render time and changes *which* MemPalace surfaces the rendered instructions invoke. Switching modes is a config change, not a reinstall.
### 5.2 Recall (read path)
- **FR-R1** At `discuss:pre`, inject a recall fragment instructing the orchestrator to run `mempalace wake-up --wing <wing>` (L0+L1, ~600–900 tokens) plus `mempalace_search(query=<phase topic>, wing=<wing>)` and surface the top drawers + any relevant `mempalace_kg_query` facts into discussion.
- **FR-R2** At `plan:pre`, a recall step (skill `mempalace-recall`) produces `MEMORY-RECALL.md` consuming `CONTEXT.md`: prior decisions, patterns, and *surprises* relevant to this plan, retrieved by semantic search + KG timeline, deduped.
- **FR-R3** Recall is read-only and side-effect-free; if MemPalace is unreachable, `MEMORY-RECALL.md` is written with an "unavailable" stub and the loop continues.
### 5.3 Capture (write path)
- **FR-C1** At `discuss:post`, file `CONTEXT.md` as a drawer in `room: decisions` (dedup via `mempalace_check_duplicate`), and extract decision facts into the KG (`mempalace_kg_add` with `valid_from` = phase date).
- **FR-C2** At `plan:post`, file `PLAN.md` as a drawer in `room: planning`.
- **FR-C3** At `verify:post`, file `SUMMARY.md`/`UAT.md` excerpts in `room: milestones`, and file confirmed *problems→fixes* in `room: problems`.
- **FR-C4** `gsd-extract-learnings` output (decisions, lessons, patterns, surprises) is mirrored into the KG and corresponding rooms, with provenance (`source_file`, `source_drawer_id`).
- **FR-C5** All captures are idempotent: re-running a phase re-files the same content without duplication (MemPalace deterministic drawer IDs + `check_duplicate`).
### 5.4 Cross-project & journaling
- **FR-X1** At `ship:post`, when `mempalace.cross_project_tunnels = true`, propose tunnels between this wing's rooms and related wings (`mempalace_find_tunnels`), creating those the user/agent confirms.
- **FR-X2** At `ship:post`, when `mempalace.diary_journal = true`, write a session-summary diary entry (`mempalace_diary_write(agent_name, entry, topic="phase-ship", wing)`).
- **FR-X3** At `ship:post`, optionally run `mempalace sync --wing <wing> --apply` to prune drawers whose source artifacts were archived/deleted (guarded: never global prune).
### 5.5 Passive auto-capture (optional, separate layer)
- **FR-P1** When `mempalace.auto_capture_hooks = true`, the capability's lifecycle hooks install MemPalace's native Claude Code hooks (`session-start`, `stop` @ every 15 human messages, `precompact`) so tool output and mid-session context are captured even between loop points. Default **off** (the deliberate loop hooks are the primary integration; this is belt-and-suspenders).
### 5.6 Transport selection (robustness)
- **FR-T1** Interactive runs prefer the **MCP tools** (rich, structured). Autonomous/headless/cron runs prefer the **CLI** (`mempalace mine|search|wake-up|sync`) because MCP servers may be absent in headless harness contexts. Rendered hook instructions name both and pick by run context.
## 6. Success metrics
| Metric | Target |
|---|---|
| Recall token cost at discuss/plan | ≤ ~1k tokens (wake-up + one search) |
| Phases with artifacts captured | ≥ 95% when enabled |
| Recall relevance (manual spot-check) | top-5 drawers judged relevant ≥ 80% of phases |
| Loop overhead when MemPalace absent | 0 (skip-on-error, no failures) |
| Cross-session decision reuse | qualitative: maintainer reports "surfaced something I'd forgotten" |
| Duplicate drawers from re-runs | ~0 (idempotent capture) |
## 7. Risks & mitigations
| Risk | Mitigation |
|---|---|
| MCP server absent in headless/cron | CLI fallback (FR-T1); never hard-depend on MCP |
| **Phase-6 not yet wired** — `loop render-hooks` is implemented but no workflow calls it yet | Interim: invoke `mempalace-recall`/`mempalace-capture` skills manually or via MemPalace's native hooks; capability ships *ready* for phase-6 cutover |
| Palace noise/drift | `check_duplicate` before file; `mempalace sync` prune; verbatim-only (no lossy summaries written) |
| AAAK is lossy (84% vs 96% R@5) | Capture stores **verbatim drawers**, not AAAK; AAAK only as an optional index (`compress`) |
| Privacy | Local-first by construction; capability adds no network egress |
| Over-capture cost | Capture only at phase boundaries + bounded artifacts; not every message (that's the optional passive layer) |
| Mode `replace` makes MemPalace a hard dep | Default `augment`; `replace` documented as opt-in with migration |
---
# Part II — ADR
## 8. Context
ADR-857 establishes the **host/core vs Capability plug-in** split: the five-step loop is the host; everything else is a Capability that contributes *data* (not control flow) at **12 stable Loop Extension Points** via three hook kinds — `step`, `contribution`, `gate`. Capabilities are declared in `capabilities/<id>/capability.json`, compiled by `scripts/gen-capability-registry.cjs` into `gsd-core/bin/lib/capability-registry.cjs`, and resolved at runtime by `loop render-hooks <point>`. Config keys are **federated** (new keys flow without editing the central `loadConfig` whitelist).
MemPalace is a natural Capability: it adds memory recall/capture behavior at loop points, owns its own skills/agents/config slice, and degrades gracefully. It calls **no gsd-core internals** — only MemPalace's MCP tools and CLI — so it fits ADR-857's "declarative + first-party, third-party code deferred" decision (the *integration glue* is first-party; MemPalace runs out-of-process).
## 9. Decision drivers
- Must be **opt-in** and **default-resilient** (G6) — memory is never load-bearing for the loop.
- Must map cleanly onto MemPalace's existing taxonomy (wings/rooms/drawers/KG) — no new MemPalace adapter.
- Must honor ADR-857's **data-not-control-flow** rule: hooks render *instructions*; the agent calls MemPalace.
- Must let the user pick coupling depth (`augment`/`kg_backend`/`replace`) without reinstall.
- Must work **headless** (CLI path), not just interactively (MCP path).
## 10. Resolved design forks
Mirroring ADR-857's "resolved decisions" structure:
1. **Capability role — `feature`.** Owns skills + agents + hooks + config slice. (A future `runtime`-role descriptor is unnecessary; MemPalace is CLI-uniform across harnesses.)
2. **Tier — `full`.** External dependency ⇒ opt-in only; never in `core`/`standard` profiles. Master toggle `mempalace.enabled` defaults **off**.
3. **Integration transport — MCP-primary, CLI-fallback.** No code module in gsd-core; rendered hook markdown instructs the agent to call `mempalace_*` tools (interactive) or `mempalace` CLI (headless). Avoids the not-yet-existing `gsd-tools runCommand` registry (ADR-857 phase-6).
4. **Capture content — verbatim drawers, not AAAK.** AAAK is lossy; we file exact artifact text. AAAK `compress` is offered only as an optional downstream index.
5. **Memory-relationship — three selectable modes, not one.** `mempalace.memory_mode ∈ {augment, kg_backend, replace}`, default `augment`. Mode is read at render time; it changes which MemPalace surfaces the rendered instructions hit (§5.1). This is the direct realization of the user's "all three as selectable options" requirement.
6. **Failure policy — skip everywhere; no gate.** Every hook is `onError: skip`; zero `blocking: true`. Memory failures never halt or fail a phase.
7. **Passive auto-capture is separate and off by default.** MemPalace's native `stop`/`precompact` hooks are a belt-and-suspenders layer behind `mempalace.auto_capture_hooks`; the deliberate loop hooks are the contract.
8. **Wing/room taxonomy is fixed by GSD semantics.** wing = project (from `project_code`/`mempalace.wing`); rooms = `decisions | planning | milestones | problems | learnings`; drawers = verbatim artifacts; KG = decision/relationship facts with phase-dated validity.
## 11. Loop Extension Point mapping
Using the 12 canonical points and per-step `agentRoles` from `loop-host-contract.cjs`. (`into` on a contribution must be a valid role at that point: discuss=`[orchestrator]`, plan=`[researcher,planner,checker]`, execute=`[executor,verifier]`, verify=`[orchestrator]`, ship=`[orchestrator]`.)
| Point | Kind | Ref / into | produces | consumes | `when` | Purpose |
|---|---|---|---|---|---|---|
| `discuss:pre` | contribution | into `orchestrator` | — | — | `mempalace.recall_on_discuss` | Inject wake-up + search recall into discussion |
| `discuss:post` | step | skill `mempalace-capture` | — | `CONTEXT.md` | `mempalace.capture_artifacts` | File CONTEXT → `decisions`; KG decision facts |
| `plan:pre` | step | skill `mempalace-recall` | `MEMORY-RECALL.md` | `CONTEXT.md` | `mempalace.recall_on_plan` | Retrieve prior decisions/patterns/surprises for the plan |
| `plan:post` | step | skill `mempalace-capture` | — | `PLAN.md` | `mempalace.capture_artifacts` | File PLAN → `planning` |
| `execute:wave:post` | contribution | into `verifier` | — | — | `mempalace.capture_artifacts` | Capture confirmed problems→fixes into `problems` |
| `verify:post` | step | skill `mempalace-capture` | — | `SUMMARY.md` | `mempalace.capture_artifacts` | File milestones; mirror `extract-learnings` → KG + `learnings` |
| `ship:post` | step | agent `gsd-mempalace-curator` | — | `UAT.md` | `mempalace.diary_journal` | Diary entry; cross-project tunnels; `sync --apply` |
All steps/contributions are `onError: skip`. No gates.
> **Note on `produces`/`consumes`:** these are the file-data spine the registry topo-sorts on. `mempalace-recall` *produces* `MEMORY-RECALL.md` so the planner can consume it; capture steps only *consume* (they emit to the palace, not to a tracked file artifact), which keeps them leaves in the topo-sort.
## 12. Palace mapping (GSD artifact → MemPalace)
| GSD artifact / event | Wing | Room | Stored as | KG facts |
|---|---|---|---|---|
| `CONTEXT.md` | `<project>` | `decisions` | drawer (verbatim) | `(<project>, decided, <decision>)` `valid_from=<phase date>` |
| `PLAN.md` | `<project>` | `planning` | drawer | `(<phase>, plans, <task>)` |
| `SUMMARY.md` / `UAT.md` | `<project>` | `milestones` | drawer excerpts | `(<phase>, delivered, <capability>)` |
| confirmed bug→fix | `<project>` | `problems` | drawer | `(<bug>, fixed_by, <fix>)` |
| `extract-learnings` (decisions/lessons/patterns/surprises) | `<project>` | `learnings` | drawer per item | typed triples w/ provenance (`source_drawer_id`) |
| superseded decision | — | — | — | `mempalace_kg_invalidate` (sets `valid_to`) |
| cross-repo pattern | two wings | — | — | `mempalace_create_tunnel(label=…)` |
**Mode behavior on this table:**
- `augment` — all *writes* above happen; *reads* (recall) come from GSD native + palace search, palace is never required.
- `kg_backend` — the KG columns route through `mempalace_kg_*`; `gsd-graphify` reads/writes the palace temporal graph instead of `.planning/graphs/`.
- `replace` — drawer + KG columns become the durable store; GSD's learnings/graph reads resolve through the palace.
## 13. The `capability.json` manifest (concrete)
`capabilities/mempalace/capability.json`:
```json
{
"id": "mempalace",
"role": "feature",
"title": "MemPalace memory",
"description": "Cross-session, cross-project memory: deliberate recall before discuss/plan and verbatim capture + temporal-KG sync at phase boundaries, via the MemPalace MCP server and CLI.",
"tier": "full",
"requires": [],
"skills": ["mempalace-recall", "mempalace-capture"],
"agents": ["gsd-mempalace-curator"],
"hooks": [],
"config": {
"mempalace.enabled": { "type": "boolean", "default": false, "description": "Master toggle for the MemPalace memory capability." },
"mempalace.memory_mode": { "type": "enum", "values": ["augment", "kg_backend", "replace"], "default": "augment", "description": "How MemPalace relates to GSD native memory: augment alongside, back the knowledge graph, or fully replace." },
"mempalace.wing": { "type": "string", "default": "", "description": "Palace wing name; empty derives from project_code / project dir." },
"mempalace.recall_on_discuss": { "type": "boolean", "default": true, "description": "Inject wake-up + search recall at discuss:pre." },
"mempalace.recall_on_plan": { "type": "boolean", "default": true, "description": "Produce MEMORY-RECALL.md at plan:pre." },
"mempalace.capture_artifacts": { "type": "boolean", "default": true, "description": "File CONTEXT/PLAN/SUMMARY and learnings into the palace at phase boundaries." },
"mempalace.mirror_kg": { "type": "boolean", "default": true, "description": "Mirror decisions/learnings into MemPalace's temporal knowledge graph." },
"mempalace.cross_project_tunnels": { "type": "boolean", "default": false, "description": "Propose/create cross-wing tunnels at ship:post." },
"mempalace.diary_journal": { "type": "boolean", "default": true, "description": "Write a per-agent diary entry at ship:post." },
"mempalace.auto_capture_hooks": { "type": "boolean", "default": false, "description": "Install MemPalace's native stop/precompact Claude Code hooks for passive mid-session capture." }
},
"steps": [
{ "point": "discuss:post", "ref": { "skill": "mempalace-capture" }, "produces": [], "consumes": ["CONTEXT.md"], "when": "mempalace.capture_artifacts", "onError": "skip" },
{ "point": "plan:pre", "ref": { "skill": "mempalace-recall" }, "produces": ["MEMORY-RECALL.md"], "consumes": ["CONTEXT.md"], "when": "mempalace.recall_on_plan", "onError": "skip" },
{ "point": "plan:post", "ref": { "skill": "mempalace-capture" }, "produces": [], "consumes": ["PLAN.md"], "when": "mempalace.capture_artifacts", "onError": "skip" },
{ "point": "verify:post", "ref": { "skill": "mempalace-capture" }, "produces": [], "consumes": ["SUMMARY.md"], "when": "mempalace.capture_artifacts", "onError": "skip" },
{ "point": "ship:post", "ref": { "agent": "gsd-mempalace-curator" }, "produces": [], "consumes": ["UAT.md"], "when": "mempalace.diary_journal", "onError": "skip" }
],
"contributions": [
{ "point": "discuss:pre", "into": "orchestrator", "fragment": { "path": "fragments/recall-discuss.md" }, "when": "mempalace.recall_on_discuss", "onError": "skip" },
{ "point": "execute:wave:post", "into": "verifier", "fragment": { "path": "fragments/capture-problems.md" }, "when": "mempalace.capture_artifacts", "onError": "skip" }
],
"gates": []
}
```
> **Validation notes (from the registry generator contract):** `id` is kebab-case and equals the folder name; `tier: full` so `requires` may be empty; each `when` key exists in this capability's own `config` block; every `contribution.into` is a valid agent role at its point; `fragment.path` is relative with no `..`; `enum` config carries `values` and a `default` in that set. Because all config keys are new (not in the central `config-schema.manifest.json`), they flow through the **federated** channel automatically — no `loadConfig` whitelist edit.
## 14. Skills & agent the capability owns
- **`mempalace-recall`** (`commands/gsd/mempalace-recall.md`) — markdown skill. Reads `CONTEXT.md`, derives a search query, runs wake-up + `mempalace_search` + `mempalace_kg_query`/`timeline`, writes `MEMORY-RECALL.md` (or an "unavailable" stub). Branches on `memory_mode` for read source. Names MCP-primary / CLI-fallback per run context.
- **`mempalace-capture`** (`commands/gsd/mempalace-capture.md`) — markdown skill. `check_duplicate` → `add_drawer` to the right room → `kg_add` facts (when `mirror_kg`). Idempotent. Branches on `memory_mode` for write target.
- **`gsd-mempalace-curator`** (`agents/gsd-mempalace-curator.md`) — agent. Ship-time curation: diary write, tunnel proposal/creation, `sync --apply` (wing-scoped, never global), and `extract-learnings` → KG mirroring with provenance.
## 15. Rollout phases
| Phase | Deliverable | Gate |
|---|---|---|
| **0 — Spike** | `mempalace init`/`mine`/`search`/`wake-up` against gsd-core's own `.planning/`; confirm wing/room mapping feels right | manual: recall surfaces real prior decisions |
| **1 — Manifest + registry** | `capabilities/mempalace/capability.json` + `gen-capability-registry.cjs --write`; CI staleness gate green; consistency gate (id≠CLUSTERS collision) | `--check` passes |
| **2 — Skills + agent + fragments** | the two skills, the curator agent, two fragment files; `augment` mode only | recall/capture work when invoked manually |
| **3 — Config + federated flow** | all `mempalace.*` keys resolve via federated config; `capability-state` resolver reports the capability | state resolver shows installed/surfaced + hook activity |
| **4 — Modes** | `kg_backend` then `replace`; `gsd-graphify` routing seam | each mode round-trips a decision |
| **5 — Passive hooks + autonomous** | `auto_capture_hooks` installs native hooks; CLI-path capture verified headless (`/gsd-autonomous`, cron) | headless run captures with no MCP |
| **6 — Loop wiring (blocked on ADR-857 phase-6)** | `loop render-hooks` called from `plan-phase.md`/`execute-phase.md`/etc. so hooks auto-fire | end-to-end auto recall/capture |
Phases 1–5 ship value **before** ADR-857's phase-6 cutover (the skills are invocable directly). Phase 6 flips them to automatic.
## 16. Registration tax (per ADR-857 + repo checklists)
1. `capabilities/mempalace/capability.json` (above).
2. `node scripts/gen-capability-registry.cjs --write` → regenerates `capability-registry.cjs` (do not hand-edit).
3. Add `commands/gsd/mempalace-recall.md`, `commands/gsd/mempalace-capture.md`.
4. Add `agents/gsd-mempalace-curator.md` (+ ripple to `scripts/research-profiles.cjs`/`docs/AGENTS.md` only if it's a research-profile agent — the curator is not, so likely n/a).
5. Add `capabilities/mempalace/fragments/recall-discuss.md` + `fragments/capture-problems.md`.
6. Config keys: new ⇒ federated automatically; **no** `loadConfig` whitelist edit.
7. Confirm `id: mempalace` does **not** collide with a `CLUSTERS` key in `src/clusters.cts` (HARD consistency gate) — if it does, match exactly or rename.
8. Surface/profile: `tier: full` ⇒ only the `full` profile; no `core`/`standard` edits.
9. `CONTEXT.md` glossary: add domain terms (Wing, Room, Drawer, Tunnel, Diary, AAAK, memory_mode) — glossary is a review gate.
10. No new `.cts` source module ⇒ skip the new-CLI-module checklist (`.gitignore`/inventory/eslint). If `kg_backend`/`replace` need a routing seam in `gsd-graphify`, that *does* trigger the CLI-module checklist for that file.
11. Docs: how-to ("Enable cross-session memory with MemPalace") + reference (config keys, modes) — missing docs is a PR blocker.
## 17. Open questions
1. **Wing identity** — one wing per repo (`project_code`) vs one per milestone? Recommendation: per-repo wing, milestone/phase as KG validity windows + rooms; revisit if wings get too coarse.
2. **`replace` migration** — do we backfill existing `.planning/graphs/` into the palace KG, or only forward-fill? Recommendation: ship a one-shot `mempalace mine .planning/` + KG import as part of mode switch.
3. **Curator agent tier** — the curator is operational (branches, API calls, error recovery) ⇒ `sonnet` model. Confirm.
4. **Headless MCP availability** — verify MemPalace's stdio MCP server *is* reachable under `/gsd-autonomous`/cron, or commit fully to the CLI path there (FR-T1).
5. **Phase-6 dependency** — accept shipping 1–5 ahead of loop wiring, or hold until phase-6 lands? Recommendation: ship ahead; the manual-invocation value is real and de-risks phase-6.
6. **Diary `agent_name`** — namespace per GSD role (`gsd-orchestrator`) or per repo? Recommendation: per repo+role so diaries don't collide across projects.
---
## Appendix A — MemPalace surfaces used
- **MCP (interactive):** `mempalace_search`, `mempalace_check_duplicate`, `mempalace_add_drawer`, `mempalace_kg_add`/`kg_query`/`kg_invalidate`/`kg_timeline`, `mempalace_create_tunnel`/`find_tunnels`, `mempalace_diary_write`/`diary_read`, `mempalace_sync`, `mempalace_get_taxonomy`/`list_wings`/`list_rooms`.
- **CLI (headless):** `mempalace wake-up --wing`, `mempalace search`, `mempalace mine`, `mempalace sync --wing --apply`, `mempalace hook run`.
- **Native hooks (optional passive layer):** `session-start`, `stop` (every 15 human messages; `silent_save`), `precompact` (captures pre-compaction tool output).
- **Retrieval cost:** wake-up = L0 (identity, ~100 tok) + L1 (auto-summary, ~500–800 tok) ≈ 600–900 tokens.
## Appendix B — Why this is a clean ADR-857 fit
- Contributes **data** (rendered recall/capture instructions), not control flow.
- One **feature bundle**: skills + agent + hooks + config slice + (no) requires.
- **Co-located manifest**, generated registry, **federated** config.
- Uses only the **stable 12-point** surface; additive-only.
- **Default-resilient**: skip-on-error, opt-in, no gate ⇒ absent MemPalace = unchanged loop.
- Calls **no gsd-core internals** ⇒ respects "third-party code deferred"; the glue is first-party, MemPalace runs out-of-process.