Sync the self-hosting stack

This commit is contained in:
2026-09-26 15:49:04 +02:00
parent 1aa6e9d05f
commit 248d6c2d52
8 changed files with 274 additions and 18 deletions
+82
View File
@@ -9,6 +9,88 @@ 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-09-26 — Attach files to a message, and upload files to a conversation's workspace `api 0.115.0` `web 0.140.0`
**Drop, paste or pick files into the composer.** Pictures, text files and PDFs, up to 10 per
message, upload as you add them and travel with the message; they are not listed in the
conversation's workspace. A text file or a PDF can be up to 10 MB. A picture is made smaller in your
browser before it leaves — scaled to 2,048 pixels on its long side and stripped of camera metadata —
so one of up to 40 MB can be dropped, and a full-page screenshot is scaled to fit rather than
refused for its height, up to 100 megapixels. The server checks what each file actually contains,
whatever its name says, and strips metadata again. SVG and HTML, Office documents, archives,
executables, and key or secret files are refused, and so is a text file that holds a private key;
scripts and public certificates are accepted as text.
**Upload files to the workspace** from the Documents panel, by button or by drop, up to 10 MB each.
They become documents everyone in the conversation sees, marked with who uploaded them. A picture
is kept as it was dropped, and the server strips its metadata. Your browser changes it only when it
has to: it scales a picture larger than 8,000 pixels on a side or 40 megapixels in all, turns a
sideways phone photo upright, converts a format Jarvis does not store, such as HEIC, when the
browser can read it, and re-encodes a picture over 10 MB at its full size until it fits — the
upload says so when it does. A download gives back the picture that was stored. A large picture
also travels with a smaller copy made for the model, so the assistant can look at it; people are
always served the picture itself.
**The assistant can use them.** It reads text files and the text of PDFs — extracted once, when the
PDF arrives; a scan with no text layer has none — and looks at pictures. **What the model
receives:** an attached picture is sent as the picture itself when the assistant answers the
message it came with, and again only if the assistant asks to look at it; a file's text is sent as
the passages the assistant reads. If the model refuses pictures, the turn is answered without them
and the picture says the model could not see it. This is the same on your own provider and on the
managed model. **If you use the managed model,** what it receives now includes the files and
pictures people attach, when the assistant uses them.
**Who can:** exactly who can send a message in the conversation. **Public links never include
attachments or uploaded files**; a guest sees that a message had attachments, nothing more. The
assistant's replies are still included, and a reply that describes a file describes it to the guest
too.
**A sent file can be removed** by whoever attached it, or by the conversation's owner. It is deleted
for everyone, the model stops receiving it from the next request on, and the message keeps a note
saying who removed it. That cannot take back what the assistant already read: whatever it quoted in
its replies or in tool output stays in the conversation.
**Pictures from other sites are no longer loaded until somebody clicks them**, in replies, in
workspace documents and on public links — in conversations written before this version too. A reply
can point a picture at any address, and fetching it tells that site the conversation is being read;
its address can carry text out of the conversation. The address is shown instead, and a click loads
it. Pictures written into the text itself (`data:` images) now display, where they used to draw as
an empty frame.
**On the audit trail:** an upload to a workspace is `document.upload` and a removal is
`attachment.remove`. An administrator who attaches or removes a file in a conversation they reach
only through their role is also recorded as `conversation.admin_attachment`, and a message they
send records how many files it carried. These entries hold ids, kinds and sizes, never a file's
name.
**Self-hosters:** api and web; publish the api first. The schema gains two tables, three types and
new columns beside a captured file's bytes, applied automatically when the api starts; it only
adds, so the schema guard has nothing to refuse. No new environment variable. **Your reverse proxy
must accept request bodies of 13,376 KiB on `/api/uploads/`** ([README](README.md#your-reverse-proxy-has-three-requirements));
below that, files between its limit and 10 MB fail with the proxy's own error while smaller ones
keep working. The web image's own nginx already does. **The api needs more memory:** an upload of
10 MB with its model copy was measured at about 310 MB while it is checked, so each api process now
takes three uploads at a time, and `04-api.yaml` raises the api's memory limit from 2Gi to 3Gi.
Give a compose host the same headroom. **Kubernetes:** apply the new `06b-ingress-uploads.yaml`,
an Ingress for uploads alone, and patch its host and TLS block like the main Ingress's: an overlay
that patches only the first leaves every file between 4 and 10 MB refused by the controller.
`06-ingress.yaml` also had its two `annotations:` blocks merged into one; `kubectl apply -f` kept
only the second, and so dropped the sync-wave.
**Rolling back past this version is not a plain image change.** An older build's schema sync would
drop the two attachment tables, the new columns and the three types. The schema guard refuses that
as soon as one file document exists — a single file copied off a machine, even before this version,
is enough, since the new columns are filled for every row — or anything has been attached, and the
api does not start. **On compose, set `JARVIS_SKIP_MIGRATIONS=true` in `.env` for the rollback**:
the older build then starts without syncing the schema, runs on the newer one without touching what
it does not know, and nothing is lost; take the variable out again before you upgrade. **On
Kubernetes** the `jarvis-migrate` Job has no such switch; it fails before the api is touched, so
this version keeps serving. Restore the dump you took before upgrading, or set
`SCHEMA_ACCEPT_DATA_LOSS=true` on the Job for that one run and put it back. Forcing it deletes every
attached file for good, and on the next upgrade files uploaded to a workspace come back as captured
files with no source, which the assistant can no longer read or preview — they still download. Take
a dump before upgrading.
## 2026-09-25 — A fresh Kubernetes install no longer asks for its own vault key `api 0.114.1`
**On the published Kubernetes stack, creating the first administrator asked for the last characters