<?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: yongchan kwon (nuckdrip)</title>
    <description>The latest articles on DEV Community by yongchan kwon (nuckdrip) (@yongchan_kwonnuckdrip_).</description>
    <link>https://dev.to/yongchan_kwonnuckdrip_</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%2F4144429%2Ffae24787-05ff-4ff8-a2a6-8cef1069410d.jpg</url>
      <title>DEV Community: yongchan kwon (nuckdrip)</title>
      <link>https://dev.to/yongchan_kwonnuckdrip_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yongchan_kwonnuckdrip_"/>
    <language>en</language>
    <item>
      <title>When a Failed Request Must Stay Failed: Reservation Replay</title>
      <dc:creator>yongchan kwon (nuckdrip)</dc:creator>
      <pubDate>Sat, 26 Sep 2026 15:54:32 +0000</pubDate>
      <link>https://dev.to/yongchan_kwonnuckdrip_/when-a-failed-request-must-stay-failed-reservation-replay-2o6o</link>
      <guid>https://dev.to/yongchan_kwonnuckdrip_/when-a-failed-request-must-stay-failed-reservation-replay-2o6o</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/kaggle-2026-09-23"&gt;Kaggle Benchmarking Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Benchmarked
&lt;/h2&gt;

&lt;p&gt;A room is occupied, so a booking request fails. The room becomes free. Should an&lt;br&gt;
identical retry now succeed?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Under this benchmark's declared contract, no.&lt;/strong&gt; The original request ID must&lt;br&gt;
replay the original rejection. A genuinely new attempt needs a new ID. This is&lt;br&gt;
the rule being tested, not a claim about every reservation API.&lt;/p&gt;

&lt;p&gt;Reservation Replay asks a model to reconstruct both the final calendar and every&lt;br&gt;
decision in a synthetic event log. Checking the calendar alone can hide a wrong&lt;br&gt;
intermediate decision. The benchmark therefore requires both.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Required decision&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create booking x in A [0,10), request r1&lt;/td&gt;
&lt;td&gt;CREATED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create booking y in A [5,8), request r2&lt;/td&gt;
&lt;td&gt;CONFLICT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cancel x at revision 1, request r3&lt;/td&gt;
&lt;td&gt;CANCELLED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retry the identical r2 request&lt;/td&gt;
&lt;td&gt;REPLAY, with cached CONFLICT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Try y again using a new request r4&lt;/td&gt;
&lt;td&gt;CREATED&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The protocol uses two fictional rooms and integer, half-open intervals; touching&lt;br&gt;
endpoints are allowed. Creates start at revision 1. Replacements and cancellations&lt;br&gt;
require the current revision, and a rejected replacement leaves the original&lt;br&gt;
booking unchanged. Proposals neither mutate state nor consume request IDs.&lt;br&gt;
Confirmed outcomes, including failures, are cached; reusing an ID with a different&lt;br&gt;
payload is rejected.&lt;/p&gt;

&lt;p&gt;The pilot contains &lt;strong&gt;8 base traces and 4 dependent metamorphic variants&lt;/strong&gt;. The&lt;br&gt;
variants rename booking IDs, swap room labels, or shift times. These are 12 test&lt;br&gt;
cases, not 12 independent observations. Expected answers were hand-enumerated and&lt;br&gt;
checked against a Python reference interpreter.&lt;/p&gt;

&lt;p&gt;The metric is &lt;strong&gt;SDK-parsed exact trace success&lt;/strong&gt;, without an LLM judge. Fields and&lt;br&gt;
types must match at the scorer boundary. Booking-list order is ignored, while&lt;br&gt;
decision order and duplicate booking IDs matter. This does not certify raw JSON&lt;br&gt;
strictness: SDK parsing can normalize a response before the scorer sees it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Models Tested
&lt;/h2&gt;

&lt;p&gt;I ran &lt;code&gt;google/gemini-2.5-flash&lt;/code&gt; and &lt;code&gt;google/gemini-3.7-flash&lt;/code&gt; through Kaggle&lt;br&gt;
Benchmarks SDK &lt;strong&gt;0.6.1&lt;/strong&gt;. Each was evaluated during development and again for the&lt;br&gt;
published task, under the same scoring policy v2. The table below reports the&lt;br&gt;
published runs. No task-level retry was added. Each case&lt;br&gt;
receives the same protocol in a fresh chat, with expected answers kept in the&lt;br&gt;
grader.&lt;/p&gt;

&lt;p&gt;The scoring policy changed &lt;strong&gt;after an observed pilot failure&lt;/strong&gt;. Gemini 2.5 Flash&lt;br&gt;
passed an initial one-case smoke test. A separate v1 full run then returned Python&lt;br&gt;
instead of JSON on its first case, raising &lt;code&gt;ResponseParsingError&lt;/code&gt; and leaving 11&lt;br&gt;
cases unattempted. That aborted run has no aggregate score.&lt;/p&gt;

&lt;p&gt;Policy v2 catches that specific error, preserves the raw response, counts the case&lt;br&gt;
as an output-contract failure, and continues. Incorrect parsed answers are a&lt;br&gt;
separate category. API, quota, and unexpected errors still abort without a valid&lt;br&gt;
aggregate. Protocol, prompts, fixtures, and parsed-answer scoring stayed unchanged.&lt;br&gt;
Earlier pilot observations are preserved and excluded from the table below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Findings
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Base traces&lt;/th&gt;
&lt;th&gt;Dependent variants&lt;/th&gt;
&lt;th&gt;Overall&lt;/th&gt;
&lt;th&gt;Output-contract failures&lt;/th&gt;
&lt;th&gt;Structured mismatches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 2.5 Flash&lt;/td&gt;
&lt;td&gt;2/8&lt;/td&gt;
&lt;td&gt;2/4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4/12&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 3.7 Flash&lt;/td&gt;
&lt;td&gt;8/8&lt;/td&gt;
&lt;td&gt;4/4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;12/12&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The observed difference was delivering the requested answer format.&lt;/strong&gt; The eight&lt;br&gt;
2.5 Flash failures produced responses the SDK could not parse into the requested&lt;br&gt;
answer, including Python code or explanatory prose. Every answer that reached the&lt;br&gt;
structured scorer passed. Returned Python was neither executed nor assumed to be&lt;br&gt;
semantically right or wrong.&lt;/p&gt;

&lt;p&gt;The earlier development evaluation scored &lt;strong&gt;6/12&lt;/strong&gt; for 2.5 Flash (4/8 base,&lt;br&gt;
2/4 variants), with six format failures and no structured mismatches. Its&lt;br&gt;
published rerun scored 4/12. Gemini 3.7 Flash scored 12/12 in both runs. These&lt;br&gt;
separate observations are not pooled or selectively replaced by the better run.&lt;/p&gt;

&lt;p&gt;That variability matters: a single score is not a stable ranking. Nor do format&lt;br&gt;
failures demonstrate that the model misunderstood the cached-rejection rule.&lt;br&gt;
In the development run, the base cached-failure trace returned code while its&lt;br&gt;
renamed counterpart answered correctly. That is a format inconsistency, not&lt;br&gt;
proof that identifier names caused a reasoning change.&lt;/p&gt;

&lt;p&gt;For a developer consuming structured model output, a useful algorithm in the&lt;br&gt;
wrong format still breaks the integration. Keeping those failures in the&lt;br&gt;
denominator prevents a benchmark from reporting only the answers it could parse.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Benchmark
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/benchmarks/yongchankwonnuckdrip/reservation-replay" rel="noopener noreferrer"&gt;Explore the public Kaggle benchmark&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The publication task fixes all 12 cases inside its exported function and uses the&lt;br&gt;
Kaggle-selected model. This avoids accidentally publishing a one-case smoke test&lt;br&gt;
as the full evaluation.&lt;/p&gt;

&lt;p&gt;This small synthetic pilot, with few runs and dependent variants, cannot establish&lt;br&gt;
production reliability or a stable model ranking.&lt;br&gt;
Longer traces, distracting proposals, and repeated runs are useful next tests.&lt;/p&gt;

&lt;p&gt;Development and editorial review used AI assistance. The fixtures, deterministic&lt;br&gt;
scorer, and preserved run evidence make the claims inspectable.&lt;/p&gt;

</description>
      <category>kagglechallenge</category>
      <category>devchallenge</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>The Museum of Almost: a museum you explore by making choices</title>
      <dc:creator>yongchan kwon (nuckdrip)</dc:creator>
      <pubDate>Sat, 26 Sep 2026 14:24:57 +0000</pubDate>
      <link>https://dev.to/yongchan_kwonnuckdrip_/the-museum-of-almost-a-museum-you-explore-by-making-choices-2lmh</link>
      <guid>https://dev.to/yongchan_kwonnuckdrip_/the-museum-of-almost-a-museum-you-explore-by-making-choices-2lmh</guid>
      <description>&lt;p&gt;&lt;em&gt;Built for the &lt;a href="https://dev.to/challenges/sanity-2026-09-16"&gt;Sanity Challenge, Path Two: Vibe-Code Something Strange&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Who should be allowed to borrow your rain?&lt;/p&gt;

&lt;p&gt;The Museum of Almost is a small interactive exhibition for people who enjoy speculative design and branching stories. Its six fictional inventions begin with everyday objects: an umbrella that replays the sound of a past rainy walk, a clock that leaves a minute uncounted, a bench that makes room for shared silence.&lt;/p&gt;

&lt;p&gt;Each asks you to make a choice. Give your rain to the neighborhood and follow the story to The Listening Bench. Keep an afternoon for yourself and discover The Borrowed Minute. Change your choice to explore another possibility, or open the map to see how the collection connects.&lt;/p&gt;

&lt;p&gt;The inventions and their imagined prototype anecdotes are labeled fiction. The six illustrations are CSS object studies. Choices follow authored branches; the app does not generate new stories at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://museum-of-almost-kwon.netlify.app/" rel="noopener noreferrer"&gt;Explore The Museum of Almost&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%2Fkagutlcsdfgop6i22v8q.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%2Fkagutlcsdfgop6i22v8q.png" alt="Six fictional exhibits in The Museum of Almost" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Choose an object, make a choice, and see what follows. Local Sanity-connected build, September 26.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public visitor walkthrough:&lt;/strong&gt; no login is needed. Open The Rain Library, choose &lt;strong&gt;Give it to the neighborhood&lt;/strong&gt;, follow the consequence to The Listening Bench, then explore the possibility map. Exhibit links and initial map choices can be shared and reopened; subsequent choices within a visit remain temporary.&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%2Far2o46ov20wrhgea2rbc.jpg" 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%2Far2o46ov20wrhgea2rbc.jpg" alt="The Rain Library and its visitor choices" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Rain Library offers a choice about sharing an afternoon. Local Sanity-connected build, September 21.&lt;/em&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%2Fza5i83pkv0l1y6h2kbeu.jpg" 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%2Fza5i83pkv0l1y6h2kbeu.jpg" alt="Possibility map connecting the six exhibits" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The possibility map shows how choices connect the collection. Local Sanity-connected build, September 21.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local curator sandbox:&lt;/strong&gt; use Node.js 24 (tested with 24.19.0) and pnpm 11.19.0. Start a fresh clone without an environment file and with &lt;code&gt;MUSEUM_STORAGE&lt;/code&gt; unset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/asdv3189/museum-of-almost.git
&lt;span class="nb"&gt;cd &lt;/span&gt;museum-of-almost
git checkout be19b9b6507b15a0f727fd10bd8ecab2aeff0591
pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--frozen-lockfile&lt;/span&gt;
pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://127.0.0.1:8792/?view=curator&lt;/code&gt;; no account or key is needed on loopback in local mode. Edit an exhibit's description and save, then open &lt;strong&gt;Review changes&lt;/strong&gt;, send for review, approve the revision, and put it on the wall. Check the exhibition before and after publication to see the draft boundary.&lt;/p&gt;

&lt;p&gt;This sandbox stores changes in local &lt;code&gt;.data/museum.json&lt;/code&gt;. It demonstrates the curator workflow without connecting to or testing Sanity. The hosted museum uses Sanity; its separate live verification is described below, and its writable curator room remains private.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/asdv3189/museum-of-almost" rel="noopener noreferrer"&gt;public source repository&lt;/a&gt; contains the Next.js app, Sanity schemas and adapter, domain rules, and tests. The published source was verified against the prepared package at &lt;a href="https://github.com/asdv3189/museum-of-almost/tree/be19b9b6507b15a0f727fd10bd8ecab2aeff0591" rel="noopener noreferrer"&gt;commit be19b9b&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That source snapshot's README still describes deployment as pending. The same source is now deployed at the demo URL above and was verified there on September 26.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Build Process
&lt;/h2&gt;

&lt;p&gt;Codex desktop produced the implementation, exhibition copy, CSS illustrations, and tests. Other agents reviewed the code and tests, and browser inspection checked the running app. These are agent observations, not human audience testing.&lt;/p&gt;

&lt;p&gt;The build brief paired six unrealized inventions with a precise constraint for the curator room: approve an exact revision, then publish only that unchanged revision. This made the schema part of the experience. A visitor's route needs a choice, a consequence, and a destination; an editor's change needs a draft, a review, and a publication boundary.&lt;/p&gt;

&lt;p&gt;The first implementation got important details wrong. A map connection opened an object but lost the selected branch, so browser review led to preserving the choice and its consequence together. A generated mapper overwrote Sanity's document type with an embedded content type; independent tests caught the collision. Namespaced document IDs also required authenticated server reads despite the public dataset, which changed the adapter's access configuration.&lt;/p&gt;

&lt;p&gt;The September 26 revision made the invitation explicit: choose an object, make a choice, see what follows. It also added URL restoration and repaired reload, Back/Forward, and keyboard-focus behavior. &lt;strong&gt;127 automated tests, typechecking, and the local production build passed.&lt;/strong&gt; Desktop and mobile browser checks used the locally running app connected to Sanity.&lt;/p&gt;

&lt;p&gt;Separately, on &lt;strong&gt;September 21&lt;/strong&gt;, eight workflow checks through the local server exercised real Sanity reads and writes, including stale-request rejection, approval invalidation, and publication visibility. Fourteen successful transitions restored the original fictional content while retaining the audit; a read-only check then matched all six published exhibits to their workspace snapshots.&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;September 26&lt;/strong&gt;, browser checks of the Netlify deployment confirmed all six Sanity-backed exhibits and the Rain Library's neighborhood-sharing consequence leading to The Listening Bench. An empty curator key was rejected; the configured key opened the workbench. A temporary draft edit stayed invisible to a separate unauthenticated visitor. Restoring the original text, requesting review, approving, and publishing then succeeded, leaving five audit events and the original public description intact. These hosted checks used the app's simulated roles; they did not rerun the 127 local tests.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Project ID:&lt;/strong&gt; &lt;code&gt;xmyaojxc&lt;/code&gt; · &lt;strong&gt;Dataset:&lt;/strong&gt; &lt;code&gt;production&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sanity holds the collection and its editing process. Branch destinations use native references. The workspace stores drafts, reviews, approvals, snapshots, and audit events; separate exhibit documents provide published content for GROQ queries.&lt;/p&gt;

&lt;p&gt;Editing invalidates approval. Publication rejects stale revisions, missing destinations, and cycles, then updates the workspace and published exhibit together in a revision-guarded Sanity transaction. Visitors keep seeing the previous published version while an edit is under review.&lt;/p&gt;

&lt;p&gt;This is a custom application workflow. Curator and reviewer are simulated roles, not separately authenticated people. The app uses neither App SDK nor Sanity's managed Workflows product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent Session
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/asdv3189/museum-of-almost/blob/be19b9b6507b15a0f727fd10bd8ecab2aeff0591/BUILD_LOG.md" rel="noopener noreferrer"&gt;build log&lt;/a&gt; records the brief, implementation decisions, failures, and verification. It is a curated account; no agent-session transcript is attached.&lt;/p&gt;

</description>
      <category>sanitychallenge</category>
      <category>devchallenge</category>
      <category>sanity</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
