Repository navigation
Description
[Frontier] [CUT15-01] Install S15 fresh on jit-vm with owner acceptance and a recoverable install
Body revised on 2026-11-03 for the owner's final decisions; the previous body (Pi-era target, Proxmox jit-work VM) remains in the issue edit history.
Parent
S15 — #316. Canonical spec: docs/specs/S15-conversational-autonomy.md.
Model tier
Frontier: production installer, service identity, host prerequisites for a protected nested VM, rollback of a failed install and owner acceptance of an exact build/policy.
Owner decisions (2026-11-03, final)
- Retire the Pi. Jit runs on the Proxmox VM
jit-vmonly. Start fresh: no Pi data (legacy or S14) is migrated. The Pi is not changed by this work; the owner retires it after cutover. - Single-host topology: the S15 controller runs on
jit-vm, and the working VM is a nested KVM guest that Jit creates and manages there (VM15-02 [Frontier] [VM15-02] Run the working VM as a Jit-managed nested KVM guest on the controller host #366, SETUP15-01 [Frontier] [SETUP15-01] Create the working computer automatically during S15 setup on KVM hosts #369). Owner-supplied VMs stay optional for extra compute (POOL15-01 [Frontier] [POOL15-01] Place work across several enrolled working computers in one team pool #370). Telegram botremoved 2026-11-06 (ADR 0085); no channel setup is needed.jit-vmhas 10 vCPU / 20 GB (verified 2026-11-03: 10 CPUs, 19 GiB usable, vmx/AVX, no AVX2,/dev/kvmusable, 195 GB root with ~152 GB free).- The old S14 test installs on
jit-vm(service usersjit/jit-s14, units, subuid ranges, Podman storage, 16 loop disks, evidence files) are test-only and are removed before the production install (authorized).
Context to read
AGENTS.md; CONTEXT.md; docs/agents/workflow.md; docs/specs/S15-conversational-autonomy.md; docs/adr/0064, 0067; install.sh; ops/package/installer/**; ops/evidence/s15-install-service.ts (the arm64 staging installer to generalize); src/s15/main.ts (S15RuntimeConfig, runS15); docs/runbooks/s14-default-cutover.md; tests/runtime-selection.test.ts.
Deliverable
- Installer (code,
Refs #341):install.sh --s15explicitly selects the S15 runtime as a separate installation (service identity, state, unit, journald namespace), never reinterpreting legacy/S14 configs or touching their data. It installs the host prerequisites the nested working VM needs (QEMU packages,kvmgroup for the service identity, lingering user manager), installs the exact release, generates the credential-free S15 runtime config without owner input, runsinit, enables the service and letssetupcreate the working computer automatically. A failed install leaves a recoverable state: the new unit is stopped/removed, the prior release (if any) stays active, other installations are untouched, and re-running repairs idempotently.--s15 --uninstallstops/removes the service and retains data like the other runtimes. Upgrade switches the release atomically with a health check and rolls back to the previous release on failure. - Live install on
jit-vm(orchestrator): remove the old S14 test installs, install the exact final reviewed build, verify health and the automatically created working computer, and record exact SHA/hashes in.local. - Owner acceptance (owner steps, last): owner password, Codex device login for the S15 service identity, the GitHub sandbox token, optional Google consent, review of the exact build/policy/rollback evidence, explicit acceptance, first ordinary conversation in the Web/PWA, then retiring the Pi.
Implementation steps
- Extend install.sh/installer with
--s15(mutually exclusive with--s14/--legacy), the S15 plan lines, prerequisites and dry-run coverage. - Generate the S15 runtime config from detected facts (installation id, directories, origin/access model consistent with the S14 installer, the approved Codex subscription route catalog, no policy, no budget, no personal GitHub rule, local working-computer pool).
- Install a hardened system unit for the controller; the nested VM runs outside the controller cgroup per VM15-02 so restarts/upgrades do not kill it.
- Transactional install/upgrade with rollback of the release symlink and unit on failure; never delete another installation's data.
- Runbook
docs/runbooks/s15-install.md: install, upgrade, rollback, uninstall, owner steps.
Acceptance criteria
-
install.sh --s15on a fresh host yields a running S15 controller with a ready working computer and no hand-edited files. - Legacy/S14 selection and omitted-runtime configs are never reinterpreted; other installations are untouched (fixtures).
- An injected failure at each install/upgrade step leaves the prior state recoverable and a re-run repairs it.
- The live install on
jit-vmruns the exact reviewed build with fresh state; old S14 test installs are gone; the Pi is unchanged. - Owner acceptance binds the exact build, host, policy revision and activation time; the first Web conversation performs real approved work and human-required gates behave as proved on [Frontier] [EVID15-01] Prove the protected boundaries and the GitHub scenario on the tested build #340.
Tests and evidence
- Installer/runtime-selection fixtures (
--dry-run --root) for--s15, conflicts with--s14/--legacy, prerequisites, generated config shape and no-secret config. - Failure-injection fixtures for each step → recoverable state; upgrade health-check failure → previous release restored.
- Live install log and service/working-computer health on
jit-vmin.local, summarized here. - Owner acceptance record (owner step).
Requirements
FR-18/23/35/36/37/38; NFR-04/07/08/10/12/14. Acceptance: S15-AC16.
Blocked by
- [Frontier] [VM15-02] Run the working VM as a Jit-managed nested KVM guest on the controller host #366 VM15-02, [Frontier] [SETUP15-01] Create the working computer automatically during S15 setup on KVM hosts #369 SETUP15-01 / [Frontier] [POOL15-01] Place work across several enrolled working computers in one team pool #370 POOL15-01, [Frontier] [CHAN15-01] Talk to S15 Jit through a bound Telegram bot #368 CHAN15-01 / [Frontier] [WORK15-02] Keep owner stall replies that wait to resume a duty durable across restart #367 WORK15-02 (code the installer composes).
- [Frontier] [POLICY15-02] Install the first standing policy from the Web UI on a fresh install #384 POLICY15-02 and [Frontier] [GIT15-04] Connect GitHub repositories from the Web UI on a fresh install #385 GIT15-04 (first standing policy and GitHub connection from the Web UI; without them a fresh install cannot do work without a config edit), [Frontier] [BROW15-02] Enable the protected browser on a fresh install without config edits #380 BROW15-02, [Frontier] [MODEL15-03] Renew route credentials before listing so a fresh process survives token expiry #381 MODEL15-03.
- [Frontier] [EVID15-01] Prove the protected boundaries and the GitHub scenario on the tested build #340 EVID15-01 for live acceptance evidence. Owner steps are last.
Contracts used/delivered
Uses S15RuntimeConfig, runS15, VM15-02/SETUP15-01/CHAN15-01 setup paths. Delivers the --s15 installer selection, generated config, unit and runbook.
Out of scope
Migrating Pi or S14 data; changing the Pi; deleting the owner's Lima VMs on the Mac without asking.
Do not
Do not touch the Pi; do not import legacy/S14 state; do not put credentials in config, logs or the repo; do not install a policy, budget or personal GitHub rule on the owner's behalf; do not add AI attribution; do not merge the implementation PR yourself.
Definition of done
Installer PR: bun install --frozen-lockfile, bun run typecheck, bun run test, git diff --check pass; PR body Refs #341 (owner steps remain). This issue closes only after the live install and explicit owner acceptance are recorded.
Owner revision 2026-11-06
Telegram was removed from Jit (ADR 0085, #441) and the default authority became Grok-style (ADR 0084, #442). Telegram steps and evidence in this issue no longer apply; the first conversation and notifications use the Web/PWA.
Activity
chayapats commentedon Nov 3, 2026
Status (2026-11-03): every S15 implementation slice is merged and composed. Main
c5f476eaf5478b585e9fbdc8c377ed918d6f408econtains the opt-in S15 runtime (init/setup/serve --s15,adoption --s15 --report), with S14 still the default and omitted-runtime configs never reinterpreted. MIG15-01 (#336, PR #364) delivered staged adoption with source preservation, a single-writer fence, conditional rollback and a read-only adoption status.The exact final build is staged on a new disposable arm64 controller with no owner or policy installed; see the evidence summary on #340. No existing installation (Pi, jit-vm, jit-arm) has been changed.
Remaining for this ticket, all owner-only: complete the #340 live evidence prerequisites, then decide the exact installation, host/topology, build, policy revision, optional personal GitHub rule and any operating budget for activation, plus the rollback window. This issue stays open until that explicit owner acceptance and the named-host preservation/rollback evidence exist.
[-][Frontier] [CUT15-01] Adopt the reviewed S15 release with owner acceptance and rollback[/-][+][Frontier] [CUT15-01] Install S15 fresh on jit-vm with owner acceptance and a recoverable install[/+]fix(install): deliver the S15 owner link before the VM wait, install …
chayapats commentedon Nov 3, 2026
Installer code merged in #379 (merge 7f06716):
install.sh --s15creates the separatejit-s15installation (controller identity, QEMU identityjit-s15-vmmwith a single-launcher sudoers rule, generated credential-free config, hardened unit, systemd-bound registry proxy socket, transactional install/upgrade/uninstall with rollback, owner link delivered right after the health check, controller-only fallback without a kvm group). Runbook: docs/runbooks/s15-install.md. Still open here: the protected browser on the install (#380), the Schway renewal adoption (#381), the live install on jit-vm, and the owner acceptance steps.chayapats commentedon Nov 3, 2026
Production install on
jit-vm(2026-11-03)Installed:
jit-s15from branchjit/341-installer-live-fixesatd129276d8d8379c83840bcccb7618266b9db0d24, which is main9082327plus the installer-only fixes in #390 (#389). The release ID is5884d9c6-8ecc-4cc9-9c5d-e0ecd16400f1. State is fresh; nothing was migrated from the Pi or from any S14/legacy install.How:
./install.sh --s15 --yesran under a pty whose output was discarded, so the first-owner link went only to that pty, was never seen, and has expired. The install log and thejit-s15journal contain notoken=. The owner gets a fresh link by re-runninginstall.sh --s15from anssh -tterminal, as the runbook says.Result: every step passed:
preflight…dependencies…owner-link-prepare→service-install→service-start→health→owner-link→working-computer.Verified on the host after install:
jit-s15.service(Userjit-s15, 0 restarts) andjit-s15-vm-proxy.socketare active; the sign-in page answers 200 on127.0.0.1:3002.jit-work-cbad1842eae9) runs asjit-s15-vmm(inkvm).jit-s15is not inkvm./etc/sudoers.d/jit-s15-vmmallows only/opt/jit-s15/libexec/jit-s15-vmmasjit-s15-vmm, and the journal shows the controller reaching QEMU only through that launcher.vm.local: trueandvm.vmm.user: jit-s15-vmm, with policy, budget, GitHub, Google and browser config all null (Web-managed).state/browser-engine/…/.jit-verified).Failures found on the way (all recoverable, as designed):
dependencies: apt ran undertimeoutwith the terminal as stdin and was stopped by SIGTTOU. I stopped it by hand; the installer reportedFailed at dependenciesand dpkg was clean. Fixed in fix(install): pass the S15 owner-link pipe flag and keep package managers off the terminal #390.Failed at release: my staged copy was group-writable. This is a correct refusal by the trusted-input rule, not a product bug.Failed at owner-link-prepare: the S15 owner-link argv lacked--output-fd 3. The fresh-install rollback removed the new state, as designed. Fixed in fix(install): pass the S15 owner-link pipe flag and keep package managers off the terminal #390.After #390 merges, I will re-run
install.sh --s15from main on this host. That exercises the in-place upgrade/repair path; the result will follow here.Remaining owner steps (Web UI only; the exact checklist is in the ignored owner notes):
/settings/provider./resources/telegram./resources/websites./setup#s15-setup-rules./resources/github, then the updated rules at/rules.Retiring the Pi stays an owner step after acceptance.