AIPM what-next Investigator (looking outside the board)
When the board cannot explain something, the Investigator looks for the reason in the person's own connected sources. It only reads a source the person said yes to, stops after five lookups or about twenty seconds, and every finding points at a snippet it really read.
What it is
Piece 4 of the smart "what next" design for the Mission Control AI Project Manager. A sharp human project manager who sees "stuck since Saturday, waiting on Marcus" goes and finds out why. The Investigator does the same: it might find Marcus's out-of-office email, or a Team Chat message saying the config went live.
It is built and tested but nothing in the app calls it yet. The answer view (piece 6) will show its progress lines, its findings and its "may I check your email?" questions.
Where to find it
There is nothing to click yet. The Investigator runs in the background when Mission Control's AI
Project Manager answers "what should I do next?", and the answer card (piece 6) will show its
progress lines, findings and source questions once that follow-up lands. In code it lives under
src/main/services/pm/intelligence/ (see "For agents" below).
How it behaves
- It only digs when the board is puzzling. Plain rules look for three things: someone waited on for two days or more, a promise written in an update that is due today or past, and work due within a week (or overdue) that has not moved in five days. With none of these, no source is touched and no AI is asked.
- Every source has the same shape. A lookup searches for a person and a few topic words in a date window, and gets back up to five short snippets, each with its source, title, text, date, author and link. The AI picks which source could prove or rule out each likely reason.
- Sources today: email (Gmail), calendar (Google Calendar), Team Chat, the person's other Mission Control boards, GitHub, Jira, KMS notes, Google Docs and Meeting recordings. Each uses a connection the person already set up in the app and is offered only while that connection is there. Slack is deliberately not a source: the goal is moving teams to Team Chat.
- Meeting recordings is one source over every meeting tool. Today it covers Omniscio's own recordings (saved on this computer, the same set the Meetings panel shows, while the Meetings feature is on) and Granola. Fathom, Zoom, Google Meet, Fireflies and Microsoft Teams are planned to join it as more tools. One lookup searches every connected tool at once, each under its own time limit, and the tools take turns filling the five snippets, so a slow or broken tool never costs the others their results. A recording's snippet is the part of the transcript that matched, not the start of the meeting; deleted meetings and meetings outside the window are never read.
- One yes for the meeting tools. Saying yes to Meeting recordings covers the meeting tools connected at that moment. When another tool is connected later, the tools already covered keep working and the next answer that looked in Meeting recordings asks again ("You connected a meeting tool since you last said yes"). A no covers every meeting tool.
- What each new source searches. GitHub: pull requests and issues in the repositories behind the
person's own registered projects (up to ten), with their own GitHub sign-in, and says whether a
pull request merged. Jira: ticket text on the person's saved Jira site, showing status, assignee
and priority, linked to the ticket. KMS notes: the configured vault only, linked to the note. Google
Docs: the person's whole Drive, read only, through their own gog sign-in when gog is signed into
the same Google account as the app; otherwise only documents the app may already see (ones it made,
or the person opened through it), and the answer carries a "sign in to read all your Docs" ask
(
signInNeeded: gog not signed in, or gog not installed). The top three Docs are read for a short excerpt. Search words can never add a search operator that reaches another repository, site, vault or file. - A yes before reading. The first time a source would help, nothing is read; the result carries a "consent needed" entry with the reason, so the screen can ask. A yes or no is remembered per signed-in person, per source. A declined source is never offered again until the person changes their mind. Another person signing in on the same computer starts with nothing approved.
- A company admin can turn outside sources off for a workspace. On the workspace's Permissions tab
in Mission Control, a company admin turns on "No outside sources" (the CLI does the same with
PATCH /pm/workspaces/:idandoutsideSourcesOff). While it is on, a question whose puzzles touch that workspace reads no email, calendar, Team Chat or any other outside source, even with a saved yes, and asks for no consent. It still checks the boards, and the result carries a plain sentence naming the workspace. A saved yes is kept and works again when the switch is turned off. - The switch is read fresh and fails closed. It lives on the Mission Control server, so every teammate's app sees the same value, and it is read for every question, so a change holds from the next question on. If a signed-in app cannot read it, outside sources stay off for that question and the sentence says it could not check. A signed-out app has no company, so the switch does not apply. Only a company admin can change it; a workspace owner who is not one is refused.
- Only the person's own accounts. Each source reads only what is connected on that person's app. A lookup can search for a teammate's name, but never inside a teammate's mailbox or calendar.
- A hard budget. At most five lookups per question, about twenty seconds in total, eight seconds per lookup, five snippets of up to 400 characters each, and a $1 daily AI cap. The rules stop it, not the AI. The owner confirmed these numbers and the Haiku model on 2026-10-22; the model may change later.
- Read-only. The AI has one tool,
lookup, and it can only read. Nothing it does can send, write or delete. - Found text is data. Snippets reach the AI fenced and neutralised by the shared prompt-injection protection, with private details such as email addresses scrubbed. An email saying "ignore your rules" changes nothing about what the Investigator is allowed to do.
- Progress lines. Before each lookup it reports a translated line such as "Checking your email…".
- Findings point at snippets. Each finding, and each reason it ruled out, names the snippets it cites. One that cites nothing it read is dropped. Snippet words and links always come from the source, never from the AI.
- Honest when it cannot dig. It says whether the AI is off, no source is available, the AI failed, or the AI's reply was unreadable, and keeps whatever it already looked up. A failing or slow source is skipped; it never fails the whole answer.
For agents
- Code:
src/main/services/pm/intelligence/pm-what-next-*—investigator.ts(entryinvestigateWhatNext),investigate-executor.ts(consent and budget enforced per tool call),investigate-loop.ts(the Anthropic tool loop, Haiku, cost sourcepm-what-next-investigate),puzzles.ts,dig-budget.ts,sources.tsand onesource-*.tsper source,consent-store.ts. Meeting recordings issource-meetings.tsover onemeeting-tool-*.tsper tool (meeting-tool-omniscio.ts: an FTS5 search ofmeetings_ftson the database worker with asnippet()excerpt;meeting-tool-granola.ts: GranolalistMeetingssummaries). investigateThenReason(input, deps)gathers the facts, investigates, then calls the reasoner (piece 3) with the findings. A reasoner claim may cite a finding as{kind:"finding", findingId}.- Types:
src/shared/types/pm-what-next-investigation.ts. - Consent table:
pm_what_next_source_consent(account, source, allowed or declined, when), read and written on the database worker. Use onlyreadSourceDecisions,recordSourceDecisionandforgetSourceDecision. A yes tomeetingsalso writes onemeetings:<tool>row per connected tool (readCoveredParts); a no or a forget clears them.readSourceDecisionsnever returns those rows. - A source can ask for a fresh yes after a lookup through an optional
freshYesReason(); the executor adds the consent ask with that reason. Meeting recordings uses it for a newly connected tool. - Adding a meeting tool: write a
meeting-tool-*.tsreturning{ id, isConnected, search }, add its id toMEETING_TOOL_IDSand its factory todefaultMeetingTools()insource-meetings.ts. No new source id, progress line or consent path is needed. - Adding a source: write a
source-*.tswithisConnectedandsearch(query, deadlineMs), add its id toWHAT_NEXT_SOURCE_IDS, a progress line, a one-lineSOURCE_HOLDSdescription ininvestigate-prompt.ts(the type checker asks for both), and add it todefaultInvestigatorDeps. - Each
source-*.tstakes a small reader whose default calls the app's existing integration lazily (githubFetch,searchJql,searchDocsByTextindrive-api-service.tsor gog'sdrive search, GranolalistMeetings); KMS notes read the notes index on the database worker throughdbAll, like the boards source. Tests pass a fake reader.searchWordsinsources.tsstrips search operators for every source. - The workspace switch:
pm-what-next-outside-sources-switch.tsreadsGET /workspacesfresh (5 s cap) and decides the block;InvestigatorDeps.outsideSourcesBlockis required, so every caller supplies it. A block offers only inside sources (WHAT_NEXT_INSIDE_SOURCE_IDS, today just the boards), so a new source is outside by default. The result field is the optionaloutsideSourcesBlocked(turned_offorunconfirmed, the workspace names and a translatednote). Server column:workspaces.outside_sources_offin monday-back. - Contracts:
pm-what-next-investigator-contract.mdand, for the GitHub, Jira, KMS notes, Google Docs and Meeting recordings sources,pm-what-next-investigator-sources-contract.md. - The workspace switch contract:
pm-workspace-outside-sources-off-contract.md.
Related
The facts it starts from and the reasoner it feeds are part of pm-cross-board-intelligence.md. Mission Control itself is described in mission-control.md.
Last verified 2026-10-22