Skip to content

FE-1763: Let Brunch build Petrinaut nets as capably as the existing assistant - #9811

Merged
lunelson merged 96 commits into
mainfrom
ln/pn-tooling-remediation
Sep 29, 2026
Merged

lunelson merged 96 commits into
mainfrom
ln/pn-tooling-remediation

Conversation

@lunelson

@lunelson lunelson commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

🌟 What is the purpose of this PR?

Brunch used to change Petrinaut nets through its own narrow editing path. That path couldn't express the sequences of changes the existing Stock assistant makes, so Brunch struggled to build a complete model from a description. This PR gives Brunch the same editing tools the Stock assistant uses. Petrinaut decides what each edit means and does, and Brunch adds what it's for: interviewing the user, keeping the Ledger of what has been agreed, proposing experiments for review, and explaining how the net came to be.

Getting there also meant removing what no longer earned its keep. The branch had carried alternative construction strategies, evaluation modes, a matched-parity evaluator, a worked-model feature, unmounted plugins and a server-side check that re-verified what the browser had already reported; all of them are gone, and with only one way left to run Brunch, so is the mode switch. A conversation opened from the Petrinaut panel is bound to its document and gets Petrinaut's tools; one opened without a binding, as on Brunch's own chat page, gets the interview and modelling guidance only. Brunch credits each net change to the tool call Petrinaut says applied it. Every Petrinaut assistant runs on one default model, which Petrinaut defines: GPT-5.5 at medium reasoning, as the original assistant did.

Browser-visible persona runs on inventory-purchasing (from #9833) show Brunch building an executable net alongside the interview, with timed supply, quality release, shelf life, FEFO draws, metrics and saved scenarios, and no failed tool calls beyond one expired browser lease. They also show where the time goes: rewriting the whole Ledger on every turn takes 70% of model time. Native Stock parity, live Voice and running a reviewed experiment draft in a production build are still unproved.

🔗 Related links

🚫 Blocked by

  • Review.

🔍 What does this change?

Petrinaut libraries

  • petrinaut-core splits the Stock prompt into a behavioural frame and reusable capability guidance, recomposed in the original order. It also exports petrinautAiModel, the default model for every Petrinaut assistant: gpt-5.5-2026-04-23 at medium, the original assistant's setting.
  • petrinaut exports executePetrinautAiMutation, so a host can run one canonical edit with Petrinaut's own no-op detection and output. The assistant panel claims and returns browser tool results while a response is still streaming, executes same-document calls in order, and cancels them on Stop. It claims each call when that call's turn in the document lane starts, so a call stopped while still queued is reported as never started.

Brunch packages

  • plugin-sdcpn mounts Petrinaut's complete tool catalogue with Brunch's prompt, SDCPN modelling skill and reviewed experiment draft whenever the conversation carries a document binding (initialData: { binding }). Without one it offers the modelling instruction and skill only.
  • Each package has a main entry that loads anywhere, and a ./flue entry for the agent hooks and skills, which only a Flue build can load. Skills use Flue's native SKILL.md import.
  • Brunch's tool, header, route, state and environment-variable names live in one file, core/src/constants.ts. The browser imports it through @hashintel/brunch-agent/constants.
  • In dev, the Brunch and website servers load Brunch packages from source through an @dev/source export condition.
  • The modelling guidance no longer ties construction or experiments to a settled Ledger, drops wording for deleted modes and repeats of Stock's own guidance, and keeps one always-on rule: after each meaning-bearing answer, update the net, confirm it already represents the answer, or record what blocks it. Stated restrictions an experiment can't carry are disclosed as unsupported rather than implied.

apps/brunch-agent

  • Credits a net change to a canonical call when Petrinaut reports it applied and the browser reports the settled document revision. The explanation tool lists those calls with the Ledger revision, turns and user messages current at each call.
  • A reviewed experiment draft requires only an earlier canonical net read; it no longer requires a settled Ledger, and admission no longer refuses a draft proposed beside a Ledger settlement.
  • When a browser call ends without a result (the browser reports a failure, its lease expires, or Stop aborts it), one classifier tells the model whether it never started, left the document unchanged because it can't change it (reads and the draft), or has an unknown effect. The model is told never to repeat only the last.
  • Admission applies its mixed-proposal allowlist directly; the agent render no longer writes a browser-tools flag into the per-request scope.
  • Runs petrinautAiModel by default, so Brunch and the Stock route share one baseline. Its local OpenAI catalogue declares that dated GPT-5.5 snapshot, which pi-ai 0.83.0 lists only as gpt-5.5, and GPT-6 Sol as an opt-in for testing.
  • Deletes the A, B, batched and validated construction variants, the Stock-over-Flue evaluation mode, the matched-parity evaluator, the worked-model feature, the unmounted Dafny, Gherkin and Claims plugins, their verification and replay machinery, and the stale-net marker.

apps/petrinaut-website

  • Binds each Brunch conversation to its document and passes the live editor handle to Petrinaut's tools. The handle is chosen in the same render that opens a document, so the conversation binding, transport and handle always name one document, and a first message can't create a conversation without its binding.
  • Restores Labs and Voice, now with FE-1778's defaults, and the reviewed experiment draft flow alongside direct createExperiment. The draft card claims its call before preparing the experiment, so the call's lease is renewed while it prepares.
  • The Stock route reads its model from petrinautAiModel, unchanged from main by default, and PETRINAUT_AI_REASONING_EFFORT can override its reasoning effort.
  • Removes the legacy brunch_ask tool and custom browser tooling.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • modifies an npm-publishable library and I have added a changeset file(s)
    • @hashintel/petrinaut: in-band browser results and executePetrinautAiMutation. @hashintel/petrinaut-core: petrinautAiModel and the separately exported Stock prompt parts.

📜 Does this require a change to the docs?

The changes in this PR:

  • require changes to docs which are made as part of this PR
    • apps/brunch-agent/README.md, apps/petrinaut-website/README.md, Brunch ARCHITECTURE.md (conversation composition, package entries and loading source in dev) and the SDCPN modelling skill.

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • affected the execution graph, and the turbo.json's have been updated to reflect this
    • The Dafny, Gherkin and Claims plugins and their tasks are gone, and the transport now depends on core, so its test:unit builds core first.

⚠️ Known issues

  • Rewriting the Ledger is the bottleneck. mutate_workpiece resubmits the whole Ledger as Markdown on every settlement. In a 45-turn persona run that was 70% of model time and 88% of output tokens, and each rewrite grew from 10 to about 90 seconds as the Ledger reached 37,000 characters. FE-1764 replaces this format.
  • A browser call's lease can expire while its tab is in the background. The browser renews each call's 25-second lease on a 5-second timer, which Chrome throttles in hidden tabs. One persona run lost an applyAutoLayout call this way, as far as the evidence shows; Brunch reported it as unknown and did not repeat it. Unverified; needs a probe.
  • A browser result for an applied mutation that arrives without its document revision is not credited. Deferred to FE-1764, which keys crediting on the document handle's revision.
  • Temporary model shim. Flue's pinned pi-ai 0.83 lists neither the dated gpt-5.5-2026-04-23 snapshot nor GPT-6, so apps/brunch-agent/src/openai-provider.ts adds that snapshot and gpt-6-sol locally, with a documented removal condition. Removing it is part of FE-1799.
  • Unproved by automation: native Stock parity, live Voice and running a reviewed draft in a production build.
  • The Ledger has no stale-read signal. If the user edits the net by hand after the model's last read, nothing tells the model. FE-1764 will address this.

🐾 Next steps

  • FE-1764: an append-only Ledger that isn't rewritten whole, with stale-read detection and revision-keyed crediting.
  • Probe browser-call lease renewal in background tabs.
  • FE-1798: carry experiment constraints in Petrinaut's AI experiment request, so drafts can enforce stated restrictions instead of disclosing them.
  • FE-1799: move to current Flue and pi releases, re-evaluating the local patches and removing the model shim.

🛡 What tests cover this?

  • Browser witness (yarn workspace @apps/brunch-agent test:manual:browser, manual): drives the built website in a real browser against the Brunch server with a faux provider, covering canonical construction with compiler feedback, a direct experiment, and a reviewed draft with Dismiss.
  • Integration suites (faux provider):
    • Brunch admission controls: mixed-proposal refusal outside the allowlist, failure attribution, server-side revision settles, and Stop during buffered admission;
    • Ledger evidence across a restart and history retention after a crash;
    • the production build artifact, including natively packaged skills;
    • website canonical state changes and workpiece refusal presentation.
  • Unit coverage:
    • net-change attribution and the explanation tool;
    • chat-agent mounting with and without a document binding, and provider admission;
    • plugin-sdcpn construction tools and the draft tool;
    • the browser-call rendezvous; how each way a call can end is reported;
    • transport continuations;
    • website tool hosting, the document handle and conversation binding, and the draft card;
    • Labs and Voice, including FE-1778's two tests.
  • Changed Petrinaut libraries: petrinaut-core prompt composition, executePetrinautAiMutation, and in-band results in the assistant panel, including claiming at the start of each call's lane turn.
  • Persona runs (yarn brunch:persona, from FE-1768: Let any coding agent play the Brunch persona through a browser bridge CLI #9833; paid, not in CI): two inventory-purchasing runs with Brunch on gpt-6-sol, compared against earlier runs; findings above.

❓ How to test this?

  1. Run yarn dev:brunch, open http://127.0.0.1:4915, and select Brunch.
  2. Describe a system, or use Surprise me, and let Brunch build the net. The Ledger and the net should update together, and the model should pass validation.
  3. Ask Brunch why an element exists, and ask for an experiment. The draft should appear as a reviewable card.
  4. For the automated browser path, run yarn workspace @apps/brunch-agent test:manual:browser.

Stack created with GitHub Stacks CLI • Give Feedback 💬

@lunelson
lunelson added this pull request to stack #9812 September 23, 2026 13:17
@vercel

vercel Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Sep 29, 2026 12:36pm UTC
petrinaut Ready Ready Preview Sep 29, 2026 12:36pm UTC
petrinaut-docs Ready Ready Preview Sep 29, 2026 12:36pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
hashdotdesign-tokens Ignored Ignored Preview Sep 29, 2026 12:36pm UTC

Request Review

@cursor

cursor Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

PR Summary

High Risk
This replaces the entire browser-tool transport and net-change attribution path for live Petrinaut editing, with ephemeral single-process browser handoffs and broad deletion of verification machinery—core to assistant behavior and document effects.

Overview
Brunch document-bound chats now mount Petrinaut’s full canonical AI tool catalogue (via petrinautAiTools) instead of the old SDCPN-specific browser tools and separate client-tool-result follow-up submissions. While the model streams, the server blocks on each browser tool through a new HTTP rendezvous (issueBrowserCall / browser-calls routes): the panel claims the call, renews a lease, and settles output; results land in Flue as ordinary tool results with a brunchBrowserResult envelope that context projection strips for the provider.

Removed the net ledger, stale-net signal, mutation sidecar verification, reported-document-revision scope, worked-model store/routes, and many integration scripts (start:test, persona/compiler tests, etc.). query_workpiece is rewritten to associate elements with chronological canonical calls from settled browser results (not deep mutation-record provenance). Default chat model aligns with petrinautAiModel (gpt-5.5-2026-04-23, medium); provider admission timeouts are lengthened and dependent tools (query_workpiece, experiment draft) require a prior getLatestNetDefinition read.

Petrinaut gains inBandBrowserTools on the assistant panel and executePetrinautAiMutation; core exports split stock prompt parts and the shared default model. Brunch env/route/tool names consolidate in @hashintel/brunch-agent constants.

Reviewed by Cursor Bugbot for commit 0e6321a. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions github-actions Bot added area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team area/tests New or updated tests area/apps labels Sep 23, 2026

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread apps/brunch-agent/src/conversation/net-ledger.ts Outdated
Comment thread apps/brunch-agent/src/agents/chat-agent/agent.ts Outdated
Comment thread apps/brunch-agent/src/conversation/net-ledger.ts Outdated
Comment thread apps/brunch-agent/src/conversation/net-ledger.ts Outdated
Comment thread apps/brunch-agent/src/evaluations/matched-parity/summary.ts Fixed
Comment thread libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts Fixed
@codecov

codecov Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 15.35%. Comparing base (5ab67f8) to head (0e6321a).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #9811       +/-   ##
===========================================
- Coverage   65.90%   15.35%   -50.56%     
===========================================
  Files        1906      210     -1696     
  Lines      209994     6677   -203317     
  Branches     8221     1154     -7067     
===========================================
- Hits       138389     1025   -137364     
+ Misses      70053     5551    -64502     
+ Partials     1552      101     -1451     
Flag Coverage Δ
antsi ?
apps.hash-ai-worker-ts ?
apps.hash-api 15.35% <ø> (ø)
apps.hash-graph ?
blockprotocol.type-system ?
error-stack ?
harpc-codec ?
harpc-net ?
harpc-tower ?
harpc-types ?
harpc-wire-protocol ?
hash-codec ?
hash-config ?
hash-graph ?
hash-graph-api ?
hash-graph-atlas ?
hash-graph-authentication ?
hash-graph-authorization ?
hash-graph-embeddings ?
hash-graph-postgres-store ?
hash-graph-store ?
hash-graph-temporal-versioning ?
hash-graph-types ?
hash-graph-validation ?
hash-middleware ?
hashql-ast ?
hashql-compiletest ?
hashql-core ?
hashql-diagnostics ?
hashql-eval ?
hashql-hir ?
hashql-mir ?
hashql-syntax-jexpr ?
local.claude-hooks ?
local.harpc-client ?
local.hash-backend-utils ?
local.hash-graph-sdk ?
local.hash-isomorphic-utils ?
problematic ?
rust.antsi ?
rust.error-stack ?
rust.harpc-codec ?
rust.harpc-net ?
rust.harpc-tower ?
rust.harpc-types ?
rust.harpc-wire-protocol ?
rust.hash-codec ?
rust.hash-config ?
rust.hash-graph-api ?
rust.hash-graph-atlas ?
rust.hash-graph-authentication ?
rust.hash-graph-authorization ?
rust.hash-graph-embeddings ?
rust.hash-graph-postgres-store ?
rust.hash-graph-store ?
rust.hash-graph-temporal-versioning ?
rust.hash-graph-types ?
rust.hash-graph-validation ?
rust.hash-middleware ?
rust.hashql-ast ?
rust.hashql-compiletest ?
rust.hashql-core ?
rust.hashql-diagnostics ?
rust.hashql-eval ?
rust.hashql-hir ?
rust.hashql-mir ?
rust.hashql-syntax-jexpr ?
rust.problematic ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@lunelson lunelson changed the title ln/pn tooling remediation FE-1763: Let Brunch build Petrinaut nets through Petrinaut's canonical tools Sep 23, 2026
Base automatically changed from ln/reduce-brunch-process to main September 24, 2026 10:54
@lunelson
lunelson requested a review from a team as a code owner September 24, 2026 10:54
@lunelson
lunelson force-pushed the ln/pn-tooling-remediation branch from 69d23b5 to 18101d9 Compare September 24, 2026 10:54
@TimDiekmann
TimDiekmann removed the request for review from a team September 24, 2026 10:55

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread apps/brunch-agent/src/agents/chat-agent/agent.ts
Comment thread apps/brunch-agent/src/conversation/why.ts Outdated

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread apps/brunch-agent/src/conversation/browser-call-rendezvous.ts Outdated
Comment thread apps/brunch-agent/src/conversation/net-changes.ts
…stale reads, and compare browser bindings key-order-independently
…and derive browser tool names from the catalogue
…from one table

The no-mode read_petrinaut_docs tool was the last tool whose result came
back as a later client-tool-result signal. It goes, with the transport's
signal send, history folding and sync/async client-tool split. Integrated
mode keeps canonical readPetrinautDoc in band.

Which canonical tools may change the document, and which element kinds
their changes name, now come from petrinautToolEffects in plugin-sdcpn.
The app catalogue, rendezvous failure wording, net-change attribution,
the why selector, and the website's revision and draft checks derive
from it instead of hand-kept name lists.
The draft checks required a settled, current Ledger before Brunch could put up a draft, but nothing linked the draft to the Ledger's content: the browser looked the Ledger up only to confirm one existed. With no Ledger, Brunch had to write filler or call createExperiment directly, which runs at once with no Run button. A draft now needs only a prior canonical net read, on the server and in the browser; the check that the read carries a document revision stays. The unused workpiece authority options are removed, and the browser witness drafts after a net read with no Ledger.
…'s Petrinaut guidance

Construction and experiment proposals no longer need to flow from, wait for or cite a settled Ledger; they follow what the person has stated, and the Ledger stays the account Brunch keeps while it asks. With one conversation mode left, the "In I" qualifiers and the construct-only branch no longer distinguish anything and are removed. Steps and rules that repeated Stock's capability guidance or the always-on instructions are gone. Experiment guidance now triggers on the person's stated decision, and the inline createExperiment steer asks Brunch to name any stated restriction the run will not enforce, since neither request shape carries constraints.
Only one mode was left, and the schema already refused it without a construction binding, so `mode` told the server nothing the binding did not. A conversation's initial data is now just `{ binding }`: when present, Brunch mounts the Petrinaut tools, the draft and the browser executor; when absent, as on Brunch's own chat page and in the deployment smoke, it offers the instruction and modelling skill only. The one-entry tool catalogue map, the website's always-true construction gate and the old persona initial-data fallbacks go with it, and names, the browser witness and its script drop "integrated", which no longer distinguishes anything.
The handle was created in an effect, so for one render after a document opened, the repository and the Brunch binding already named the new document while the handle still edited the old one. A gate hid the browser executor and the conversation binding in that render; a first message sent then would create the new conversation without its binding, and Flue records creation data only once. Creating a handle has no side effects, so the handle is now chosen in the render that opens the document, which lets the gate go: the binding, transport and handle always name the same document. The subscription that saves the handle's changes stays in an effect.
Clearing a save failure recorded for a document other than the open one was an effect that adjusted state after the document changed. It depends only on the current values, so it now happens in render, before anything reads the failure. Saving the handle's changes stays an effect, with a note on why: it subscribes to the handle, the subscription must end with that handle, and render may create handles that React discards.
The chat agent's render wrote whether the conversation had a document binding into the per-request admission scope, so the provider wrapper could allow mixed browser/server proposals made only of allow-listed tools. A conversation without a binding mounts no browser tools and cannot propose a mixed call, so the flag was true whenever it mattered. The wrapper now applies the allow-list alone, and the render no longer writes ambient state. The registration test now proves admission scoping with a proposal refused in every Brunch scope: a workpiece query beside the net read it depends on.
…g instruction

The prompt weeding removed this rule from the always-on instruction as a duplicate of the skill body, but the skill body arrives once, as a tool result on the first turn, and loses weight as the conversation grows. A persona run without it built the net on 5 of 37 turns, mostly early. The rule is back, keyed to each meaning-bearing answer rather than to a Ledger settlement.
Flue resolves models through pi-ai 0.83.0, which predates GPT-6, so Brunch could not select `openai/gpt-6-sol`. Its entry is copied from pi-ai 0.87.1's OpenAI catalogue beside GPT-6 Luna, which it matches apart from name and prices, and shares Luna's removal condition.
Admission listed `mutate_workpiece` among the draft's dependencies, so a proposal that settled the Ledger and drafted an experiment together was refused as if the draft read the Ledger's result. Drafting now needs only a prior canonical net read, so that read is the draft's one dependency.
The shim was for `@ai-sdk/openai` 3.0.63, which predated GPT-6 and dropped the reasoning effort unless forced. Its removal condition, 3.0.113 or later project-wide, is met by main's bump to 3.0.114, which treats every GPT model from version 5 as a reasoning model.
…e document unchanged

A browser call ends without a result in three ways: the browser reports a failure, its lease expires, or Stop aborts it. Only the failure path checked whether the tool can change the document, so a stopped or expired read or draft was reported as an attempted document effect of unknown outcome, which the model is told never to repeat. One classifier now builds the error for all three: unstarted, document unchanged, or unknown.
The panel claimed each issued call as soon as it streamed in, before it waited behind earlier document calls, and the server takes a claimed call as possibly started. Stop during a multi-tool turn therefore reported queued, never-started calls as unknown writes, and the model would not redo them. Claiming at the start of the call's lane turn makes a claimed call a started one, so a queued call stopped before its turn is reported unstarted.
…etry that could not succeed

The draft card read its authority from history and prepared the experiment before claiming the issued call, so nothing renewed the call's lease meanwhile and a slow read could expire it. The card now claims first and prepares under the renewed lease. "Retry preparation" re-ran the claim after the one-use call had already been claimed and settled, so it could never succeed; the model can redraft instead, and the card still shows the failure.
`@hashintel/petrinaut`'s changeset now covers `executePetrinautAiMutation` and when an in-band call is claimed, and `@hashintel/petrinaut-core`'s covers the stock prompt's separately exported behavioural frame and capability guidance.
…head of them

Since the browser claims a call only when its document-lane turn starts, calls queued behind a running one were unclaimed and expired 25 s after issue. A renewal now extends the unclaimed calls on the same binding, so queued calls expire only once the browser stops renewing.
The five planning and review notes under `libs/@hashintel/brunch-agent/docs/refactoring/` were local working material for the restack. They now live in an ignored `_holding/` directory.
`petrinautAiModel` returns to the original assistant's `gpt-5.5-2026-04-23` at `medium`, so the Stock route matches `main` and Brunch shares its baseline. Brunch's local OpenAI catalogue declares that dated snapshot, which pi-ai 0.83.0 lists only as `gpt-5.5`, keeps GPT-6 Sol as an opt-in for testing, and drops GPT-6 Luna.
`inBandBrowserTools` exposed Brunch's handoff protocol (claim, prepare, fail, release and submit) as Petrinaut public API. Petrinaut now calls `run(call, execute)` at the call's turn in same-document order, with a signal that aborts on Stop; the host decides whether the call may start, calls `execute` at most once, and reports the output or failure itself. Claiming, lease renewal and failure dispositions stay in the website.
…ics again

The canonical read and mutation tools already return a call's recorded output when it runs again after a remount or history replay; the diagnostics read now does the same.
Positions are layout, which is not part of what an element means. The position tools and applyAutoLayout still count as document changes, so a net read still goes stale, but query_workpiece no longer lists them as changes to an element; applyAutoLayout named no IDs, so it was never credited anyway.
@lunelson

Copy link
Copy Markdown
Contributor Author

Good question, and you're right that it was Brunch's protocol leaking into Petrinaut's API. Narrowed in b3d0ac4: inBandBrowserTools is now { has(toolName), run(call, execute) }. Petrinaut keeps what is its own: it calls run at the call's turn in same-document order, passes a signal that aborts on Stop, and does the execution inside execute; an experiment lets the next call start once it has captured its source. The host decides whether the call may start, calls execute at most once, and reports the output or the failure itself, so claiming, lease renewal and the unstarted/failed disposition now live only in the website. The one new behaviour: a started call that ends without an output is now reported as failed rather than released silently; only an interactive tool the host also routes in-band could hit it, and the website routes none.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0e6321a. Configure here.

Comment thread apps/brunch-agent/src/evaluations/persona/browser-turn.ts
Comment thread apps/brunch-agent/src/conversation/net-changes.ts
Comment thread apps/petrinaut-website/src/main/app/shared/petrinaut-jsdom.ts

@hashdotai hashdotai left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legal approval – license changes are only deleted licenses in removed packages.

This branch was successfully deployed

5 active (2 outdated) deployments
Preview – hash — 0e6321aa Deployed Sep 29, 2026 by vercel[bot]
Preview – petrinaut-docs — 0e6321aa Deployed Sep 29, 2026 by vercel[bot]
Preview – petrinaut — 0e6321aa Deployed Sep 29, 2026 by vercel[bot]
pull-request — 4d4ff547 Deployed Sep 24, 2026 by lunelson via Sourcemaps (@apps/hash-integration-worker) #37382
Preview – hashdotdesign-tokens — dbbb6bc9 Deployed Sep 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) area/tests New or updated tests type/eng > backend Owned by the @backend team type/eng > frontend Owned by the @frontend team type/legal Owned by the @legal team

Development

Successfully merging this pull request may close these issues.

6 participants