If you’re new here: OneCamp is an open-source, self-hosted workspace (chat, docs, tasks, projects, calls, boards, tables, an API) that runs on your infrastructure. I build it, sell it, and operate the demo, which means I get to find out what breaks.
Last week’s post was about features that made false claims. This week is the sequel and the shape is different. Nothing lied. Everything worked. Almost none of it could be reached.
OneCamp’s meeting recap posts a summary, the decisions and the action items into the channel after a call. It is the headline AI feature.
It only ran if somebody pressed record.
Four independent layers enforced that, and every one of them is correct in isolation. The transcription agent refuses to send a line without a recording id. The API rejects a transcript that has none. Transcripts are stored as children of a recording node, so with no recording there is nowhere to put them. The recap skips a call with too few lines.
Put together: a team with a “we do not record our meetings” policy got no recaps, ever, with no error to search for. And that is exactly the kind of team that buys a self-hosted workspace.
I fixed it by giving a call its own identity so a transcript can hang off the call instead of the recording. Wanting written notes and wanting a stored video of your colleagues are different decisions, and they are separate settings now.
defaultMode = ModeFrontend.
Out of the box, OneCamp transcribes in each participant’s browser, draws the captions, and throws the words away when the call ends.
So on a fresh install there was no transcript, no recap, no meeting notes and nothing for a workflow to react to, until an admin found the transcription settings and switched to the server-side agent. Every piece of AI meeting work I had shipped was real, correct, and invisible to a new customer.
The browser was already producing the text. It was already publishing it to the room so other people saw captions. It just never reached the server.
Five features. All built. All correct. None reachable by the person they were for.
A feature has two halves and only one of them is satisfying to build. The mechanism is a problem with a right answer: the transcript hangs off the call, the acceptance rate is approved over decided, the revision stores the previous text. You know when it is done because it is testable.
Reachability has no such moment. There is no test that fails when a working endpoint has no button. The build is green. The suite passes. The feature is finished by every measure the tooling has.
The only thing that catches it is asking a duller question than “does it work”: who would ever see this, and how would they get there. I was not asking it. I was asking whether the code was right, and it was, every time.
Every one of these has the same fingerprint: something was built for a person and then measured by a machine.
An endpoint with no caller passes every test it has. A feature behind a default nobody changes passes too. A document with no link is indistinguishable, in CI, from a document with one. The tooling I built to keep myself honest, and I have built a lot of it this month, is very good at “is this correct” and completely blind to “is this reachable”.
Correctness has a proxy. Reachability does not. So it does not get measured, and what does not get measured is where the work quietly does not land.
Making a thing reachable is usually small, which is the annoying part.
The browser now posts the final version of each utterance to the server. That is a new endpoint and about twenty lines in the transcriber, and it turns the default install from “no AI meeting features” into “all of them”.
The endpoint took the care, not the wiring. The agent’s transcript API is server-to-server behind a shared secret and a browser cannot hold one, so this one is authenticated as the person: the speaker comes from the session and never from the request body, presence in the room is checked against the call server, and the call identity is resolved server-side rather than accepted. The worst a participant can do is put words they did not say into a call they are actually in, under their own name, which is what speaking already lets them do.
The recap links the document. The activity feed got a card. Skills got an editor. None of it was hard. All of it was invisible.
The default is fixed and browser transcription still only works in Chrome and Edge, because that is the only place the Web Speech API exists. A participant on Firefox or Safari contributes nothing. The recap now says so when it happens rather than presenting a partial transcript as a whole one, but the gap is real and the honest fix is the bundled speech server, which now ships and runs on your own machine.
All of this is in v2.7.0 and v1.5.0, out today. The other half of this release is the unglamorous bit: AI governance is mostly boring plumbing. What that looks like as a changelog, with the click path for each change: a changelog is useless without directions.
OneCamp is an open-source, self-hosted workspace: one payment, unlimited users, your server. Find it at onemana.dev.