* fix(#3479): treat absent default-true mempalace keys as enabled in every prose gate
The #2982 absent-key fix (capture_artifacts === false) was applied to only
one of the sibling gates. Five more hand-written gates in the mempalace
skill/command mirrors and the curator agent still used positive presence
('when <key> is true'), silently skipping default-enabled behavior
(mirror_kg, diary_journal) whenever the key was absent from
.planning/config.json — inverted from the registry-declared defaults.
Corrected sites, each now disabled only on an explicit false:
- skills/gsd-mempalace-capture/SKILL.md step 3 (mirror_kg)
- commands/gsd/mempalace-capture.md step 3 (mirror_kg)
- skills/gsd-mempalace-recall/SKILL.md step 3 (mirror_kg)
- commands/gsd/mempalace-recall.md step 3 (mirror_kg)
- agents/gsd-mempalace-curator.md tasks 1+2 (diary_journal, mirror_kg)
Default-false keys (mempalace.enabled, cross_project_tunnels) keep their
positive-presence gates. New #3479 regression cases in
tests/mempalace-capture-gate-default.test.cjs lock each site's absent/explicit-false
boundary and add a registry-parity guard: no gate file may positively gate
any mempalace boolean whose registry-declared default is true.
* chore(#3479): acknowledge curator size growth from the gate rewording
* chore(#3479): add changeset fragment for PR #3527
---------
Co-authored-by: sim <sim@local>
* test(#2641): add regression for mempalace-capture gate default inversion
* fix(#2641): treat absent capture_artifacts as enabled (schema default)
The gate used `capture_artifacts !== true` which treated absent (undefined)
as disabled — inverted from the capability registry's declared default of
true. Changed to `capture_artifacts === false` (disabled only on explicit
false), matching the sibling gsd-mempalace-recall skill's correct pattern.
* chore(#2641): add changeset fragment
* chore(#2641): backfill changeset PR number 2982
---------
Co-authored-by: sim <sim@local>
* fix(#2414): mempalace-capture rooms example must be dicts with name key
The skill's Step 3 'Add the drawer (verbatim)' example wrote a flat list
of bare strings under rooms: in the embedded mempalace.yaml. mempalace's
miner (detect_room + _mine_impl) indexes room["name"] — a bare-string
list crashes the first 'mempalace mine' invocation with
TypeError: string indices must be integers, not 'str'
Following the documented example verbatim and running the capture crashed
every time, before any file was routed. The bug shipped in #2220's fix
(commit d8af61be4) — the same commit that replaced the invalid --room
flag with detect_room() staging also introduced this rooms: block with
the wrong (string, not dict) entry shape.
Fix: convert each '- <room>' to '- name: <room>' in both shipped source
files (skills/gsd-mempalace-capture/SKILL.md and commands/gsd/mempalace-capture.md).
The two files are byte-for-byte duplicates of the broken block; both are
corrected in lockstep so the installer regenerates consistent copies into
the user's runtime config dir (gsd-pristine/ and gsd-local-patches/ are
install-time-generated, no separate edit needed).
Tests: tests/mempalace-capture-headless-invocation.test.cjs gains a #2414
describe block that extracts the YAML block from each file, parses it with
js-yaml, and asserts every entry under rooms: is a dict carrying a
non-empty 'name' string. A second belt-and-suspenders check forbids any
bare '- <word>' line under rooms: so a future reversion can't slip back in
silently if the YAML parser is ever removed/refactored.
References: #2414; #2220 (same origin commit, distinct failure mode);
mempalace's miner dict-shape contract (miner.py:1708 built-in default
uses [{"name": "general", "description": "All project files"}]).
* chore(#2414): backfill pr:2464 in .changeset/eager-pandas-jump.md
* fix(#2220): replace invalid 'mine --room' with detect_room() staging approach
mempalace mine has no --room flag (only search does) — verified against
MemPalace 3.5.0 official docs (mempalaceofficial.com/reference/cli.html).
The headless capture path used --room, causing every headless/no-MCP run
to fail with 'unrecognized arguments: --room' and silently skip capture.
Fix: replace the flag with a staging-based approach that uses detect_room()'s
documented folder-path match — stage the artifact under a room-named subfolder
with a mempalace.yaml room taxonomy, then run 'mempalace mine <stage> --wing'.
Docs sources cited in-file:
- CLI reference: https://mempalaceofficial.com/reference/cli.html
- Mining guide: https://mempalaceofficial.com/guide/mining.html
- Config guide: https://mempalaceofficial.com/guide/configuration.html
Changes:
- skills/gsd-mempalace-capture/SKILL.md: headless staging instructions
- commands/gsd/mempalace-capture.md: same
- capabilities/mempalace/fragments/capture-problems.md: reference staging
- .gitignore: exclude .planning/.mempalace-stage/
- tests/mempalace-capture-headless-invocation.test.cjs: regression test
- Golden install parity fixtures + workflow-size baseline regenerated
* docs: backfill changeset PR number (#2260)
* fix: regenerate golden fixtures after next merge
Wire the two forward-declared mempalace.memory_mode modes so they actually
route recall/capture instead of silently behaving as `augment`:
- kg_backend: the palace temporal KG is the primary knowledge-graph source;
native .planning/graphs/ is the fallback. Non-KG drawer recall stays additive.
- replace: recall resolves through the palace as the source of truth; native
artifacts are the fallback.
Every mode stays onError:skip and default-resilient — an unreachable palace
degrades to native memory and GSD keeps writing .planning/graphs/, so no memory
is lost. Cross-mode .planning/graphs/ migration remains a documented open
question (PRD/ADR §17), out of scope here.
Surfaces updated (instruction-only contract): recall/capture commands (+ generated
skills), discuss/wave fragments, curator agent, capability.json schema. Docs:
how-to Step 3, CONFIGURATION, FEATURES, CONTEXT glossary. Regenerated
capability-registry, golden install-parity fixtures (mempalace hashes only),
agent-size-baseline. Added a routing-contract + cross-surface parity test.
Incidental (folded per no-defer rule): removed pre-existing unused imports
(spawnSync in capability-registry.test.cjs; fs in issue-498-package-identity.test.cjs)
that eslint flagged in/alongside the touched files.
Closes#2007
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat(#956): add MemPalace memory capability (ADR-857 feature plug-in)
Adds an opt-in, default-resilient ADR-857 feature capability that wires
MemPalace (local-first memory: MCP server + CLI) into the GSD loop:
deliberate recall before discuss/plan and verbatim + temporal-KG capture
at phase boundaries. Three memory modes (augment default; kg_backend and
replace forward-declared). Master gate mempalace.enabled (default off);
every hook onError:skip, zero gates; absent/disabled MemPalace => loop
unchanged. Transport is rendered-markdown only — MemPalace runs
out-of-process, no third-party code in gsd-core (ADR-857 §7).
Capability: capabilities/mempalace/ (manifest + 2 fragments), skills
commands/gsd/mempalace-{recall,capture}.md, agent
agents/gsd-mempalace-curator.md. Registration: ns-context router,
utility cluster, KNOWN_SKILLS, help full.md, model-catalog, copilot
install list, size baselines; regenerated capability-registry +
inventory manifest. ship:post wired into ship.md (wire-on-demand).
HELD on #1196: this capability also declares hooks at discuss:pre and
discuss:post, which are structurally un-wireable until the host-loop
conformance model covers the discuss phase (discuss-phase.md is not in
HOST_LOOP_FILES). The phase6-capstone-conformance gate therefore fails
on exactly those two orphaned points by design — see #1196. Once #1196
lands, rebase onto next and the gate goes green with no further change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(#956): backfill changeset PR number (#1201)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>