Sync the self-hosting stack

This commit is contained in:
2026-08-31 16:39:23 +02:00
parent 219f996766
commit 51538252c2
+83 -3
View File
@@ -9,6 +9,86 @@ 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 Every version published to a channel appears here. Nothing is written from memory afterwards: a build
cannot be published without its entry. cannot be published without its entry.
## 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
conversation: the work that is on a calendar, and the half of Microsoft 365 that Graph does not
reach.
### Scheduled work
Everything Jarvis did until now happened inside the turn that asked for it. That is right for an
investigation and wrong for the licence reconciliation on the first of the month, the mailbox audit
every Monday, or the service restart at 03:00 on Sunday because that is when nobody is using it.
**A new section, "Scheduled work".** Write an instruction, choose when it runs — once, or on a
repeating pattern — and it runs on its own, in a conversation you can read afterwards. You can also
just ask: "check the backups every morning at seven" now works in a conversation, and what Jarvis
writes down is an ordinary row on the same screen.
**Times are yours, not the server's.** A repeating schedule is stored with the time zone you wrote
it in, so 02:00 stays 02:00 when the clocks change. The form shows you the next three runs it will
actually make, because a cron expression is otherwise something you find out about afterwards.
**It runs as the person who scheduled it, and that is checked when it fires — not when it was
written.** If somebody's access to a machine is revoked, the work they left behind stops reaching
that machine the same day and says so on its row. Nothing about their rights is stored on the
schedule, so there is no standing permission to forget about.
**Nobody is at the keyboard, and Jarvis behaves accordingly.** An occurrence that would stop for
your approval has nobody to ask: a scheduled _instruction_ waits in the transcript as usual, and a
scheduled _single operation_ is refused with a sentence telling you to raise the conversation's
autonomy or narrow the operation. It will not sit there for an hour and then fail anyway.
**Failures are bounded so they stay readable.** One failure changes nothing — a tenant throttled on
Tuesday is usually fine on Wednesday. Three in a row switch the schedule off and mark it, because
the thirtieth identical failure is one nobody reads, and a switched-off schedule is what makes
somebody go and fix the credential.
**Two new permissions**, `schedule:view` and `schedule:manage`. Viewers can see what the
organization has scheduled; operators and above can write and cancel. Neither reaches a machine on
its own — what an occurrence may actually do is still the asset grant of whoever owns it.
**Worth knowing before you use it:** scheduled work is visible to everyone in the organization who
can see the section, including the conversation each occurrence writes into. If you pin a schedule
to an existing private conversation, that conversation's name becomes visible alongside it. Leave
the schedule to open its own conversation each time if that matters to you.
**Nothing to configure.** The schema change is applied by the usual migrate step; there is no new
environment variable and no new service.
### Exchange Online
Jarvis reaches Microsoft 365 through Microsoft Graph, and Graph does not reach Exchange. Mail flow
and transport rules, connectors, accepted domains, journaling, retention and litigation hold,
mailbox and calendar permissions, shared and resource mailboxes, anti-spam and anti-phishing policy,
address lists, message trace — none of it has a Graph endpoint. Until this build, Jarvis could
manage users and licences in a tenant and could not touch any of that.
**It now runs the Exchange Online PowerShell module**, which is the only administrative surface
Microsoft supports for those areas. It uses the same app registration you already configured for the
Microsoft 365 connection — including one that authenticates with a client _secret_, which the
documented Microsoft recipe does not allow for app-only Exchange.
**You have to grant it two things, and only the first looks like a normal permission.** On the app
registration, add `Exchange.ManageAsApp` as an **application** permission and grant admin consent.
Then assign the application's service principal a directory role Exchange honours — **Exchange
Administrator** to make changes, **Global Reader** to read only. Graph consent alone authenticates
perfectly and is then refused by every cmdlet, which is the usual way this ends up looking broken;
`m365_check_permissions` cannot see either of these, because neither is a Graph permission. **Test
connection** on the tenant now tells you whether the PowerShell side is available at all.
**The two new operations are treated as unrestricted**, like the raw Graph request and the shell
commands: a person needs the "unrestricted operations" switch on their asset grant to use them, and
that switch is off by default. This is deliberate and worth taking seriously — an Exchange script is
as open-ended as a shell command, and the risk classification in front of it is a list of cmdlet
verbs that cannot be complete.
**The api image is about 210 MB larger** because it now carries PowerShell 7 and the module. If you
mirror images or run on constrained storage, this is the change to plan for. Nothing else about
running the stack changes, and every existing tool works exactly as before on an image without it —
only the two Exchange operations depend on it.
## 2026-08-31 — Nothing in the console changes, and that is the whole of it `web 0.123.0` ## 2026-08-31 — Nothing in the console changes, and that is the whole of it `web 0.123.0`
**This is the same console as `web 0.122.0`.** No behaviour changed, no bug was fixed, nothing in **This is the same console as `web 0.122.0`.** No behaviour changed, no bug was fixed, nothing in
@@ -24,7 +104,7 @@ is nothing to notice. The next entry describes a real change.
## 2026-08-29 — Keep several conversations on the go, and switch between them `api 0.100.0` `web 0.122.0` ## 2026-08-29 — Keep several conversations on the go, and switch between them `api 0.100.0` `web 0.122.0`
Opening a conversation used to mean being *in* it: to reach another you left it, found the one you Opening a conversation used to mean being _in_ it: to reach another you left it, found the one you
wanted in the list, and went in. That is a poor deal when Jarvis runs unattended for twenty minutes wanted in the list, and went in. That is a poor deal when Jarvis runs unattended for twenty minutes
against a real machine — the thing you most need to know is that a plan is blocked in a thread you against a real machine — the thing you most need to know is that a plan is blocked in a thread you
are not looking at. are not looking at.
@@ -53,8 +133,8 @@ notice first.
**Activity was announced to everyone in the organization.** The "Jarvis is working" marks in the **Activity was announced to everyone in the organization.** The "Jarvis is working" marks in the
conversation list were broadcast to every member of an organization, for every conversation in it — conversation list were broadcast to every member of an organization, for every conversation in it —
including private conversations they take no part in and cannot open. Nothing in the interface ever including private conversations they take no part in and cannot open. Nothing in the interface ever
displayed them, but the identifiers, the live state and the *name of the colleague running the displayed them, but the identifiers, the live state and the _name of the colleague running the
thread* were delivered to browsers that had no business receiving any of it. They now go only to the thread_ were delivered to browsers that had no business receiving any of it. They now go only to the
people who take part in the conversation, and organization membership is re-checked at the moment of people who take part in the conversation, and organization membership is re-checked at the moment of
sending rather than trusted to a stale row. **Take both images to close this**; the api is the half sending rather than trusted to a stale row. **Take both images to close this**; the api is the half
that matters. that matters.