Skip to content

computeBriefingFingerprint does synchronous recursive I/O on the briefing request path #236

@Ovaculos

Description

@Ovaculos

Problem

computeBriefingFingerprint (src/services/briefing-cache.ts) fingerprints the
workspace activity-log dir and every running bundle's entity-data dir by walking
each tree with synchronous readdirSync + lstatSync (dirSignature). It runs
inside the async nb__briefing tool handler (src/tools/core-source.ts:754), on
every briefing call that is not a force_refresh.

Bun runs on a single event-loop thread. A synchronous directory walk blocks that
thread — no other request (chat stream, tool call, page load) is served until the
walk returns.

Today this is cheap: fresh workspaces have a handful of log files and small entity
dirs. But entity-backed bundles (todo, CRM, notes) store one file per row/note, so
a long-lived heavy workspace accumulates thousands of files. Every home-dashboard
load then stat()s every one of them synchronously, freezing the process for the
walk duration — and the freeze lands on unrelated requests, not just that user.

Fix

Make the walk async — fs/promises readdir / lstat, computeBriefingFingerprint
returns Promise<string>, await it at the core-source.ts call site. The thread
can serve other requests while waiting on disk.

Optional follow-on: cap the walk (max file count / max depth) and fall back to the
TTL if a tree is too large to fingerprint cheaply.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions