<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mukeshkbj</title>
    <description>The latest articles on DEV Community by mukeshkbj (@mukeshkbj).</description>
    <link>https://dev.to/mukeshkbj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F472917%2F83bf8750-8f03-42fb-beab-13a09a6fefd2.png</url>
      <title>DEV Community: mukeshkbj</title>
      <link>https://dev.to/mukeshkbj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mukeshkbj"/>
    <language>en</language>
    <item>
      <title>Bureau of Almost-Happened Events — a counterfactual archive on a document graph</title>
      <dc:creator>mukeshkbj</dc:creator>
      <pubDate>Wed, 30 Sep 2026 04:54:36 +0000</pubDate>
      <link>https://dev.to/mukeshkbj/bureau-of-almost-happened-events-a-counterfactual-archive-on-a-document-graph-2dc1</link>
      <guid>https://dev.to/mukeshkbj/bureau-of-almost-happened-events-a-counterfactual-archive-on-a-document-graph-2dc1</guid>
      <description>&lt;h1&gt;
  
  
  Bureau of Almost-Happened Events
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;A counterfactual story archive where every docket is a branching document graph — and the editors build that graph on a live investigation board instead of a CMS form.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Live archive&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bureau-events.pages.dev" rel="noopener noreferrer"&gt;https://bureau-events.pages.dev&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Repository&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/mukeshkbj/bureau-events" rel="noopener noreferrer"&gt;https://github.com/mukeshkbj/bureau-events&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Studio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bureau-events.sanity.studio" rel="noopener noreferrer"&gt;https://bureau-events.sanity.studio&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bureau Board (App SDK app)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.sanity.io/@o041d79wc/application/iv082hu12r39wvgimogfoxhc" rel="noopener noreferrer"&gt;https://www.sanity.io/@o041d79wc/application/iv082hu12r39wvgimogfoxhc&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sanity project&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;9n512feo&lt;/code&gt; · dataset &lt;code&gt;production&lt;/code&gt; (public read)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Astro 7 · Studio v6 · App SDK (React 19) · Functions + Blueprints · Cloudflare Pages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;The Bureau files incident reports for events that &lt;em&gt;almost&lt;/em&gt; happened. A visitor&lt;br&gt;
opens a docket — say, &lt;strong&gt;The Town That Arrived One Minute Late&lt;/strong&gt; — and reads the&lt;br&gt;
first incident report. Each report ends in labeled choices; each choice is a&lt;br&gt;
door into another incident. Evidence (stopwatches, memos, photographs) arrives&lt;br&gt;
taped into the reports. Every path terminates in a stamped designation:&lt;br&gt;
&lt;strong&gt;REPRIEVE&lt;/strong&gt;, &lt;strong&gt;ANOMALY&lt;/strong&gt;, or &lt;strong&gt;CATASTROPHE&lt;/strong&gt;. The Bureau does not explain the&lt;br&gt;
difference.&lt;/p&gt;

&lt;p&gt;The unusual part is the authoring surface. The archive's stories are stored as&lt;br&gt;
a &lt;em&gt;graph of documents&lt;/em&gt;, so the editorial tool is a &lt;strong&gt;live investigation board&lt;/strong&gt;&lt;br&gt;
— nodes pinned to a desk, edges drawn between them, diagnostics stamped on&lt;br&gt;
broken graphs, all updating in real time over the Sanity App SDK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fizb18ntduo82zfkrkfi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fizb18ntduo82zfkrkfi5.png" alt="The docket index — every case filed as a card-catalog entry" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffzolevkukaiy398z1mkv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffzolevkukaiy398z1mkv.png" alt="A dossier: classification strip, premise, and the bureau sigil" width="800" height="889"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnhcxixhqgt12f1oxuxg8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnhcxixhqgt12f1oxuxg8.png" alt="An incident mid-branch — drop cap, taped-on evidence card, route trail" width="800" height="889"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft9m3a7ppm6c1ukoyq6rq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft9m3a7ppm6c1ukoyq6rq.png" alt="A path terminated — the ANOMALY designation stamped down" width="800" height="889"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The schema is the product
&lt;/h2&gt;

&lt;p&gt;Four document types, no plumbing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;caseFile&lt;/code&gt;&lt;/strong&gt; — a docket: title, slug, premise, filing code (&lt;code&gt;BAH-####&lt;/code&gt;),
sigil, and a review status that gates publication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;incident&lt;/code&gt;&lt;/strong&gt; — one node in the graph. &lt;code&gt;order == 0&lt;/code&gt; marks the entry point.
&lt;code&gt;choices[]&lt;/code&gt; are objects holding a label, a Bureau-voiced "consequence note",
and a &lt;code&gt;next&lt;/code&gt; &lt;strong&gt;reference to a sibling incident&lt;/strong&gt;. An incident with no choices
must declare &lt;code&gt;ending.isEnding&lt;/code&gt; — enforced by document-level validation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;artifact&lt;/code&gt;&lt;/strong&gt; — evidence attached to an incident (&lt;code&gt;evidence → artifact&lt;/code&gt;),
rendered in the reader as taped-on registry cards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;review&lt;/code&gt;&lt;/strong&gt; — an append-only approval trail. Each round carries the author's
note, then the curator's decision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the story &lt;em&gt;is&lt;/em&gt; the reference graph, the public reader is a single GROQ&lt;br&gt;
projection: one query returns the docket plus every incident with its resolved&lt;br&gt;
choices (&lt;code&gt;choices[]{ "nextId": next._ref }&lt;/code&gt;), ending, and dereferenced&lt;br&gt;
evidence. The frontend walks it as a pure client-side graph traversal with&lt;br&gt;
&lt;code&gt;#i=&amp;lt;incident-id&amp;gt;&lt;/code&gt; deep links.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmoicua20m9mje2oqj891.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmoicua20m9mje2oqj891.png" alt="System map — editors, board, lake, function, archive" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Past the Studio: the Bureau Board (App SDK)
&lt;/h2&gt;

&lt;p&gt;The board is a standalone Sanity app, not a Studio plugin. It shows the same&lt;br&gt;
documents — live — but as the shape an editor actually thinks in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;case rail&lt;/strong&gt; listing dockets with their review status pills.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;graph canvas&lt;/strong&gt;: incidents as pinned cards, SVG edges between choices,
layered by BFS distance from the entry. Endings, entry points, and flagged
nodes each get their own look.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live diagnostics&lt;/strong&gt; — the same validator the tests run, projected on the
board: unreachable nodes, choices pointing at missing targets, non-endings
with no way out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full authoring&lt;/strong&gt;: file a new docket (auto-assigns the next &lt;code&gt;BAH-####&lt;/code&gt; and a
slug), add incidents straight onto the board, grow branches with "+ New
incident linked from here", edit reports/endings in a drawer, attach or
create artifacts as evidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review panel&lt;/strong&gt;: submit a round with an author's note; curators approve or
request changes in place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activity toasts&lt;/strong&gt; for document events — open the board in two windows and
watch edits land.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything the board writes goes through &lt;code&gt;useCreateDocument&lt;/code&gt; /&lt;br&gt;
&lt;code&gt;useEditDocument&lt;/code&gt; / &lt;code&gt;useApplyDocumentActions&lt;/code&gt; — real documents, real&lt;br&gt;
persistence, real-time. The Studio keeps its own job: schema validation plus&lt;br&gt;
two custom document actions, &lt;strong&gt;Submit for review&lt;/strong&gt; and &lt;strong&gt;Publish case graph&lt;/strong&gt;&lt;br&gt;
(the latter publishes the docket and every child draft in one transaction).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqnbwex3pk8mpmkhlrrz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqnbwex3pk8mpmkhlrrz6.png" alt="Bureau Board — the incident graph pinned to the desk, diagnostics stamped clean" width="799" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflows: review as data, a Function as the messenger
&lt;/h2&gt;

&lt;p&gt;The challenge asked to see a process modeled next to the content. Here it is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An author files a &lt;code&gt;review&lt;/code&gt; document (&lt;code&gt;decision: pending&lt;/code&gt;, round number,
author's note) from the board or Studio.&lt;/li&gt;
&lt;li&gt;A curator edits that same document — &lt;code&gt;decision&lt;/code&gt;, &lt;code&gt;decisionNote&lt;/code&gt;, &lt;code&gt;reviewer&lt;/code&gt;
— and publishes it.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Sanity Function&lt;/strong&gt; (&lt;code&gt;sync-review-decision&lt;/code&gt;, deployed via a Blueprint)
listens for review events, unions the event payload with the queryable
reviews so the firing document is authoritative, and patches
&lt;code&gt;caseFile.reviewStatus&lt;/code&gt; → &lt;code&gt;approved&lt;/code&gt; / &lt;code&gt;changesRequested&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Only &lt;code&gt;reviewStatus == "approved"&lt;/code&gt; dockets are picked up by the public
build — the approval literally turns the site on.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Round-tripping works: request changes → author resubmits round N+1 → approved.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(The review panel sits in the same board — the pasted screenshot above shows it collapsed; the Function's own log records each decision patch it applies.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The build story (the honest part)
&lt;/h2&gt;

&lt;p&gt;A few things broke in instructive ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Imagined SDK APIs.&lt;/strong&gt; First pass of the board was written against the App
SDK hooks I &lt;em&gt;assumed&lt;/em&gt; existed (&lt;code&gt;useQuery&lt;/code&gt; returning pages, separate draft
saves). The real &lt;code&gt;@sanity/sdk-react&lt;/code&gt; surface is different — &lt;code&gt;useDocuments&lt;/code&gt;
for type queries, &lt;code&gt;useQuery({query, params})&lt;/code&gt; for GROQ, &lt;code&gt;useEditDocument&lt;/code&gt;
with whole-document updaters. The fix was reading the type declarations and
rewriting five components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dotted &lt;code&gt;_id&lt;/code&gt;s are anonymous-invisible.&lt;/strong&gt; The seed used IDs like
&lt;code&gt;incident.clk-00&lt;/code&gt;. The dataset was public, authenticated queries worked — but
anonymous reads returned &lt;code&gt;omitted: permission&lt;/code&gt;. Only a raw &lt;code&gt;curl&lt;/code&gt; revealed
that &lt;code&gt;.&lt;/code&gt; in an &lt;code&gt;_id&lt;/code&gt; namespaces the document away from public access.
Everything was re-seeded with hyphenated IDs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Function race that looked like a no-op.&lt;/strong&gt; The Function queried "latest
review" after receiving the event — but the event can fire before the new
document is visible to the query index. Round 3 silently computed against
stale data and the idempotency check skipped the patch &lt;em&gt;permanently&lt;/em&gt;. The fix
folds &lt;code&gt;event.data&lt;/code&gt; into the decision set so the firing document is always
authoritative. Logs confirmed the patch landing on round 4.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layering a cyclic graph.&lt;/strong&gt; The first &lt;code&gt;computeLayers&lt;/code&gt; used longest-path
relaxation — which diverges on cycles. Replaced with shortest-path BFS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;Astro 7 (static) · Sanity Studio v6 · App SDK (React 19) · Sanity Functions +&lt;br&gt;
Blueprints · Cloudflare Pages · pnpm monorepo with a shared&lt;br&gt;
&lt;code&gt;@bureau/content-model&lt;/code&gt; package (schemas, GROQ, graph validator + tests, seed).&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity Project Details
&lt;/h2&gt;

&lt;p&gt;Project name    Bureau of Almost-Happened Events&lt;br&gt;
Live site   &lt;a href="https://bureau-events.pages.dev" rel="noopener noreferrer"&gt;https://bureau-events.pages.dev&lt;/a&gt;&lt;br&gt;
Repository  &lt;a href="https://github.com/mukeshkbj/bureau-events" rel="noopener noreferrer"&gt;https://github.com/mukeshkbj/bureau-events&lt;/a&gt;&lt;br&gt;
Studio  &lt;a href="https://bureau-events.sanity.studio" rel="noopener noreferrer"&gt;https://bureau-events.sanity.studio&lt;/a&gt;&lt;br&gt;
App (Bureau Board)  &lt;a href="https://www.sanity.io/@o041d79wc/application/iv082hu12r39wvgimogfoxhc" rel="noopener noreferrer"&gt;https://www.sanity.io/@o041d79wc/application/iv082hu12r39wvgimogfoxhc&lt;/a&gt;&lt;br&gt;
Organization    o041d79wc&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read the archive&lt;/strong&gt; — &lt;a href="https://bureau-events.pages.dev" rel="noopener noreferrer"&gt;https://bureau-events.pages.dev&lt;/a&gt; — no login needed; take a path to an ending.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The editorial surfaces&lt;/strong&gt; (Bureau Board app + Studio) are gated by Sanity org
membership — the Board link is above, and the screenshots, walkthrough videos,
and the repo's README show the full authoring loop end to end.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judges&lt;/strong&gt; — Sanity project ID &lt;code&gt;9n512feo&lt;/code&gt;, public dataset &lt;code&gt;production&lt;/code&gt;:
&lt;code&gt;https://9n512feo.api.sanity.io/v2026-09-01/data/query/production?query=*%5B_type%20%3D%3D%20%22caseFile%22%5D&lt;/code&gt;
returns the docket graph anonymously.&lt;/li&gt;
&lt;li&gt;Repo README has setup, seeding (token or CLI-session import), deploy steps,
and the docket-authoring walkthrough.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Demo walkthrough — index → dossier → choices → evidence → ending (62s, &lt;code&gt;docs/media/archive-walkthrough.webm&lt;/code&gt;; upload to DEV as a video embed):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mukeshkbj/bureau-events/blob/master/docs/media/archive-walkthrough.webm" rel="noopener noreferrer"&gt;https://github.com/mukeshkbj/bureau-events/blob/master/docs/media/archive-walkthrough.webm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Editorial round-trip — Bureau Board files docket BAH-0007, submits it for&lt;br&gt;
review, a curator approves, and the &lt;code&gt;sync-review-decision&lt;/code&gt; Function lands the&lt;br&gt;
&lt;code&gt;APPROVED&lt;/code&gt; decision on the review trail — live, unedited (46s,&lt;br&gt;
&lt;code&gt;docs/media/editorial-review-roundtrip.webm&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mukeshkbj/bureau-events/blob/master/docs/media/editorial-review-roundtrip.webm" rel="noopener noreferrer"&gt;https://github.com/mukeshkbj/bureau-events/blob/master/docs/media/editorial-review-roundtrip.webm&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>astro</category>
      <category>sanitychallenge</category>
    </item>
  </channel>
</rss>
