Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb2cb2305c | |||
| 8ae1659273 | |||
| 3b1c67a9bf | |||
| c693aa341d |
+211
@@ -11,6 +11,217 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
|
||||
|
||||
---
|
||||
|
||||
## v1.12.2 — 2026-10-22
|
||||
|
||||
Patch release. Headline: **pi `1.4.0`** (audited, see *Changed* below), plus
|
||||
two upstream **security releases** baked into the base image: **Node
|
||||
`v24.22.1`** (8 CVEs) and **git-lfs `v3.8.1`** (4 CVEs). Also **pi-studio
|
||||
`v0.11.1`** (`-studio` tags only), uv `0.13.5`, agent-browser `0.39.2`, and
|
||||
`~/.ssh/config` is Included even if it appears after start (*Fixed*, below).
|
||||
Surveyed 2026-10-22. Unchanged since v1.12.1: mempalace `3.11.0` (PyPI
|
||||
`latest`), pi-atelier `v0.16.0` (`3b42825`, newest tag),
|
||||
pi-observational-memory `022da5e` (= `master`), pi-toolkit `7c05901`,
|
||||
pi-extensions `4c1d28d`, pi-fork `e69725c`, mempalace-toolkit `d5a03f4`. The
|
||||
skillset snapshot needs no refresh (`vendor-mempalace-skill.sh --check`: OK,
|
||||
still `96b840e`). The base image is rebuilt because `rootfs/` changed, so apt
|
||||
and the base tools pinned to `latest` re-resolve. Of those, Node, git-lfs, uv
|
||||
and agent-browser moved upstream (*Changed*, below). gitea-mcp `v1.10.0`, nvim
|
||||
`0.12.6`, fzf `0.74.5`, gitleaks `8.30.1`, bat `0.26.1`, eza `0.23.5`, zoxide
|
||||
`0.10.0`, gosu `1.19`, micro `2.0.15`, tealdeer `1.9.0`, typst `0.15.1`, yq
|
||||
`4.54.1` and playwright `1.64.1` match their newest releases. Each was compared
|
||||
against the v1.12.1 image on tor-ms22.
|
||||
|
||||
### Components that move with this release
|
||||
|
||||
| Component | Baked in v1.12.1 | v1.12.2 | Why |
|
||||
|---|---|---|---|
|
||||
| **pi** | `1.3.0` | **`1.4.0`** | audited, see *Changed* below |
|
||||
| **pi-studio** (`-studio` tags) | `v0.10.2` (`4b4abd1`) | **`v0.11.1`** (`8a410b4`) | newest tag, see *Changed* below |
|
||||
| **Node** (base) | `v24.22.0` | **`v24.22.1`** (or later: NodeSource `node_24.x` at build time) | security release, see *Changed* below |
|
||||
| **git-lfs** (base) | `v3.8.0` | **`v3.8.1`** (or later: `latest` at build time) | security release, see *Changed* below |
|
||||
| uv (base) | `0.13.1` | **`0.13.5`** (or later: `latest` at build time) | see *Changed* below |
|
||||
| agent-browser (base) | `0.39.1` | **`0.39.2`** (or later: `latest` at build time) | see *Changed* below |
|
||||
|
||||
### Upgrade notes
|
||||
|
||||
- **pi-studio's REPL pane now echoes each send by default** (`-studio` tags
|
||||
only). From 0.11.0, *Pane echo* defaults to **Summary**, as in pi-repl: the
|
||||
tmux pane shows each submitted block (up to 20 lines or 2,000 characters)
|
||||
above its output. Before, the default was **Off**. The same default applies
|
||||
to the agent's `studio_repl_send` tool when it passes no `echoMode`. A choice
|
||||
of **Full** made in Studio is kept. To get the old quiet pane back, choose
|
||||
**Off** under the REPL pane's **More**, or set
|
||||
`PI_STUDIO_REPL_ECHO_MODE=off` for the agent tool. What Studio *records* is
|
||||
unchanged: only the code and its output.
|
||||
|
||||
### Changed
|
||||
|
||||
- **pi `1.3.0` → `1.4.0`** (npm `latest`, published 2026-10-21). No breaking
|
||||
changes listed. Fixes that land on how this fleet uses pi: compaction and
|
||||
branch summaries no longer fail with "generation hit the token cap" when
|
||||
reasoning uses most of the old fixed summary limit (#9512, #9075); resumed
|
||||
sessions and `/tree` no longer leave extension tools inactive (#11062); a
|
||||
session no longer breaks after recovering from a reply cut off at the output
|
||||
limit (#11227); codemode scripts wait up to 60 s for a free worker instead
|
||||
of failing (#11184); the terminal is restored when pi exits without its
|
||||
normal teardown (#11170); concurrent extension dialogs no longer lose a
|
||||
promise (#11166); the `grep` tool runs `rg --no-config` (#11203); and
|
||||
extensions can import `@earendil-works/pi-ai/models` (#11156). Audited
|
||||
2026-10-22 on tor-ms22. The only API changes that could reach us are the
|
||||
attribution headers that `before_provider_headers` handlers no longer see,
|
||||
`generateSummary()` ignoring `reserveTokens`, and two removed exports
|
||||
(`mergeProviderAttributionHeaders`, `getPiUserAgent`). None is used by any
|
||||
companion, fleet extension or mempalace-toolkit. pi-agent-core changes only
|
||||
by the new optional `identity` field, so obsmem's `finishTurn` turn cap is
|
||||
untouched. All 58 names our extensions import from pi resolve in 1.4.0.
|
||||
With a copy of tor-ms22's real `~/.pi/agent`, `pi -p` exits 0 with nothing
|
||||
on stderr. The TUI loads the same extensions as on 1.3.0, with no
|
||||
extension issues. Atelier paints in both renderers, and the bridge registers
|
||||
its 45 tools. Full audit next to `ARG PI_VERSION` in `Dockerfile.variant`.
|
||||
- **pi-studio `v0.10.2` → `v0.11.1`** (`8a410b4`, `-studio` tags only). Five
|
||||
upstream releases, 2026-10-19 to 2026-10-22. 0.10.3: IPython prints a value
|
||||
once (`Out[5]: …`), not twice, and after a Quick send the cursor returns to
|
||||
the input box. 0.10.4: Stop works again on a Mac that has a process running
|
||||
as `nobody`. That was a 0.10.2 regression: macOS lists that uid as `-2`, and
|
||||
the 0.10.2 parser refused to stop anything. **It does not affect the
|
||||
image**: inside the container, `ps` shows only the container's own
|
||||
processes, and none has a negative uid. Measured 2026-10-19 on tor-ms22.
|
||||
0.10.2's own `readStopProcessTable` parsed the live process table (9 rows,
|
||||
min uid 1000). Control: a macOS-style `-2` row made it throw "Could not parse
|
||||
process ownership data". 0.10.5: the Quick-send result shows while the
|
||||
cursor stays in the box, and the Prompt toolbar fits on one row on a
|
||||
13-inch screen. 0.11.0: the REPL pane runs Ruby (irb), Java (JShell), Octave,
|
||||
MATLAB, gnuplot and C++ (Cling) when they are on `PATH` (none is baked into
|
||||
this image), a send ends within seconds when its runtime crashes instead of
|
||||
waiting out the 20 s timeout, and the pane-echo default changes (see
|
||||
*Upgrade notes*). 0.11.1: a shorter run status beside **Stop**, and the line
|
||||
above a response shows which one you are on ("9/9"). Dependencies are
|
||||
unchanged: `package-lock.json` differs from 0.10.2's only in the package's
|
||||
own version, and `ws` is still the only runtime dependency. Loaded into pi
|
||||
`1.4.0` with `pi --no-extensions -e <clone>/index.ts -p`, it registers the
|
||||
same four tools (`studio_repl_status`, `studio_repl_send`,
|
||||
`studio_export_pdf`, `studio_export_html`), rc 0, nothing on stderr.
|
||||
Control: without `-e`, none.
|
||||
- **Node `v24.22.0` → `v24.22.1`** (base, NodeSource `node_24.x`). An LTS
|
||||
security release with 8 CVEs in http, dns, tls, permission, crypto and
|
||||
brotli. On 2026-10-21 NodeSource still served only `24.22.0`, so a rebuild
|
||||
then would not have picked it up. On 2026-10-22 it serves
|
||||
`24.22.1-1nodesource1` for both arm64 and amd64.
|
||||
- **git-lfs `v3.8.0` → `v3.8.1`** (base). A security release (2026-10-22)
|
||||
with 4 CVEs. Among them: remote commands sent over SSH are now fully quoted
|
||||
(CVE-2026-69260), and Cookie headers are no longer forwarded to another host
|
||||
after a redirect (CVE-2026-69261).
|
||||
- **uv `0.13.1` → `0.13.5`** (base). Bundled root certificates updated,
|
||||
dropped GET and HEAD requests retried, `uv export` faster with extras, lower
|
||||
peak memory when resolving, and new CPython builds (3.15.1, 3.14.9, 3.13.17).
|
||||
No breaking changes.
|
||||
- **agent-browser `0.39.1` → `0.39.2`** (base). Bug fixes only. The ones an
|
||||
agent notices: a click or double-click on a hidden, disabled or off-viewport
|
||||
element now returns an error instead of reporting success, an ambiguous
|
||||
stale element reference fails instead of picking another element, and an
|
||||
unreadable or invalid policy file denies actions instead of being ignored.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`~/.ssh/config` is Included even if it appears after the container
|
||||
started.** Same rule as the `ssh-lan.conf` fix in v1.12.1. `setup-lan-access.sh`
|
||||
wrote `Include ~/.ssh/config` into `~/.ssh-local/config` only if
|
||||
`~/.ssh/config` was readable at container start, so a file that appeared
|
||||
later (a host provisioned after its first `docker compose up`) was ignored
|
||||
until a restart. Entries *added* to a file that already existed were never
|
||||
affected: ssh reads Included files on every connection, and the bind mount is
|
||||
live. Measured 2026-10-19 on tor-ms22: on the Mac, a newly created file, an
|
||||
atomic replace (write + `mv`, as editors do) and an append each showed up in
|
||||
the container within a second. The line is now written whether or not the
|
||||
file exists. A file that exists but is unreadable is still left out, with a
|
||||
warning on stderr, because ssh would abort every connection. When the file
|
||||
exists at start the generated config is byte-identical to v1.12.1's (checked
|
||||
with and without `ssh-lan.conf`). When it is absent, the only difference is
|
||||
the added Include block. `scripts/smoke-test.sh` gains two checks, Included
|
||||
when created after start and left out when unreadable. Against the v1.12.1
|
||||
script the first fails and the second passes; against this one both pass.
|
||||
|
||||
## v1.12.1 — 2026-10-19
|
||||
|
||||
Patch release. Headline: **`ssh-lan.conf` is Included even if it is created
|
||||
after the container started** (*Fixed*, below). Also **pi-studio `v0.10.2`**,
|
||||
pi-toolkit `7c05901` (new Bedrock defaults for fresh volumes) and gitea-mcp
|
||||
`v1.10.0`. Surveyed 2026-10-19; no other upstream moved. Unchanged since v1.12.0:
|
||||
pi `1.3.0` (npm `latest`), mempalace `3.11.0` (PyPI `latest`), pi-atelier `v0.16.0`
|
||||
(`3b42825`, newest tag), pi-observational-memory `022da5e` (= `master`),
|
||||
pi-extensions `4c1d28d`, pi-fork `e69725c`, mempalace-toolkit `d5a03f4`. The
|
||||
skillset snapshot needs no refresh (`vendor-mempalace-skill.sh --check`: OK,
|
||||
still `96b840e`). The base image is rebuilt because `rootfs/` changed, so apt
|
||||
and the base tools pinned to `latest` re-resolve. Of those, only gitea-mcp moved
|
||||
upstream: `v1.9.0` → `v1.10.0`. uv `0.13.1`, Node `v24.22.0`, nvim `0.12.6`,
|
||||
fzf `0.74.5`, gitleaks `8.30.1`, bat `0.26.1`, eza `0.23.5`, zoxide `0.10.0`,
|
||||
git-lfs `3.8.0`, gosu `1.19`, micro `2.0.15`, tealdeer `1.9.0`, typst `0.15.1`,
|
||||
yq `4.54.1`, agent-browser `0.39.1` and playwright `1.64.1` match their newest
|
||||
releases. Each was compared against the v1.12.0 image on tor-ms22.
|
||||
|
||||
### Components that move with this release
|
||||
|
||||
| Component | Baked in v1.12.0 | v1.12.1 | Why |
|
||||
|---|---|---|---|
|
||||
| **pi-studio** (`-studio` tags) | `v0.10.1` (`76db01f`) | **`v0.10.2`** (`4b4abd1`) | newest tag, see *Changed* below |
|
||||
| pi-toolkit | `3760d90` | **`7c05901`** (or later: CI resolves `main` at build time) | `settings.example.json` defaults move to Claude 5.5 on Bedrock, see *Changed* below |
|
||||
| gitea-mcp (base) | `v1.9.0` | **`v1.10.0`** (or later: `latest` at build time) | additive, see *Changed* below |
|
||||
|
||||
### Changed
|
||||
|
||||
- **pi-studio `v0.10.1` → `v0.10.2`** (`-studio` tags only). Windows fixes. The
|
||||
REPL waits for the runtime's prompt before saying it started. Stopping a
|
||||
session ends its processes. Code goes only to the exactly named session. The
|
||||
selected session follows what you choose. One behaviour change for agents: a
|
||||
`studio_repl_send` that names no session now fails when Studio shows none
|
||||
selected ("No REPL session is selected in Studio …"). Before, it picked a
|
||||
session. Audited 2026-10-19 on tor-ms22. Dependencies are unchanged:
|
||||
`package-lock.json` packages are identical to 0.10.1's, `ws` is the only
|
||||
runtime dependency, and pi peers are `*`. Loaded into this image's pi `1.3.0`
|
||||
with `pi --no-extensions -e <clone>/index.ts -p`, it registers the same four
|
||||
tools as 0.10.1 (`studio_repl_status`, `studio_repl_send`, `studio_export_pdf`,
|
||||
`studio_export_html`), with no extension error and rc 0. Control: the same
|
||||
run against the baked 0.10.1.
|
||||
- **pi-toolkit `3760d90` → `7c05901`:** `settings.example.json` now defaults to
|
||||
`eu.anthropic.claude-opus-5-5`. `enabledModels` becomes opus/sonnet/haiku `-5-5`,
|
||||
and the observational-memory and pi-fork `fast`/`balanced`/`deep` models move
|
||||
to the same family. Also a `*.bak-*` gitignore. **Only a fresh
|
||||
`devbox-pi-config` volume gets these defaults.** On an existing volume, the
|
||||
entrypoint's settings merge fills in only *missing* keys and keeps arrays
|
||||
verbatim, so a model you already set stays. All three IDs are in pi
|
||||
`1.3.0`'s built-in `amazon-bedrock` registry, and `eu.anthropic.claude-opus-5-5`
|
||||
is this session's default model on tor-ms22.
|
||||
- **gitea-mcp `v1.9.0` → `v1.10.0`** (base, `latest` at build time). Additive: three
|
||||
new tools (`compare_commits`, `get_commit_status`, `create_commit_status`) and
|
||||
new methods on existing ones. The fix that matters for stdio clients: logs go
|
||||
to stderr, and `-d` no longer writes to stdout, where it corrupted the protocol.
|
||||
Measured 2026-10-19 with a stdio `initialize` + `tools/list` against
|
||||
gitea.jordbo.se: 1.9.0 lists 58 tools, 1.10.0 lists 61. None were removed,
|
||||
and stdout carried JSON only. The image only bakes the binary; nothing in it
|
||||
configures it.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`~/.config/devbox-shell/ssh-lan.conf` is Included even if it is created
|
||||
after the container started.** `setup-lan-access.sh` wrote the
|
||||
`Include ~/.config/devbox-shell/ssh-lan.conf` line only if the file was
|
||||
readable at container start. A file created afterwards was visible in the
|
||||
container and silently ignored, so ssh fell through to `~/.ssh/config`. Hit on
|
||||
EMB-3HXGNXJ0 on 2026-10-18: its `tor-ms22` override (container key, no
|
||||
passphrase) was skipped. ssh then used the Mac's passphrase-protected key, and
|
||||
`BatchMode` failed with `Permission denied (publickey,…)`. Rerunning the script
|
||||
inside the container fixed it. The line is now written whether or not the file
|
||||
exists. With this image's OpenSSH 10.0p2, an `Include` whose file (or parent
|
||||
directory) is missing is skipped. A file created later is read on the next
|
||||
connection, and a directory at that path is ignored. A file that **exists but
|
||||
is unreadable** makes ssh abort every connection (`Can't open user config
|
||||
file`), so that one case is still left out, now with a warning on stderr.
|
||||
Output is byte-identical to v1.12.0 when the file exists at start.
|
||||
`scripts/smoke-test.sh` gains two checks: Included when created after start,
|
||||
and left out when unreadable. Against the v1.12.0 script the first fails and
|
||||
the second passes. README *Naming LAN peers* no longer says that creating the
|
||||
file needs a restart.
|
||||
|
||||
## v1.12.0 — 2026-10-18
|
||||
|
||||
Minor release. Headlines: **pi 1.3.0**, **mempalace 3.11.0**, **pi-atelier
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
# content-addressed over this file, so any byte change invalidates the
|
||||
# cache. Recommended cadence: once per release for security updates.
|
||||
#
|
||||
# BASE_REBUILD_DATE: 2026-10-18 (v1.12.0 — mempalace 3.11.0, link-pi-extensions.sh, studio-expose and skill doc fixes; apt and base tools re-resolve (upstream on 2026-10-18: uv 0.13.1, gitea-mcp 1.9.0, Node v24.22.0; nvim 0.12.6, fzf 0.74.5 unchanged); previous marker 2026-10-14 / v1.11.1)
|
||||
# BASE_REBUILD_DATE: 2026-10-22 (v1.12.2 — setup-lan-access.sh always Includes ~/.ssh/config; apt and base tools re-resolve (upstream on 2026-10-22: Node v24.22.1 and git-lfs 3.8.1 security releases, uv 0.13.5, agent-browser 0.39.2; gitea-mcp 1.10.0, nvim 0.12.6, fzf 0.74.5 unchanged); previous marker 2026-10-19 / v1.12.1)
|
||||
#
|
||||
# ── Lineage note ─────────────────────────────────────────────────────
|
||||
# Adapted from opencode-devbox/Dockerfile.base (commit before v1.16.2).
|
||||
|
||||
+36
-1
@@ -317,7 +317,42 @@ ARG USER_NAME=developer
|
||||
# extension with no [Extension issues], the bridge registers its 45 tools,
|
||||
# /om:status, /om:view and the /studio commands are offered, and atelier
|
||||
# paints ACTIVITY/READY/TOOLS in both renderers (controls with -ne: none).
|
||||
ARG PI_VERSION=1.3.0
|
||||
#
|
||||
# v1.12.2: 1.3.0 -> 1.4.0 (npm latest, published 2026-10-21T22:48Z). MEASURED
|
||||
# 2026-10-22 on tor-ms22 from isolated npm prefixes for 1.3.0 and 1.4.0, with
|
||||
# the published tarballs unpacked side by side:
|
||||
# 1. NO `### Breaking Changes` section in 1.4.0. Behaviour changes, none of
|
||||
# which reaches us: attribution headers come from pi-ai's client identity,
|
||||
# so `before_provider_headers` handlers no longer see them, and
|
||||
# `generateSummary()` ignores `reserveTokens`. 0 uses of either
|
||||
# (`before_provider_headers`, `generateSummary`, `reserveTokens`) in
|
||||
# pi-extensions, pi-fork, obsmem, pi-atelier and pi-studio. Control: the
|
||||
# same grep finds `registerTool` in 18 files.
|
||||
# 2. pi-agent-core 1.3.0 -> 1.4.0 is NOT byte-identical this time, but every
|
||||
# changed line in dist (4 files) is the new optional `identity` field and
|
||||
# `DEFAULT_AGENT_IDENTITY`; 0 changed lines mention finishTurn, so obsmem's
|
||||
# turn cap is untouched. pi-tui adds only exit-restore methods
|
||||
# (`restoreOnExit`, `getExitRestorePrefix/Suffix`, #11170); atelier's
|
||||
# internals TuiMainScreen / renderLayoutFrame are in the same 10 dist
|
||||
# files. The extension loader only gains the `@earendil-works/pi-ai/models`
|
||||
# alias (#11156). pi-mcp and pi-codemode dist are byte-identical.
|
||||
# 3. Public API: the only removed .d.ts exports are
|
||||
# `mergeProviderAttributionHeaders` (pi-coding-agent) and `getPiUserAgent`
|
||||
# (pi-ai). 0 consumers. All 58 runtime-imported names across pi-toolkit,
|
||||
# pi-extensions, pi-fork, obsmem, pi-studio (0.10.2 and 0.11.1),
|
||||
# pi-atelier, mempalace-toolkit, ~/.pi/agent/extensions and /opt/fleet-pi
|
||||
# resolve in 1.4.0, and in 1.3.0 (control: an injected fake name is
|
||||
# reported missing).
|
||||
# 4. engines.node is still `>=22.19.0`. Peer ranges: atelier >=0.84.0, fork
|
||||
# >=0.75.0, obsmem and studio `*`.
|
||||
# Exercised before tagging, with a copy of tor-ms22's real ~/.pi/agent
|
||||
# (pi-studio swapped for v0.11.1): `pi -p` answers PONG, rc 0 in 10 s (1.3.0:
|
||||
# 9 s), nothing on stderr. In the TUI the [Extensions] list is the same as on
|
||||
# 1.3.0, with no [Extension issues]. The bridge registers its 45 tools, and
|
||||
# TOOLS shows 58 / 64 on both. /om:status, /om:view and the /studio commands
|
||||
# are offered, and atelier paints ACTIVITY/READY/TOOLS in both renderers
|
||||
# (control with -ne: none).
|
||||
ARG PI_VERSION=1.4.0
|
||||
ARG PI_TOOLKIT_REF=main
|
||||
ARG PI_EXTENSIONS_REF=main
|
||||
# Repo URLs default to the canonical gitea origin but are overridable so a
|
||||
|
||||
@@ -1174,12 +1174,20 @@ published image (they are a fact about your LAN, not the image). Alternatively,
|
||||
set `DEVBOX_LAN_AUTOJUMP_PRIVATE=1` to ProxyJump *any* RFC1918 address through
|
||||
the host without naming peers (see `.env.example`).
|
||||
|
||||
Once the file exists it is re-read on every connection, so *edits* take effect
|
||||
immediately — no container or session restart. **Creating it for the first time
|
||||
does need one restart**, because `setup-lan-access.sh` only emits the
|
||||
`Include ~/.config/devbox-shell/ssh-lan.conf` line when the file is already
|
||||
readable at container start (`if [ -r "$SSH_LAN_CONF" ]`). Until then ssh never
|
||||
looks at it — which reads exactly like "my override is being ignored".
|
||||
ssh reads the file on every connection, so creating it and editing it both take
|
||||
effect immediately — no container or session restart. Since v1.12.1,
|
||||
`setup-lan-access.sh` writes the `Include ~/.config/devbox-shell/ssh-lan.conf`
|
||||
line whether or not the file exists yet (ssh skips an `Include` whose file is
|
||||
missing). Images up to and including v1.12.0 wrote that line only if the file
|
||||
was readable at container start. There, a file created afterwards is ignored
|
||||
until a restart, or until you run `bash /usr/local/lib/pi-devbox/setup-lan-access.sh`
|
||||
in the container.
|
||||
That looks exactly like "my override is being ignored". One case still needs
|
||||
action: a file that exists but the container cannot read is left out, because
|
||||
ssh would otherwise refuse every connection. The script then prints a warning at
|
||||
start. Two other permission traps apply to this file as to any ssh config.
|
||||
ssh rejects it if it is world-writable (`Bad owner or permissions`). And on native
|
||||
Linux, the host user's uid must match the container's `developer` (1000).
|
||||
|
||||
#### Giving the container its own key for a peer
|
||||
|
||||
@@ -1289,7 +1297,7 @@ persisted volumes survived, and pi runtime wiring is intact:
|
||||
```bash
|
||||
./scripts/recreate-sanity-check.sh # auto-detects variant
|
||||
./scripts/recreate-sanity-check.sh --expected-image-version 1.8.9 # assert the pi-devbox release tag
|
||||
./scripts/recreate-sanity-check.sh --expected-version 1.3.0 # assert the pi coding agent version
|
||||
./scripts/recreate-sanity-check.sh --expected-version 1.4.0 # assert the pi coding agent version
|
||||
```
|
||||
|
||||
Those are **two different versions**, and the flags are not interchangeable:
|
||||
@@ -1328,7 +1336,7 @@ resolved to `latest` at build time:
|
||||
|
||||
| Component | Pin | Where |
|
||||
|---|---|---|
|
||||
| pi | `1.3.0` | `ARG PI_VERSION` — `Dockerfile.variant` |
|
||||
| pi | `1.4.0` | `ARG PI_VERSION` — `Dockerfile.variant` |
|
||||
| pi-obsmem | `022da5e5554d04dfdc876ed7dac4a42c6b83dfd4` | `ARG PI_OBSMEM_REF` — `Dockerfile.variant` |
|
||||
| pi-atelier | `v0.16.0` | `ARG PI_ATELIER_REF` — `Dockerfile.variant` |
|
||||
| mempalace | `3.11.0` | `ARG MEMPALACE_VERSION` — `Dockerfile.base` |
|
||||
|
||||
@@ -51,8 +51,8 @@
|
||||
# HOST-OWNED PEER POLICY (portable; keeps this image generic)
|
||||
# Named LAN peers are facts about a *specific* host's network, not about the
|
||||
# image — a roaming laptop sees different LANs. So we never bake peer names
|
||||
# here. Instead, if the host bind-mounts ~/.config/devbox-shell/ssh-lan.conf
|
||||
# (the same devbox-shell bridge dir used for shared aliases), we Include it
|
||||
# here. Instead we Include ~/.config/devbox-shell/ssh-lan.conf (the host
|
||||
# bind-mounts the devbox-shell bridge dir, also used for shared aliases)
|
||||
# *before* ~/.ssh/config. That file holds the host's own jump overrides, e.g.
|
||||
# Host pve pve-2 pbs-vm
|
||||
# ProxyJump host
|
||||
@@ -151,8 +151,22 @@ EOF
|
||||
|
||||
# Optional host-owned named-peer jump overrides (portable: lives on the host,
|
||||
# not in the image). Included BEFORE ~/.ssh/config so its ProxyJump wins.
|
||||
#
|
||||
# Included even when the file does not exist yet. ssh skips an Include whose
|
||||
# file is missing, and reads it on the next connection once it appears.
|
||||
# Through v1.12.0 the Include was written only if the file was readable at
|
||||
# container start. A file created later was then visible in the container but
|
||||
# ignored, until a restart (EMB-3HXGNXJ0, 2026-10-18: its tor-ms22 override
|
||||
# was skipped, so ssh fell back to a passphrase key and BatchMode failed).
|
||||
# Only a file that EXISTS but cannot be read is left out. ssh aborts every
|
||||
# connection on one ("Can't open user config file"), which would break all
|
||||
# ssh, git included. A directory at that path is harmless (ssh ignores it).
|
||||
# Measured with this image's OpenSSH 10.0p2; scripts/smoke-test.sh checks
|
||||
# both cases.
|
||||
SSH_LAN_CONF="${HOME}/.config/devbox-shell/ssh-lan.conf"
|
||||
if [ -r "$SSH_LAN_CONF" ]; then
|
||||
if [ -e "$SSH_LAN_CONF" ] && [ ! -r "$SSH_LAN_CONF" ]; then
|
||||
echo "setup-lan-access: $SSH_LAN_CONF exists but is not readable, so it is not Included (ssh would refuse every connection). Fix its permissions, then rerun this script or restart the container." >&2
|
||||
else
|
||||
LAN_CONF_BLOCK=$(cat <<'EOF'
|
||||
|
||||
# Host-owned named-peer jump overrides (bind-mounted; edit on the host).
|
||||
@@ -182,8 +196,17 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
# Same rule as ssh-lan.conf above: Included even when ~/.ssh/config does not
|
||||
# exist yet, so a file that appears after container start (a host provisioned
|
||||
# after its first `docker compose up`) is read on the next ssh. Entries added to
|
||||
# a file that already existed were always picked up: ssh reads Includes on every
|
||||
# connection and the mount is live. Through v1.12.1 the line was written only if
|
||||
# the file was readable at start. Only a file that EXISTS but cannot be read is
|
||||
# left out, because ssh would then abort every connection, git included.
|
||||
INCLUDE_BLOCK=""
|
||||
if [ -r "${HOME}/.ssh/config" ]; then
|
||||
if [ -e "${HOME}/.ssh/config" ] && [ ! -r "${HOME}/.ssh/config" ]; then
|
||||
echo "setup-lan-access: ${HOME}/.ssh/config exists but is not readable, so it is not Included (ssh would refuse every connection). Fix its permissions, then rerun this script or restart the container." >&2
|
||||
else
|
||||
INCLUDE_BLOCK=$(cat <<'EOF'
|
||||
|
||||
# Your own target hosts. Scope reset to match-all so this Include applies to
|
||||
|
||||
@@ -696,6 +696,51 @@ exec_test "git core.sshCommand matches sidecar presence" '
|
||||
else
|
||||
[ -z "$cmd" ] || exit 1; echo "no sidecar, correctly unset"
|
||||
fi'
|
||||
# ssh-lan.conf is Included whether or not it exists at container start. Until
|
||||
# v1.12.0 the Include was written only if the file was readable at start, so a
|
||||
# file created later was silently ignored (EMB-3HXGNXJ0, 2026-10-18). ssh skips
|
||||
# an Include whose file is missing, and picks the file up once it appears, with no
|
||||
# restart. The exception is a file that exists but cannot be read: ssh then
|
||||
# aborts every connection, so that case is still left out. 644 is set
|
||||
# explicitly because ssh rejects a world-writable config file.
|
||||
exec_test "ssh-lan.conf Included even if created after start" '
|
||||
T=$(mktemp -d) && mkdir -p $T/.config/devbox-shell &&
|
||||
HOME=$T DEVBOX_LAN_ACCESS=jump bash /usr/local/lib/pi-devbox/setup-lan-access.sh >/dev/null 2>&1 &&
|
||||
grep -qx "Include ~/.config/devbox-shell/ssh-lan.conf" $T/.ssh-local/config &&
|
||||
HOME=$T ssh -F $T/.ssh-local/config -G lanpeer 2>/dev/null | grep -qx "hostname lanpeer" &&
|
||||
printf "Host lanpeer\n HostName 10.9.9.9\n" > $T/.config/devbox-shell/ssh-lan.conf &&
|
||||
chmod 644 $T/.config/devbox-shell/ssh-lan.conf &&
|
||||
HOME=$T ssh -F $T/.ssh-local/config -G lanpeer 2>/dev/null | grep -qx "hostname 10.9.9.9"
|
||||
r=$?; rm -rf $T; exit $r'
|
||||
exec_test "unreadable ssh-lan.conf left out (ssh would abort)" '
|
||||
T=$(mktemp -d) && mkdir -p $T/.config/devbox-shell && : > $T/.config/devbox-shell/ssh-lan.conf &&
|
||||
chmod 000 $T/.config/devbox-shell/ssh-lan.conf &&
|
||||
HOME=$T DEVBOX_LAN_ACCESS=jump bash /usr/local/lib/pi-devbox/setup-lan-access.sh >/dev/null 2>&1 &&
|
||||
! grep -q "ssh-lan.conf$" $T/.ssh-local/config &&
|
||||
HOME=$T ssh -F $T/.ssh-local/config -G lanpeer >/dev/null 2>&1
|
||||
r=$?; rm -rf $T; exit $r'
|
||||
# ~/.ssh/config gets the same rule as ssh-lan.conf above: Included whether or
|
||||
# not it exists at container start, except when it exists but cannot be read.
|
||||
# Entries added to a file that already existed at start were always picked up
|
||||
# (ssh reads Includes on every connection, and the mount is live). This covers
|
||||
# only a file that appears after start, e.g. a host provisioned after its first
|
||||
# `docker compose up`. Through v1.12.1 that file was ignored until a restart.
|
||||
exec_test "~/.ssh/config Included even if created after start" '
|
||||
T=$(mktemp -d) &&
|
||||
HOME=$T DEVBOX_LAN_ACCESS=jump bash /usr/local/lib/pi-devbox/setup-lan-access.sh >/dev/null 2>&1 &&
|
||||
grep -qx "Include ~/.ssh/config" $T/.ssh-local/config &&
|
||||
HOME=$T ssh -F $T/.ssh-local/config -G ownpeer 2>/dev/null | grep -qx "hostname ownpeer" &&
|
||||
mkdir -p $T/.ssh && printf "Host ownpeer\n HostName 10.8.8.8\n" > $T/.ssh/config &&
|
||||
chmod 600 $T/.ssh/config &&
|
||||
HOME=$T ssh -F $T/.ssh-local/config -G ownpeer 2>/dev/null | grep -qx "hostname 10.8.8.8"
|
||||
r=$?; rm -rf $T; exit $r'
|
||||
exec_test "unreadable ~/.ssh/config left out (ssh would abort)" '
|
||||
T=$(mktemp -d) && mkdir -p $T/.ssh && printf "Host x\n" > $T/.ssh/config &&
|
||||
chmod 000 $T/.ssh/config &&
|
||||
HOME=$T DEVBOX_LAN_ACCESS=jump bash /usr/local/lib/pi-devbox/setup-lan-access.sh >/dev/null 2>&1 &&
|
||||
! grep -qx "Include ~/.ssh/config" $T/.ssh-local/config &&
|
||||
HOME=$T ssh -F $T/.ssh-local/config -G ownpeer >/dev/null 2>&1
|
||||
r=$?; chmod 600 $T/.ssh/config; rm -rf $T; exit $r'
|
||||
# The vendored mempalace snapshot is refreshed MANUALLY per release (see
|
||||
# rootfs/usr/local/share/pi-devbox/skills/VENDORED.md). Through v1.8.4 it also
|
||||
# silently SHADOWED the live skillset copy, so staleness was invisible — and the
|
||||
|
||||
Reference in New Issue
Block a user