mempalace 3.6.0 -> 3.7.1. Verified against the 3.7.1 source rather than its
changelog, because the risk lands on palaces users cannot reconstruct: legacy
drawers lack the new chunk_total marker and both decision sites trust them, so
no mass re-mine; NORMALIZE_VERSION is 2 in both; chromadb stays <2 so no
index-format migration; no auto-migration exists; logstream.sqlite3 is created
lazily. Downgrade remains possible (3.6.0 has zero references to chunk_total).
Two behaviour changes documented in the CHANGELOG: ALLOW_PEER_WRITER no longer
works on local/chroma palaces, and writer-lock setup failures fail closed.
Neither affects this image's MCP-server-plus-CLI-feeder pattern, which already
serialised on the same lock under 3.6.0 -- the upstream "process-lifetime
single-writer" entry describes tightened escape hatches, not a new lease.
The motivation is the shared central palace: 3.7.1 drops the stale chromadb
SharedSystemClient cache on reconnect (3.6.0 could let a stale in-memory HNSW
segment overwrite a peer's writes, "index count going backwards"), releases the
writer lease on SIGTERM/SIGHUP, and stops treating an interrupted mine as
complete. The fleet primary was upgraded to 3.7.1 and restarted before this tag,
because 3.7.1 refuses writes when the served library drifts and reconnect cannot
clear that. opencode-devbox still pins 3.6.0, so the lockstep is broken until it
cuts its own release.
Vendored mempalace skill snapshot refreshed to skillset 936fed8 (was 63f3bf5).
This closes a gap that had been invisible for two commits: ~/.agents/skills/
mempalace symlinks to the IMAGE-BAKED copy, entrypoint-user.sh creates that link
first, and the skillset deploy never clobbers an existing name -- so in a devbox
container the vendored snapshot always wins and editing skillset alone changes
nothing a container reads. Brings the multi-machine shared-palace section and
the hand-crafted-provenance guard.
pi-global-AGENTS.append.md already carried the three shared-palace damage rules
(a55f636); this tags them into a release.
mempalace-census gets the /usr/local/bin symlink its three siblings have had all
along, plus chmod and a build-time --help smoke check, so RFC-002 Phase A
censuses no longer need an absolute path.
Two new smoke assertions, both confirmed to FAIL against a v1.8.2 container so
they are not tautological: the vendored snapshot must contain the multi-machine
section (a stale manual snapshot is otherwise invisible), and mempalace-census
must be on PATH.
No other pins move: pi stays 0.84.2 (npm latest), pi-atelier v0.8.1, and every
git-ref component was checked against its upstream head and is unchanged.
The managed block already tells agents to load the mempalace skill, but said
nothing about the palace being shared with other machines. Three failure modes
observed tonight while onboarding tor-ms22's feeders, all of which do damage
rather than merely confuse:
- `mempalace sync` prunes drawers whose source files look gitignored, deleted
or moved. On a central palace that describes most of the content, including
every other machine's. Compounded by RFC-001 7.2: feeders now stage inside
the palace root, so a scoped sync can delete the drawers it just filed.
- A client-side timeout is not a failure. The palace is single-writer and one
large mine blocks every client for minutes, so
`[mempalace ext] feed (tick) failed: mine timed out after 30000ms` usually
means the mine COMPLETED. Verified: drawers from a timed-out tick were
present 35 s after the client gave up. A blind retry files a duplicate.
- The `mempalace` CLI has zero references to MEMPALACE_REMOTE_URL, so it always
opens a palace on local disk and can silently disagree with the MCP tools.
Orientation depth stays in the skill; only damage-prevention belongs here,
because this file is always read and the skill's later sections often are not.
Vendored floor snapshot re-synced from pi-extensions 98eb07b, which documents
the mechanism behind fork boundary violations (full parent-transcript
inheritance via index.ts:47) plus the corrected claims about tool restriction
and narrative invention. CI resolves PI_EXTENSIONS_REF from main HEAD, so a
normal build ships the package-owned copy; this keeps the committed floor
identical so scripts/smoke-test.sh's cmp assertion holds either way.
Closes the drift found in 4d4abd9's investigation: the Temporal grounding
guidance was authored straight into this vendored fallback (904fe85) and never
returned to skillset, the declared owner. skillset 63f3bf5 now carries it (with
the wording generalized from "a pi-devbox container" to "a devbox container
(pi-devbox or opencode-devbox)", since opencode-devbox vendors the same skill),
so this snapshot is a pure mirror of the owner again.
VENDORED.md: refresh commands now copy each snapshot FROM ITS OWNER. The
pi-extensions lines previously pointed at <skillset>/skills/pi-extensions/,
which has been a downstream duplicate since a7f3044 co-located the canonical
skill in the package repo — following the old instruction would have silently
regressed the snapshot (e.g. undoing pi-extensions e73cb9f). Provenance bumped
to skillset 63f3bf5 / pi-extensions pkg e73cb9f.
~/.agents/skills/ lives in the ephemeral container layer and is rebuilt by
entrypoint-user.sh on every start from two sources, so an edit made through the
symlink may vanish on the next recreate. Adds to §1 (persistence tiers):
- `readlink -f ~/.agents/skills/<name>` as the first move, with a tier table:
resolves under /workspace/skillset → edit in place; resolves under
/usr/local/share/pi-devbox/skills → image layer, edit the canonical repo and
`sudo cp` to activate for the running session.
- Canonical owner per baked skill (pi-devbox-environment → this repo;
pi-extensions → the package repo's skill/, plus this repo's floor snapshot;
mempalace → the private skillset repo), pointing at VENDORED.md as
authoritative.
- The shadowing gotcha: image-baked links are created first and only when
absent, and deploy-skills.sh --prune-stale leaves foreign links alone, so for
a name present in BOTH sources the image copy wins and a skillset edit has no
effect in the container. Documented with the live example found while writing
this: the baked mempalace snapshot carries a Temporal grounding section
(904fe85) that skillset at its snapshot point (8e8db64) lacks.
- Checklist gets a matching line.
Found while adding session findings to the pi-extensions skill (e73cb9f), where
the same resolve-first step was what kept the edit out of the image layer.
Sync the image-baked "floor" copy at
rootfs/usr/local/share/pi-devbox/skills/pi-extensions/SKILL.md with
pi-extensions e73cb9f, which documents package-registration forensics
(packages[] vs whole-file grep), that /reload suffices for a newly installed
package, and a fork-output caveat — the findings from the fork-guard bug fixed
in 8248688.
Dockerfile.variant copies the pinned package's skill/ over this snapshot at
build time, so the vendored copy is only the fallback floor; it was byte-
identical to the package copy before this change, and keeping it in sync
prevents a silent divergence for builds whose PI_EXTENSIONS_REF predates the
skill.
Discoverability follow-up to baking agent-browser into the base: agents won't
reach for a browser they don't know they have (the exact gap that made this
capability easy to miss). Add a short pointer section to the pi-devbox managed
block — capability, the preset AGENT_BROWSER_EXECUTABLE_PATH, and
`agent-browser skills get core --full` for the command set. Pointer only; depth
stays in the skill. rootfs change → folds into the same base-<hash> rebuild.
CHANGELOG note updated.
Accented filenames on a macOS host are stored decomposed (NFD), so a precomposed
(NFC) remote path in scp/dscp silently fails with 'No such file or directory'.
Document the wildcard / list-first workaround in the pi-devbox-environment skill,
next to the dssh/dscp alias table. (Hit while copying a screenshot named
'Skärmavbild ….png' from the host.)
The base only shipped ncurses-base (xterm-256color, tmux), so SSHing in from
WezTerm/Alacritty/foot/Ghostty degraded to a dumb TERM fallback. Following the
maintainer's ansible common role:
- Dockerfile.base: install ncurses-term (terminfo for wezterm, alacritty,
foot, st, base ghostty entry, and many more).
- rootfs/.../terminfo-src/ghostty.terminfo: thin xterm-ghostty alias
(use=ghostty) — Ghostty connects as TERM=xterm-ghostty, which no distro
packages. Compiled into the system db with 'tic -x'; build asserts it
resolved via infocmp.
- kitty (xterm-kitty) already covered by kitty-terminfo; iTerm2 uses
xterm-256color (ncurses-base).
- smoke-test: assert ncurses-term emulators + xterm-ghostty alias resolve.
Validated end-to-end in a throwaway container: ncurses-term brings the
entries, the alias compiles and equals the ghostty capability set. hadolint
clean, bash -n OK. Base-affecting, rebuilds base-<hash>. No tag.
Baked mempalace SKILL.md now instructs agents to establish current date/time
and compute the delta against the actual diary/drawer timestamp before using
relative terms (yesterday/last week), and explicitly that a container recreate
or fresh session is NOT a day boundary (pi-devbox restarts several times a day).
Phase 1 wake-up section + anti-pattern bullet. CHANGELOG Unreleased.
Baking the mempalace fallback skill fixed *availability*, but mempalace had
no proactive-load directive anywhere (pi-toolkit's global AGENTS.md only
points to pi-extensions), so a new container would still surface it only via
description-matching — the same under-utilisation the pi-extensions directive
was created to fix.
Add a session-start pointer to the pi-devbox managed AGENTS.md block
(pi-global-AGENTS.append.md): gated to pi-devbox containers and conditional on
the MemPalace MCP tools being present. Memory continuity matters most in a
frequently-recreated container — the palace is its only cross-recreate memory.
- pi-global-AGENTS.append.md: '## Session start: load the mempalace skill'.
- smoke-test: assert the pointer merges into the global AGENTS.md at build.
- docs: VENDORED.md, README, CHANGELOG [Unreleased].
Now both skills are complete in pi-devbox: directive + skill file.
pi-extensions = directive (pi-toolkit) + baked skill; mempalace = directive
(this block) + baked skill.
The pi-toolkit global AGENTS.md tells every pi session to read
~/.agents/skills/pi-extensions/SKILL.md at start (the fork/recall
under-utilisation fix), but that skill lived only in the private skillset
repo — so the pointer dangled in any container started without skillset
mounted. Bake fallbacks so the pointer always resolves.
- pi-extensions (Option 1 + Option 2, layered):
* Canonical skill promoted to the public pi-extensions package repo under
skill/ (separate commit there); co-located with the code it documents.
* rootfs/ carries a committed snapshot (the floor).
* Dockerfile.variant copies /opt/pi-extensions/skill/ over the snapshot
after the pinned clone, so a normal build ships the fresh package copy
(recorded via PI_EXTENSIONS_REF) and an old-ref/mirror build still ships
the snapshot. Helper evaluate-extension-usage.py travels with it.
- mempalace (Option 2 only): snapshot in rootfs/. Its consumer skill has no
public package home (mempalace-toolkit ships a different skill,
opencode-mempalace-bridge), so no build-time refresh.
- entrypoint links both (only-when-absent; mounted skillset still wins).
- smoke-test: build-time presence + package-match check + runtime symlink
assertions; readiness gate now waits on the last-linked skill.
- docs: skills/VENDORED.md (provenance + refresh), README, AGENTS.md,
CHANGELOG [Unreleased].
Note: shipped in the NEXT release; v1.2.0 (run 409) predates this.
Ship skills inside the image (independent of any mounted skillset repo):
- rootfs/usr/local/share/pi-devbox/skills/<name>/ symlinked into
~/.agents/skills/ by entrypoint-user.sh (foreign-link, survives volume
recreate, never clobbers a skillset/user skill of the same name).
- New pi-devbox-environment skill: persistence model, host/LAN SSH
reachability, split-DNS mechanisms, interactive-vs-tool-shell alias
gotcha, tmux 0-index, uv-first Python, pi-studio reachability. Agnostic
to host OS / hostnames / domains / nameservers (discovered at runtime).
- Dockerfile.variant appends pi-global-AGENTS.append.md onto pi-toolkit's
pi-global-AGENTS.md (single global slot) so the skill is loaded
proactively; gated on /usr/local/lib/pi-devbox/. Idempotent.
- smoke-test: baked-skill + append-snippet + merged-marker presence and a
runtime symlink assertion.
- docs: README 'Agent skills' section, AGENTS.md layout, DOCKER_HUB.md;
moved studio-tex roadmap to v1.3.0.
pi 0.79.7 -> 0.79.10 (auto-resolved from npm latest at build).