Sync the self-hosting stack

This commit is contained in:
2026-09-24 22:27:44 +02:00
parent d73e813471
commit 3228bb01a6
2 changed files with 168 additions and 11 deletions
+74
View File
@@ -9,6 +9,80 @@ 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-24 — A licensed instance can choose a managed model, and this is exactly what it sends `api 0.112.0` `web 0.137.0`
**No conversation content leaves unless somebody chooses it.** The assistant keeps using your own
OpenAI-compatible provider after this upgrade, exactly as before. What is new is a second option
under **Settings → Platform → Model**: a model your Jarvis provider runs for instances with a paid
or trial licence, with no endpoint and no key of your own to manage. Only a platform administrator
can choose it, only on that screen, and only after ticking a box under a statement of what leaves
the instance. No environment variable, licence or server answer selects it, and a community instance
cannot use it. On a licensed instance, opening that screen asks the licence server whether the
managed model is offered and which model it is, with a request signed like the licence report that
carries the product, the licence id, the instance id and public key, and the version — no content.
**Once chosen, conversation content goes to your Jarvis provider rather than to your own endpoint.**
Every request the assistant makes to the model carries each message, the conversation so far, the
instructions and the list of tools Jarvis gives the model, and the output of every tool the
assistant ran — command output, file contents and API responses from the systems you administer —
including runs nobody is watching, such as scheduled wake-ups and runs resumed after a restart; your
own provider receives the same on every request it answers. It goes over HTTPS to the host your
licence reports to (`checkin.luxit.be` on current licences), never following a redirect away from
it, with a short-lived credential your instance obtains by signing a request exactly as it signs its
licence report, and from there to the model provider named on the settings screen. A relay in front
of the licence server must also forward `/api/inference/`.
**What your provider keeps is metadata, never content**: when, which model, the Jarvis version, the
request's size, token counts, timings and outcome — each request's record for 90 days, and daily and
monthly totals for 26 months. **Usage counts against a monthly allowance per licence**, in UTC and
shared by every instance on the licence. When it is used up, or the licence is no longer in force,
the assistant refuses new requests with a sentence saying why and, for a spent allowance, when it
renews. It never falls back to your own provider by itself; everything else in Jarvis keeps working,
and your own provider's settings, key included, are kept as they were so switching back is one
click. The [README](README.md#if-you-choose-the-managed-model) has the full statement, including how
a request whose usage the model did not report is counted.
**What earlier entries said about "no conversation content" is still true of the licence report**:
the report's fields have not changed, and the managed model travels on a separate channel, which
carries content only once a platform administrator has chosen it.
**Also in this release.** The model step of the install wizard says the managed model exists and
where to choose it later — it cannot be chosen during installation, because an instance is only
bound to its licence once it has reported, after setup. A run the managed model refuses, or cannot
reach, now explains itself in the reader's own language in the conversation, with a link to the
model settings for a platform administrator; a refusal Jarvis decided on its own — a licence no
longer in force, an identity key it cannot decrypt — is no longer presented as something your
provider said. When the managed model is waiting on a licence report — an instance not yet bound, or
a licence your provider has just reactivated — the model settings offer to send one now.
**A licence key you remove stays removed.** The licence server answers every report with the licence
it still has your instance bound to, and the next report used to put a removed key straight back,
silently. That licence is now taken back only when somebody pastes it on the licence screen — not
from a report, and not from `JARVIS_LICENSE_KEY` at a restart. Every licence your instance does take
from a report, a renewal included, is now on the audit trail as `settings.license.adopted`.
**A provider that is briefly unable to answer is no longer called a misconfiguration.** A rate limit
or a 5xx from your own provider, or from a proxy in front of it, was retried and then written into
the conversation as "a configuration or account fault … it will repeat identically until it is
fixed". It now says the provider could not answer, how many times Jarvis tried, and that you can ask
it to continue.
**Self-hosters:** api and console. The schema gains five things, applied automatically when the api
starts: which of the two providers is chosen, when that last changed, which version of the
disclosure was accepted, on each assistant message which of the two answered it, and which licence
was last removed on the licence screen. They only add, so the schema guard has nothing to refuse. No
new environment variable.
**Rolling back past this version is not a plain image change.** An older build's schema sync would
drop `aiProvider`, `aiProviderChangedAt`, `aiManagedDisclosure` and `licenseReleasedId` on the
instance settings, `aiProvider` on messages, and the `AiProvider` type; the schema guard refuses
that and the api does not start. To go back anyway, set `SCHEMA_ACCEPT_DATA_LOSS=true` for that one
deploy — in `.env` on compose, on the `jarvis-migrate` Job on Kubernetes — then put it back. What is
lost is only the choice itself, the record of the disclosure accepted, which of the two answered
each message and which licence was removed — no conversation and none of your own provider's
settings — and the older build answers with your own provider, and takes a removed licence back at
its next report. Take a dump first either way.
## 2026-09-12 — Long conversations open quickly, and you can search inside them `web 0.136.0`
A conversation of several hundred turns had become slow in a way that spread past itself. Opening one
+94 -11
View File
@@ -20,7 +20,8 @@ the project.
**And no licence key.** A fresh install comes up on the **community edition**: one organization,
three users, five agents, ten assets, no expiry, nothing to renew. Everything Jarvis does works
inside those numbers — every connector, the agent, the remote terminal, the assistant itself. A
licence from your provider raises the limits; it does not switch anything on.
licence from your provider raises the limits and can include an optional managed model; it switches
nothing in Jarvis on or off.
When you outgrow it, **ask for a licence from inside Jarvis** — Settings → Licence — and the key
arrives on your instance by itself. A community instance reports its version and its counts so that
@@ -42,6 +43,7 @@ is listed in full below.
- [Removing it](#removing-it)
- [The community edition](#the-community-edition)
- [Licence keys, and what your instance reports](#licence-keys-and-what-your-instance-reports)
- [If you choose the managed model](#if-you-choose-the-managed-model)
- [Asking for a licence](#asking-for-a-licence)
- [Getting a licence, and getting help](#getting-a-licence-and-getting-help)
@@ -150,9 +152,9 @@ target and the API is never reachable from outside the compose network.
| `redis` | Socket fan-out, nonces and rate-limit counters. |
The assistant streams a turn, executes the tool calls the model asked for **strictly after the
stream is fully drained**, then feeds the results back — up to fifty rounds per user turn. That
ordering is what makes retrying a broken stream safe: at the moment a stream fails, no tool of that
round has run, so replaying it re-generates intent and never re-runs an operation.
stream is fully drained**, then feeds the results back — up to two hundred rounds per user turn.
That ordering is what makes retrying a broken stream safe: at the moment a stream fails, no tool of
that round has run, so replaying it re-generates intent and never re-runs an operation.
**A run that was in flight when the api stopped is picked up when it comes back.** A shutdown aborts
each loop and lets it write out what it had streamed with a note saying why the transcript ends
@@ -192,8 +194,9 @@ to how the containers are scheduled.
builds for Linux, macOS and Windows.
- A hostname and a TLS terminator in front of it. Jarvis speaks plain HTTP and does not manage
certificates.
- An API key for an OpenAI-compatible endpoint. The install screen asks for it and tests it before
saving; you do not need it in hand before you start.
- An API key for an OpenAI-compatible endpoint — or a paid or trial licence that includes the
[managed model](#if-you-choose-the-managed-model), which you choose after installing. The install
screen asks for the key and tests it before saving; you do not need it in hand before you start.
- **No licence key.** Jarvis runs the [community edition](#the-community-edition) out of the box; a
key raises the limits when you outgrow them.
- Roughly 2 GB of RAM for the stack and room for Postgres to grow.
@@ -674,6 +677,7 @@ community edition:
| Term | Perpetual. No expiry, nothing to renew, no key to lose |
| Reporting | Version, counts and address — the same fields a licensed instance sends, and not optional |
| Features | All of them — every connector, the agent, the remote terminal, the assistant |
| Managed model | Not included — the assistant uses your own provider |
Nothing is disabled, watermarked or time-limited. What a licence buys is a **higher ceiling**, not
the product: the same images, the same code, larger numbers. This is deliberate and it is the reason
@@ -721,15 +725,19 @@ carries your term and your limits, and it needs no network to be checked.
**A licence that stops applying drops back to the community edition**, and never to nothing. Expired,
withdrawn, or a key that will not verify: the instance keeps every allowance in the table above and
keeps running everything already set up. There is no state in which Jarvis stops being usable because
of a billing question, and there never will be.
keeps running everything already set up — the assistant included, on your own provider; the
[managed model](#if-you-choose-the-managed-model) is a service that comes with a licence and ends
with it. Nothing you run on your own infrastructure stops being usable because of a billing
question, and it never will.
**Every instance reports**, licensed or not. A licensed one reports to the address written into its
key; a community one to `checkin.luxit.be`, compiled into the build. The interval is your provider's
to set — every ten minutes on the current arrangement, so that a renewal or a revocation reaches you
promptly rather than tomorrow.
This is everything either of them sends, in full:
This is everything the licence report and a licence request send, in full. The managed model, if you
choose it, sends conversation content — see
[If you choose the managed model](#if-you-choose-the-managed-model).
| Field | What it is |
| ------------------------ | ------------------------------------------------- |
@@ -758,16 +766,91 @@ the arrangement a matter of opinion. If that does not suit your deployment, take
you deploy anything.
The reply can carry a renewed key, which your instance adopts on its own — so a renewal reaches you
without anybody re-pasting anything.
without anybody re-pasting anything. A key you **removed** on the licence screen is the exception:
that licence is not taken back from a reply, nor from `JARVIS_LICENSE_KEY` at a restart, until
somebody pastes it there again.
**Your platform does not stop working because of a licence.** Expiry gives you a grace period — as
long as your key says, which on the current plans is 30 days, and none at all on a trial. After it,
the instance returns to the community edition's allowances: everything already set up keeps running,
the assistant included, and only creating something beyond those numbers is refused. There is no
the assistant included on your own provider — the managed model is a service that comes with a
licence and ends with it — and only creating something beyond those numbers is refused. There is no
state in which Jarvis disables, deletes or locks you out of something you are already using. If the
check-in cannot reach the server, nothing changes at all: the key you hold is what governs, and it is
checked without a network.
## If you choose the managed model
**Off unless a platform administrator turns it on, and only on a paid or trial licence.** Your
Jarvis provider can run a model for licensed instances, so that the assistant works without an
endpoint or a key of your own. A platform administrator chooses it under **Settings → Platform →
Model**, on a screen that states everything below and asks them to confirm they have read it.
Nothing else selects it: no environment variable, no licence, no answer from the licence server. A
community instance cannot use it; its assistant runs on your own provider, as it always has.
**While it is chosen, conversation content goes to your Jarvis provider instead of the endpoint you
configured.** Every request the assistant then makes to the model carries:
- each message, and the conversation so far;
- the instructions and the list of tools Jarvis gives the model;
- the output of every tool the assistant ran — command output, file contents and API responses from
the systems you administer.
That includes runs nobody is watching: scheduled wake-ups, and runs resumed after a restart. Your own
provider receives exactly the same content on every request — that is how the assistant works on
either path. Choosing the managed model changes who receives it, not what is sent.
Each request also carries a short-lived credential. Your instance obtains it with a request signed
exactly as its licence report is, which carries the product (`jarvis`), the licence id, the instance
id and public key, and the version — nothing else — and it keeps the credential in memory only.
**Opening the screen already asks.** On a licensed instance, opening **Settings → Platform → Model**
sends that signed request, so the screen can say whether the managed model is offered to you and
which model it is — whether or not anybody then chooses it. It carries the fields above and no
conversation content, and your Jarvis provider sees that this instance asked.
**Where it goes.** Over HTTPS to the host your licence reports to — the address written into your
licence key, `checkin.luxit.be` on current licences, which is where its licence report goes too. The
settings screen names that host before anybody confirms. Jarvis refuses to send content to an address
that is not HTTPS, and never follows a redirect away from it. Anything your network puts between the
instance and that host must pass `/api/inference/` as well as the licence report, or the screen says
the managed model is not served there. From that host the content goes on to the model provider
named on the same screen, which runs the model. Your Jarvis provider decides which model it is, how
hard it thinks and how long its answers may be.
**What is kept.** Your Jarvis provider does not store or log the content — no message, no tool
output, no instructions — and does not ask the model provider to keep it. It keeps metadata about
each request, against your instance and its licence: when it started and ended, which model, the
Jarvis version that sent it, its size in bytes, how many tokens of each kind it used, how long it
took and how it ended. Each request's record is kept for 90 days, and daily and monthly totals for
26 months. The settings screen shows the current figures, and they are the ones that apply.
**The allowance.** Each licence has a monthly allowance of model tokens, counted per calendar month
in UTC and shared by every instance on the licence; the settings screen shows how much is used and
when it renews. A request is admitted while any allowance is left and then runs to its end, so a
month can close slightly above its allowance, never far above it. When the allowance is used up, or
the licence is no longer in force, the assistant refuses new requests with a sentence saying why —
and, for a spent allowance, when it renews. It does not switch to your own provider by itself,
because that would change who receives your content and who pays for it. Everything else in Jarvis
keeps working.
**How a request is counted.** The tokens the model reports for it — input, cached input, output and
reasoning, all at the same weight. When the model reports none, an estimate from the size of what
was sent and what came back, at about four bytes a token; a request stopped once its answer had
started — by you, by a timeout, or by the model failing part-way — counts that estimate too. A
request that was refused, or that failed before any answer, counts nothing, and neither does one cut
short by your Jarvis provider's own restart or outage. A request the assistant sends again after a
dropped connection is a new request, and counts again.
**Your own provider is kept.** Choosing the managed model does not delete or change your own
provider's settings, key included, and they stay editable. Switching back — **Use your own
provider**, on the same screen — takes effect from the assistant's next request to the model, and
Jarvis records for each answer which of the two produced it.
**Network.** The managed model needs what the licence report needs: outbound HTTPS from the api to
that host, and nothing inbound. Jarvis has no support for an outbound proxy, so an instance behind a
mandatory egress proxy can use neither this, nor its own provider, nor the licence report.
## Asking for a licence
**From inside your own instance: Settings → Licence → Ask for a licence.** Fill in who you are — a