Skip to content

FE-1580: Reconcile Voice turn behavior on the shared Brunch conversation - #9531

Draft
kostandinang wants to merge 52 commits into
ln/fe-1574-direct-voice-fluefrom
kostandin/fe-1580-harden-voice-safety-and-ux-on-the-unified-flue-route
Draft

FE-1580: Reconcile Voice turn behavior on the shared Brunch conversation#9531
kostandinang wants to merge 52 commits into
ln/fe-1574-direct-voice-fluefrom
kostandin/fe-1580-harden-voice-safety-and-ux-on-the-unified-flue-route

Conversation

@kostandinang

@kostandinang kostandinang commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🌟 What is the purpose of this PR?

This PR builds on #9528's unified Flue conversation route and restores the Voice safety and UX behavior needed on top of it.

A completed spoken transcript now follows the same path as typed input:

Voice → shared panel useChat → browser Flue transport → /agents/chat/:instanceId

The response shown in the panel is the same canonical Brunch text passed to TTS. Initial speech can now start from a durably completed, submission-correlated canonical segment while the rest of the Flue submission continues; settlement still gates replay and the next input turn. This PR does not restore Brunch /api/chat, add a direct Voice FlueClient.send() path, rewrite responses with a simplifier, mount brunch_ask, or include Petri-net generation.

🔗 Related links

🚫 Blocked by

🔍 What does this change?

  • Makes completed gpt-4o-transcribe output the sole authoritative spoken answer.
  • Forwards projected Flue message-started and message-completed boundaries with stream position and submission identity, then schedules only new finalized canonical segments in stable canonical order.
  • Preserves stable Flue admission identity and surfaces rejected, conflicting, ambiguous, and locally aborted outcomes without automatic retry.
  • Adds acknowledged half-duplex handoff: Your turn cancels playback immediately and waits for both provider cancellation acknowledgement and Brunch settlement before reopening the microphone.
  • Adds exact Read full response and Repeat question playback using canonical Brunch text and explicit question markers.
  • Keeps local playback cancellation distinct from durable Flue Stop.
  • Preserves supported client-tool Voice provenance across projection, hydration, and reopen.
  • Keeps finalized spoken turns live in the transcript; initial-modal Voice opens with its consent card above a compact dock, composer Voice stays expanded, and ending from a collapsed ghost-button dock closes the AI panel without unmounting hidden content.
  • Preserves full Flue and browser-tool failures through persistent, copyable notifications and inline tool errors.
  • Removes dormant brunch_ask behavior from the production Voice path.
  • Local Brunch startup now prebuilds both the Brunch server and Petrinaut website dependency graphs.

Observed timing diagnostic

Boundary Before After
Finalized transcript → Flue admission 48.5 ms 68.5 ms
Admission → first canonical text 3,366.6 ms 5,101.4 ms
First canonical text → submission settled 0.0 ms 0.7 ms
Settlement → TTS request 0.3 ms 0.0 ms (same observed tick)
TTS request → first audible audio 628.3 ms 724.0 ms

These are single real microphone-to-audible-TTS diagnostic turns, not the controlled 10+10 comparative acceptance sample. The post-change target gap was only 0.7 ms, so this change did not meaningfully improve that turn. Its dominant 5.10 s admission-to-canonical delay belongs to the tool/construction work in #9538, not Mission 5.

Acceptance ledger

Requirement Implementation / regression / production proof Status
Parent architecture / path B local-storage-demo-app.tsx, brunch-panel-transport.ts, and panel submitVoiceInput; repository audit finds only the OpenAI data-channel .send() in Voice source Implemented and verified; #9528 remains the parent authority
Mission 1 — transcript authority and ownership Session, bridge, controller, and preview tests cover keyed completed transcripts, current-turn boundary, all rejection states, canonical-request invalidation, closed microphone, and fresh post-handoff speech Implemented and verified; focused race 4/4
Mission 2 — idempotent admission Transport → tracker → submitVoiceInputWithAdmission → bridge preserves rejection, 409 original submissionId, ambiguity, and local abort; every failure path calls send() once and never retries Implemented and verified; focused integration 3/3; transport 26/26
Mission 3 — cancellation / Stop Session/controller wait for input/output acknowledgements and targeted terminal events; Your turn additionally waits for Brunch settlement; latest mute wins; app seam cancels queued Voice speech before the unchanged durable FlueClient.abort() Implemented and verified; parent-owned Stop races remain excluded
Mission 4 — committed speech and exact replay Raw Flue completion boundaries correlate finalized canonical segments to the active Voice submission; stable segment ids deduplicate continuation speech; settlement and audio terminality still gate exact replay Implemented and verified; streaming-state speech, noncanonical silence, continuation ordering, hydration, cancellation, replay, and handoff regressions pass
Mission 5 — Voice provenance Persisted client-tool-result signals preserve multiple successful Voice origins through sibling failure, projection, hydration, and reopen Implemented and verified for client-tool results
Direct-user provenance Flue 2.0.3 projects neither caller metadata nor caller idempotency onto canonical user messages; forbidden browser/text/synthetic-message workarounds are absent Blocked pending supported Flue projection or explicit owner deferral
Mission 6 — dormant ask Production Brunch supplies interactiveTools: []; canonical speech ignores brunch_ask; dormant source is unmounted Implemented exclusion and verified
Mission 7 — real witness One real microphone-to-audible turn verified the amended production timing path; the complete handoff, unsettled Stop, reload, snapshot, settlement, and same-origin artifact bundle remains outstanding Partially observed; full retained witness remains unverified
Mission 8 — latency One before/after physical timing diagnostic found only a 0.7 ms post-change canonical-to-settlement gap and therefore no meaningful latency benefit on that turn Diagnostic complete; acceptance incomplete pending the specified 10 donor + 10 candidate trials
Mission 9 — verification/docs/package Seven-workspace checks, architecture docs, focused suites, README/user guide, mission/evidence, and one Petrinaut patch changeset Current timing amendment pushed and locally verified through 756ed4f63e; the prior seven-workspace gate passed at f3f5c4ebc7; current CI is pending
Full error reporting — bounded Petrinaut exception A shared bounded serializer preserves Error causes, strings, and plain-object JSON across both Flue failure paths; AI errors persist with wrapped detail, copy, and close actions; browser-tool rejections enter AI SDK output-error state and failed tool cards lead with the inline error Pushed candidate implemented and locally verified; transport 32/32, Petrinaut 617/617, and rendered error toast/tool-card states inspected; CI pending
Always-live transcript and dock-only collapse — bounded Petrinaut exception Finalized spoken turns render immediately; deferral/reveal modules and the transcription toggle are removed; initial-modal Voice shows its consent/microphone card above a compact dock while composer Voice stays expanded; the collapse control remains ghost; collapsed live content stays mounted, and ending closes the panel while expanded ending returns to the composer Pushed candidate implemented and locally verified; production panel 46/46, mounted-hidden and end-without-pause regressions pass, and compact/expanded Storybook states were inspected; CI pending
Donor #9496 Adopt serialized exact TTS queue, terminal gating, full-response/question replay; reject simplification and response rewriting Adopted behavior implemented; rejected behavior absent
Donor #9500 Adopt completed-transcript identity/normalization/limits/rejections and disabled Realtime tools/responses; reject ask correlation Adopted behavior implemented; rejected behavior absent
Donor #9507 Port nothing; keep temporary brunch_ask shim unmounted and unrecognized Rejected and verified absent from production
Donor #9512 Adopt acknowledged half-duplex handoff, fresh capture, replay gating, supported provenance; reject topology, ask UI, preparation Adopted supported behavior implemented; rejected behavior absent
Donor retirement All four donor PRs remain open and untouched Deferred until #9531 acceptance plus explicit approval from each donor owner

How donor PRs are used

The existing Voice PRs are reference implementations, not branches merged into this stack. Their useful behavior was reimplemented against #9528's Flue architecture:

  • #9500: completed-transcript authority and rejection rules.
  • #9496: serialized exact canonical playback and replay mechanics; the simplifier is excluded.
  • #9512: acknowledged cancellation, explicit handoff, replay gating, and supported provenance.
  • #9507: deliberately not ported because its temporary brunch_ask shim is no longer part of the architecture.

The donor PRs remain open and unchanged until this replacement is accepted and their owners approve retirement.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

  • Modifies the npm-publishable @hashintel/petrinaut package and includes a patch changeset.

📜 Does this require a change to the docs?

  • Required documentation changes are included.

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

  • No Turbo execution-graph change is required.

⚠️ Known issues

  • Direct user-message Voice attribution cannot yet survive canonical Flue hydration because Flue 2.0.3 does not project caller metadata or idempotency keys onto user messages. No unsupported workaround is included.
  • One paired real microphone timing diagnostic is recorded above. It does not replace the full retained witness or the 10+10 comparative latency gate; both remain incomplete.
  • Parent-owned FE-1574: Let Voice and the typed panel share one canonical Brunch conversation #9528 behavior remains outside this PR's ownership.
  • Cold-cache startup may take longer.
  • Turbo caching and deduplication reduce repeat cost.
  • Dependency libraries are built once at startup, not continuously watched.

🐾 Next steps

  1. Run and retain the real typed/Voice/handoff/Stop/reload witness.
  2. Compare audible latency against the pinned FE-1570: Optimize spoken Brunch responses for Voice mode #9496 implementation.
  3. Resolve or explicitly defer direct-user provenance.
  4. Complete review.
  5. After acceptance, obtain donor-owner approval before closing any donor PR.

🛡 What tests cover this?

  • Current head 756ed4f63e passes the complete transport suite (32/32) and Petrinaut website suite (289/289), both production builds, both TypeScript checks, and both ESLint checks with zero errors. One pre-existing React effect warning remains.
  • Prior head f3f5c4ebc7 ran the full required Turbo command locally with exit 0, 39/39 tasks and 1,123/1,123 tests — Brunch app 80, core 86, binding 18, SDCPN 8, transport 32, Petrinaut 617, website 282.
  • Pending-canonical-speech race: exit 0, 4/4 selected. Ambiguity/conflict/local-abort path: exit 0, 3/3 selected, preserving the original conflict submissionId, keeping local abort distinct from durable abort, and calling send() once per path.
  • Question marker 9/9; transport/live/snapshot projection and error serialization 32/32; real Flue integration 1/1; production panel 46/46; replay/session/controller 79/79.
  • Petrinaut architecture docs: exit 0 — 68 layers, 337 edges, 690 files, 69 generated pages, 38 authored pages. The local candidate has a 72-file diff; yarn lint:format accepts all 5,527 matched files, and git diff --check passes.
  • New UX/error regressions pass inside the Petrinaut and transport suites: all finalized Voice turns render live; compact consent sits above the dock; collapsed content remains mounted; collapsed ending closes without a redundant pause; Flue error shapes serialize without [object Object]; browser-tool rejection enters output-error; and error toasts expose persistent detail, copy, and Ark close actions. Chrome inspection confirms the compact and expanded consent renders, ghost collapse control, wrapped persistent error detail, and inline tool-card failure.
  • Launcher head 9d753b2068d3: yarn workspace @apps/brunch-agent vitest run test/local-dev-origins.test.ts passes 4/4; pre-commit formatting and task-dependency checks pass.
  • Previous head d64f809c2233 has a 60-file diff. Its code-push GitHub check set completed with 70 successful and 8 intentionally skipped checks, no failures or cancellations: Preflight, CodSpeed, Bench, Semgrep, Lint, Test (including Brunch units and Playwright), and Deploy all pass. Subsequent PR-metadata Preflight checks also pass.
  • The earlier compact Voice consent UI commits and planning-artifact removal are covered by d64f809c2233 CI. The current compact-dock refinement is pushed and locally verified; CI is pending.

❓ How to test this?

  1. Run the local Brunch/Petrinaut pair and select the Brunch preview.
  2. Start Voice mode and submit a spoken answer; confirm exactly one completed transcript appears immediately in the shared conversation and exact canonical speech may begin while the remaining Flue submission is still settling.
  3. Collapse the live session and confirm only the Voice dock remains; end Voice and confirm the AI panel closes. In a second session, expand and confirm the transcript and host Voice region return at the same scroll position.
  4. During playback, press Your turn and confirm fresh capture begins only after cancellation completes.
  5. Exercise Read full response, Repeat question, and durable Stop.
  6. Trigger an assistant or tool failure; confirm the complete detail is visible, copyable, and remains until closed, and that the failed tool card shows its error inline.
  7. Hard-reload the same conversation and confirm there is no resubmission or automatic replay.

📹 Demo

One real before/after microphone-to-audible timing diagnostic is recorded above. The complete retained browser/microphone/handoff/Stop/reload witness remains pending.

@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
petrinaut Ready Ready Preview Sep 4, 2026 5:57pm UTC
petrinaut-docs Ready Ready Preview Sep 4, 2026 5:57pm UTC
2 Skipped Deployments
Project Deployment Actions Updated
hash Ignored Ignored Preview Sep 4, 2026 5:57pm UTC
hashdotdesign-tokens Ignored Ignored Preview Sep 4, 2026 5:57pm UTC

Request Review

@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 labels Sep 3, 2026
@github-actions github-actions Bot added area/tests New or updated tests area/apps labels Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@kostandinang kostandinang changed the title FE-1580: Harden Voice safety and UX on the unified Flue route FE-1580: Make Voice turns reliable in the shared Brunch conversation Sep 4, 2026
@kostandinang kostandinang changed the title FE-1580: Make Voice turns reliable in the shared Brunch conversation FE-1580: Reconcile Voice turn behavior on the shared Brunch conversation Sep 4, 2026
@lunelson
lunelson changed the base branch from ln/fe-1574-direct-voice-flue to graphite-base/9531 September 4, 2026 09:38
Co-authored-by: Cursor <cursoragent@cursor.com>
@codspeed-hq

codspeed-hq Bot commented Sep 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ 6 benchmarks measured no execution time

Nothing ran under measurement, usually because the compiler removed the code under test. These results are not comparable, so they count as unchanged.

Preventing compiler optimizations

✅ 98 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
⚠️ as_constant < 1 ns < 1 ns N/A
⚠️ constant_equal < 1 ns < 1 ns N/A
⚠️ constant_not_equal < 1 ns < 1 ns N/A
⚠️ access < 1 ns < 1 ns N/A
⚠️ runtime_equal < 1 ns < 1 ns N/A
⚠️ runtime_not_equal < 1 ns < 1 ns N/A

Comparing kostandin/fe-1580-harden-voice-safety-and-ux-on-the-unified-flue-route (756ed4f) with ln/fe-1574-direct-voice-flue (eecbe99)

Open in CodSpeed

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Benchmark results

@rust/hash-graph-benches – Integrations

policy_resolution_large

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2002 $$25.6 \mathrm{ms} \pm 220 \mathrm{μs}\left({\color{gray}0.189 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.40 \mathrm{ms} \pm 21.6 \mathrm{μs}\left({\color{gray}-1.437 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1002 $$12.1 \mathrm{ms} \pm 95.3 \mathrm{μs}\left({\color{gray}0.681 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$42.3 \mathrm{ms} \pm 440 \mathrm{μs}\left({\color{gray}-0.486 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$14.2 \mathrm{ms} \pm 115 \mathrm{μs}\left({\color{gray}-0.275 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1527 $$23.3 \mathrm{ms} \pm 199 \mathrm{μs}\left({\color{gray}-0.853 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$26.0 \mathrm{ms} \pm 180 \mathrm{μs}\left({\color{gray}-2.194 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.74 \mathrm{ms} \pm 22.4 \mathrm{μs}\left({\color{gray}0.854 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$12.9 \mathrm{ms} \pm 102 \mathrm{μs}\left({\color{gray}-1.237 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$3.68 \mathrm{ms} \pm 21.9 \mathrm{μs}\left({\color{gray}-1.597 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.96 \mathrm{ms} \pm 16.3 \mathrm{μs}\left({\color{gray}-0.260 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 52 $$3.31 \mathrm{ms} \pm 20.4 \mathrm{μs}\left({\color{gray}-1.596 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.06 \mathrm{ms} \pm 26.1 \mathrm{μs}\left({\color{gray}-1.491 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.53 \mathrm{ms} \pm 18.2 \mathrm{μs}\left({\color{gray}-1.436 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 108 $$4.10 \mathrm{ms} \pm 22.7 \mathrm{μs}\left({\color{gray}-1.201 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.39 \mathrm{ms} \pm 27.8 \mathrm{μs}\left({\color{gray}0.518 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.38 \mathrm{ms} \pm 19.4 \mathrm{μs}\left({\color{gray}-0.542 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.01 \mathrm{ms} \pm 25.2 \mathrm{μs}\left({\color{gray}-3.537 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.73 \mathrm{ms} \pm 21.6 \mathrm{μs}\left({\color{gray}1.23 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.70 \mathrm{ms} \pm 15.8 \mathrm{μs}\left({\color{gray}1.34 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 2 $$2.78 \mathrm{ms} \pm 13.6 \mathrm{μs}\left({\color{gray}-0.853 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$3.10 \mathrm{ms} \pm 26.1 \mathrm{μs}\left({\color{gray}1.62 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.82 \mathrm{ms} \pm 14.1 \mathrm{μs}\left({\color{gray}-1.858 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$3.13 \mathrm{ms} \pm 17.7 \mathrm{μs}\left({\color{gray}0.292 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.08 \mathrm{ms} \pm 15.8 \mathrm{μs}\left({\color{gray}0.310 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.76 \mathrm{ms} \pm 11.8 \mathrm{μs}\left({\color{gray}-0.593 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 26 $$2.96 \mathrm{ms} \pm 18.3 \mathrm{μs}\left({\color{gray}0.245 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.46 \mathrm{ms} \pm 20.3 \mathrm{μs}\left({\color{gray}0.145 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.06 \mathrm{ms} \pm 15.2 \mathrm{μs}\left({\color{gray}0.192 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 27 $$3.25 \mathrm{ms} \pm 16.5 \mathrm{μs}\left({\color{gray}-1.569 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.40 \mathrm{ms} \pm 18.8 \mathrm{μs}\left({\color{gray}-0.581 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.04 \mathrm{ms} \pm 14.8 \mathrm{μs}\left({\color{gray}-1.260 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.28 \mathrm{ms} \pm 21.0 \mathrm{μs}\left({\color{gray}-1.141 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$31.1 \mathrm{ms} \pm 162 \mathrm{μs}\left({\color{gray}-0.521 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$66.6 \mathrm{ms} \pm 329 \mathrm{μs}\left({\color{gray}-1.386 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$35.6 \mathrm{ms} \pm 288 \mathrm{μs}\left({\color{gray}2.48 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$37.6 \mathrm{ms} \pm 210 \mathrm{μs}\left({\color{gray}-0.633 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$40.4 \mathrm{ms} \pm 235 \mathrm{μs}\left({\color{gray}-1.690 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$32.6 \mathrm{ms} \pm 195 \mathrm{μs}\left({\color{gray}-0.398 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$389 \mathrm{ms} \pm 1.04 \mathrm{ms}\left({\color{gray}-0.827 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$82.4 \mathrm{ms} \pm 471 \mathrm{μs}\left({\color{lightgreen}-5.154 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$70.1 \mathrm{ms} \pm 442 \mathrm{μs}\left({\color{gray}-1.333 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$266 \mathrm{ms} \pm 982 \mathrm{μs}\left({\color{lightgreen}-10.858 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$10.0 \mathrm{ms} \pm 46.9 \mathrm{μs}\left({\color{gray}-2.050 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$10.2 \mathrm{ms} \pm 53.4 \mathrm{μs}\left({\color{gray}-0.841 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$10.4 \mathrm{ms} \pm 73.4 \mathrm{μs}\left({\color{gray}-1.345 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$10.2 \mathrm{ms} \pm 50.7 \mathrm{μs}\left({\color{gray}-0.395 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$10.4 \mathrm{ms} \pm 57.7 \mathrm{μs}\left({\color{gray}-0.063 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$10.2 \mathrm{ms} \pm 75.0 \mathrm{μs}\left({\color{gray}0.252 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$10.2 \mathrm{ms} \pm 56.4 \mathrm{μs}\left({\color{gray}1.07 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$10.1 \mathrm{ms} \pm 60.7 \mathrm{μs}\left({\color{gray}-0.236 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$10.3 \mathrm{ms} \pm 58.8 \mathrm{μs}\left({\color{gray}0.271 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$10.4 \mathrm{ms} \pm 65.8 \mathrm{μs}\left({\color{gray}-1.033 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity

Function Value Mean Flame graphs
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1 $$10.6 \mathrm{ms} \pm 86.7 \mathrm{μs}\left({\color{gray}1.30 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$10.7 \mathrm{ms} \pm 70.5 \mathrm{μs}\left({\color{gray}0.826 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$10.7 \mathrm{ms} \pm 63.3 \mathrm{μs}\left({\color{gray}2.06 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$10.6 \mathrm{ms} \pm 61.8 \mathrm{μs}\left({\color{gray}-0.898 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$10.6 \mathrm{ms} \pm 79.4 \mathrm{μs}\left({\color{gray}0.675 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$10.6 \mathrm{ms} \pm 77.1 \mathrm{μs}\left({\color{gray}1.80 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$10.7 \mathrm{ms} \pm 76.7 \mathrm{μs}\left({\color{gray}-0.355 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$10.6 \mathrm{ms} \pm 53.5 \mathrm{μs}\left({\color{gray}-0.258 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$10.6 \mathrm{ms} \pm 61.0 \mathrm{μs}\left({\color{gray}-0.462 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity_type

Function Value Mean Flame graphs
get_entity_type_by_id Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba $$7.79 \mathrm{ms} \pm 36.3 \mathrm{μs}\left({\color{gray}-0.621 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$54.4 \mathrm{ms} \pm 417 \mathrm{μs}\left({\color{gray}0.931 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$104 \mathrm{ms} \pm 574 \mathrm{μs}\left({\color{gray}-0.736 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$60.5 \mathrm{ms} \pm 373 \mathrm{μs}\left({\color{gray}0.837 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$69.1 \mathrm{ms} \pm 481 \mathrm{μs}\left({\color{gray}0.378 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$77.8 \mathrm{ms} \pm 509 \mathrm{μs}\left({\color{gray}0.478 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$84.2 \mathrm{ms} \pm 469 \mathrm{μs}\left({\color{gray}-0.414 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$43.5 \mathrm{ms} \pm 209 \mathrm{μs}\left({\color{gray}-0.658 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$70.8 \mathrm{ms} \pm 350 \mathrm{μs}\left({\color{gray}0.294 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$50.0 \mathrm{ms} \pm 238 \mathrm{μs}\left({\color{gray}0.513 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$58.3 \mathrm{ms} \pm 369 \mathrm{μs}\left({\color{gray}-0.453 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$60.9 \mathrm{ms} \pm 440 \mathrm{μs}\left({\color{gray}0.648 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$60.3 \mathrm{ms} \pm 381 \mathrm{μs}\left({\color{gray}-0.761 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$117 \mathrm{ms} \pm 531 \mathrm{μs}\left({\color{lightgreen}-7.090 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$130 \mathrm{ms} \pm 569 \mathrm{μs}\left({\color{gray}-4.202 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$21.6 \mathrm{ms} \pm 145 \mathrm{μs}\left({\color{gray}3.46 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$542 \mathrm{ms} \pm 898 \mathrm{μs}\left({\color{gray}-1.036 \mathrm{\%}}\right) $$ Flame Graph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps > hash.design Affects the `hash.design` design site (app) area/apps 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 > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

1 participant