Delivered to hosted production 2026-08-29 (channel entry 0.12.23-estate-20260829-seq10), station-validated on live meetings before release.
Fixed
- Teams bots join with a separate
passcode(#892, #1201). A numeric meeting ID + passcode now builds the join URL Teams actually uses; the passcode never appears in any log line. Proven live against a passcode-required meeting. - A broken audio capture no longer ends a live meeting as
completed(left_alone)(#1192, #1195). Connected streams delivering nothing are treated as a capture fault: the bot holds the meeting, logs it, and attempts one capture restart. On platforms that keep a server-side mix alive (Teams), affected runs now end at themaxActiveMsceiling rather than reporting a false success. - Restarting mid-leave no longer strands a meeting in "stopping" (#1280).
- Every gate failure prints its diagnostic (#1107, #1114) — an empty stdout Buffer was swallowing the real error at all 21 call sites.
Added
- Delete a completed meeting's artifacts (#116, #1293). Owners erase transcripts and recording artifacts from primary stores; the meeting row remains as a tombstoned usage record. Active meetings answer
409. This is what makes the published privacy promise true. GET /meetings/{platform}/{native_meeting_id}/participants(#451, #1275) — who was in a meeting, each row labelled bysource(invite/speaker), withobserved_roster: "not_recorded"stating honestly what the core does not know.- Spawned bot and agent-worker Pods declare CPU/memory requests and limits (#1005, #1093) — quota-controlled and
ResourceQuota/LimitRange namespaces now admit dynamically created Pods; sizing is configurable per profile. - MCP
report_issue(#1272) — an agent can file a ticket from inside its own session; off untilVEXA_TICKET_SINK_URLis set. - Interactive capabilities get one API home (#1089, ADR-0035) —
POST /bots/{platform}/{native_meeting_id}/acts, with speak/chat kept as aliases.
Changed
GET /meetingsorders by event time (#1226) — non-terminal meetings pinned on top; calendar-imported meetings sort where they happened, not where they were created.- The minio-init Job is pinnable and sized (#1321) — its client image is a value (pin by digest for reproducibility); the Job declares its own resources.
Docs
- The meeting completion-reason taxonomy — all ten values, who owns each, and what a
failedrow does and does not tell you (#1284). Operability numbers with the commands that reproduce them (#1285). API-key provenance on the pages that carry snippets (#1301, #1302). "Air-gapped" corrected to self-hosted across the comparison pages (#1304). The MCP page linked from where agents actually look (#1345). 0.10 → 0.12 upgrade runbook (#1332).