feeders: stage beside the palace, not in ~/.cache; document Phase 1 exposure
Staging default moves out of ~/.cache to <palace-root>/pi-stage (pi) and <palace-root>/opencode-stage (opencode), resolved with mempalace's own palace-path precedence ($MEMPALACE_PALACE_PATH -> $MEMPAL_PALACE_PATH -> ~/.mempalace/config.json -> ~/.mempalace/palace), then dirname. Why: the convos miner keys dedup on the *staged* path, so a wiped stage plus a sync scoped to include it prunes the drawers mined from those sources -- deleting memories, not a cache. Under ~/.cache that state was reachable by anything treating a cache as disposable. Staging inside the palace makes the coupling structural: the stage cannot be wiped without touching the palace itself. Overrides ($MEMPALACE_PI_STAGE / $MEMPALACE_SESSION_STAGE, --stage) are unchanged. Note the old default had never been created on any host, so this closed a latent hazard, not a live one. Measured, and the docs now claim only this much: sync prunes only within the scope it is given -- wing-only, 1299 scanned / 1299 out of scope / 0 removed; scoped at the palace root, 651 kept / 648 out of scope. The previous blanket "sync prunes every drawer" wording overstated it, which is a liability: the next reader disproves the overstatement and discards the real constraint with it. Also in this change: - cron log dir ~/.cache/mempalace-session -> ~/.cache/mempalace-logs. The stage left that namespace, so the old name now read as "the stage". - AGENTS.md: the convos miner *does* check mtime (verified against upstream convo_miner.py); the previous "no mtime check" claim was wrong. - smoke-test assertions use `mktemp -d` for --sessions-dir. One pointed at /tmp, which still held earlier synthetic transcripts, so a --dry-run exported a fake session into the real stage: --dry-run skips the mine, not the export. docs/phase-1-exposure-runbook.md -- the newt/DNS/auth step that RFC 001 and the synlig runbook leave open (runbook section 4, items 2 and 5). Port 8765 at /mcp, newt targets 172.17.0.1, and the authentication is the single shared bearer token (RFC 6.2, decided 2026-08-09) rather than per-device proxy users. The latter cannot work today: mempalace validates exactly one token, and Pangolin's SSO/PIN/password are browser-shaped while every client here is a headless JSON-RPC POST -- enabling that protection breaks the clients it protects. The per-device axis that *does* exist is the feeder's SSH key + per-device inbox. New finding recorded there: a loopback bind does not merely 403 behind a tunnel (already known, runbook 2.4) -- it also silently starts the server with no token at all, because auto-minting is gated on the bind being non-loopback. extensions/pi/README.md: the HTTP transport IS authenticated as of mempalace 3.6.0; the "sessionless and unauthenticated" note dated from the v1.3.0 era. Closes the RFC section 8 Phase-0 hygiene item.
This commit is contained in:
+20
-5
@@ -2,6 +2,16 @@
|
||||
|
||||
Manual invocation of the session-mining wrappers is fine on a machine you actively drive. For long-running devboxes, a weekly automated mine keeps the palace fresh without thinking about it. This directory ships ready-to-use templates for two common scheduling mechanisms, for each wrapper.
|
||||
|
||||
> **pi machines: check whether you need this at all.** If the pi bridge
|
||||
> extension (`extensions/pi/mempalace.ts`) is installed, it already feeds the
|
||||
> palace by itself on `session_shutdown` and a debounced `agent_settled` —
|
||||
> see [`extensions/pi/README.md` § Automatic transcript feeding](../extensions/pi/README.md#automatic-transcript-feeding).
|
||||
> The templates below were written when scheduling was the *only* path for
|
||||
> both harnesses; that's still true for **opencode** (no such extension
|
||||
> exists), but for pi they're now a fallback — useful for a bare pi install
|
||||
> without the bridge, a host-level catch-up job, or belt-and-braces coverage
|
||||
> of a hard container kill (the extension's triggers don't fire on `SIGKILL`).
|
||||
|
||||
> **Before using either**: confirm the toolkit is installed and the wrapper works —
|
||||
> `mempalace-session --dry-run` (and/or `mempalace-pi-session --dry-run`) should list qualifying sessions. If that errors, fix the install before scheduling.
|
||||
|
||||
@@ -171,17 +181,22 @@ rm /tmp/mempalace-session.cron
|
||||
crontab -l | grep mempalace
|
||||
```
|
||||
|
||||
Ensure `~/.cache/mempalace-session/` exists so the log file can be written:
|
||||
Ensure `~/.cache/mempalace-logs/` exists so the log file can be written:
|
||||
|
||||
> This is the **log** directory only. The staging dir — the transcripts the
|
||||
> palace keys its `source_file` dedup on — lives beside the palace
|
||||
> (`<palace-root>/opencode-stage/`), not in `~/.cache`, precisely so it cannot
|
||||
> be cleaned away while the palace survives. Logs here are disposable.
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.cache/mempalace-session
|
||||
mkdir -p ~/.cache/mempalace-logs
|
||||
```
|
||||
|
||||
**Verify a run is happening:**
|
||||
|
||||
```bash
|
||||
# Tail the log the cron entry writes to
|
||||
tail -f ~/.cache/mempalace-session/cron.log
|
||||
tail -f ~/.cache/mempalace-logs/cron.log
|
||||
|
||||
# Or force a run manually to prove the command is well-formed
|
||||
mempalace-session
|
||||
@@ -282,11 +297,11 @@ cat contrib/cron/mempalace-session-devbox.cron
|
||||
(crontab -l 2>/dev/null; cat contrib/cron/mempalace-session-devbox.cron) | crontab -
|
||||
|
||||
# Ensure the log directory exists
|
||||
mkdir -p ~/.cache/mempalace-session
|
||||
mkdir -p ~/.cache/mempalace-logs
|
||||
|
||||
# Verify
|
||||
crontab -l | grep mempalace-session-devbox
|
||||
tail -f ~/.cache/mempalace-session/cron-devbox.log
|
||||
tail -f ~/.cache/mempalace-logs/cron-devbox.log
|
||||
```
|
||||
|
||||
**Uninstall:**
|
||||
|
||||
@@ -35,4 +35,4 @@ CONTAINER_USER=developer
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
# m h dom mon dow command
|
||||
0 3 * * 1 /bin/sh -c 'docker ps --filter "name=^/${CONTAINER}$" --filter "status=running" -q | grep -q . && docker exec -u "${CONTAINER_USER}" "${CONTAINER}" mempalace-session >> "$HOME/.cache/mempalace-session/cron-devbox.log" 2>&1'
|
||||
0 3 * * 1 /bin/sh -c 'docker ps --filter "name=^/${CONTAINER}$" --filter "status=running" -q | grep -q . && docker exec -u "${CONTAINER_USER}" "${CONTAINER}" mempalace-session >> "$HOME/.cache/mempalace-logs/cron-devbox.log" 2>&1'
|
||||
|
||||
@@ -16,4 +16,4 @@
|
||||
PATH=/home/USER/.local/bin:/usr/local/bin:/usr/bin:/bin
|
||||
|
||||
# m h dom mon dow command
|
||||
0 3 * * 1 mempalace-session >> /home/USER/.cache/mempalace-session/cron.log 2>&1
|
||||
0 3 * * 1 mempalace-session >> /home/USER/.cache/mempalace-logs/cron.log 2>&1
|
||||
|
||||
@@ -8,7 +8,7 @@ ConditionPathExists=!%t/mempalace-session.lock
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# The wrapper writes to ~/.cache/mempalace-session/ and the palace.
|
||||
# The wrapper writes to ~/.cache/mempalace-logs/ and the palace.
|
||||
# Keep stdout/stderr in the journal — inspect with:
|
||||
# journalctl --user -u mempalace-session --since today
|
||||
ExecStart=%h/.local/bin/mempalace-session
|
||||
|
||||
Reference in New Issue
Block a user