<?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: Sharon Basovich</title>
    <description>The latest articles on DEV Community by Sharon Basovich (@sharonbasovich).</description>
    <link>https://dev.to/sharonbasovich</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%2F4158309%2F90ac846d-aac2-46e3-9a73-e8ee0de96d02.jpg</url>
      <title>DEV Community: Sharon Basovich</title>
      <link>https://dev.to/sharonbasovich</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sharonbasovich"/>
    <language>en</language>
    <item>
      <title>The server locked the scores. The judge’s screen still said “Update.”</title>
      <dc:creator>Sharon Basovich</dc:creator>
      <pubDate>Sat, 03 Oct 2026 23:17:07 +0000</pubDate>
      <link>https://dev.to/sharonbasovich/the-server-locked-the-scores-the-judges-screen-still-said-update-1ko1</link>
      <guid>https://dev.to/sharonbasovich/the-server-locked-the-scores-the-judges-screen-still-said-update-1ko1</guid>
      <description>&lt;p&gt;Glassbox had a misleading screen at exactly the moment a judging platform needs to be clearest.&lt;/p&gt;

&lt;p&gt;An organizer published the results. The server correctly refused further score changes. But the judge’s page still looked editable.&lt;/p&gt;

&lt;p&gt;A judge could spend time revising a comment, press Update, and discover that the action had already become impossible.&lt;/p&gt;

&lt;p&gt;This turned up during the build’s browser walkthrough. The fix is small enough to read in &lt;a href="https://github.com/sharonbasovich/glassbox-dogfood/commit/96cd0e1a586fa2b64e3d0f6f2dee4216bc24ffd3" rel="noopener noreferrer"&gt;one commit&lt;/a&gt;. The underlying lesson reaches beyond hackathons: a state transition has to change both what the system permits and what it tells people they can do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building around the moment results become final
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sharonbasovich/glassbox-dogfood" rel="noopener noreferrer"&gt;Glassbox&lt;/a&gt; is an open-source, self-hosted submission and judging portal built for DOGFOOD 2026. It uses Node 24, TypeScript, built-in SQLite, and server-rendered HTML, with no runtime npm dependencies.&lt;/p&gt;

&lt;p&gt;Its most consequential button is Publish.&lt;/p&gt;

&lt;p&gt;Before publication, judges can revise their assigned scores and organizers can inspect raw and calibrated rankings. After publication, people need a stable answer to “What were the results?”&lt;/p&gt;

&lt;p&gt;The implementation makes that transition explicit. Publication computes the ranking, serializes an aggregate results snapshot, hashes it with SHA-256, stores it, marks the event published, and appends an audit entry in a transaction. Public results are served from the stored snapshot rather than recalculated on every request. See the &lt;a href="https://github.com/sharonbasovich/glassbox-dogfood/blob/5094890c44d7394bf05c48b32b1d09ebe402514a/src/services/results.ts" rel="noopener noreferrer"&gt;publication service&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That gives the public page a specific artifact to display. It also keeps individual judges’ score rows out of the public payload.&lt;/p&gt;

&lt;p&gt;The browser had missed that transition.&lt;/p&gt;

&lt;h2&gt;
  
  
  A regression test for the promise on the screen
&lt;/h2&gt;

&lt;p&gt;The fix derives the score form’s locked state from the event phase. Once published, the page displays a locked notice, disables the score fields, and removes the save and recusal actions.&lt;/p&gt;

&lt;p&gt;The backend remains responsible for rejecting forbidden writes. The disabled form makes the restriction understandable before someone wastes effort.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/sharonbasovich/glassbox-dogfood/blob/5094890c44d7394bf05c48b32b1d09ebe402514a/tests/ui.test.ts" rel="noopener noreferrer"&gt;regression test&lt;/a&gt; follows the transition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open an assigned score page as a judge and confirm that saving is available.&lt;/li&gt;
&lt;li&gt;Publish the event through the organizer API.&lt;/li&gt;
&lt;li&gt;Fetch the judge page again.&lt;/li&gt;
&lt;li&gt;Check for the locked notice and disabled fieldset.&lt;/li&gt;
&lt;li&gt;Check that save and recusal controls are gone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That test checks rendered HTML. The &lt;a href="https://github.com/sharonbasovich/glassbox-dogfood/pull/1#issuecomment-5853794460" rel="noopener noreferrer"&gt;build’s separate browser retest&lt;/a&gt; also records checking that the fields could no longer be changed and that the saved score stayed unchanged.&lt;/p&gt;

&lt;p&gt;Both checks matter. An API test can prove that an invalid write fails while missing a screen that encourages the write.&lt;/p&gt;

&lt;h2&gt;
  
  
  A ranking also needs an explanation
&lt;/h2&gt;

&lt;p&gt;Publication freezes a number, but the number still needs a defensible path from the ballots.&lt;/p&gt;

&lt;p&gt;Glassbox converts each review into a weighted total and offers shrunk z-score calibration. A judge’s mean and spread are blended with the event-wide pool, using three pseudo-reviews by default. Sparse judging histories therefore receive more pooling than large ones.&lt;/p&gt;

&lt;p&gt;The important product choice is that the adjusted ranking does not erase the raw ranking. Organizers can compare them, inspect judge offsets and spreads, and export review-level values. The dashboard, exports, and publication use the same &lt;a href="https://github.com/sharonbasovich/glassbox-dogfood/blob/5094890c44d7394bf05c48b32b1d09ebe402514a/src/scoring/normalize.ts" rel="noopener noreferrer"&gt;normalization implementation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a model with assumptions. If a judge sees unusually strong projects, high scores can resemble leniency. Showing the adjustment makes that assumption inspectable; it does not establish that every ranking change is correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the evidence establishes
&lt;/h2&gt;

&lt;p&gt;The committed &lt;a href="https://github.com/sharonbasovich/glassbox-dogfood/blob/5094890c44d7394bf05c48b32b1d09ebe402514a/acceptance-report.txt" rel="noopener noreferrer"&gt;acceptance report&lt;/a&gt; records seven passing checks and verifies the claimed T1 and T2 tiers. Those checks cover public gallery behavior, deadline rejection, score access isolation, and CSV export. This is the build’s historical report; no new test run is claimed here.&lt;/p&gt;

&lt;p&gt;They do not establish production readiness or real-world fairness.&lt;/p&gt;

&lt;p&gt;Glassbox remains a single-node SQLite application. It has no community voting, email delivery, or built-in login rate limiting. The hash chain detects inconsistent edits, but an administrator controlling the database could rewrite the chain; there is no external trust anchor.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reusable lesson
&lt;/h2&gt;

&lt;p&gt;For an irreversible-looking moment such as publication, test three things together: the forbidden write, the newly rendered screen, and the artifact people will rely on afterward.&lt;/p&gt;

&lt;p&gt;That small “Update” button exposed a gap between a correct backend and an understandable product. Closing that gap made the judging lifecycle much easier to defend.&lt;/p&gt;

&lt;p&gt;Built for DOGFOOD 2026, organized by &lt;a href="https://dev.to/raptorsdev"&gt;Hackathon Raptors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;#HackathonRaptors&lt;/p&gt;

</description>
      <category>hackathonraptors</category>
      <category>hackathon</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Claim Ledger gives a project review a paper trail</title>
      <dc:creator>Sharon Basovich</dc:creator>
      <pubDate>Fri, 02 Oct 2026 22:10:16 +0000</pubDate>
      <link>https://dev.to/sharonbasovich/claim-ledger-gives-a-project-review-a-paper-trail-1nae</link>
      <guid>https://dev.to/sharonbasovich/claim-ledger-gives-a-project-review-a-paper-trail-1nae</guid>
      <description>&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;In a fictional project, a README says the app works offline. Its limitations file says route planning still needs a connection. What should the handoff actually promise?&lt;/p&gt;

&lt;p&gt;Claim Ledger puts the claim beside the source passages worth checking, then keeps the reviewer's decision with those receipts. In the fictional TrailMend example, the offline claim and its narrower limitation appear together. The model finds candidate evidence; the reviewer decides what the claim can support.&lt;/p&gt;

&lt;p&gt;I built this for a teammate who takes an independent second pass through my projects. Their handoff can span a README, setup notes, test records and known limitations. The goal is to make each review decision traceable to the words it was based on.&lt;/p&gt;

&lt;p&gt;Try the fictional packet below. Open a source passage, record a verdict, and export the review with its filenames, line ranges and content fingerprints. If the evidence changes, the earlier approval needs another look.&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%2F0uef80lkzvutboagr9wm.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%2F0uef80lkzvutboagr9wm.png" alt="Illustration comparing the fictional TrailMend offline claim with its narrower source limitation. Hybrid ranking supplies candidate passages; the reviewer decides." width="799" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Excerpts from the running app's fictional TrailMend packet. Hybrid ranking surfaced both passages; this illustration preserves their meaning but is not an app screenshot. Similarity does not determine the verdict.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://sharonbasovich.github.io/claim-ledger/" rel="noopener noreferrer"&gt;Try Claim Ledger&lt;/a&gt;. No account or API key is needed. Start with &lt;strong&gt;Load fictional example packet&lt;/strong&gt;, then enable on-device AI ranking or use the labelled keyword mode. The included TrailMend, PantryPal and Inkwell documents are synthetic examples.&lt;/p&gt;

&lt;p&gt;Try “Can I use the trail planner on a plane with no signal?” TrailMend's README discusses downloaded routes, while its limitations document excludes offline route planning and GPX import. Open the source context before deciding what the broad phrase “works offline” should mean.&lt;/p&gt;

&lt;p&gt;A separate automated check exercised a deliberately small evidence-change scenario: a claim said an import limit was 200 items; its source was replaced with a version saying 210. The repaired app invalidated the earlier confirmation through replacement, reranking and reload. The old note remained, labelled as having been recorded against earlier evidence. Explicitly choosing Confirmed again records a new review.&lt;/p&gt;

&lt;p&gt;The review can be exported as Markdown or JSON. These are review records, not certificates of truth.&lt;/p&gt;

&lt;p&gt;A supplementary AI review exercised nine frozen, AI-authored public-document cases on the deployed app. All 11 supplied excerpts and their exported receipts retained exact text and manually entered provenance. The stale 48-second demo description still ranked first in the version-check case; reviewer judgment and a Follow-up note were needed. With only one to four chunks per case and expected guidance visible to the AI reviewer, this is workflow evidence, not accuracy or human validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use unique filenames for different versions or projects:&lt;/strong&gt; same-named sources replace one another. An initial harness run made this mistake; both its invalid outcomes and the corrected filename run were retained.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/sharonbasovich/claim-ledger" rel="noopener noreferrer"&gt;View the application source on GitHub&lt;/a&gt;. The application is Apache-2.0 licensed. Source, tests, benchmark cases, raw results and correction history are included. Model and runtime binaries are distributed separately from the small source archive.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Build and evaluation disclosure
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Fully Autonomous:&lt;/strong&gt; AI agents researched, implemented, tested and drafted this project under my direction. The independent QA described here was automated. My teammate has not tried the tool yet, so I have no recipient feedback or measured time savings to report.&lt;/p&gt;

&lt;p&gt;A README assertion, a supplied test record and an actual reviewer observation have different meanings. The interface labels those distinctions. A similar passage gives someone a place to investigate; it doesn't establish that a feature works.&lt;/p&gt;

&lt;p&gt;The retrieval core combines BM25 keyword search with the open &lt;code&gt;mixedbread-ai/mxbai-embed-xsmall-v1&lt;/code&gt; embedding model. The pinned revision is &lt;code&gt;e6ac24e5d6efb8782b59de1647b3ececb4ece94e&lt;/code&gt;, using q8 ONNX weights through Transformers.js 4.3.0 and CPU/WASM in a Web Worker. The model is Apache-2.0 licensed.&lt;/p&gt;

&lt;p&gt;The model ranks candidate excerpts. It doesn't write answers or set verdicts. Hybrid mode combines lexical and semantic rankings with reciprocal-rank fusion. Keyword mode remains available without enabling the model.&lt;/p&gt;

&lt;p&gt;Independent automated QA caught problems that mattered to the workflow: older receipts could pick up replacement text, confirmation could survive changed evidence, and multiline Markdown excerpts could escape their intended formatting. Those cases are now covered by targeted regression checks. A separate reviewer rebuilt the repaired source archive and matched its compiled JavaScript byte-for-byte to the deployed application. Typecheck, build, 48 unit tests and 16 end-to-end tests passed in that review. The browser regression runs used the byte-identical local build.&lt;/p&gt;

&lt;p&gt;The benchmark has a less tidy story, and the source archive keeps it. It uses 48 AI-created questions over fictional documents: 40 answerable and eight no-answer cases. On the preserved exploratory run, BM25 retrieved the labelled passage first for 20/40 answerable questions; semantic and hybrid retrieval each did so for 23/40. All three methods correctly abstained on &lt;strong&gt;0/8&lt;/strong&gt; no-answer questions. Keyword search outperformed semantic search on the negation category.&lt;/p&gt;

&lt;p&gt;These are exploratory results. Chunking and the threshold were changed after inspecting results, on the same set. The original first raw output was overwritten and lost. A later rerun and an older differently chunked result remain separately labelled, alongside the correction manifest. The repaired release preserves those benchmark files unchanged. This is not a held-out evaluation or evidence of improved review quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;An openly licensed model makes this narrow use of AI inspectable and replaceable. Developers can compare semantic search against the keyword baseline, inspect every failed query, and decide whether the model helps their documents.&lt;/p&gt;

&lt;p&gt;Inference processes the documents in the browser. The host still serves the site, model and runtime assets and receives ordinary network metadata. In the tested canary scenario, the reviewer observed same-origin GET requests and no transmission of the canary text. That observation is scoped to the tested flow, not a universal privacy guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits and Next Steps
&lt;/h2&gt;

&lt;p&gt;Only Chromium has been tested; Firefox, Safari and real phones remain untested. The model-loading progress display can sit at zero while WASM initializes. An immediate reload can lose the most recent approval, which fails safely by losing the approval rather than inventing one. Deleting and re-adding byte-identical evidence can restore the earlier confirmation while also showing a stale indicator. One split receipt covers only part of its cited line, and JSON exports omit a claim's original source-line field.&lt;/p&gt;

&lt;p&gt;The first trial with the intended teammate is still ahead. For now, the result is a working, inspectable claim-to-evidence review workflow with automated checks and visible limitations.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
