Product design

Granola: bring your own priorities into AI meeting notes

Granola is an AI notepad for people who spend much of their time in meetings. It combines your brief notes with a transcript to create an editable record whose sources you can revisit.

Break down the problem and try your own design and implementation first. Then explore the reasoning to check states, edge cases, trade-offs, and ways to test your approach. The guide offers a reasoning path, not a complete implementation.

01
CODE EXERCISEAdvanced

Merge source highlights without losing citation ownership

Scenario

Design the data-processing module behind “view evidence” in your own meeting-notes tool. Clicking a conclusion should reveal its cited transcript passages. Citations may overlap, and a file with the same name may have changed. Prevent misplaced highlights while retaining which conclusion each original citation supports.

Input and terminology

  1. A source is identified by documentId + revisionId; that version's text is immutable. The caller has already converted it into a Unicode code-point array of length L. Encoding and tokenization are outside this problem. Two versions are different sources even if their filenames match.
  2. Each citation contains a unique citationId, claimId, documentId, revisionId, start and end. The half-open interval [start, end) includes start and excludes end. Coordinates must be safe integers satisfying 0 ≤ start < end ≤ L. A claim can have multiple citations. The caller guarantees field types and nonempty IDs; you check unique citation IDs, the existence of the exact source version and valid ranges.
  3. There are at most 100,000 citations. All source versions are supplied as read-only data. If any citation is invalid, return errors identifying input positions and reasons without replacing currently displayed highlights. Networking, collaborative editing and rendering code are out of scope.

Required behavior

  1. On success, output highlights for each source version. Merge overlapping or touching intervals and sort the result by start. Never merge different documents or versions.
  2. Also retain an index from citationId to claim, version and original interval. Merging visual coverage must not collapse distinct evidence relationships or discard original ranges.
  3. If a citation names an old version but only the new version is available, report the missing version; never apply the old coordinates to the new text automatically.

Trace this input by hand

Document D has v1 of length 12 and v2 of length 15. For v1: c1→claim A [2,5), c2→claim B [4,8), c3→claim A [8,10). For v2: c4→claim A [2,5). Draw the highlights and explain what clicking c2 should retrieve. Then change c3's end to 13 and describe what the interface retains after failure.

Deliverables

Propose a validation order, grouping and index structures, an interval-merging invariant, and a way to replace displayed results once on success. Give expected behavior for the example, duplicate IDs, empty input and a missing old version, and explain time and additional-space complexity. Do not write a complete implementation or line-by-line pseudocode.

Explore the reasoning
  1. Bind coordinates to the exact version. Look up length using document and version together, never the filename's “latest” content. Preserve input positions for errors and use a set to detect duplicate citation IDs. You may report the first error or all errors for an item, but keep that policy consistent.
  2. Separate validation from display. Check the entire batch in temporary results. On error, return without modifying the current display. Only after full validation should the new highlights and citation index be committed together.
  3. Group by version, sort and maintain coverage. Sort each group by start. A following interval whose start is no greater than the current end belongs to the same continuous coverage; extend the end to the larger endpoint. Otherwise close the current range. Keep original citations separately rather than reconstructing a claim's evidence from merged ranges.
  4. Verify coverage and ownership independently. D/v1 covers [2,10) and D/v2 covers [2,5). Clicking c2 still identifies claim B's v1 [4,8), not the whole merged range. An out-of-range c3 rejects the batch and preserves the previous display. Reject duplicate IDs; empty input is valid empty coverage; v2 cannot replace a missing v1.
  5. Account for the full scale. With n citations and d supplied versions, constructing a version table and validating takes expected O(d+n); sorting takes O(n log n) in the worst case and scanning O(n). Additional space is O(d+n). If a directly queryable read-only version table already exists, excluding its existing storage gives O(n) new space. Text is already a read-only code-point array and is not copied; loading text and rendering are outside these bounds. These bounds use a unit-cost model for ID hashing, equality checks and map access. With variable-length string IDs, account separately for the work of hashing and comparing those strings.