diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e03f8b..c04a7ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 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` **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` -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 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. @@ -53,8 +133,8 @@ notice first. **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 — 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 -thread* were delivered to browsers that had no business receiving any of it. They now go only to 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 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 that matters.