Sync the self-hosting stack

This commit is contained in:
2026-08-31 21:43:38 +02:00
parent 70db57d367
commit fdd35f2d27
5 changed files with 352 additions and 0 deletions
+109
View File
@@ -9,6 +9,115 @@ one of them changed. An entry says which artefact and which version, so `web 0.1
Every version published to a channel appears here. Nothing is written from memory afterwards: a build
cannot be published without its entry.
## 2026-08-31 — Jarvis can wake itself up, knows what day it is, and can read the web `api 0.102.0` `web 0.125.0` `browser 0.1.0`
**The schema step stops once on the way in — see the upgrade note below.** It is the same guard as
`api 0.101.0`, tripped by a different change.
### Taking this build: the schema step stops once again
Same guard as `api 0.101.0`, tripped by a different change — and for the same reason it is harmless
here. Reshaping scheduled tasks around the conversation drops the columns the old organization-wide
version needed, and the guard refuses a drop without being told to:
```
⚠️ There might be data loss when applying the changes:
• The `Schedule` table will lose columns: kind, autonomy, toolName, assetId, …
Error: Use the --accept-data-loss flag …
```
**Nothing of yours is in those columns.** They existed only in `api 0.101.0`, which was published
this afternoon, and only a wake-up created through the removed Settings screen could have filled
them. Check before you take our word for it:
```sql
SELECT count(*) FROM "Schedule";
```
If that is 0 — which it is on every instance that upgraded straight from 0.100.0 or earlier — the
migration cannot lose anything. If it is not 0, those rows are wake-ups you created today and they
will be dropped; note down what they were before you continue, and recreate them by asking Jarvis
inside the conversation you want them in.
Then let it through **once**, and put the guard back:
- **compose** — set `SCHEMA_ACCEPT_DATA_LOSS=true` in `.env`, `docker compose up -d`, wait for the
api, then remove the line. Leaving it set would let a genuinely destructive change through
unannounced on some future release.
- **Kubernetes** — set the same variable on the `jarvis-migrate` Job, run it to completion, then take
it off. The api pods keep serving the old build while the Job fails, so there is no outage.
### Scheduled tasks are now part of a conversation
`api 0.101.0` shipped these a few hours ago as an organization-wide screen, and that was the wrong
shape. **The "Scheduled work" section and the `schedule:view` / `schedule:manage` permissions are
gone**; if you had started using them, nothing is silently broken — but read on, because what
replaced them is not in the same place.
The thing people actually want this for needs the conversation. Two cases, and both:
- **Waiting.** A rebuild is running, a DNS change is propagating, a maintenance window opens at
03:00. Jarvis leaves itself a note and picks the work up later with everything it had already
established still in front of it.
- **A standing check.** "Look at that file every day at noon." Every occurrence lands in the same
thread, so the seventh day can say "unchanged since Tuesday" instead of reporting into a vacuum.
The old version opened a _fresh_ conversation for each occurrence — which meant "carry on where you
left off" was impossible, because the woken assistant arrived knowing nothing. Now a wake-up belongs
to one conversation, wakes back into it, and appears under a new **Tasks** tab in that
conversation's workspace, beside the documents and the approvals. You pause, run and cancel from
there; you create one by asking ("check this again tomorrow morning"), because the instruction is
written with the conversation around it.
**It runs as whoever scheduled it, checked when it fires rather than when it was written.** If
somebody's access to a machine is revoked, the work they left behind stops reaching it the same day
and says so on its row. Three failures in a row switch a wake-up off, so a broken one becomes a
thing you find rather than a notification you learn to ignore.
Wake-ups inherit the conversation's autonomy and its asset scope; they cannot raise either.
### Jarvis knows what the date is
It did not before, and it did not know that it did not. Asked what day it is, a language model
answers from its training data — confidently, and usually months out. Everything an administrator
asks is dated: "the logs from the last week", "has this certificate expired", "wake me tomorrow at
noon". Each of those was a subtraction from a number nothing was giving it.
The current time is now stated at the start of every turn, and there is a `current_time` tool for
reading the clock during a long run and for converting into a customer's time zone. Nothing to
configure. If you have ever been given a date that was quietly wrong, this is why.
### Jarvis can read the web — if you turn it on
Two new abilities: search the web, and open a page and read it. A real browser, so pages that build
themselves with JavaScript work — vendor advisories, status pages, release notes, consoles.
It also fixes the same class of problem as the clock: a model's knowledge has a cut-off. Versions,
end-of-life dates, advisories and prices are exactly what it will otherwise answer from memory and
get wrong, so it is now told to look things up instead.
**It is off by default, and turning it on is a deliberate act.** An assistant that can read the
internet is a new kind of input into a system that administers your customers. To enable it:
- **compose** — `COMPOSE_PROFILES=browser docker compose up -d`, and set `BROWSER_URL=http://browser:3000`.
- **Kubernetes** — uncomment `09-browser.yaml` in `kustomization.yaml` and `BROWSER_URL` in
`02-config.yaml`.
With it off, the two tools report themselves unavailable and nothing else changes.
**Chromium runs in its own container, never in the api.** The api holds your vault key and talks to
your database; a browser's whole job is to run code written by strangers. Keeping them apart is what
stops a web page being used to read your database, your cache or your cloud provider's metadata
endpoint. The browser container holds no secret, no volume and no database credentials, and the
Kubernetes manifest ships a NetworkPolicy that denies it every private address range. **That policy
needs a CNI that enforces NetworkPolicy** — Calico, Cilium and most managed clusters do; plain
flannel does not, in which case the in-process address check is the only control and it cannot
survive a redirect.
**What comes back is treated as untrusted.** Page text is delimited and labelled as data rather than
instruction, because a page can be written specifically to be read by an assistant with access to
your systems. The tools only read: no clicking, no forms, no signing in.
## 2026-08-31 — Jarvis works while you are asleep, and can finally administer Exchange `api 0.101.0` `web 0.124.0`
Two capabilities, and both are about the half of managed services that does not happen in a