diff --git a/docs/plans/2026-10-20_case2-rows.md b/docs/plans/2026-10-20_case2-rows.md index af187c667..3c1d1ca56 100644 --- a/docs/plans/2026-10-20_case2-rows.md +++ b/docs/plans/2026-10-20_case2-rows.md @@ -748,7 +748,8 @@ precheck take `--profile factory|library`, default `library`: `case2-unit.sh` is the 2c step. Root runs it from a root-owned checkout of the reviewed commit outside `/srv/mosaic`, never from the release, because `mosaic` can write the release. It does the following: - It renders the unit from the checkout's template, with the user, the home and the copy id as inputs. -- It refuses unless `User=`, `Group=`, `ExecStart=` and the hardening lines match fixed values. The +- It refuses unless `User=`, `Group=`, `ExecStart=`, `EnvironmentFile=` and the hardening lines match + fixed values. `EnvironmentFile=` is the line in `packages/cli/systemd/mosaic-bus.service.in:24`. The copy id is the one part of `ExecStart=` that varies, so a re-pin to a new copy can re-render the unit (row 195). It must be exactly 40 lowercase hex characters naming a copy that holds `scripts/mosaic`, directly under `/.local/share/mosaic-stack/copies`. That is the rule `copy_root` uses @@ -774,19 +775,29 @@ The precheck refuses unless all of these hold: - `bwrap --unshare-all --ro-bind / / true` exits 0 as ``. Without it no session starts. Row 195 found no bwrap on .53, and `kernel.apparmor_restrict_unprivileged_userns=1`, and .54 may be the same. On a refusal, the precheck prints the sysctl's value and whether `bwrap` is on PATH. -- One marker prompt run through the host's claude with `--system-prompt-file` shows that it replaces - the default prompt. The claude version is printed. +- When some creative instance's harness is claude-code, one marker prompt run through the host's claude + with `--system-prompt-file` shows that it replaces the default prompt. The claude version is printed. + With design r9's model path, Bean and Chet run pi, so this check is skipped unless she adds a + claude-code specialist. +- When an instance's provider is `zai`, `/secrets/claude-session.env` exists, is a regular + file owned by `` at 0600, and sets a nonempty `ZAI_API_KEY` (design 10 step 2d). A pi launch + has no credential check, so without this the first turn is where a missing key shows. The precheck + prints the name and never the value. - `library.sync` fetches her repo read-only, and `library.status` lists R-problems. - No Discord binding exists. It also prints free memory and verifies HOME is `/srv/mosaic`. Tests run against a scratch data root and a local bare repo. Each precheck refusal has a case. The -claude check runs against a fake claude that appends rather than replaces, and that case refuses. +claude check runs against a fake claude that appends rather than replaces, and that case refuses. With +no claude-code instance the claude check doesn't run, and a test shows a missing claude passes. The key +file refuses when missing, at 0644, a symlink, or with `ZAI_API_KEY=` empty. A search of the test +output for the fixture key value finds nothing. `case2-unit.sh` runs against a scratch unit directory. These cases refuse: - an installed unit edited to `User=root` - an edited `ExecStart=` - a template with a hardening line removed +- a template with the `EnvironmentFile=` line removed or pointing elsewhere - a symlink at the unit path - a template with `ExecStartPre=+/srv/mosaic/x` - a template with `ExecStartPre=-+/srv/mosaic/x` @@ -882,7 +893,7 @@ its first turn, as `packages/cli/README.md:439-444` says. ### Out of scope -Placing a key anywhere. The hub's own key on the Z.ai account is design 10 step 2, and it is Jason's. +Placing a key anywhere. The hub's own key on the Z.ai account is design 10 step 2d, and it is Jason's. Any pi launch or live check: running a pi role waits on #383. Chet's Codex login (row B, #428). A credential check for pi launches.