Compare commits

...

4 Commits

Author SHA1 Message Date
pi bff810c1eb docs(dockerfile): sync mempalace stall-protection comment with self-heal
mempalace.ts now self-heals (respawn with capped backoff) instead of
latching unavailable, and the init-timeout default is 300000. Update the
explanatory comment + tunable list (MEMPALACE_MCP_MAX_RESPAWNS,
MEMPALACE_MCP_RESPAWN_BACKOFF_MS). Comment-only; no build/ENV change.
2026-06-26 00:22:43 +02:00
pi 904fe85249 skill(mempalace): teach temporal grounding (recreate != new day)
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.
2026-06-25 22:53:31 +02:00
pi cda488c565 base: yq follows latest (was pinned v4.53.3), gate on major v4
Match the repo's latest-following convention (tealdeer/uv/etc.) and keep the
container in sync with the Mac's brew yq. smoke-test now asserts mikefarah AND
major v4, so a surprise yq v5 fails CI instead of silently breaking
provision.sh. Pin still available via --build-arg YQ_VERSION=vX.Y.Z.
2026-06-25 16:33:27 +02:00
pi 9ab9a28458 base: install mikefarah yq (pinned v4.53.3), drop Debian python yq
Debian/Ubuntu `apt install yq` is kislyuk/yq (Python, v3.x), incompatible
with the mikefarah v4 syntax the cloud-init repo's provision.sh/deploy.sh
require. Replace the apt package with a pinned mikefarah Go binary, mirroring
the existing tealdeer ARG (latest-or-pin) pattern, multi-arch amd64/arm64.
smoke-test.sh now asserts `yq --version` reports mikefarah so CI catches a
regression. CHANGELOG: Unreleased entry.
2026-06-25 16:29:51 +02:00
4 changed files with 89 additions and 11 deletions
+28
View File
@@ -11,6 +11,34 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
--- ---
## Unreleased
### Fixed
- **`yq` is now mikefarah's Go yq, not Debian's Python `yq`.** The base image
previously apt-installed `yq`, which on Debian/Ubuntu is the unrelated
kislyuk/`yq` (a jq wrapper, v3.x) — incompatible with the mikefarah v4 syntax
the `cloud-init` repo's `provision.sh`/`deploy.sh` expect. Dropped the apt
package and install the mikefarah binary instead (multi-arch amd64/arm64,
following the repo's `latest` convention like `tealdeer`/`uv`; pin a tag
with `--build-arg YQ_VERSION=vX.Y.Z`). The build-time `smoke-test.sh` gate
asserts `yq --version` reports `mikefarah` **and** major **v4**, so both a
regression to the Python package and a surprise future yq v5 fail CI.
### Changed
- **Baked `mempalace` skill now teaches temporal grounding.** Added a
*Temporal grounding* rule to the image-baked
`skills/mempalace/SKILL.md` (Phase 1 wake-up + a matching anti-pattern):
before using relative time terms ("yesterday", "last week"), establish the
current date/time and compute the delta against the actual diary/drawer
timestamp. Explicitly calls out that a **container recreate or fresh session
is not a day boundary** — pi-devbox restarts several times a day, so two
entries minutes apart can straddle a recreate. Fixes agents mislabelling
same-day sessions as "yesterday".
---
## v1.2.2 — 2026-06-24 ## v1.2.2 — 2026-06-24
Patch release: pick up **pi `0.80.2`** (npm `latest`) and **mempalace `3.5.0`**, Patch release: pick up **pi `0.80.2`** (npm `latest`) and **mempalace `3.5.0`**,
+36 -10
View File
@@ -51,7 +51,8 @@ ENV DEBIAN_FRONTEND=noninteractive
# See the bundled `dot-watch` helper for live .dot -> PNG # See the bundled `dot-watch` helper for live .dot -> PNG
# re-render (handy with pi-studio's image preview). # re-render (handy with pi-studio's image preview).
# imagemagick — image conversion / resizing for thumbnails, etc. ~50 MB. # imagemagick — image conversion / resizing for thumbnails, etc. ~50 MB.
# yq — YAML-aware companion to jq. # (yq is NOT apt-installed: Debian's `yq` is the unrelated Python tool;
# mikefarah's Go yq is installed as a pinned binary further down.)
# socat — TCP relay. Powers `studio-expose`, which bridges # socat — TCP relay. Powers `studio-expose`, which bridges
# pi-studio's container-loopback server to the container's # pi-studio's container-loopback server to the container's
# external interface so a published port can reach it. # external interface so a published port can reach it.
@@ -66,7 +67,6 @@ RUN apt-get update && \
openssh-client \ openssh-client \
gnupg \ gnupg \
jq \ jq \
yq \
ripgrep \ ripgrep \
fd-find \ fd-find \
tree \ tree \
@@ -289,15 +289,21 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64"
# Always installed in the base. Set INSTALL_MEMPALACE=false at base-build # Always installed in the base. Set INSTALL_MEMPALACE=false at base-build
# time to shave ~300 MB. # time to shave ~300 MB.
# #
# Stall protection (fixed 2026-06-13): mempalace-mcp is launched by the # Stall protection (fixed 2026-06-13; self-heal added 2026-06-25):
# `mempalace.ts` pi extension from mempalace-toolkit (cloned below). That # mempalace-mcp is launched by the `mempalace.ts` pi extension from
# extension now applies a per-REQUEST timeout in its JSON-RPC client and # mempalace-toolkit (cloned below). That extension applies a per-REQUEST
# kills the child on stall, so a virtiofs cold-open of chroma.sqlite3 / # timeout in its JSON-RPC client and kills the child on stall, so a virtiofs
# HNSW load can no longer hang the pi TUI uninterruptibly. Tunables: # cold-open of chroma.sqlite3 / HNSW load can no longer hang the pi TUI
# uninterruptibly. A stall-kill is no longer a permanent latch either: the
# next tool call respawns the server with capped exponential backoff (the
# budget resets on any successful response). Tunables:
# MEMPALACE_MCP_TIMEOUT_MS (default 60000), MEMPALACE_MCP_INIT_TIMEOUT_MS # MEMPALACE_MCP_TIMEOUT_MS (default 60000), MEMPALACE_MCP_INIT_TIMEOUT_MS
# (default 120000); 0 disables. A standalone stdio-watchdog shim is NOT # (default 300000 — generous so a genuine first cold-open isn't killed),
# needed — the extension already owns request/response correlation. See # MEMPALACE_MCP_MAX_RESPAWNS (default 2; 0 disables self-heal),
# CHANGELOG.md "Unreleased > Fixed". # MEMPALACE_MCP_RESPAWN_BACKOFF_MS (default 1000); timeouts of 0 disable.
# Defaults live in the extension, so no ENV is needed here. A standalone
# stdio-watchdog shim is NOT needed — the extension already owns
# request/response correlation. See CHANGELOG.md "Unreleased > Fixed".
ARG INSTALL_MEMPALACE=true ARG INSTALL_MEMPALACE=true
# Pin to a known-good version. Bump deliberately, not implicitly: an # Pin to a known-good version. Bump deliberately, not implicitly: an
# unpinned install silently swept in mempalace 3.3.x/3.4.0 with a broken # unpinned install silently swept in mempalace 3.3.x/3.4.0 with a broken
@@ -404,6 +410,26 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64"
chmod +x /usr/local/bin/tldr && \ chmod +x /usr/local/bin/tldr && \
tldr --version tldr --version
# ── yq (mikefarah) — YAML processor, jq's companion for YAML ─────────
# Installed as the mikefarah Go binary — NOT Debian's `yq` apt package, which
# is the unrelated Python kislyuk/yq (a jq wrapper with different syntax and
# version line, e.g. 3.x). The cloud-init repo's deploy.sh/provision.sh
# require mikefarah yq v4 (the unrelated Debian python yq is v3.x). Follows
# the repo's `latest` convention (like tealdeer/uv/etc.); the smoke test pins
# the contract to major v4, so a future yq v5 fails CI instead of silently
# breaking provision.sh. Pin a specific tag with --build-arg YQ_VERSION=vX.Y.Z.
ARG YQ_VERSION=latest
RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "amd64" ;; arm64) echo "arm64" ;; *) echo "amd64" ;; esac) && \
V="${YQ_VERSION}" && \
if [ "$V" = "latest" ]; then \
V=$(curl -sI --retry 5 --retry-delay 5 --retry-all-errors "https://github.com/mikefarah/yq/releases/latest" | awk 'tolower($1)=="location:" { sub(/\r$/,"",$2); n=split($2,a,"/"); print a[n] }'); \
fi && \
[ -n "$V" ] && \
echo "Installing mikefarah yq ${V}" && \
curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "https://github.com/mikefarah/yq/releases/download/${V}/yq_linux_${ARCH}" -o /usr/local/bin/yq && \
chmod +x /usr/local/bin/yq && \
yq --version
# ── AWS CLI v2 (for SSO/Bedrock authentication) ───────────────────── # ── AWS CLI v2 (for SSO/Bedrock authentication) ─────────────────────
RUN ARCH=$(case "${TARGETARCH}" in \ RUN ARCH=$(case "${TARGETARCH}" in \
amd64) echo "x86_64" ;; \ amd64) echo "x86_64" ;; \
@@ -43,6 +43,29 @@ Run these immediately when a session begins, before responding to the user:
Do NOT announce this to the user. Just do it silently to orient yourself. Do NOT announce this to the user. Just do it silently to orient yourself.
### Temporal grounding — compute time deltas, don't guess
Diary entries and drawers carry real timestamps (`timestamp`, `created_at`).
Before describing *when* something happened — "yesterday", "earlier today",
"last week", "a while back" — **establish the current date/time first and
compute the delta against the actual timestamp.** Get "now" from the injected
session date or by running `date` in a shell; never infer it.
**A container recreate or a fresh session is NOT a day boundary.** A pi-devbox
container is frequently restarted — often several times within the *same* day —
and each restart begins a new session with a fresh wake-up. Do not reason "new
session ⇒ last session was yesterday": two diary entries 90 minutes apart can
straddle a container recreate. The only authoritative clock is the timestamp on
the memory, not the session/container boundary.
**Practical rule:** prefer explicit, checkable phrasing — e.g. "earlier today,
~8h ago (both 2026-06-25)" — over a vague relative term. If you catch yourself
about to write "yesterday" / "last week", subtract `now entry.timestamp` and
state the computed result. (Remember timestamps may be UTC while the wall clock
is local — reconcile the offset before computing the delta.) Note too that
session feeders can lag up to a week (see *Multi-harness palace*), so a recent
absence in `wing_conversations` is not proof nothing happened.
### Phase 2: Active Session (during work) ### Phase 2: Active Session (during work)
#### Search Before You Speak #### Search Before You Speak
@@ -294,6 +317,7 @@ Entity-relationship triples with temporal validity. Query with `mempalace_kg_que
## Anti-Patterns ## Anti-Patterns
- **Don't guess when you can search.** If a question touches past work, search first. - **Don't guess when you can search.** If a question touches past work, search first.
- **Don't infer elapsed time from session or container boundaries.** A restart isn't a new day. Compare the actual timestamp (`timestamp` / `created_at`) against the current date/time before saying "yesterday", "last week", etc.
- **Don't skip the diary.** A session without a diary entry is a session forgotten. - **Don't skip the diary.** A session without a diary entry is a session forgotten.
- **Don't summarize drawer content.** File verbatim — the embedding model needs the original words. - **Don't summarize drawer content.** File verbatim — the embedding model needs the original words.
- **Don't mine .git directories or node_modules.** The CLI miner respects .gitignore by default. - **Don't mine .git directories or node_modules.** The CLI miner respects .gitignore by default.
+1 -1
View File
@@ -76,7 +76,7 @@ run "mempalace-mcp" "mempalace-mcp --help"
run "pandoc" "pandoc --version" run "pandoc" "pandoc --version"
run "graphviz (dot)" "dot -V" run "graphviz (dot)" "dot -V"
run "imagemagick" "magick --version" run "imagemagick" "magick --version"
run "yq" "yq --version" run "yq (mikefarah v4)" "yq --version | grep -qE 'mikefarah.*version v4'"
run "tldr (tealdeer)" "tldr --version" run "tldr (tealdeer)" "tldr --version"
run "socat" "socat -V" run "socat" "socat -V"
run "studio-expose helper" "test -x /usr/local/bin/studio-expose" run "studio-expose helper" "test -x /usr/local/bin/studio-expose"