Commit Graph

8169 Commits

Author SHA1 Message Date
Katia Bulatova 7a645e5149 chore(webapp): drop the comments the code already says 2026-08-06 10:49:04 +00:00
Katia Bulatova 3336a47d1e test(webapp): give the container-backed user-actor scope tests their own timeout 2026-08-06 10:32:58 +00:00
Katia Bulatova f700174b44 fix(webapp): ceiling an exchanged environment JWT by what the delegated token can do
A user-actor token declaring no scope cap could mint an environment JWT with any
scopes it asked for. The exchange now clamps the minted scopes to the actor's own
ability, so a capless token is read-only, and only mints for its claimed environment.
2026-08-06 10:32:56 +00:00
Katia Bulatova a7fc406781 fix(webapp): keep a delegated token's claims on the authenticated identity
The direct PAT authentication path returned identity only, so a user-actor token
reaching it (admin routes and other direct callers) lost its environment scope. The
claims now ride on the authentication result itself.
2026-08-06 10:32:55 +00:00
Katia Bulatova d00b1266e4 fix(webapp): bind a delegated token's environment claim on the project-wide routes
The environments and runs listings are project-wide, so an environment-scoped
user-actor token could read every environment its user can reach. Both routes now
resolve the claim into a mandatory filter, and a conflicting request filter is
refused rather than overridden.
2026-08-06 10:32:54 +00:00
Katia Bulatova 4e00b7952f style(webapp): format the sweep's authorization helper 2026-08-06 10:29:14 +00:00
Katia Bulatova 478b30cc2c chore(dashboard-agent): drop the test comments the assertions already say 2026-08-06 10:28:07 +00:00
Katia Bulatova 240799d0aa chore(dashboard-agent): drop the comments the code already says 2026-08-06 10:28:06 +00:00
Katia Bulatova 210863ea76 fix(webapp): separate a watch's last look from its last check in the batch order
A tick that could read nothing now moves the group's fairness key only, so a watch
with a permanently broken reader stops crowding out the rest of an over-cap group.
Dueness and the streak facts still follow the last real check.
2026-08-06 10:28:05 +00:00
Katia Bulatova 22bf6d919a fix(webapp): cancel the watch a losing submit's winner does not name
A refusal that won the race kept the reserved watch id, so the user was told
nothing was created while that watch stayed active.
2026-08-06 10:28:04 +00:00
Katia Bulatova 09d1b55e22 fix(webapp): require the watch card's request id instead of falling back to its condition
A per-condition fallback identified the condition rather than the submit, so a
re-watch could replay a stale terminal outcome from the retention window.
2026-08-06 10:28:03 +00:00
Katia Bulatova 9daa8f92eb docs(dashboard-agent): tell the judge the error category is derived, the message withheld
Also reuse the policy's errored-output check instead of a second copy of it.
2026-08-06 10:28:02 +00:00
Katia Bulatova fb99526809 feat(dashboard-agent): tell the eval judge a failure's kind without its message
Classify a failed tool result locally into one of seven categories and send only
the label; the message is dropped with every other free-text field. Unrecognised
failures are unknown rather than guessed, and a bare string error field is now
withheld too.
2026-08-06 10:28:01 +00:00
Katia Bulatova 5adba81b9b docs: document CSP_IMG_SRC_ALLOWLIST for self-hosted image hosts 2026-08-06 10:28:00 +00:00
Katia Bulatova cd112ba2a3 test(webapp): assert the document img-src has no wildcard host 2026-08-06 10:27:59 +00:00
Katia Bulatova 48d0d4a707 fix(webapp): drop the img-src wildcard host for a validated origin allowlist
Replaces https://*.googleusercontent.com (a host with public write access)
with CSP_IMG_SRC_ALLOWLIST: exact origins only, https outside development,
deduplicated, bad entries warned about instead of failing the boot.
2026-08-06 10:27:58 +00:00
Katia Bulatova d73f3f5c61 chore: ignore the agent worktrees directory 2026-08-06 10:27:43 +00:00
Katia Bulatova 05b3472801 Merge branch 'main' into feat/dashboard-agent-flows
Route conflicts were the tab-title work meeting the agent page-context handle: both
sides kept, duplicate meta exports resolved to pageMeta, duplicate imports merged
with unused bindings dropped. Lockfile regenerated from the merged manifests.
2026-08-06 10:27:43 +00:00
Katia Bulatova 933aeb9ea4 test(webapp): stub the agent proxy's environment lookup, not a Prisma row
The hand-built row stopped satisfying every column the authenticated-environment
mapper reads, so both proxy cases failed. Stubbing the lookup keeps the fixture
independent of the row's columns.
2026-08-06 09:44:50 +00:00
Katia Bulatova 82f4a73b9d style(webapp): drop a needless escape in the image regex 2026-08-06 09:42:47 +00:00
Katia Bulatova d9ff853f09 style(webapp): format the agent eval and step-cache tests 2026-08-06 09:42:46 +00:00
Katia Bulatova 32553b903d style(webapp): format the agent markdown test 2026-08-06 09:42:46 +00:00
Katia Bulatova 488621e033 perf(webapp): cache the agent's accumulated tool results between steps
A step-level 5-minute cache breakpoint rolls onto the growing history once it is large enough for the write to pay for itself, and each step logs the provider's cache write and read counts.
2026-08-06 09:42:45 +00:00
Katia Bulatova 1aee9cac35 fix(webapp): send the eval judge only the turn's structural facts
The judged turn now passes an allow-list of structural fields instead of a deny-list of known-sensitive names, unfolds the tool-output envelope so error text is redacted too, truncates inputs as well as outputs, and caps the whole turn.
2026-08-06 09:42:45 +00:00
Katia Bulatova 94ec67fd53 perf(webapp): keep the agent transcript's investigation winners stable
The winners map was rebuilt on every streamed token and handed to the memoized turns as a fresh reference, re-rendering the transcript. The reference is now reused while the winners hold.
2026-08-06 09:42:44 +00:00
Katia Bulatova dd90b6e968 fix(webapp): never render an image the agent's model authored
A remote image in model output fetches on render, so its URL is an exfiltration channel. No image is rendered at all, and the document CSP now names the hosts images may come from.
2026-08-06 09:42:43 +00:00
Katia Bulatova a0640ba248 style(webapp): format the watch tenancy changes 2026-08-06 09:40:30 +00:00
Katia Bulatova a63708c6e6 test(webapp): assert the derived chat id before the submit outcome 2026-08-06 09:40:29 +00:00
Katia Bulatova 5176e3e8c4 test(webapp): pin the watch ledger's tenancy, the once-only alert and the owner-scoped unsubscribe 2026-08-06 09:40:29 +00:00
Katia Bulatova 5f2f5fe241 fix(webapp): scope the watch submission ledger and its alerts to one tenant
The chat id a fresh submit derives, the transcript appends, the create's chat read
and the ledger replay are all owner-scoped now, the fire callback alerts once per
terminal outcome, and a failed email subscription is stated instead of dropped.
2026-08-06 09:40:28 +00:00
Katia Bulatova 012ce0de53 test(webapp): drop an unsafe optional chain from the sweep boundary test 2026-08-06 09:39:17 +00:00
Katia Bulatova 4846cf8ea0 fix(dashboard-agent): finish a wake in the transcript, or don't count it
A settled investigation now lands as one more revision of the same card, so the
in-progress card and its working line end. An empty narration writes nothing and
says so, and only an acknowledged append marks a wake delivered.
2026-08-06 09:39:17 +00:00
Katia Bulatova bd2559a7a8 fix(webapp): record only a real evaluation from a batch tick
An unreadable check is not an observation, so writing it moved the watch down the
rotation for a whole cadence and overwrote the facts a streak lives in.
2026-08-06 09:39:16 +00:00
Katia Bulatova e4852090aa perf(webapp): resolve the sweep's authorization and readers once per group
An incident expires a whole group at once, which is the worst time to repeat the
same authorization read per row. Bounded concurrency caps one tenant's share.
2026-08-06 09:39:15 +00:00
Katia Bulatova d2511bd264 fix(webapp): hand the sweep's final check the previous facts
A stateful condition is a transition across checks, so a boundary evaluation
without the last observation can never see a stall and records a reset.
2026-08-06 09:39:15 +00:00
Katia Bulatova d12e6a85ca style(webapp): merge duplicate imports on the user-actor auth path 2026-08-06 09:24:09 +00:00
Katia Bulatova f58a9dcc89 fix(webapp): only let the browser set the agent's page context
The chat turn's metadata is now a whitelist: the page the user is on is all the browser can set, and every identity, tenancy and token field is filled in by the server.
2026-08-06 09:24:09 +00:00
Katia Bulatova d51cb9a736 fix(webapp): stop the OSS fallback handing a delegated token blanket access
Without an RBAC plugin, a user-actor token got the same permissive ability a personal access token gets. It now gets only what its own scope cap allows, and reads only when it declares no cap. Personal access tokens are unchanged.
2026-08-06 09:24:08 +00:00
Katia Bulatova 9d45284112 fix(webapp): keep the agent token's environment claim on the actor through every route builder
The claim rode beside the authentication result, so a route builder that only forwarded the user id lost it. It now travels on the authenticated actor itself, and a route's resolved org/project/environment is checked against it — a mismatch fails closed.
2026-08-06 09:24:07 +00:00
Katia Bulatova 880bf60f48 test(tsql): pin that no mutating query can pass the query boundary
The agent's run_query path compiles TRQL, which has no write statements, so a
mutation cannot parse. Cover the deny-list evasions a keyword filter would miss
(casing, comments, a statement smuggled after a semicolon) and keep positive
controls so the negatives can't pass by rejecting everything.
2026-08-06 09:10:22 +00:00
Katia Bulatova f5a146b30c fix(webapp): cap the agent's body on any method and on a mixed-case path 2026-08-06 08:50:11 +00:00
Katia Bulatova 337dda1e97 feat(webapp): name of the page in tab titles (#4517)
Adds a shared `pageMeta()` helper and 74 route declarations, so a title
reads `run_abc | Runs | Trigger.dev` — the specific thing first, then
the page. Org pages also carry the organization: `Team | Acme |
Trigger.dev`. Inside a project no scope is added, because the dashboard
switches projects in every tab at once.

Page names are unchanged; what's new is that a page says which one it is
at all. Three wording changes on purpose: the queue page now names the
queue, the model page names the model, and entity pages carry their
section.
2026-08-06 10:34:30 +02:00
Katia Bulatova 85b98ab8dc fix(webapp): mint the agent's token for the caller's own environment, or not at all 2026-08-06 08:20:52 +00:00
Katia Bulatova 62b598da27 docs(webapp): say which layer refuses an oversized agent body
The route-level check only sees a declared content-length; a body without one is
already ended mid-stream by the ingress cap.
2026-08-06 07:14:41 +00:00
Katia Bulatova 1cdf1f087d refactor(webapp): split the dashboard agent's maintenance cron along the watch seam
dashboardAgent.sweepWatches ran the watch sweep, the investigation sweep, the
batch re-arm and eval retention together. Watch is about to ship as its own
stacked PR, so the job is split where the cut will be: dashboardAgent.maintenance
keeps the investigation sweep and eval retention, dashboardAgent.watchMaintenance
takes watch expiry, delivery and the batch re-arm. Same cadence, and each backstop
keeps its own try/catch.
2026-08-06 07:14:41 +00:00
Katia Bulatova 50fd10bf1b fix(webapp): replay a watch submission's recorded outcome instead of re-running it
A retried card submit was only repairable while the first attempt's watch was
still active. Once it had fired, expired, or answered in one shot, the retry
re-evaluated the condition and created a second operation.

A watch_submissions ledger, keyed (chat_id, client_request_id), is now written
before the condition is read and carries the outcome once there is one. A retry
looks it up first: a recorded outcome is replayed, a different draft under the
same id conflicts, and only a pending row proceeds - converging on the watch id
reserved up front rather than creating another.
2026-08-06 07:14:40 +00:00
Katia Bulatova 4ff8859e1d fix(webapp): keep the agent's alert delete to channels the watch type is on 2026-08-06 01:54:46 +00:00
Katia Bulatova cbc2edc879 test(webapp): pin the watch submit's ordering, its retry repair and its refusal record 2026-08-06 01:54:45 +00:00
Katia Bulatova 49a953871a fix(webapp): record a watch request before the watch starts, and repair a retried submit 2026-08-06 01:54:44 +00:00
Katia Bulatova 28b1f3896c fix(webapp): cap the agent's request body while it streams, not after
The message-size checks ran after the body had been read, so a request without a
content-length was buffered and parsed in full before being refused. An ingress
cap on the agent's paths now counts the bytes as they arrive, and the chat proxy
reads its body with a ceiling instead of reading it whole first.
2026-08-06 01:53:17 +00:00