Flow
Decisions

0028 — Evidence does not need a project

Notes, meetings, and chat threads can be attached to any number of projects or none. A person can read one when they wrote it or they are named on its roster, and a platform admin can read all of them.

Decided. Workspace has a new domain called evidence. It stores three kinds of thing: notes somebody typed, meeting transcripts, and chat threads copied in from Slack. Each one is called a record.

A record is owned by the person who made it, not by a project. It can be attached to as many projects as you like, or to none at all.

By default the intelligence service reads a record and turns it into claims the company can search. A flag on the record turns that off.

Who can read a record

The rule in one sentence: you can read a record when you wrote it, when you are named on its roster, or when you are a platform admin. Belonging to a project the record is filed on does not open it. A record that feeds company knowledge does not open it either. That flag only decides whether intelligence may turn the text into claims.

A connector writes the record as a service account. That account can read what it wrote. The people who were in the meeting or the thread are on the roster, and they can read it too.

Editing is stricter than reading: the author, or a platform admin. Attaching a note to a shared project does not let the other members read it or change it.

Alternatives

Make every record belong to a project, the way conversations do. This would leave the service with one access rule instead of two, and no "attached to nothing" case to handle.

Rejected because people write things down before the work has a name. If a project were required, the first thing you would do is create a fake one to hold the note — and that fake project then appears in every project list, every digest, and every permission check from then on. Meetings and Slack channels have the opposite problem: they cover several projects at once, so picking one is also wrong.

Give every person a private project when they join. This keeps the "everything belongs to a project" rule technically true.

Rejected because the rule then means nothing. A project with one member that exists only so a database column is not empty is not a project. It also puts a membership wall around every personal note, which is the opposite of what a company-wide knowledge layer is for.

Let only the author and the roster read a record. This is the current rule. An earlier version of this decision rejected it, because a company-wide claim would then point at text some people cannot open. That tradeoff is accepted: the claim stays visible to the company, and the record stays with the people who wrote it or were in it.

Put notes and the Slack and Zoom connectors in a separate service. Notes would then live apart from the projects and conversations they relate to, and searching would mean calling two services and merging the results for no benefit.

The connectors themselves are a separate question and still open. They need URLs the internet can reach and stored login tokens per vendor, and workspace is the service the UI depends on, so that is not a good place for them.

Why

  • People write things down before anyone decides who owns them. A system that demands the filing first is a system nobody writes anything into.
  • Slack and Zoom do not know what a Flow project is. A connector knows a channel and a list of speakers. Filing the record on a project is a label. It does not decide who can read it.
  • The speaker has to be recorded, not the caller. Every line stores who said it: a display name, plus a Flow account and the vendor's own user id where those are known. A Slack bot posting Alice's message records Alice. Without this, every imported line looks like the bot wrote it, and counting how many different people said something becomes meaningless.

Consequences

  • The read rule is written twice: in Go, in evidence.CanRead, for reading one record, and in SQL for search. The two have to be kept in step. Search cannot filter after ranking, because a result you may not see would still take a slot in the top ten, and its absence would tell you it exists.
  • Somebody in a meeting who does not work at Flow is recorded at the external tier (ADR 0027). What they said can be quoted as the source of a claim. It never counts toward "several independent people said this", because three customers agreeing is three people outside the company agreeing.
  • Turning the knowledge flag off is not a hint. Intelligence runs the same cleanup it runs for a deleted line: every claim resting on that record is flagged for review. The claims are not deleted, because other evidence may also support them.
  • Notes and conversations have different minimums before we spend money on a model. A conversation needs four messages and 800 characters. A note needs 200 characters and nothing else, because a note is one piece of text somebody chose to write.
  • "Everything in this project" is now two lists: what the project owns, and what has been attached to it.

On this page