Interactions and findings
Interactions and Findings read the same records. Every inspection an agent performs produces an interaction record, and the Findings list shows every record where at least one detection matched. Findings is therefore the same table with that filter permanently on, offering severity where Interactions offers the action taken.
Not every match is counted as a finding. A match on text already reported earlier in the same conversation, a match in an earlier turn that an AI coding tool re-sends with every request, and the removal of content already blocked earlier in the conversation are recorded, but counted as agent activity. See Service limits for the exact rule. Hide repeats, on by default on Findings, hides those matches, which the Findings today figure on Overview does not count either. Conversely, a Block or Redact, or a would have blocked or would have redacted, that no detection explains (an access rule, or a policy whose default action blocks) is counted as a finding but matched nothing, so it is on Interactions, with the action it took, and not on Findings. For a worked example (one secret re-sent through a 40-request coding session: one finding, 39 rows of agent activity), see One secret in a 40-request session.
Interactions — everything, with the action Lumen applied:

Findings — the subset that matched, with severity and the rule that decided:

What each table shows
| Interactions | Findings |
|---|---|
| Time | Severity |
| Endpoint | Detection class, with its subclass where there is one |
| Application and model | Score |
| Prompt or response | The rule that decided |
| Detection classes that matched | Endpoint and application |
| Action taken | Action taken |
| Time |
The Detections column on Interactions names the detection the finding is about and counts the rest. On Findings, the Detection chip and the Score always describe the same detection: the one the rule that decided actually matched, or, when no rule decided, the strongest non-language match. A language identification only leads a row when a language rule decided it. See The console for how severity is derived and what Shadow means.
Filters
| Filter | Interactions | Findings |
|---|---|---|
| Time range | Yes, the last 24 hours by default | Yes, the last 7 days by default |
| Free-text search | Yes | Yes |
| Action taken | Yes | No |
| Severity | No | Yes |
| Prompts or responses | Yes | No |
| Who wrote the text (origin) | Yes | No |
| Where a finding matched | No | Yes |
| Detection class | Yes | Yes |
| Collector | Yes | Yes |
| Endpoint | Yes | Yes |
| Hide repeats | No | Yes, on by default |
Filtering happens on the server, over the whole time range rather than over the rows on screen, and changing any filter returns to the first page. Changes to the selects are applied together a moment after the last one, so setting three of them costs one query.
Every list covers a time range. Findings opens on the last 7 days and Interactions on the last 24 hours; the range select also offers the last hour, the last 30 days, and All retained, which is everything your plan keeps (30 days on Free; on Pro a year for findings and prompts and 90 days for agent activity, see Service limits). A narrow range is what keeps a large workspace's lists fast, since every filter is answered only over the records inside it. When a list comes back empty it says which range it searched and offers the next wider one, such as Search the last 30 days.
What the search covers
The search runs when you press Enter or select Search, not as you type, and
needs at least 3 characters (up to 200). Clearing the box removes the search at
once. It matches the text literally: % and _ are those characters, not
wildcards.
The search is a case-insensitive substring match across the captured text, the
interaction identifier, the rule that decided the action, the reason recorded
with that decision, the reporting hostname, the collector identifier, the
application, the provider, the model and the user. It reads the application,
provider and model under every name a collector records them, so a record the
browser extension captured is found by the site's name, as the Application
column shows it: searching chatgpt, claude, perplexity, gemini or
Google Gemini returns those conversations. The user is the one the
record shows: the name a collector recorded or, when none did, the person who
ran the agent's installer on that endpoint.
A search can be up to 200 characters long, and spaces around it are ignored.
Every character is matched as typed: 50% finds "50%" and not "500", and
max_tokens finds only that word. Each field is searched on its own, so a
search that runs from the end of one field into the next (the text and then
the hostname, say) finds neither.
The search is the slowest filter, because it reads what was captured. The
others (the time range, severity, class, collector, endpoint and the rest) are
applied first, and the search reads only the records they leave, so a search
over a narrow filter, such as Critical findings from the last 7 days, answers
about as fast as the filter alone.
The captured text being one of them has a consequence worth stating plainly. Anyone who can open the console can free-text search what colleagues typed into a model, and what the model replied. See What Lumen stores.
Paging and order
Both tables page 25 rows at a time on the server. The pager below the table moves to the First, Previous and Next page, and every page loads as fast as the first, however far into the list it is. Rows captured in the same instant keep a fixed order, so moving between pages never repeats or skips one.
Time is the one sort. The rows are newest first; select the Time column header to see the oldest first, and select it again to go back. The sort applies to the whole list across every page, not only to the rows on screen, and it stays as you change the filters. The other column headers do not sort: a header that re-ordered the 25 rows on screen would look like it sorted the whole result, and it would not.
The total is counted separately. Beside the pager, the list says how many records match its filters and time range, for example 19,086 findings in the last 7 days. The rows do not wait for that count: it can read Counting… for a moment after they appear, and when everything fits on the first page it is simply the rows on screen. The console counts at most 10,000 matching records, so a larger total reads 10,000+ findings (there are at least that many). On Findings the 10,000 include the hidden matches, so a count can also stop at, say, 9,000+ findings, and the line saying how many matches are hidden (N matches hidden, not counted as findings) then carries a + too. A count that would take too long is abandoned and reads Count unavailable, while the rows, the pager and the sort keep working. Narrowing the time range or the filters brings back an exact count. Moving between pages or changing the sort never counts again.
While a list loads, and when it cannot
A list always says what it is doing. After a filter change the rows from the previous filters stay on screen, dimmed, under an Updating… line until the new ones arrive, and a list that is still empty reads Loading… rather than "no results". After a few seconds the line says the view is taking longer than usual. When the rows are current, the line says when they were loaded (Updated 10:42 AM) next to a Refresh button: the lists do not reload themselves when you come back to the tab.
A list that fails shows why instead of the table, never the previous filters' rows and never an empty result. This view took too long to load means the query ran out of time: it offers a narrower time range, such as Last 24 hours, and Retry. Any other failure shows the reason and Retry. A record's detail view says it may have aged out of retention only when it no longer exists; if it could not be loaded, it says so and offers Retry.
The address keeps the view
The search, the filters, the time range, the sort and the page are part of the
page's address, for example /findings/?q=token&severity=critical&range=24h&order=asc,
followed by a cursor that marks the page once you move past the first.
Reloading the page keeps them, going back from a record's detail returns to
the same filtered page, and copying the address shares the view with anyone in
the same workspace. The address carries only what differs from the defaults,
so the unfiltered Findings page is just /findings/. A time range such as the
last 7 days is measured from when the address is opened, so the same link
opened tomorrow shows tomorrow's last 7 days. Filtering does not add a step to
the browser's history: Back leaves the page, as it does from any other.
Hide repeats is your own choice, remembered for you rather than written in the address, so a shared link shows repeats the way the person opening it chose to, and its pages count that way too. The one exception is the Findings today figure below, whose link hides repeats for that view.
A value in an address that a filter does not offer, such as a severity that
does not exist, is ignored and that filter shows its default. The origin,
where a finding matched and endpoint filters keep a value as written, so a
misspelled one finds nothing rather than everything. An address whose page no
longer holds anything, such as a page reloaded after its records aged out of
the time range, says so and offers Go to the first page, and so does an
address whose page the console cannot open, such as one edited by hand. An
address saved before the pager changed, with a page=3 in it, opens the first
page of the same filtered list.
The figures on other pages link through the same way. The four day-scoped figures on Overview count the current UTC day, and open their list on the last 24 hours, which covers it: interactions and findings (with Hide repeats on), and Interactions with the action filter applied for blocked and redacted. The list can therefore also show rows from before 00:00 UTC, and the Findings list leaves out a finding that matched nothing (above). Each detector on the Detectors page opens Findings filtered to its class over the last 30 days.
The detail panel
Selecting a row opens the whole record.

- The verdict. The action taken, the severity where the record is a finding, a Shadow badge where an access rule capped the outcome, a Block not applied or Block unconfirmed badge where the browser did not apply the policy's decision (below), and whether this was a prompt or a response.
- The captured text, as stored. No matched value is ever in it: a value a
rule redacted appears as its
[REDACTED…]placeholder, and a value that was only logged (monitor mode, a log rule) as[MASKED…], and both are highlighted. A record written by an agent release that predates this masking shows its matched values as captured, and says so under the text. A text that was cut says which cut it was, and how much the endpoint sent (see the table below). - The decision, in the engine's own words.
- Each detection that matched, with its class, its subclass, its score and where in the record it was found.
- The context: time, endpoint, user, application, provider and model,
the collector that captured it, the policy and version that judged it, and the
rule that decided the action. A browser record names the site it was
captured on (ChatGPT, Claude, Perplexity, Google Gemini) and its vendor, and its collector
line also names the extension build that captured it (Browser · extension
v2.8.0); records from extensions of v2.7.0 and earlier show Browser alone,
because those builds did not report a version. A call to the agent's
local inspection API that sent no context shows the
collector_idthe caller gave, marked (collector id). A field nothing recorded shows—. - The interaction identifier, with a control that copies it.
Text that was cut or not stored
How much text the console keeps depends on the kind of event and on the endpoint's daily allowance (Service limits). The captured-text section says what happened to a record's text, in words:
| The panel says | What happened |
|---|---|
| Trimmed to a 16 KB window around the match | A finding longer than 16 KB, cut around where it matched. The note gives what the endpoint sent |
| Trimmed to the last 16 KB | A finding longer than 16 KB whose detector does not report where in the text it matched. The newest text, where the current turn is, was kept |
| Trimmed to the first 8 KB or Trimmed to the last 8 KB | A prompt or a clean agent event longer than 8 KB. Clean events keep 8 KB, findings a 16 KB window |
| Text not stored: over the day's allowance of prompts and agent events | The endpoint had already stored the text of its daily allowance for the day the event is counted against. Lumen inspected the event and applied the policy as usual, and the row keeps when it happened, the tool, the model and the destination |
| Command excerpt only: over the day's allowance | The same, for a tool call: the start and the end of its command are kept, with whitespace collapsed, and the note gives the full command's size |
| Text not stored: the endpoint did not send it as text | A finding whose text field arrived as something other than text. Findings have no allowance, so this is never a volume decision; the finding is counted and kept like any other |
| A short utility call from the client | A title or topic request the client made on its own. Its text is not uploaded |
| Truncated | The endpoint cut the text itself before uploading it (at most 64 KB, or 8,192 characters for the MCP wrapper) and no service-limit cut applied, as on records stored before the service limits |
Two more notes can appear. Some fields of this event were shortened to fit the service limits means something other than the text, such as an oversized context field, was cut. On an endpoint past a capacity ceiling, a row that stands for others says so: +N similar findings this hour were counted but not stored, or events for anything that is not a finding. The Partially inspected note names why the bounded detectors stopped, when the endpoint reported it.
In the tables, a row without its text shows Text not stored: over the daily allowance (or Text not stored: not sent as text for a finding), and a utility call Utility call: text not uploaded, where the text would be.
When the endpoint's clock ran ahead and Lumen stored the event at its arrival time instead, the time line also says what the endpoint claimed (the endpoint claimed …). See Late records.
A block the browser did not apply
The action column says what happened, which for a browser record is not always what the policy decided. The browser extension applies Block and Redact in the page, holding the prompt while it waits for the agent's verdict, and it sends the prompt unchanged when the verdict does not arrive in time (see Browser extension, known limits). It then tells the agent whether it applied each Block or Redact, and the record states that:
| The row shows | What happened |
|---|---|
| Block | The browser stopped the prompt before it was sent. The detail panel's context lists Enforcement: Applied in the browser. |
| Log with Block not applied | The policy decided to block, but the decision reached the browser after the prompt had been sent. The prompt went to the provider, and the provider may have answered it. |
| Log with Block unconfirmed | The policy decided to block, and the browser never confirmed it applied the block (the tab or the browser closed first, for example). The prompt may have been sent. |
| Log with Redact not applied or Redact unconfirmed | The same, for a redaction: the prompt went, or may have gone, as typed. The stored text still has the matched values masked, as [MASKED…] rather than [REDACTED…], since nothing was removed before sending. |
These records keep the severity of what the policy decided, so a late block of a credential still reads High or Critical, and they count toward Overview's would have been blocked figure, never toward Blocked. A blocked prompt's text is not stored whether or not the block was applied, so the detail panel explains the absence instead of showing an empty box. Records from extension builds of v2.7.0 and earlier do not report whether a block was applied, and show the policy's decision as they always have.
Long records are shown up to a point. A record carries the text that was inspected, and a coding assistant re-sends its whole transcript on every turn, so records grow with the conversation rather than with the message. The table loads at most the first 4096 characters of each one, and the detail panel renders what the table loaded, so a long transcript is abridged there.