Today · Today

Decide what to open next

Set the repository and environment in the scope bar, then start with the case that needs you. Today predicts one next action, ranks open cases overdue first and then by severity, and opens each case with its evidence coverage. A class that nothing observes reads no source, never zero.

For: the engineer who opens the app in the morning, and the team lead who reads the same queue over every repository they may see

What it does, and why it helps

The scope bar above the page sets Repository, Environment, Service and Time once for the six primary pages; Custom range takes a From and a To date. On the desktop, Change repository picks the repository, and Environment, Service and Time narrow this page's case list only: the bar says so, for example Environment narrows this page's case list only. Its other panels are not narrowed by it. On the hosted page they narrow the cases and every panel whose reader takes them, and a panel that cannot take one says so on the panel.

The page reads the case store and says what to do first. The next action is predicted in a fixed order: the oldest critical case past its SLA, else the built fix that has waited longest at the gate, else the connector in a health state, else the quiet state. Under it sit five figures: open cases by class, fixes waiting on you, cases past SLA, source families observed out of five, and today's build spend against the cap (the hosted page reads Build spend and adds Resolution cost). Then the cases, each a row that opens the case in a dialog over the queue, and an aside that names every connector's health by its code, what the loop built overnight, the last three lessons written, and on the desktop this machine's sync and daemon state. On the desktop, Agent work on this machine counts the agent attempts captured here by state. Its Ready for review is agent work waiting on a person (it finished and nothing has checked it yet), which is a different count from Fixes waiting on you, the built fixes at the gate.

Every case carries an Evidence coverage section: seven evidence families (runtime event payload; deployment, commit and PR links; session metadata; transcript; tool records; source receipts; diagnostics), each captured, partial, not requested, unsupported, expired or restricted, under a summary such as 4 of 7 evidence families captured. None of those states is zero. On the hosted case an owner or admin can press Retrieve missing evidence, which checks stored content first and then asks the linked installations; on the desktop the button is disabled and says retrieval runs from the hosted case. On the hosted page an owner or admin also sees managed repositories whose required evidence is not arriving, in the Collection health aside: Managed coverage failure: <developer>, <device>, <repo>, with the problem, such as delivery blocked, disk pressure: capture at risk, or required collaborator with no current installation.

On the local combined view, repository-only details are not requested. Choose a repository for its fixes, build spend, lessons and agent workflow. The case filters below apply to the queue; repository details keep their stated window. With no repository connected, Open setup provides the next step. A failed read within a selected repository still reads unavailable. If some local case history cannot be read, valid cases remain visible with an incomplete-history warning. Case totals are unavailable, and an empty partial result does not establish that no cases exist. Refresh retries the read.

On the desktop, the case queue appears as soon as its own read finishes. Source health, fixes, lessons and sync fill in separately. Loading means a read is still pending; it does not mean there are no sources or no cases. Changing a filter cancels the previous case read. If an older page fails, the cases already shown stay in place and Show older cases lets you retry. After a restart the capture service has usually prepared the first read already: the line under the heading says how old it is, for example Prepared 4 min ago by the capture service, and the page refreshes it in the background. Once that refresh lands, the line says so, for example Prepared 9 min ago by the capture service, refreshed just now on this machine. When nothing is prepared yet, or the capture service is not running, the line says so and the page reads the store as it opens.

The figures tell you when they are not measuring. A class with no case whose family no connected source observes reads no source; a read that failed reads Unavailable; a store that could not be read says so instead of reading empty. The eleven filters are URL parameters spelled the same on the desktop tab and on the hosted page, so a pasted link reproduces the view for a colleague within their own scope. Today changes nothing by itself. Its one write is the report form, which records a problem a person saw.

The pain. A home screen full of tiles answers every question except the one that matters at nine in the morning: what do I open first. And a column that reads zero is read as good news when the truth is that nothing was watching it.

The point of view. A queue should predict its own next action and name its own blind spots. Rank by what is late, then by what is severe, and write no source where a zero would be a lie.

What gets easier. Starting. The next action names one case, one fix or one connector with the reason. The count line says how many match and in what order. A filtered view is a link you can paste.

When it helps. Any morning on a machine with at least one tracked repository, and any time a source reports a problem, a local detector fires, or the remediation loop builds a fix and waits.

Its limits. Today opens cases only through the report form; everything else it shows was written by a source, a detector or the loop. It does not set the SLA hours on the desktop, where the defaults apply. It does not merge, roll back or delete anything. A quiet page on a machine with no connected source is an absence, and the figures say so.

Understand it in 30 seconds

30.1 s, captions on. Narration: Microsoft Zira Desktop (provisional voice; an approved narration source is pending).Transcript
Read the narration
  1. 0:00 Start with the case that needs you: overdue first, then by severity.
  2. 0:06 Set repository, environment, service and time once.
  3. 0:10 The page says how old its read is.
  4. 0:13 A class nothing observes reads no source, never zero.
  5. 0:17 Open the case, and Evidence coverage shows what is missing.
  6. 0:23 A built fix still waits for your decision.
  7. 0:25 A failing source is named, not hidden.

Synthetic example. Read the guide

Where to find it

Where to find it

  • Desktop: localhost:4000, then Today, one of the six primary pages in the sidebar.
  • Hosted: repoops.ai/team/today, from Today in the sidebar.
  • Keyboard: ⌘ K, then type “Today”.

When to use it

The first look of the day, on the desktop

Situation. Two repositories are tracked. Overnight the correlator opened a critical production case in one of them and nobody has touched it. Its four-hour clock ran out before you sat down.

What you do. Open Today. Read the next action, then press Open the case. The case opens in a dialog over the queue and the URL carries case=, so the same link reopens it.

What you see. The next action reads Decide <case>: critical, 3 h past its SLA, and nobody owns it, with the case id, the repository and either the attribution band or No attribution recorded. The row's meta reads the id, owner: unassigned and 3 h over. Past SLA counts it by severity.

What it establishes. You are inside the case with its seven sections, not scanning tiles. What is known and what is not is on the case; Today only put it first.

A security column that reads zero, on the hosted page

Situation. A team lead opens /team/today and sees no security case in any repository. The Source families observed figure reads 3 of 5 and its line reads security and cost: no source.

What you do. Read the Open cases line, where Security reads no source rather than 0. Open Collection health in the aside, where each connector carries its state by name. Press Manage sources, or on a desktop check that Session signals has scanned a session.

What you see. On the desktop the aside reads Session signals, this machine: no session scanned yet until a session has been scanned, and Cost sources: none connected. On the hosted page a connector that never fetched reads Never fetched, and a refused read names its code, such as Provider denied the read (403): a permission or a repository setting.

What it establishes. The zero was an absence, and the page said so. Once a source observes the family the same column becomes a measurement; nothing on the page claims it was clean before that.

Before you start

Supported versions
RepoOps desktop v0.3.1, the release this guide was read against. The unattended pass that opens cases from findings runs on the capture daemon's hourly cycle only when its flag is set; without it, cases open from a source's push, a report or the open route.
Where it runs
Local: Today is the first primary page. The combined view shows the case queue and source coverage. Select a repository for its fixes, build spend, lessons and agent workflow; changing that selection reloads all readers into the same repository. Hosted: /team/today, over every repository the member's scope allows, with the filters applied in SQL before counting and paging and the select choices computed from the scoped set.
Permissions
The desktop tab has no per-user access; the report form is gated to same-origin requests. On the hosted page a member sees the cases their repository scope allows; an owner or admin sets the team's SLA hours on Settings.
Connections
None to read the queue. To observe a family you need a connected observation source: Sentry, Vercel, GitHub Actions and alerts, PostHog or the report form; the local session-signals scan credits security once it has scanned a session; the Postgres slow log is evidence only and opens no case. Build figures need the remediation loop to have built something.
Plan
No plan gate was found on the tab or on its routes. Seeing the hosted page follows the hosted dashboard tiers.

Configure it

  1. Set the scope bar: a repository, then environment, service and time.

    The scope bar carries these across the six primary pages; Apply scope sets them and Clear scope removes them. On the desktop the shell passes ?repo=<id> and Change repository picks another. The Case filters form below keeps its own Repository select, which offers every tracked repository plus Machine-wide (no repo), so choosing one leaves the others on offer. Fixes waiting on you and Build spend today read Unavailable when no repository is in scope, because the bands route answers for one repository.

  2. Read the next action before the figures.

    It is computed from the same rows the queue shows, in a fixed order: past SLA, then the fix that has waited longest, then a connector in a health state, then quiet. Its button opens the case, the case's Fix section, or Settings. On the hosted page a built fix sends you to Remediation, because the decision is taken on the desktop that built it.

  3. Narrow with the filters and let the URL carry them.

    Class chips (All, Production, Performance, Security, Cost), then Repository, Environment, Service, Severity, Developer, Status, Owner, Seen within and Include closed cases. Every change is written back to the address bar under the contract name; Clear filters removes them all. The developer select's Unattributed entry selects cases that name nobody, which differs from Owner: Unassigned, a case nobody has taken.

  4. Work the queue in its order.

    Rows are ranked overdue first, then by severity, and the count line says so: N of M, overdue first, then by severity. The first page is 100 rows on the desktop and 50 on the hosted page; Show older cases (N more) appends the next page after a cursor, and the count and the figures are computed over the whole filtered set, never the page.

  5. Read the aside for what is not delivering.

    Collection health lists each enabled adapter for the repository by its state: Delivering, last read N ago; Stale, last read N ago; Never fetched; No credential stored; or the provider's code with the attempt count and the retry due. Overnight counts what the loop built, declined and held in the last 24 hours. Sync reads the daemon state with buffered, delivered and acknowledged counts.

  6. Report a problem a source did not see.

    The Report a problem form takes the repository id, Class, Severity (medium by default), what went wrong (5 to 200 characters), environment, service and a note. Report the problem writes one record keyed on the problem, so a repeat folds and reads Already reported at that time; nothing new was written. The case opens by rule on the next pass, under the floors below.

SettingWhereA sensible choiceWhy it matters
repo, environment, service, class, severity, developer, unattributed, status, assignee, since, until, openthe address bar, written by the Case filters form on both appswhatever narrows the queue to what you own todayAn unknown value reads as no filter, never as a value the store would refuse. A link naming both developer and unattributed asks for two disjoint sets; the developer is dropped and the count line says so.
sinceSeen within, or since= in the URL24h, 7d or 30d, or an ISO instantA window is resolved against now on each load, so a shared link keeps meaning the last seven days rather than a fixed date.
untilthe scope bar's custom range, or until= in the URLan ISO instant; a date from the bar covers its whole dayA case is kept when it was seen inside the range: last seen after the start, first seen before the end. An end before the start is dropped and the count line says so, so a mistyped range never reads as a quiet week.
openInclude closed cases, or open=0 in the URLleave it off; tick it to see resolved, false positive and duplicate casesThe queue is open cases only unless a status is named or open=0 asks for everything.
REPOOPS_AIR_CASE_MIN_SEVERITYthe data directory's .envhigh (the default)A security finding at this severity or worse opens a case. It decides how full the queue gets; preview a value with the open route's dryRun before committing to it.
REPOOPS_AIR_PROD_RECURRENCEthe data directory's .env3 (the default)A production incident carries no severity, so its floor is a count of distinct sightings before a case opens.
REPOOPS_AIR_OPEN_SCHEDULEthe data directory's .env1 to open cases on the daemon's hourly tick, unset to leave it to a buttonOff unless the value is exactly 1. Set the floors first: the shipped defaults measured on one repository would have opened 210 cases in a single tick.
dailyBuildCapUsdRemediation, the Build policy card, Daily build cap (USD)10 (the default), or 0 to stop unattended buildsBuild spend today meters measured spend against it. With no cap read the figure says measured; no cap read; with 0 it says cap $0: unattended builds off. The hosted page has no team cap and says so.
Incident SLA hourshosted Settings, the Incident SLA (owner/admin) card, then Save; no desktop controlthe defaults, critical 4, high 24, medium 72, low 168 hours, until the team decides otherwiseThe due clock, Past SLA and the first rung of the next action read these hours. The desktop tab uses the defaults; no environment key changes them.
ⓘ
To stop or undo
Today has no switch; it is a read over stores other features write. To quiet it, clear the filters, or raise REPOOPS_AIR_CASE_MIN_SEVERITY and unset REPOOPS_AIR_OPEN_SCHEDULE so fewer cases open. A report cannot be withdrawn from this page; the case it opens is closed on the case itself.

What you should see

A late critical case

Configuration. One tracked repository with a critical case whose four-hour clock has run out, no built fix, and a delivering source.

Expect. The next action reads Decide <case>: critical, N past its SLA and offers Open the case. Past SLA reads 1 with 1 critical under it. The row sits first, its due column reading N over.

Verify. The count line reads 1 of 1, overdue first, then by severity. Open the case; the URL gains case=<id>, and reloading it opens the same case in the dialog.

A quiet machine with nothing connected

Configuration. A fresh install, one tracked repository, no adapter enabled, no session scanned yet.

Expect. The next action reads Fix the Session signals, this machine connector: no session scanned yet, or Nothing waits on you once it has scanned. Open cases reads 0 with Production: no source, Performance: no source, Security: no source, Cost: no source. Source families observed reads 0 of 5.

Verify. The aside reads Session signals, this machine with no session scanned yet and Cost sources with none connected. The cases area shows the zero state with Connect a source. No figure reads a bare 0 for a class.

A built fix waiting at the gate

Configuration. No case past its SLA; the remediation loop has built one fix with a recorded verdict and the pull request is open.

Expect. The next action reads Approve the fix for <case>, or reject it with a reason, with when it was built, five checks green or a check failed, and the PR number, and offers Open the Fix section. Fixes waiting on you reads 1 with 1 of 1 with five checks green. The row's meta reads fix built, PR #<n>.

Verify. The lead line reads 1 fix is built and waiting on you. Overnight in the aside counts it under Built once its build finished in the last 24 hours. The decision itself is on the case's Fix section, described in the auto-remediation guide.

Data and cost

What is captured
Today writes nothing of its own. The filters are the URL. The focused page reads the case queue, remediation bands, collection health, lessons and sync state. Opening it does not start fleet analysis, coaching or recommendation scans. The one write is Report the problem, which appends one production event record to the repository's brain, keyed on the problem so a repeat folds.
Who can see it
Local: anyone who can open the desktop app on this machine. Hosted: a member sees the cases in the repositories their scope allows, and the Repository, Environment, Service and Developer choices are computed from that scope, so nobody is offered a repository they cannot open.
How long it is kept
The case store is read over a 24-month window of monthly files. Today holds no data of its own to expire. No retention knob exists on the tab; see Delete below.
What leaves the machine
The queue makes no model call and sends nothing off the machine; it reads local routes. What the daemon delivers to a bound team is other features' work, and the Sync line reports it as buffered, delivered and acknowledged counts. The previous folded analysis and coaching panels are retired from Today.
What it costs
Nothing for the queue. Build spend today is the remediation loop's measured spend, shown here, not spent here. The page makes no model call.

When the result differs

SymptomLikely causeNext action
A class reads no source.No connected source observes that family for the repository in scope. Security is credited only once the session-signals scan reports at least one scanned session; Cost needs a cost observation source.Connect a source in Settings, or run one Claude Code session in the repository and press Refresh.
The cases area reads The case store could not be read. This is not an empty queue.GET /api/ai-incidents failed or answered without rows.Press Refresh. If it persists, the server log names the repository whose store failed.
The count line ends with partial: some repositories could not be read.One repository's case store threw; the others were read and ranked.Check that repository's path in repos.config.json; the route lists it under soft_failed_repos.
A shared link shows fewer cases and the count line says developer filter ignored.The URL names both developer and unattributed, two disjoint sets.Remove one of the two keys; the parser keeps unattributed.
Fixes waiting on you and Build spend today read Unavailable.GET /api/remediation/bands answers for one repository and refused without one, or its read failed.Open the tab with a repository in scope, then Refresh.
Build spend today says measured; no cap read.The account policy read failed, or no daily cap is stored.Set Daily build cap (USD) on the Build policy card on Remediation and Save policy.
Past SLA on the hosted page says on this page.There is a next page, and the hosted count covers the rows loaded so far.Narrow the filters until the queue fits one page; the desktop figure counts the whole filtered set.
The scope bar says Environment narrows this page's case list only.On the desktop, environment, service and time reach the case list; the fixes, lessons and sync panels read the whole repository.Read those panels as repository-wide. The hosted page names each panel the scope cannot narrow.
Retrieve missing evidence is disabled.On the desktop retrieval runs from the hosted case. On the hosted case the reason is under the button, for example: This repository has no managed capture policy, so no enrolled installation can be asked.Open the case on the hosted page as an owner or admin, or enroll the repository in a managed capture policy.
You reported a problem and no case row appeared.The page answers Reported. It is recorded as an incident now and opens as a case in this queue by rule on the next pass, under the severity and recurrence floors.Wait for the next pass, or preview what the floors would open with the open route's dryRun as .env.example shows.
Disable
Not provided. Today is a read over the case store and has no switch. Fewer cases open when REPOOPS_AIR_CASE_MIN_SEVERITY is raised and REPOOPS_AIR_OPEN_SCHEDULE is unset; the tab itself stays.
Roll back
Not provided, and nothing to roll back: the filters are the URL and Clear filters resets them. A report already written cannot be withdrawn; the case it opens is decided on the case.
Revoke access
Local: not provided; the desktop tab has no per-user access. Hosted: the page applies the member's repository scope on every read (website/lib/member-repo-scope.ts, website/lib/team-repo-narrowing.ts), so narrowing a member's scope narrows their queue at once.
Delete
Not provided. No route deletes a case; the desktop file is the repository brain's incidents/cases/YYYY-MM.jsonl and the hosted rows sit in the team's case store. Today shows them and does not own them.

Maintenance evidence

Feature id
today (spine leaf today)
Owner
Incident-response tab map, step 3 (LDG-0661; the filter contract LDG-0682, paging LDG-0687, the report form LDG-0689). Guide: LDG-0717.
Supported product version
RepoOps main at 509e8e8ad (after v0.3.2)
Last verified
2026-09-26, read again against origin/main at 509e8e8ad for the scope bar (public/lib/scope-bar.js, lib/scope-bar-contract.mjs, website/lib/page-scope.ts), the readiness line (public/lib/page-readiness.js), the case dialog (public/lib/case-dialog.js), Evidence coverage (lib/raw-fidelity/case-coverage.mjs, website/components/case-coverage.tsx) and the hosted managed coverage failures (website/lib/managed-compliance.ts). First read 2026-09-15 at 52366bb6d: labels from public/today.html, public/lib/today-queue.js, website/app/team/(home)/today/page.tsx and website/components/incident-workspace-queue.tsx; the SLA defaults, the case floors and the bands route from lib/ai-incident-case.mjs, .env.example and lib/routes/today.mjs.
Example fixtures
test/fixtures/today-query-parity.json, the one query-string fixture both parsers must read the same way (test/today-query-parity.test.mjs). The rest is inline: public/lib/today-queue.test.mjs (the eleven filters, the next-action order, the no-source rule, health by code, the 24-hour overnight tally), website/lib/today-filters.test.ts, website/app/team/(home)/today/page.test.tsx, lib/today-remediation.test.mjs and lib/incident-source-contract.test.mjs.
Source references
lib/canonical-spine.json, lib/incident-source-contract.mjs, lib/routes/ai-incidents.mjs, lib/routes/today.mjs, lib/routes/integrations.mjs, lib/ai-incident-case.mjs, lib/ai-incident-intake.mjs, lib/zero-states.mjs, public/today.html, public/lib/today-queue.js, public/settings.html, website/app/team/(home)/today/page.tsx, website/lib/today-filters.ts, website/app/team/(home)/settings/incident-sla-card.tsx, public/lib/scope-bar.js, lib/scope-bar-contract.mjs, public/lib/page-readiness.js, public/lib/case-dialog.js, lib/raw-fidelity/case-coverage.mjs, website/components/case-coverage.tsx, website/lib/managed-compliance.ts
Documentation review
Revised 2026-09-26 by the authoring agent against the code (LDG-0988); independent review not yet recorded.
Video review
Narrated story rendered and published 2026-09-26 (render 65fbcea2a66b, LDG-0988), beside the desktop navigation with the six pages as they ship. Six frames, the captions and the transcript were reviewed by the authoring agent, not an independent reviewer; the audio was not listened to by a person. It is a labeled synthetic explanation, not a recording of the app. The in-browser TodayWalkthrough plays when no published story is listed.

Last updated