<?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: John Joseph Bassey</title>
    <description>The latest articles on DEV Community by John Joseph Bassey (@josephjbassey).</description>
    <link>https://dev.to/josephjbassey</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%2F4023286%2Fd7825d80-62d5-4f32-9137-baec0f9d2260.png</url>
      <title>DEV Community: John Joseph Bassey</title>
      <link>https://dev.to/josephjbassey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/josephjbassey"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>John Joseph Bassey</dc:creator>
      <pubDate>Tue, 03 Nov 2026 23:09:07 +0000</pubDate>
      <link>https://dev.to/josephjbassey/-347c</link>
      <guid>https://dev.to/josephjbassey/-347c</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/josephjbassey/synapsehealer-building-an-autonomous-self-healing-interoperability-dlq-with-intersystems-iris-ai-2hjj" class="crayons-story__hidden-navigation-link"&gt;SynapseHealer: Building an Autonomous, Self-Healing Interoperability DLQ with InterSystems IRIS AI Hub&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/josephjbassey" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F4023286%2Fd7825d80-62d5-4f32-9137-baec0f9d2260.png" alt="josephjbassey profile" class="crayons-avatar__image" width="204" height="204"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/josephjbassey" class="crayons-story__secondary fw-medium m:hidden"&gt;
              John Joseph Bassey
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                John Joseph Bassey
                
                
              
              &lt;div id="story-author-preview-content-4971912" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/josephjbassey" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F4023286%2Fd7825d80-62d5-4f32-9137-baec0f9d2260.png" class="crayons-avatar__image" alt="" width="204" height="204"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;John Joseph Bassey&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/josephjbassey/synapsehealer-building-an-autonomous-self-healing-interoperability-dlq-with-intersystems-iris-ai-2hjj" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Nov 3&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/josephjbassey/synapsehealer-building-an-autonomous-self-healing-interoperability-dlq-with-intersystems-iris-ai-2hjj" id="article-link-4971912"&gt;
          SynapseHealer: Building an Autonomous, Self-Healing Interoperability DLQ with InterSystems IRIS AI Hub
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/interoperability"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;interoperability&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/vectorsearch"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;vectorsearch&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/intersystemsiris"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;intersystemsiris&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/josephjbassey/synapsehealer-building-an-autonomous-self-healing-interoperability-dlq-with-intersystems-iris-ai-2hjj" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/josephjbassey/synapsehealer-building-an-autonomous-self-healing-interoperability-dlq-with-intersystems-iris-ai-2hjj#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              6&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
          
          &lt;div class="only-sidebar-menu-item trusted-visible-block print-hidden align-center"&gt;
                
                    
                
          &lt;/div&gt;

        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>backend</category>
      <category>database</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>SynapseHealer: Building an Autonomous, Self-Healing Interoperability DLQ with InterSystems IRIS AI Hub</title>
      <dc:creator>John Joseph Bassey</dc:creator>
      <pubDate>Tue, 03 Nov 2026 22:36:09 +0000</pubDate>
      <link>https://dev.to/josephjbassey/synapsehealer-building-an-autonomous-self-healing-interoperability-dlq-with-intersystems-iris-ai-2hjj</link>
      <guid>https://dev.to/josephjbassey/synapsehealer-building-an-autonomous-self-healing-interoperability-dlq-with-intersystems-iris-ai-2hjj</guid>
      <description>&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%2Fq5ghejewzs66orjukpsl.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%2Fq5ghejewzs66orjukpsl.png" alt="SynapseHealer obsidian console" width="800" height="1034"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Built for the InterSystems Programming Contest: AI Agents in Interoperability Workflows (2026)&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: the DLQ is a graveyard
&lt;/h2&gt;

&lt;p&gt;In healthcare and supply-chain integrations, the dead-letter queue is where transactions go to die. A vendor renames &lt;code&gt;client_uuid&lt;/code&gt; to &lt;code&gt;customer_id&lt;/code&gt; with no warning. An EHR bridge emits &lt;code&gt;1985-02-31&lt;/code&gt;, an impossible calendar day. An HL7 &lt;code&gt;ADT^A01&lt;/code&gt; arrives with &lt;code&gt;PV1&lt;/code&gt; before &lt;code&gt;PID&lt;/code&gt;. A lab note contains an unescaped pipe. The integration engine rejects the message, and it sits in the queue until an engineer opens a hex dump, decodes the schema violation, writes a one-off script, and resubmits — days later, if at all.&lt;/p&gt;

&lt;p&gt;SynapseHealer replaces that manual bottleneck with an autonomous pipeline on InterSystems IRIS AI Hub: a custom inbound adapter, native vector search over repair runbooks, a governed &lt;code&gt;%AI.Agent&lt;/code&gt;, and a tri-branch router that auto-heals, escalates to the InterSystems Workflow Engine, or quarantines.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. AI Hub experience: DeadLetterHealerBP orchestrates the agent
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Synapse.Process.DeadLetterHealerBP&lt;/code&gt; is the arbitrator. &lt;code&gt;OnRequest&lt;/code&gt; takes a &lt;code&gt;Synapse.Msg.DeadLetterRequest&lt;/code&gt; from &lt;code&gt;ChaosIngestService&lt;/code&gt;, and &lt;code&gt;ProcessDeadLetter&lt;/code&gt; picks the execution mode: &lt;code&gt;live&lt;/code&gt; when &lt;code&gt;SYNAPSE_MODE=live&lt;/code&gt; and an API key exists, otherwise &lt;code&gt;replay&lt;/code&gt; — a deterministic mode that needs zero API keys.&lt;/p&gt;

&lt;p&gt;In live mode it instantiates &lt;code&gt;Synapse.Agent.DeadLetterHealerAgent&lt;/code&gt;, an &lt;code&gt;%AI.Agent&lt;/code&gt; bound to &lt;code&gt;Synapse.Agent.HealerToolSet&lt;/code&gt;, sends it the payload ID, source system, format, validation error, and raw body, strips any markdown fences, and parses the JSON contract: &lt;code&gt;decisionBranch&lt;/code&gt;, &lt;code&gt;confidenceScore&lt;/code&gt;, &lt;code&gt;riskLevel&lt;/code&gt;, &lt;code&gt;matchedPatternId&lt;/code&gt;, &lt;code&gt;healedPayload&lt;/code&gt;, &lt;code&gt;reasoning&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The agent cannot improvise. Its toolset — &lt;code&gt;Synapse.Agent.HealerToolSet&lt;/code&gt; (&lt;code&gt;%AI.ToolSet&lt;/code&gt;) wrapping &lt;code&gt;Synapse.Agent.HealerTools&lt;/code&gt; (&lt;code&gt;%AI.Tool&lt;/code&gt;) — exposes exactly three governed calls: &lt;code&gt;SearchRunbookRAG&lt;/code&gt;, &lt;code&gt;ValidateRepairedPayload&lt;/code&gt;, and &lt;code&gt;CalculateRiskScore&lt;/code&gt;. It looks up the nearest verified runbook in the 384-dimensional vector index (&lt;code&gt;VECTOR_COSINE&lt;/code&gt;, sub-45ms), applies the deterministic transformation, and must pass validation before anything is resubmitted.&lt;/p&gt;

&lt;p&gt;Credentials never appear in plaintext logs. &lt;code&gt;Synapse.Config.AIHubSetup.StoreWalletSecret&lt;/code&gt; writes the API key into the IRIS Wallet (&lt;code&gt;%Wallet.KeyValue&lt;/code&gt;, collection &lt;code&gt;SynapseSecrets&lt;/code&gt;, key &lt;code&gt;SynapseSecrets.LLMKey&lt;/code&gt;) at startup, and &lt;code&gt;BuildProviderSettings&lt;/code&gt; references it through &lt;code&gt;@{env:LLM_API_KEY}&lt;/code&gt; indirection instead of embedding the literal key. The same setup registers &lt;code&gt;%ConfigStore&lt;/code&gt; and &lt;code&gt;Ens.Config.Credentials&lt;/code&gt; when those classes exist, with graceful fallback on builds that lack them.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Models and cost control
&lt;/h2&gt;

&lt;p&gt;We default to &lt;code&gt;gemini-1.5-flash&lt;/code&gt; (&lt;code&gt;gpt-4o-mini&lt;/code&gt; is the OpenAI alternative). Heal decisions are structural, not creative, so a fast, cheap model is the right choice.&lt;/p&gt;

&lt;p&gt;Every inference lands in &lt;code&gt;Synapse.Data.AuditTelemetry&lt;/code&gt;, a persistent table storing prompt tokens, completion tokens, estimated USD cost, latency, the full tool-call trace, decision branch, risk level, and workflow status. Cost is computed from the counts — &lt;code&gt;prompt × 0.00000015 + completion × 0.0000006&lt;/code&gt; — and written to the table in real time; the Next.js dashboard reads &lt;code&gt;/api/synapse/status&lt;/code&gt; and shows the cumulative USD counter and auto-heal rate live.&lt;/p&gt;

&lt;p&gt;Across our 10 regression suites: 479 prompt tokens, 176 completion tokens, $0.00018 per heal, ~145 ms end to end, 90% auto-heal rate across the seven canonical chaos scenarios. Replay mode consumes no tokens, and the telemetry table is pre-seeded with golden traces for every scenario, so the dashboard is populated from the first second.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Observability and tracing: the three-step spine
&lt;/h2&gt;

&lt;p&gt;Each heal produces a governed three-step trace, stored in &lt;code&gt;ToolTraceJSON&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;SearchRunbookRAG&lt;/code&gt; — error and format in, matched runbook and similarity out (~42 ms)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ValidateRepairedPayload&lt;/code&gt; — strict HL7 v2 / JSON syntax and schema check (~56 ms)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CalculateRiskScore&lt;/code&gt; — clinical and financial risk classification (~35 ms)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The trace is surfaced live in the Next.js console: a step gauge per call, side-by-side diff of the corrupted and healed payloads, and the agent's reasoning. &lt;code&gt;HUMAN_WORKFLOW&lt;/code&gt; messages land in the workflow queue where an operator Approves (→ &lt;code&gt;ResubmitDeliveryOp&lt;/code&gt;) or Rejects (→ &lt;code&gt;QuarantineVaultOp&lt;/code&gt;) with reviewer notes. Everything is queryable via &lt;code&gt;/api/synapse/workflow/tasks&lt;/code&gt; and the persistent audit ledger.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. IRIS agentic development: MCP build tooling, guardrails, %AI syntax, and IPM packaging
&lt;/h2&gt;

&lt;p&gt;We separated development-time agentic tooling from runtime governance. During development, we paired our IDE with the &lt;code&gt;iris-agentic-dev&lt;/code&gt; MCP toolkit (&lt;code&gt;iris_symbols_local&lt;/code&gt; for local AST verification across 150+ symbols and &lt;code&gt;objectscript-guardrails&lt;/code&gt; to enforce method-scoped &lt;code&gt;Quit&lt;/code&gt; rules and &lt;code&gt;$IsObject&lt;/code&gt; checks before container compilation). At runtime inside the container, governance is 100% native to IRIS AI Hub—powered by an &lt;code&gt;%AI.ToolSet&lt;/code&gt; of &lt;code&gt;%AI.Tool&lt;/code&gt; methods rather than an external sidecar.&lt;/p&gt;

&lt;p&gt;The ObjectScript guardrails are the part I trust most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every class is &lt;code&gt;ProcedureBlock&lt;/code&gt;, and the business process checks &lt;code&gt;%Dictionary.CompiledClass.%ExistsId&lt;/code&gt; before instantiating the agent, so a missing compile fails closed instead of guessing.&lt;/li&gt;
&lt;li&gt;The agent's system prompt enforces a response contract: one JSON document with fixed fields, no prose.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ValidateRepairedPayload&lt;/code&gt; rejects messages that don't start with &lt;code&gt;MSH&lt;/code&gt;, put &lt;code&gt;PV1&lt;/code&gt; before &lt;code&gt;PID&lt;/code&gt;, use non-&lt;code&gt;YYYYMMDD&lt;/code&gt; dates in &lt;code&gt;PID-7&lt;/code&gt;, leave unescaped pipes in &lt;code&gt;OBX&lt;/code&gt;, or retain legacy keys like &lt;code&gt;client_uuid&lt;/code&gt; after a v2 migration. &lt;code&gt;CalculateRiskScore&lt;/code&gt; quarantines anything matching &lt;code&gt;&amp;lt;script&lt;/code&gt;, &lt;code&gt;eval(&lt;/code&gt;, &lt;code&gt;union select&lt;/code&gt;, &lt;code&gt;drop table&lt;/code&gt;, &lt;code&gt;--&lt;/code&gt;, or &lt;code&gt;javascript:&lt;/code&gt;, and escalates impossible dates like February 31 to human review.&lt;/li&gt;
&lt;li&gt;We learned the container-startup &lt;code&gt;&amp;lt;DIRECTORY&amp;gt;&lt;/code&gt; bug the hard way: &lt;code&gt;Config.Databases.Create&lt;/code&gt; registers the database in &lt;code&gt;iris.cpf&lt;/code&gt; but does not format the physical &lt;code&gt;IRIS.DAT&lt;/code&gt; file, crashing auto-start on restart. The fix: a declarative &lt;code&gt;merge.cpf&lt;/code&gt; (&lt;code&gt;[Actions]&lt;/code&gt;: &lt;code&gt;CreateDatabase&lt;/code&gt;, &lt;code&gt;CreateNamespace&lt;/code&gt;, &lt;code&gt;Interop=1&lt;/code&gt;) plus an &lt;code&gt;iris.script&lt;/code&gt; fallback that initializes &lt;code&gt;IRIS.DAT&lt;/code&gt; via &lt;code&gt;SYS.Database&lt;/code&gt; when absent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For %AI syntax, the agent resolves its provider via &lt;code&gt;AIHubSetup.GetProviderConfig&lt;/code&gt; and &lt;code&gt;BuildProviderSettings&lt;/code&gt;, creates &lt;code&gt;%AI.Provider&lt;/code&gt;, calls &lt;code&gt;agent.CreateSession()&lt;/code&gt; then &lt;code&gt;agent.Chat(session, prompt)&lt;/code&gt;, and parses the result with &lt;code&gt;%DynamicObject.%FromJSON&lt;/code&gt;. It compiled cleanly on the IRIS 2027.1 AI Hub EAP build.&lt;/p&gt;

&lt;p&gt;Packaging is automated: &lt;code&gt;module.xml&lt;/code&gt; declares &lt;code&gt;&amp;lt;SystemRequirements Version="&amp;gt;=2026.3" Interoperability="enabled"/&amp;gt;&lt;/code&gt;, and &lt;code&gt;SetupAll&lt;/code&gt; — run by IPM on install — executes &lt;code&gt;Configure()&lt;/code&gt; (Wallet, config store, credentials), seeds the runbooks and replay telemetry, then starts &lt;code&gt;Synapse.Production&lt;/code&gt;. &lt;code&gt;zpm install synapse-healer&lt;/code&gt; or &lt;code&gt;zpm load /opt/irisapp -v&lt;/code&gt; gives you a running production with a seeded dashboard. The module shipped with +11 contest bonus points across the custom adapter, embedded Python, vector search, workflow engine, and IPM integration.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Prerequisite: Load the InterSystems AI Hub EAP tarball (Build 109 or 154)&lt;/span&gt;
&lt;span class="c"&gt;# docker image load -i iris-community-2027.1.0AI.109.0-docker.tar.gz&lt;/span&gt;

git clone https://github.com/josephjbassey/synapse-healer.git
&lt;span class="nb"&gt;cd &lt;/span&gt;synapse-healer
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;ui &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:3000&lt;/code&gt;, press 1–7 to inject chaos payloads, and watch the pipeline heal them. No API key required; set &lt;code&gt;SYNAPSE_MODE=live&lt;/code&gt; with an &lt;code&gt;LLM_API_KEY&lt;/code&gt; for live AI Hub inference.&lt;/p&gt;

&lt;p&gt;It's not magic. It's governed tool calls, deterministic validation, and a telemetry table that actually gets read.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>interoperability</category>
      <category>vectorsearch</category>
      <category>intersystemsiris</category>
    </item>
    <item>
      <title>Restoring Academic Due Process: How We Built Margin with Next.js 16 and Clocked AI</title>
      <dc:creator>John Joseph Bassey</dc:creator>
      <pubDate>Thu, 22 Oct 2026 12:35:48 +0000</pubDate>
      <link>https://dev.to/josephjbassey/restoring-academic-due-process-how-we-built-margin-with-nextjs-16-and-clocked-ai-19pl</link>
      <guid>https://dev.to/josephjbassey/restoring-academic-due-process-how-we-built-margin-with-nextjs-16-and-clocked-ai-19pl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"An 87% AI probability score is not evidence. It is an expulsion notice without due process."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the age of large language models (LLMs), universities face an academic integrity crisis. Commercial AI detectors produce opaque, probabilistic verdicts that can disproportionately affect non-native English speakers, trigger flawed disciplinary proceedings, and erode trust between students and faculty.&lt;/p&gt;

&lt;p&gt;Meanwhile, traditional plagiarism checkers focus on finding copied passages across the public web. They can miss &lt;strong&gt;intra-cohort collusion&lt;/strong&gt; (two students in the same seminar sharing work) and &lt;strong&gt;ungrounded factual claims&lt;/strong&gt;, including fabricated research papers, invented benchmarks, and unsupported assertions.&lt;/p&gt;

&lt;p&gt;We built &lt;strong&gt;Margin&lt;/strong&gt; for the &lt;strong&gt;Clocked Build Challenge 2026&lt;/strong&gt; to address these problems.&lt;/p&gt;

&lt;p&gt;Margin is an academic review system that helps course conveners and lecturers examine batches of student submissions using a transparent, evidence-first workflow.&lt;/p&gt;

&lt;p&gt;Our guiding principle is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The machine flags; the educator decides.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why We Built Margin with Clocked AI
&lt;/h2&gt;

&lt;p&gt;Margin uses Clocked's inference endpoints to build an evidentiary pipeline that helps educators investigate potential inconsistencies without treating AI-generated scores as proof of misconduct.&lt;/p&gt;

&lt;p&gt;Here is how the system works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Student Manuscripts (.txt / .docx)
              |
              v
    1. Clocked Protect
       Remove direct identifiers
              |
              v
     2. Clocked Compare
       Compare submissions pairwise
              |
              v
      3. Clocked Verify
       Ground claims in course materials
              |
              v
       4. Clocked Rerank
       Prioritize supporting evidence
              |
              v
      Human Reviewer Ledger
       Compare evidence and record decisions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F5rhw3yuxhcuqn15zjitg.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%2F5rhw3yuxhcuqn15zjitg.png" alt="Margin Side-by-Side Review Sheet" width="800" height="732"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 1: The tactile side-by-side verification sheet highlighting contradictory empirical findings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Each stage produces information for human review rather than an automatic academic misconduct verdict.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Privacy-Conscious Ingestion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;POST /clocked/pii&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Before submissions enter the comparison workflow, Margin sends them through Clocked Protect to identify and remove direct identifiers such as student names, matriculation numbers, and email addresses.&lt;/p&gt;

&lt;p&gt;The system then uses anonymous tokens such as &lt;code&gt;S-01&lt;/code&gt; and &lt;code&gt;S-02&lt;/code&gt; to distinguish submissions throughout the downstream workflow.&lt;/p&gt;

&lt;p&gt;This design helps reduce the influence of identifying information during evidence review and supports a more privacy-conscious assessment process.&lt;/p&gt;

&lt;p&gt;An important distinction: removing direct identifiers is a privacy safeguard, not a guarantee of FERPA compliance. Actual compliance depends on the complete system, its data handling, institutional obligations, and applicable law.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Pairwise Collision and Contradiction Analysis
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;POST /clocked/compare&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Instead of relying exclusively on public-web plagiarism searches, Margin compares submissions within the same cohort.&lt;/p&gt;

&lt;p&gt;For a group of (n) submissions, the number of unique pairs is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;n × (n - 1) / 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fihjzqrgw0fngz0bfeuw4.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%2Fihjzqrgw0fngz0bfeuw4.png" alt="Margin Pairwise Overlap Review" width="512" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 2: Pairwise review interface sorting direct contradictions to the top with pen-wash highlights.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The comparison pipeline looks for two important patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contradictions:&lt;/strong&gt; Direct factual inconsistencies between submissions. For example, two papers might describe an apparently identical experiment but report 45 and 120 iterations, respectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared facts and near-duplicates:&lt;/strong&gt; Similar reasoning or overlapping passages that may warrant closer inspection. Margin uses pen-wash highlights to make relevant text easier to compare.&lt;/p&gt;

&lt;p&gt;These signals are leads for investigation, not proof of copying. Similarity can have legitimate explanations, and contradictory results can arise from different methods, assumptions, or reporting errors.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Syllabus-Grounded Verification
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;POST /clocked/grounding&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A submission can sound convincing while containing unsupported claims. Margin addresses this by checking student assertions against the course syllabus or assigned reading pack.&lt;/p&gt;

&lt;p&gt;Claims are classified into three categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;supported&lt;/code&gt; — evidence in the supplied course materials supports the claim.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;partial&lt;/code&gt; — the materials provide incomplete or qualified support.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unsupported&lt;/code&gt; — the supplied materials do not provide sufficient support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unsupported claims are prioritized for faculty review.&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%2F5mx245vjw179feaqomi4.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%2F5mx245vjw179feaqomi4.png" alt="Margin Claims Check Grounding" width="512" height="428"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 3: Claims check interface validating student statements directly against the course syllabus.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The distinction matters: a claim that cannot be verified against a particular reading pack is not necessarily false. It may require another source, additional context, or a more careful interpretation.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Citation Triage and Evidence Prioritization
&lt;/h2&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%2Ftsnqauw4jcwzbvx8rdfb.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%2Ftsnqauw4jcwzbvx8rdfb.png" alt="Margin Decisions Summary and Audit Ledger" width="512" height="397"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 4: The faculty decision ledger with downloadable audit-ready Markdown report.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;POST /clocked/rerank&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once Margin identifies claims that need further investigation, Clocked Rerank helps evaluate relevant reading-pack excerpts and determine how useful each piece of context is.&lt;/p&gt;

&lt;p&gt;The triage process assigns one of three actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;use&lt;/code&gt; — the evidence is relevant enough to include in the review.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;expand&lt;/code&gt; — additional surrounding context may be necessary.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;skip&lt;/code&gt; — the excerpt is unlikely to help resolve the claim.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps reviewers focus on meaningful evidence instead of manually inspecting every passage with equal priority.&lt;/p&gt;

&lt;p&gt;The final step is the &lt;strong&gt;Human Reviewer Ledger&lt;/strong&gt;, where educators can examine submissions side by side, inspect character-offset evidence, and record their own decisions.&lt;/p&gt;
&lt;h2&gt;
  
  
  What We Learned: Engineering Margin for Reliability
&lt;/h2&gt;

&lt;p&gt;Building an application around an AI API involves more than connecting endpoints. We also had to consider API costs, repeated requests, concurrency, and failure handling.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Guarding Against the O(n²) Pair Explosion
&lt;/h3&gt;

&lt;p&gt;Consider a seminar containing 30 student submissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;30 × 29 / 2 = 435 unique comparisons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Making hundreds of API calls for a single batch can become expensive quickly.&lt;/p&gt;

&lt;p&gt;We introduced two safeguards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local n-gram pre-filtering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Submissions are tokenized into character n-grams in memory. Pairs with no detected vocabulary overlap can be pruned before making an API request, reducing unnecessary calls.&lt;/p&gt;

&lt;p&gt;This is a cost-saving heuristic, not a definitive test of whether two submissions are related. It must be interpreted accordingly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The MAX_PAIRS guard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The interface displays a live estimate of the number of comparisons required. A server-side limit, configured through &lt;code&gt;MAX_PAIRS&lt;/code&gt; with a default of &lt;code&gt;20&lt;/code&gt;, prevents unexpectedly large batches from proceeding without an appropriate limit configuration.&lt;/p&gt;

&lt;p&gt;This adds a second line of defence against accidental credit depletion.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Deterministic Content-Hash Disk Cache
&lt;/h3&gt;

&lt;p&gt;Repeated development requests should not needlessly consume API credits.&lt;/p&gt;

&lt;p&gt;To address this, we implemented a file-backed cache under &lt;code&gt;clocked_cache/&lt;/code&gt; using SHA-256 content hashes.&lt;/p&gt;

&lt;p&gt;The cache-key function looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;computeCacheKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serialized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;canonicalJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;serialized&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;canonicalJson&lt;/code&gt; helper recursively sorts JSON object keys before serialization. This means equivalent payloads produce the same cache key regardless of object-key insertion order.&lt;/p&gt;

&lt;p&gt;We also implemented a strict &lt;strong&gt;Never-Cache-Error&lt;/strong&gt; policy. Transient failures are not stored as successful cache results, allowing subsequent requests to retry rather than reusing stale errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Concurrency Limits, Backoff, and Jitter
&lt;/h3&gt;

&lt;p&gt;Unrestricted parallel requests can overwhelm an external API or cause avoidable rate-limit failures.&lt;/p&gt;

&lt;p&gt;Margin wraps outbound requests in a four-worker concurrency pool using &lt;code&gt;p-limit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For HTTP 429 and 5xx responses, the retry strategy uses exponential backoff with randomized jitter. This spaces retries out and reduces the likelihood that simultaneous requests will repeatedly collide with the same rate limit.&lt;/p&gt;

&lt;p&gt;Together, these measures make API usage more controlled and predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design System: Why Paper, Ink, and Cobalt?
&lt;/h2&gt;

&lt;p&gt;We deliberately avoided another dark dashboard filled with purple gradients and neon effects.&lt;/p&gt;

&lt;p&gt;Margin uses a tactile &lt;strong&gt;Paper–Ink–Cobalt&lt;/strong&gt; design language inspired by printed examination scripts, annotated documents, and academic journals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Warm Paper — &lt;code&gt;#F4F1EA&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The background evokes physical exam scripts, term papers, and archival documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deep Ink — &lt;code&gt;#101426&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One-pixel borders and hard shadows, such as &lt;code&gt;3px 3px 0 #101426&lt;/code&gt;, create a sense of physical depth and make interface elements feel deliberate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Translucent Pen-Wash — &lt;code&gt;#C5CEFF&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Evidence highlights use an inset box shadow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;box-shadow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;inset&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="nt"&gt;-0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nt"&gt;em&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--wash&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The effect resembles a professor's highlighter passing over a relevant passage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No UI framework bloat&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The interface uses vanilla CSS custom properties rather than Tailwind or an external UI component library.&lt;/p&gt;

&lt;p&gt;The result is a focused, document-oriented experience where evidence and reviewer decisions take priority over decorative dashboard elements.&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%2F5rhw3yuxhcuqn15zjitg.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%2F5rhw3yuxhcuqn15zjitg.png" alt="Margin — The tool flags. The lecturer decides." width="800" height="732"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  One-Click Judge Mode and Reproducibility
&lt;/h2&gt;

&lt;p&gt;We wanted judges and developers to evaluate Margin without unnecessary setup friction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One-click judge access&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The landing page includes a &lt;strong&gt;⚖️ Judge Access&lt;/strong&gt; option that authenticates the reviewer into a pre-seeded GNS102 Informatics &amp;amp; Formal Methods batch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Offline mock engine&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;CLOCKED_API_KEY&lt;/code&gt; is not configured, Margin falls back to deterministic, precomputed fixture data. This allows developers and judges to explore the workflow without live API credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated tests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The project includes 34 automated tests across six test suites, run through Node.js's native test runner using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These features make the application easier to evaluate, reproduce, and develop locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Margin Yourself
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/Josephjbassey/margin-review" rel="noopener noreferrer"&gt;github.com/Josephjbassey/margin-review&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clone the project and start the development server:&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/Josephjbassey/margin-review.git
&lt;span class="nb"&gt;cd &lt;/span&gt;margin-review
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run seed
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can explore the application with the offline mock engine when &lt;code&gt;CLOCKED_API_KEY&lt;/code&gt; is omitted. Live Clocked API functionality requires the appropriate credentials and configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Academic integrity tools should help educators ask better questions, not replace their judgment with a probability score.&lt;/p&gt;

&lt;p&gt;Margin explores a different approach: compare submissions within their actual cohort, check claims against assigned materials, surface relevant evidence, and give educators the context they need to make informed decisions.&lt;/p&gt;

&lt;p&gt;There are still difficult questions around privacy, false positives, interpretation, and the limits of automated analysis. Those questions deserve to be part of the design process, not an afterthought.&lt;/p&gt;

&lt;p&gt;Our goal is not to automate accusations. It is to make academic review more transparent, evidence-based, and fair.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built by Joseph John Bassey for the Clocked Build Challenge 2026.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Explore the code: &lt;a href="https://github.com/Josephjbassey/margin-review" rel="noopener noreferrer"&gt;Margin on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>clockedchallenge</category>
      <category>ai</category>
      <category>webdev</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>John Joseph Bassey</dc:creator>
      <pubDate>Thu, 09 Jul 2026 22:52:16 +0000</pubDate>
      <link>https://dev.to/josephjbassey/-5hlo</link>
      <guid>https://dev.to/josephjbassey/-5hlo</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/josephjbassey/i-got-tired-of-django-being-left-behind-in-ui-so-i-built-a-shadcnui-equivalent-3b6e" class="crayons-story__hidden-navigation-link"&gt;I got tired of Django being left behind in UI, so I built a shadcn/ui equivalent.&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/josephjbassey" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F4023286%2Fd7825d80-62d5-4f32-9137-baec0f9d2260.png" alt="josephjbassey profile" class="crayons-avatar__image" width="204" height="204"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/josephjbassey" class="crayons-story__secondary fw-medium m:hidden"&gt;
              John Joseph Bassey
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                John Joseph Bassey
                
                
              
              &lt;div id="story-author-preview-content-4109034" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/josephjbassey" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F4023286%2Fd7825d80-62d5-4f32-9137-baec0f9d2260.png" class="crayons-avatar__image" alt="" width="204" height="204"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;John Joseph Bassey&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/josephjbassey/i-got-tired-of-django-being-left-behind-in-ui-so-i-built-a-shadcnui-equivalent-3b6e" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 9&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/josephjbassey/i-got-tired-of-django-being-left-behind-in-ui-so-i-built-a-shadcnui-equivalent-3b6e" id="article-link-4109034"&gt;
          I got tired of Django being left behind in UI, so I built a shadcn/ui equivalent.
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/django"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;django&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/llm"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;llm&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/josephjbassey/i-got-tired-of-django-being-left-behind-in-ui-so-i-built-a-shadcnui-equivalent-3b6e" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/josephjbassey/i-got-tired-of-django-being-left-behind-in-ui-so-i-built-a-shadcnui-equivalent-3b6e#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
          
          &lt;div class="only-sidebar-menu-item trusted-visible-block print-hidden align-center"&gt;
                
                    
                
          &lt;/div&gt;

        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>I got tired of Django being left behind in UI, so I built a shadcn/ui equivalent.</title>
      <dc:creator>John Joseph Bassey</dc:creator>
      <pubDate>Thu, 09 Jul 2026 22:48:29 +0000</pubDate>
      <link>https://dev.to/josephjbassey/i-got-tired-of-django-being-left-behind-in-ui-so-i-built-a-shadcnui-equivalent-3b6e</link>
      <guid>https://dev.to/josephjbassey/i-got-tired-of-django-being-left-behind-in-ui-so-i-built-a-shadcnui-equivalent-3b6e</guid>
      <description>&lt;p&gt;For years, the React and Next.js ecosystems have had a massive advantage: premium, plug-and-play UI components. Tools like shadcn/ui completely changed how developers build interfaces by offering beautifully styled, accessible components with zero vendor lock-in.&lt;/p&gt;

&lt;p&gt;Meanwhile, if you were building a monolith with Django, htmx, and Alpine.js, you were left out in the cold. You either had to wire up custom HTML/CSS from scratch, fight with the complex configurations of heavy runtime libraries, or rely on locked pip packages where changing a simple button color required CSS overrides or forking a repo.&lt;/p&gt;

&lt;p&gt;I realized Django didn't need another heavy library. It needed a delivery system.&lt;/p&gt;

&lt;p&gt;Enter Djinn UI.&lt;/p&gt;

&lt;p&gt;Djinn UI (available now on PyPI) is a CLI-based component registry for Django. It brings the copy-paste ownership model directly to your Python backend.&lt;/p&gt;

&lt;p&gt;How it works:&lt;br&gt;
Instead of adding a dependency to your INSTALLED_APPS, you simply run:&lt;br&gt;
djinn add dashboard&lt;/p&gt;

&lt;p&gt;Djinn drops the raw, perfectly styled HTML and Tailwind code directly into your templates/ folder. It uses native&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="cp"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tags. No custom syntax to learn, no runtime overhead. It is your code, and you own it completely.&lt;/p&gt;

&lt;p&gt;Built for the Agentic Era:&lt;br&gt;
We aren't just catching up to React; we are jumping ahead. Djinn UI is the first Django UI system built with AI in mind. It ships with a built-in MCP server. If you use tools like Cursor, you can simply say, "Build a pricing page using my Djinn components," and watch your AI agent scaffold your UI seamlessly.&lt;/p&gt;

&lt;p&gt;Stop wasting weeks building components. Reclaim the power of the monolith.&lt;/p&gt;

&lt;p&gt;Try it out: pip install djinn-ui&lt;br&gt;
Check out the pypi package here: &lt;a href="https://pypi.org/project/djinn-ui/" rel="noopener noreferrer"&gt;https://pypi.org/project/djinn-ui/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>django</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
