/** * A resolved decision is a margin marker beside the prose it produced. * * Geometry, hover, pinning, scrolling and the highlight registry are browser * behaviour, so this runs in Chromium; the pure pieces (which options were not * chosen, how hover and pin combine, where things sit) are in * `packages/editor/src/resolved.test.ts`. * * Anchors are seeded with a stale epoch and the block's digest, which is how * the server finds a block again after its history is gone. */ import { createHash } from "node:crypto"; import { authenticate, content, expect, roomPath, test } from "./room"; import type { Locator, Page } from "@playwright/test"; const FIRST = "The rollout goes team by team, starting with the docs team."; const SECOND = "After two weeks we review the pilot and decide whether to widen it."; const WIDGET_A = "01K0N4TR8K7JGM4R1J7PW4R8YJ"; const WIDGET_B = "01K0N4TR8K7JGM4R1J7PW4R8YK"; const QUESTION_A = "01K0N4V4E7Y6P4MJ5WD8XZF3B2"; const QUESTION_B = "01K0N4V4E7Y6P4MJ5WD8XZF3B3"; const AT = "2026-09-23T15:13:00.000Z"; function digest(text: string): string { return `sha256:${createHash("sha256").update(`${text}\n`).digest("hex")}`; } /** A ULID, which is what the dialect insists an option id is. */ function optionId(question: string, index: number): string { return `${question.slice(0, 22)}${question.slice(-2)}0${index}`; } function options(question: string, labels: string[]): string { return labels.map((label, index) => `